00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00035 #include <ddi/ddi.h>
00036 #include <arch/ddi/ddi.h>
00037 #include <proc/task.h>
00038 #include <arch/types.h>
00039 #include <typedefs.h>
00040 #include <adt/bitmap.h>
00041 #include <mm/slab.h>
00042 #include <arch/pm.h>
00043 #include <errno.h>
00044 #include <arch/cpu.h>
00045 #include <cpu.h>
00046 #include <arch.h>
00047 #include <align.h>
00048
00059 int ddi_iospace_enable_arch(task_t *task, __address ioaddr, size_t size)
00060 {
00061 count_t bits;
00062
00063 bits = ioaddr + size;
00064 if (bits > IO_PORTS)
00065 return ENOENT;
00066
00067 if (task->arch.iomap.bits < bits) {
00068 bitmap_t oldiomap;
00069 __u8 *newmap;
00070
00071
00072
00073
00074
00075 newmap = (__u8 *) malloc(BITS2BYTES(bits), FRAME_ATOMIC);
00076 if (!newmap)
00077 return ENOMEM;
00078
00079 bitmap_initialize(&oldiomap, task->arch.iomap.map, task->arch.iomap.bits);
00080 bitmap_initialize(&task->arch.iomap, newmap, bits);
00081
00082
00083
00084
00085 bitmap_set_range(&task->arch.iomap, oldiomap.bits, bits - oldiomap.bits);
00086
00087
00088
00089
00090
00091 if (oldiomap.bits) {
00092 bitmap_copy(&task->arch.iomap, &oldiomap, oldiomap.bits);
00093 free(oldiomap.map);
00094 }
00095 }
00096
00097
00098
00099
00100 bitmap_clear_range(&task->arch.iomap, (index_t) ioaddr, (count_t) size);
00101
00102
00103
00104
00105 task->arch.iomapver++;
00106
00107 return 0;
00108 }
00109
00117 void io_perm_bitmap_install(void)
00118 {
00119 count_t bits;
00120 ptr_16_32_t cpugdtr;
00121 descriptor_t *gdt_p;
00122 count_t ver;
00123
00124
00125 spinlock_lock(&TASK->lock);
00126 ver = TASK->arch.iomapver;
00127 if ((bits = TASK->arch.iomap.bits)) {
00128 bitmap_t iomap;
00129
00130 ASSERT(TASK->arch.iomap.map);
00131 bitmap_initialize(&iomap, CPU->arch.tss->iomap, TSS_IOMAP_SIZE * 8);
00132 bitmap_copy(&iomap, &TASK->arch.iomap, TASK->arch.iomap.bits);
00133
00134
00135
00136
00137 bitmap_set_range(&iomap, ALIGN_UP(TASK->arch.iomap.bits, 8), 8);
00138 }
00139 spinlock_unlock(&TASK->lock);
00140
00141
00142
00143
00144
00145 gdtr_store(&cpugdtr);
00146 gdt_p = (descriptor_t *) cpugdtr.base;
00147 gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + BITS2BYTES(bits));
00148 gdtr_load(&cpugdtr);
00149
00150
00151
00152
00153
00154 gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL;
00155 tr_load(selector(TSS_DES));
00156
00157
00158
00159
00160
00161 CPU->arch.iomapver_copy = ver;
00162 }
00163