Changeset 7de18418 in mainline for kernel/arch


Ignore:
Timestamp:
2013-09-08T10:34:41Z (12 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
29a3886
Parents:
063a74b9
Message:

partial implementation of a two-level bitmap data structure

Location:
kernel/arch
Files:
5 edited

Legend:

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

    r063a74b9 r7de18418  
    4242#include <errno.h>
    4343#include <arch/cpu.h>
     44#include <cpu.h>
    4445#include <arch.h>
    4546#include <align.h>
     
    5859int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
    5960{
    60         size_t bits = ioaddr + size;
    61         if (bits > IO_PORTS)
     61        size_t elements = ioaddr + size;
     62        if (elements > IO_PORTS)
    6263                return ENOENT;
    6364       
    64         if (task->arch.iomap.bits < bits) {
     65        if (task->arch.iomap.elements < elements) {
    6566                /*
    6667                 * The I/O permission bitmap is too small and needs to be grown.
    6768                 */
    6869               
    69                 uint8_t *newmap = (uint8_t *) malloc(BITS2BYTES(bits), FRAME_ATOMIC);
    70                 if (!newmap)
     70                void *store = malloc(bitmap_size(elements, 0), FRAME_ATOMIC);
     71                if (!store)
    7172                        return ENOMEM;
    7273               
    7374                bitmap_t oldiomap;
    74                 bitmap_initialize(&oldiomap, task->arch.iomap.map,
     75                bitmap_initialize(&oldiomap, task->arch.iomap.elements, 0,
    7576                    task->arch.iomap.bits);
    76                 bitmap_initialize(&task->arch.iomap, newmap, bits);
     77               
     78                bitmap_initialize(&task->arch.iomap, elements, 0, store);
    7779               
    7880                /*
    7981                 * Mark the new range inaccessible.
    8082                 */
    81                 bitmap_set_range(&task->arch.iomap, oldiomap.bits,
    82                     bits - oldiomap.bits);
     83                bitmap_set_range(&task->arch.iomap, oldiomap.elements,
     84                    elements - oldiomap.elements);
    8385               
    8486                /*
     
    8890                if (oldiomap.bits) {
    8991                        bitmap_copy(&task->arch.iomap, &oldiomap,
    90                             oldiomap.bits);
    91                         free(oldiomap.map);
     92                            oldiomap.elements);
     93                       
     94                        free(oldiomap.bits);
    9295                }
    9396        }
     
    9699         * Enable the range and we are done.
    97100         */
    98         bitmap_clear_range(&task->arch.iomap, (size_t) ioaddr, (size_t) size);
     101        bitmap_clear_range(&task->arch.iomap, (size_t) ioaddr, size);
    99102       
    100103        /*
     
    118121        /* First, copy the I/O Permission Bitmap. */
    119122        irq_spinlock_lock(&TASK->lock, false);
     123       
    120124        size_t ver = TASK->arch.iomapver;
    121         size_t bits = TASK->arch.iomap.bits;
    122         if (bits) {
    123                 ASSERT(TASK->arch.iomap.map);
     125        size_t elements = TASK->arch.iomap.elements;
     126       
     127        if (elements > 0) {
     128                ASSERT(TASK->arch.iomap.bits);
    124129               
    125130                bitmap_t iomap;
    126                 bitmap_initialize(&iomap, CPU->arch.tss->iomap,
    127                     TSS_IOMAP_SIZE * 8);
    128                 bitmap_copy(&iomap, &TASK->arch.iomap, bits);
     131                bitmap_initialize(&iomap, TSS_IOMAP_SIZE * 8, 0,
     132                    CPU->arch.tss->iomap);
     133                bitmap_copy(&iomap, &TASK->arch.iomap, elements);
    129134               
    130135                /*
     
    132137                 * I/O access.
    133138                 */
    134                 bitmap_set_range(&iomap, bits, ALIGN_UP(bits, 8) - bits);
     139                bitmap_set_range(&iomap, elements,
     140                    ALIGN_UP(elements, 8) - elements);
     141               
    135142                /*
    136143                 * It is safe to set the trailing eight bits because of the
    137144                 * extra convenience byte in TSS_IOMAP_SIZE.
    138145                 */
    139                 bitmap_set_range(&iomap, ALIGN_UP(bits, 8), 8);
     146                bitmap_set_range(&iomap, ALIGN_UP(elements, 8), 8);
    140147        }
     148       
    141149        irq_spinlock_unlock(&TASK->lock, false);
    142150       
    143151        /*
    144152         * Second, adjust TSS segment limit.
    145          * Take the extra ending byte will all bits set into account.
     153         * Take the extra ending byte with all bits set into account.
    146154         */
    147155        ptr_16_64_t cpugdtr;
     
    149157       
    150158        descriptor_t *gdt_p = (descriptor_t *) cpugdtr.base;
    151         gdt_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + BITS2BYTES(bits));
     159        size_t size = bitmap_size(elements, 0);
     160        gdt_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + size);
    152161        gdtr_load(&cpugdtr);
    153162       
  • kernel/arch/amd64/src/proc/task.c

    r063a74b9 r7de18418  
    3434
    3535#include <proc/task.h>
     36#include <typedefs.h>
     37#include <adt/bitmap.h>
    3638#include <mm/slab.h>
    37 #include <typedefs.h>
    3839
    3940/** Perform amd64 specific task initialization.
     
    4546{
    4647        task->arch.iomapver = 0;
    47         bitmap_initialize(&task->arch.iomap, NULL, 0);
     48        bitmap_initialize(&task->arch.iomap, 0, 0, NULL);
    4849}
    4950
     
    5556void task_destroy_arch(task_t *task)
    5657{
    57         if (task->arch.iomap.map)
    58                 free(task->arch.iomap.map);
     58        if (task->arch.iomap.bits != NULL)
     59                free(task->arch.iomap.bits);
    5960}
    6061
  • kernel/arch/ia32/src/ddi/ddi.c

    r063a74b9 r7de18418  
    5959int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
    6060{
    61         size_t bits = ioaddr + size;
    62         if (bits > IO_PORTS)
     61        size_t elements = ioaddr + size;
     62        if (elements > IO_PORTS)
    6363                return ENOENT;
    6464       
    65         if (task->arch.iomap.bits < bits) {
     65        if (task->arch.iomap.elements < elements) {
    6666                /*
    6767                 * The I/O permission bitmap is too small and needs to be grown.
    6868                 */
    6969               
    70                 uint8_t *newmap = (uint8_t *) malloc(BITS2BYTES(bits), FRAME_ATOMIC);
    71                 if (!newmap)
     70                void *store = malloc(bitmap_size(elements, 0), FRAME_ATOMIC);
     71                if (!store)
    7272                        return ENOMEM;
    7373               
    7474                bitmap_t oldiomap;
    75                 bitmap_initialize(&oldiomap, task->arch.iomap.map,
     75                bitmap_initialize(&oldiomap, task->arch.iomap.elements, 0,
    7676                    task->arch.iomap.bits);
    77                 bitmap_initialize(&task->arch.iomap, newmap, bits);
     77               
     78                bitmap_initialize(&task->arch.iomap, elements, 0, store);
    7879               
    7980                /*
    8081                 * Mark the new range inaccessible.
    8182                 */
    82                 bitmap_set_range(&task->arch.iomap, oldiomap.bits,
    83                     bits - oldiomap.bits);
     83                bitmap_set_range(&task->arch.iomap, oldiomap.elements,
     84                    elements - oldiomap.elements);
    8485               
    8586                /*
     
    8990                if (oldiomap.bits) {
    9091                        bitmap_copy(&task->arch.iomap, &oldiomap,
    91                             oldiomap.bits);
    92                         free(oldiomap.map);
     92                            oldiomap.elements);
     93                       
     94                        free(oldiomap.bits);
    9395                }
    9496        }
     
    9799         * Enable the range and we are done.
    98100         */
    99         bitmap_clear_range(&task->arch.iomap, (size_t) ioaddr, (size_t) size);
     101        bitmap_clear_range(&task->arch.iomap, (size_t) ioaddr, size);
    100102       
    101103        /*
     
    119121        /* First, copy the I/O Permission Bitmap. */
    120122        irq_spinlock_lock(&TASK->lock, false);
     123       
    121124        size_t ver = TASK->arch.iomapver;
    122         size_t bits = TASK->arch.iomap.bits;
    123         if (bits) {
    124                 ASSERT(TASK->arch.iomap.map);
     125        size_t elements = TASK->arch.iomap.elements;
     126       
     127        if (elements > 0) {
     128                ASSERT(TASK->arch.iomap.bits);
    125129               
    126130                bitmap_t iomap;
    127                 bitmap_initialize(&iomap, CPU->arch.tss->iomap,
    128                     TSS_IOMAP_SIZE * 8);
    129                 bitmap_copy(&iomap, &TASK->arch.iomap, bits);
     131                bitmap_initialize(&iomap, TSS_IOMAP_SIZE * 8, 0,
     132                    CPU->arch.tss->iomap);
     133                bitmap_copy(&iomap, &TASK->arch.iomap, elements);
    130134               
    131135                /*
     
    133137                 * I/O access.
    134138                 */
    135                 bitmap_set_range(&iomap, bits, ALIGN_UP(bits, 8) - bits);
     139                bitmap_set_range(&iomap, elements,
     140                    ALIGN_UP(elements, 8) - elements);
     141               
    136142                /*
    137143                 * It is safe to set the trailing eight bits because of the
    138144                 * extra convenience byte in TSS_IOMAP_SIZE.
    139145                 */
    140                 bitmap_set_range(&iomap, ALIGN_UP(bits, 8), 8);
     146                bitmap_set_range(&iomap, ALIGN_UP(elements, 8), 8);
    141147        }
     148       
    142149        irq_spinlock_unlock(&TASK->lock, false);
    143150       
     
    150157       
    151158        descriptor_t *gdt_p = (descriptor_t *) cpugdtr.base;
    152         gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + BITS2BYTES(bits));
     159        size_t size = bitmap_size(elements, 0);
     160        gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + size);
    153161        gdtr_load(&cpugdtr);
    154162       
  • kernel/arch/ia32/src/proc/task.c

    r063a74b9 r7de18418  
    4040/** Perform ia32 specific task initialization.
    4141 *
    42  * @param t Task to be initialized.
     42 * @param task Task to be initialized.
     43 *
    4344 */
    44 void task_create_arch(task_t *t)
     45void task_create_arch(task_t *task)
    4546{
    46         t->arch.iomapver = 0;
    47         bitmap_initialize(&t->arch.iomap, NULL, 0);
     47        task->arch.iomapver = 0;
     48        bitmap_initialize(&task->arch.iomap, 0, 0, NULL);
    4849}
    4950
    5051/** Perform ia32 specific task destruction.
    5152 *
    52  * @param t Task to be initialized.
     53 * @param task Task to be initialized.
     54 *
    5355 */
    54 void task_destroy_arch(task_t *t)
     56void task_destroy_arch(task_t *task)
    5557{
    56         if (t->arch.iomap.map)
    57                 free(t->arch.iomap.map);
     58        if (task->arch.iomap.bits != NULL)
     59                free(task->arch.iomap.bits);
    5860}
    5961
  • kernel/arch/ia64/src/ddi/ddi.c

    r063a74b9 r7de18418  
    5656{
    5757        if (!task->arch.iomap) {
    58                 uint8_t *map;
    59 
    6058                task->arch.iomap = malloc(sizeof(bitmap_t), 0);
    61                 map = malloc(BITS2BYTES(IO_MEMMAP_PAGES), 0);
    62                 if(!map)
     59                if (task->arch.iomap == NULL)
    6360                        return ENOMEM;
    64                 bitmap_initialize(task->arch.iomap, map, IO_MEMMAP_PAGES);
     61               
     62                void *store = malloc(bitmap_size(IO_MEMMAP_PAGES, 0), 0);
     63                if (store == NULL)
     64                        return ENOMEM;
     65               
     66                bitmap_initialize(task->arch.iomap, IO_MEMMAP_PAGES, 0, store);
    6567                bitmap_clear_range(task->arch.iomap, 0, IO_MEMMAP_PAGES);
    6668        }
     
    6971        size = ALIGN_UP(size + ioaddr - 4 * iopage, PORTS_PER_PAGE);
    7072        bitmap_set_range(task->arch.iomap, iopage, size / 4);
    71 
     73       
    7274        return 0;
    7375}
Note: See TracChangeset for help on using the changeset viewer.