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