Subversion Repositories shark

Rev

Rev 422 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
422 giacomo 1
#ifndef __ARCH_DESC_H
2
#define __ARCH_DESC_H
3
 
4
#include <asm/ldt.h>
5
#include <asm/segment.h>
6
 
7
#ifndef __ASSEMBLY__
8
 
9
#include <linux/preempt.h>
10
#include <linux/smp.h>
11
 
12
#include <asm/mmu.h>
13
 
14
extern struct desc_struct cpu_gdt_table[NR_CPUS][GDT_ENTRIES];
15
 
16
struct Xgt_desc_struct {
17
        unsigned short size;
18
        unsigned long address __attribute__((packed));
19
        unsigned short pad;
20
} __attribute__ ((packed));
21
 
22
extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS];
23
 
24
#define load_TR_desc() __asm__ __volatile__("ltr %%ax"::"a" (GDT_ENTRY_TSS*8))
25
#define load_LDT_desc() __asm__ __volatile__("lldt %%ax"::"a" (GDT_ENTRY_LDT*8))
26
 
27
/*
28
 * This is the ldt that every process will get unless we need
29
 * something other than this.
30
 */
31
extern struct desc_struct default_ldt[];
32
extern void set_intr_gate(unsigned int irq, void * addr);
33
 
34
#define _set_tssldt_desc(n,addr,limit,type) \
35
__asm__ __volatile__ ("movw %w3,0(%2)\n\t" \
36
        "movw %%ax,2(%2)\n\t" \
37
        "rorl $16,%%eax\n\t" \
38
        "movb %%al,4(%2)\n\t" \
39
        "movb %4,5(%2)\n\t" \
40
        "movb $0,6(%2)\n\t" \
41
        "movb %%ah,7(%2)\n\t" \
42
        "rorl $16,%%eax" \
43
        : "=m"(*(n)) : "a" (addr), "r"(n), "ir"(limit), "i"(type))
44
 
45
static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
46
{
47
        _set_tssldt_desc(&cpu_gdt_table[cpu][entry], (int)addr, 235, 0x89);
48
}
49
 
50
#define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
51
 
52
static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size)
53
{
54
        _set_tssldt_desc(&cpu_gdt_table[cpu][GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
55
}
56
 
57
#define LDT_entry_a(info) \
58
        ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
59
 
60
#define LDT_entry_b(info) \
61
        (((info)->base_addr & 0xff000000) | \
62
        (((info)->base_addr & 0x00ff0000) >> 16) | \
63
        ((info)->limit & 0xf0000) | \
64
        (((info)->read_exec_only ^ 1) << 9) | \
65
        ((info)->contents << 10) | \
66
        (((info)->seg_not_present ^ 1) << 15) | \
67
        ((info)->seg_32bit << 22) | \
68
        ((info)->limit_in_pages << 23) | \
69
        ((info)->useable << 20) | \
70
        0x7000)
71
 
72
#define LDT_empty(info) (\
73
        (info)->base_addr       == 0    && \
74
        (info)->limit           == 0    && \
75
        (info)->contents        == 0    && \
76
        (info)->read_exec_only  == 1    && \
77
        (info)->seg_32bit       == 0    && \
78
        (info)->limit_in_pages  == 0    && \
79
        (info)->seg_not_present == 1    && \
80
        (info)->useable         == 0    )
81
 
82
#if TLS_SIZE != 24
83
# error update this code.
84
#endif
85
 
86
static inline void load_TLS(struct thread_struct *t, unsigned int cpu)
87
{
88
#define C(i) cpu_gdt_table[cpu][GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]
89
        C(0); C(1); C(2);
90
#undef C
91
}
92
 
93
static inline void clear_LDT(void)
94
{
95
        int cpu = get_cpu();
96
 
97
        set_ldt_desc(cpu, &default_ldt[0], 5);
98
        load_LDT_desc();
99
        put_cpu();
100
}
101
 
102
/*
103
 * load one particular LDT into the current CPU
104
 */
105
static inline void load_LDT_nolock(mm_context_t *pc, int cpu)
106
{
107
        void *segments = pc->ldt;
108
        int count = pc->size;
109
 
110
        if (likely(!count)) {
111
                segments = &default_ldt[0];
112
                count = 5;
113
        }
114
 
115
        set_ldt_desc(cpu, segments, count);
116
        load_LDT_desc();
117
}
118
 
119
static inline void load_LDT(mm_context_t *pc)
120
{
121
        int cpu = get_cpu();
122
        load_LDT_nolock(pc, cpu);
123
        put_cpu();
124
}
125
 
126
#endif /* !__ASSEMBLY__ */
127
 
128
#endif