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 <arch.h>
00046 #include <align.h>
00047
00058 int ddi_iospace_enable_arch(task_t *task, __address ioaddr, size_t size)
00059 {
00060 count_t bits;
00061
00062 bits = ioaddr + size;
00063 if (bits > IO_PORTS)
00064 return ENOENT;
00065
00066 if (task->arch.iomap.bits < bits) {
00067 bitmap_t oldiomap;
00068 __u8 *newmap;
00069
00070
00071
00072
00073
00074 newmap = (__u8 *) malloc(BITS2BYTES(bits), FRAME_ATOMIC);
00075 if (!newmap)
00076 return ENOMEM;
00077
00078 bitmap_initialize(&oldiomap, task->arch.iomap.map, task->arch.iomap.bits);
00079 bitmap_initialize(&task->arch.iomap, newmap, bits);
00080
00081
00082
00083
00084 bitmap_set_range(&task->arch.iomap, oldiomap.bits, bits - oldiomap.bits);
00085
00086
00087
00088
00089
00090 if (oldiomap.bits) {
00091 bitmap_copy(&task->arch.iomap, &oldiomap, oldiomap.bits);
00092 free(oldiomap.map);
00093 }
00094 }
00095
00096
00097
00098
00099 bitmap_clear_range(&task->arch.iomap, (index_t) ioaddr, (count_t) size);
00100
00101
00102
00103
00104 task->arch.iomapver++;
00105
00106 return 0;
00107 }
00108
00116 void io_perm_bitmap_install(void)
00117 {
00118 count_t bits;
00119 ptr_16_64_t cpugdtr;
00120 descriptor_t *gdt_p;
00121 tss_descriptor_t *tss_desc;
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_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + BITS2BYTES(bits));
00148 gdtr_load(&cpugdtr);
00149
00150
00151
00152
00153
00154 tss_desc = (tss_descriptor_t *) &gdt_p[TSS_DES];
00155 tss_desc->type = AR_TSS;
00156 tr_load(gdtselector(TSS_DES));
00157
00158
00159
00160
00161
00162 CPU->arch.iomapver_copy = ver;
00163 }
00164