Changes in kernel/arch/ia32/src/ddi/ddi.c [e9e5b9ab:98000fb] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/ia32/src/ddi/ddi.c
re9e5b9ab r98000fb 36 36 #include <arch/ddi/ddi.h> 37 37 #include <proc/task.h> 38 #include < typedefs.h>38 #include <arch/types.h> 39 39 #include <adt/bitmap.h> 40 40 #include <mm/slab.h> … … 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, bits); 130 131 /* 132 * Set the trailing bits in the last byte of the map to disable 133 * I/O access. 134 */ 135 bitmap_set_range(&iomap, bits, ALIGN_UP(bits, 8) - bits); 136 bitmap_copy(&iomap, &task->arch.iomap, task->arch.iomap.bits); 136 137 /* 137 138 * It is safe to set the trailing eight bits because of the 138 139 * extra convenience byte in TSS_IOMAP_SIZE. 139 140 */ 140 bitmap_set_range(&iomap, ALIGN_UP( bits, 8), 8);141 bitmap_set_range(&iomap, ALIGN_UP(TASK->arch.iomap.bits, 8), 8); 141 142 } 142 irq_spinlock_unlock(&TASK->lock, false);143 143 spinlock_unlock(&TASK->lock); 144 144 145 /* 145 146 * Second, adjust TSS segment limit. 146 147 * Take the extra ending byte with all bits set into account. 147 148 */ 148 ptr_16_32_t cpugdtr;149 149 gdtr_store(&cpugdtr); 150 151 descriptor_t *gdt_p = (descriptor_t *) cpugdtr.base; 150 gdt_p = (descriptor_t *) cpugdtr.base; 152 151 gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + BITS2BYTES(bits)); 153 152 gdtr_load(&cpugdtr); 154 153 155 154 /* 156 155 * Before we load new TSS limit, the current TSS descriptor … … 158 157 */ 159 158 gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL; 160 tr_load( GDT_SELECTOR(TSS_DES));159 tr_load(gdtselector(TSS_DES)); 161 160 162 161 /*
Note:
See TracChangeset
for help on using the changeset viewer.