Subversion Repositories HelenOS-historic

Rev

Rev 1702 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1702 Rev 1780
Line 84... Line 84...
84
static tss_t tss;
84
static tss_t tss;
85
 
85
 
86
tss_t *tss_p = NULL;
86
tss_t *tss_p = NULL;
87
 
87
 
88
/* gdtr is changed by kmp before next CPU is initialized */
88
/* gdtr is changed by kmp before next CPU is initialized */
89
ptr_16_32_t bootstrap_gdtr = { .limit = sizeof(gdt), .base = KA2PA((__address) gdt) };
89
ptr_16_32_t bootstrap_gdtr = { .limit = sizeof(gdt), .base = KA2PA((uintptr_t) gdt) };
90
ptr_16_32_t gdtr = { .limit = sizeof(gdt), .base = (__address) gdt };
90
ptr_16_32_t gdtr = { .limit = sizeof(gdt), .base = (uintptr_t) gdt };
91
 
91
 
92
void gdt_setbase(descriptor_t *d, __address base)
92
void gdt_setbase(descriptor_t *d, uintptr_t base)
93
{
93
{
94
    d->base_0_15 = base & 0xffff;
94
    d->base_0_15 = base & 0xffff;
95
    d->base_16_23 = ((base) >> 16) & 0xff;
95
    d->base_16_23 = ((base) >> 16) & 0xff;
96
    d->base_24_31 = ((base) >> 24) & 0xff;
96
    d->base_24_31 = ((base) >> 24) & 0xff;
97
}
97
}
98
 
98
 
99
void gdt_setlimit(descriptor_t *d, __u32 limit)
99
void gdt_setlimit(descriptor_t *d, uint32_t limit)
100
{
100
{
101
    d->limit_0_15 = limit & 0xffff;
101
    d->limit_0_15 = limit & 0xffff;
102
    d->limit_16_19 = (limit >> 16) & 0xf;
102
    d->limit_16_19 = (limit >> 16) & 0xf;
103
}
103
}
104
 
104
 
105
void idt_setoffset(idescriptor_t *d, __address offset)
105
void idt_setoffset(idescriptor_t *d, uintptr_t offset)
106
{
106
{
107
    /*
107
    /*
108
     * Offset is a linear address.
108
     * Offset is a linear address.
109
     */
109
     */
110
    d->offset_0_15 = offset & 0xffff;
110
    d->offset_0_15 = offset & 0xffff;
111
    d->offset_16_31 = offset >> 16;
111
    d->offset_16_31 = offset >> 16;
112
}
112
}
113
 
113
 
114
void tss_initialize(tss_t *t)
114
void tss_initialize(tss_t *t)
115
{
115
{
116
    memsetb((__address) t, sizeof(struct tss), 0);
116
    memsetb((uintptr_t) t, sizeof(struct tss), 0);
117
}
117
}
118
 
118
 
119
/*
119
/*
120
 * This function takes care of proper setup of IDT and IDTR.
120
 * This function takes care of proper setup of IDT and IDTR.
121
 */
121
 */
Line 137... Line 137...
137
             * The syscall interrupt gate must be calleable from userland.
137
             * The syscall interrupt gate must be calleable from userland.
138
             */
138
             */
139
            d->access |= DPL_USER;
139
            d->access |= DPL_USER;
140
        }
140
        }
141
       
141
       
142
        idt_setoffset(d, ((__address) interrupt_handlers) + i*interrupt_handler_size);
142
        idt_setoffset(d, ((uintptr_t) interrupt_handlers) + i*interrupt_handler_size);
143
        exc_register(i, "undef", (iroutine) null_interrupt);
143
        exc_register(i, "undef", (iroutine) null_interrupt);
144
    }
144
    }
145
    exc_register(13, "gp_fault", (iroutine) gp_fault);
145
    exc_register(13, "gp_fault", (iroutine) gp_fault);
146
    exc_register( 7, "nm_fault", (iroutine) nm_fault);
146
    exc_register( 7, "nm_fault", (iroutine) nm_fault);
147
    exc_register(12, "ss_fault", (iroutine) ss_fault);
147
    exc_register(12, "ss_fault", (iroutine) ss_fault);
Line 180... Line 180...
180
 
180
 
181
    /*
181
    /*
182
     * Update addresses in GDT and IDT to their virtual counterparts.
182
     * Update addresses in GDT and IDT to their virtual counterparts.
183
     */
183
     */
184
    idtr.limit = sizeof(idt);
184
    idtr.limit = sizeof(idt);
185
    idtr.base = (__address) idt;
185
    idtr.base = (uintptr_t) idt;
186
    gdtr_load(&gdtr);
186
    gdtr_load(&gdtr);
187
    idtr_load(&idtr);
187
    idtr_load(&idtr);
188
   
188
   
189
    /*
189
    /*
190
     * Each CPU has its private GDT and TSS.
190
     * Each CPU has its private GDT and TSS.
Line 209... Line 209...
209
   
209
   
210
    gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL;
210
    gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL;
211
    gdt_p[TSS_DES].special = 1;
211
    gdt_p[TSS_DES].special = 1;
212
    gdt_p[TSS_DES].granularity = 0;
212
    gdt_p[TSS_DES].granularity = 0;
213
   
213
   
214
    gdt_setbase(&gdt_p[TSS_DES], (__address) tss_p);
214
    gdt_setbase(&gdt_p[TSS_DES], (uintptr_t) tss_p);
215
    gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE - 1);
215
    gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE - 1);
216
 
216
 
217
    /*
217
    /*
218
     * As of this moment, the current CPU has its own GDT pointing
218
     * As of this moment, the current CPU has its own GDT pointing
219
     * to its own TSS. We just need to load the TR register.
219
     * to its own TSS. We just need to load the TR register.
Line 222... Line 222...
222
   
222
   
223
    clean_IOPL_NT_flags();    /* Disable I/O on nonprivileged levels and clear NT flag. */
223
    clean_IOPL_NT_flags();    /* Disable I/O on nonprivileged levels and clear NT flag. */
224
    clean_AM_flag();          /* Disable alignment check */
224
    clean_AM_flag();          /* Disable alignment check */
225
}
225
}
226
 
226
 
227
void set_tls_desc(__address tls)
227
void set_tls_desc(uintptr_t tls)
228
{
228
{
229
    ptr_16_32_t cpugdtr;
229
    ptr_16_32_t cpugdtr;
230
    descriptor_t *gdt_p;
230
    descriptor_t *gdt_p;
231
 
231
 
232
    gdtr_store(&cpugdtr);
232
    gdtr_store(&cpugdtr);