Changes in kernel/arch/amd64/src/ddi/ddi.c [6eeb4a3:9d58539] 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
r6eeb4a3 r9d58539 42 42 #include <errno.h> 43 43 #include <arch/cpu.h> 44 #include <cpu.h>45 44 #include <arch.h> 46 45 #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 } 47 107 48 108 /** Install I/O Permission bitmap. … … 58 118 /* First, copy the I/O Permission Bitmap. */ 59 119 irq_spinlock_lock(&TASK->lock, false); 60 61 120 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); 121 size_t bits = TASK->arch.iomap.bits; 122 if (bits) { 123 ASSERT(TASK->arch.iomap.map); 66 124 67 125 bitmap_t iomap; 68 bitmap_initialize(&iomap, TSS_IOMAP_SIZE * 8,69 CPU->arch.tss->iomap);70 bitmap_copy(&iomap, &TASK->arch.iomap, elements);126 bitmap_initialize(&iomap, CPU->arch.tss->iomap, 127 TSS_IOMAP_SIZE * 8); 128 bitmap_copy(&iomap, &TASK->arch.iomap, bits); 71 129 72 130 /* … … 74 132 * I/O access. 75 133 */ 76 bitmap_set_range(&iomap, elements, 77 ALIGN_UP(elements, 8) - elements); 78 134 bitmap_set_range(&iomap, bits, ALIGN_UP(bits, 8) - bits); 79 135 /* 80 136 * It is safe to set the trailing eight bits because of the 81 137 * extra convenience byte in TSS_IOMAP_SIZE. 82 138 */ 83 bitmap_set_range(&iomap, ALIGN_UP( elements, 8), 8);139 bitmap_set_range(&iomap, ALIGN_UP(bits, 8), 8); 84 140 } 85 86 141 irq_spinlock_unlock(&TASK->lock, false); 87 142 88 143 /* 89 144 * Second, adjust TSS segment limit. 90 * Take the extra ending byte wi th all bits set into account.145 * Take the extra ending byte will all bits set into account. 91 146 */ 92 147 ptr_16_64_t cpugdtr; … … 94 149 95 150 descriptor_t *gdt_p = (descriptor_t *) cpugdtr.base; 96 size_t size = bitmap_size(elements); 97 gdt_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + size); 151 gdt_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + BITS2BYTES(bits)); 98 152 gdtr_load(&cpugdtr); 99 153
Note:
See TracChangeset
for help on using the changeset viewer.
