Changes in kernel/arch/ia32/src/ddi/ddi.c [da1bafb:d99c1d2] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/ia32/src/ddi/ddi.c
rda1bafb rd99c1d2 50 50 * Interrupts are disabled and task is locked. 51 51 * 52 * @param task 52 * @param task Task. 53 53 * @param ioaddr Startign I/O space address. 54 * @param size 54 * @param size Size of the enabled I/O range. 55 55 * 56 56 * @return 0 on success or an error code from errno.h. 57 *58 57 */ 59 58 int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size) 60 59 { 61 size_t bits = ioaddr + size; 60 size_t bits; 61 62 bits = ioaddr + size; 62 63 if (bits > IO_PORTS) 63 64 return ENOENT; 65 66 if (task->arch.iomap.bits < bits) { 67 bitmap_t oldiomap; 68 uint8_t *newmap; 64 69 65 if (task->arch.iomap.bits < bits) {66 70 /* 67 71 * The I/O permission bitmap is too small and needs to be grown. 68 72 */ 69 73 70 uint8_t *newmap = (uint8_t *) malloc(BITS2BYTES(bits), FRAME_ATOMIC);74 newmap = (uint8_t *) malloc(BITS2BYTES(bits), FRAME_ATOMIC); 71 75 if (!newmap) 72 76 return ENOMEM; 73 77 74 bitmap_t oldiomap;75 78 bitmap_initialize(&oldiomap, task->arch.iomap.map, 76 79 task->arch.iomap.bits); 77 80 bitmap_initialize(&task->arch.iomap, newmap, bits); 78 81 79 82 /* 80 83 * Mark the new range inaccessible. … … 82 85 bitmap_set_range(&task->arch.iomap, oldiomap.bits, 83 86 bits - oldiomap.bits); 84 87 85 88 /* 86 89 * In case there really existed smaller iomap, 87 90 * copy its contents and deallocate it. 88 */ 91 */ 89 92 if (oldiomap.bits) { 90 93 bitmap_copy(&task->arch.iomap, &oldiomap, … … 93 96 } 94 97 } 95 98 96 99 /* 97 100 * Enable the range and we are done. 98 101 */ 99 102 bitmap_clear_range(&task->arch.iomap, (size_t) ioaddr, (size_t) size); 100 103 101 104 /* 102 105 * Increment I/O Permission bitmap generation counter. 103 106 */ 104 107 task->arch.iomapver++; 105 108 106 109 return 0; 107 110 } … … 113 116 * 114 117 * Interrupts must be disabled prior this call. 115 *116 118 */ 117 119 void io_perm_bitmap_install(void) 118 120 { 121 size_t bits; 122 ptr_16_32_t cpugdtr; 123 descriptor_t *gdt_p; 124 size_t ver; 125 119 126 /* First, copy the I/O Permission Bitmap. */ 120 irq_spinlock_lock(&TASK->lock, false); 121 size_t ver = TASK->arch.iomapver; 122 size_t bits = TASK->arch.iomap.bits; 123 if (bits) { 127 spinlock_lock(&TASK->lock); 128 ver = TASK->arch.iomapver; 129 if ((bits = TASK->arch.iomap.bits)) { 130 bitmap_t iomap; 131 task_t *task = TASK; 132 124 133 ASSERT(TASK->arch.iomap.map); 125 126 bitmap_t iomap;127 134 bitmap_initialize(&iomap, CPU->arch.tss->iomap, 128 135 TSS_IOMAP_SIZE * 8); 129 bitmap_copy(&iomap, &TASK->arch.iomap, TASK->arch.iomap.bits); 130 136 bitmap_copy(&iomap, &task->arch.iomap, task->arch.iomap.bits); 131 137 /* 132 138 * It is safe to set the trailing eight bits because of the … … 135 141 bitmap_set_range(&iomap, ALIGN_UP(TASK->arch.iomap.bits, 8), 8); 136 142 } 137 irq_spinlock_unlock(&TASK->lock, false);138 143 spinlock_unlock(&TASK->lock); 144 139 145 /* 140 146 * Second, adjust TSS segment limit. 141 147 * Take the extra ending byte with all bits set into account. 142 148 */ 143 ptr_16_32_t cpugdtr;144 149 gdtr_store(&cpugdtr); 145 146 descriptor_t *gdt_p = (descriptor_t *) cpugdtr.base; 150 gdt_p = (descriptor_t *) cpugdtr.base; 147 151 gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + BITS2BYTES(bits)); 148 152 gdtr_load(&cpugdtr); 149 153 150 154 /* 151 155 * Before we load new TSS limit, the current TSS descriptor
Note:
See TracChangeset
for help on using the changeset viewer.