Changes in kernel/arch/amd64/src/ddi/ddi.c [9d58539:6eeb4a3] in mainline
- File:
-
- 1 edited
-
kernel/arch/amd64/src/ddi/ddi.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/amd64/src/ddi/ddi.c
r9d58539 r6eeb4a3 42 42 #include <errno.h> 43 43 #include <arch/cpu.h> 44 #include <cpu.h> 44 45 #include <arch.h> 45 46 #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 }107 47 108 48 /** Install I/O Permission bitmap. … … 118 58 /* First, copy the I/O Permission Bitmap. */ 119 59 irq_spinlock_lock(&TASK->lock, false); 60 120 61 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); 124 66 125 67 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); 129 71 130 72 /* … … 132 74 * I/O access. 133 75 */ 134 bitmap_set_range(&iomap, bits, ALIGN_UP(bits, 8) - bits); 76 bitmap_set_range(&iomap, elements, 77 ALIGN_UP(elements, 8) - elements); 78 135 79 /* 136 80 * It is safe to set the trailing eight bits because of the 137 81 * extra convenience byte in TSS_IOMAP_SIZE. 138 82 */ 139 bitmap_set_range(&iomap, ALIGN_UP( bits, 8), 8);83 bitmap_set_range(&iomap, ALIGN_UP(elements, 8), 8); 140 84 } 85 141 86 irq_spinlock_unlock(&TASK->lock, false); 142 87 143 88 /* 144 89 * Second, adjust TSS segment limit. 145 * Take the extra ending byte wi ll all bits set into account.90 * Take the extra ending byte with all bits set into account. 146 91 */ 147 92 ptr_16_64_t cpugdtr; … … 149 94 150 95 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); 152 98 gdtr_load(&cpugdtr); 153 99
Note:
See TracChangeset
for help on using the changeset viewer.
