Subversion Repositories HelenOS

Rev

Rev 3386 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3386 Rev 4153
Line 48... Line 48...
48
#include <userspace.h>
48
#include <userspace.h>
49
#include <console/console.h>
49
#include <console/console.h>
50
#include <proc/uarg.h>
50
#include <proc/uarg.h>
51
#include <syscall/syscall.h>
51
#include <syscall/syscall.h>
52
#include <ddi/irq.h>
52
#include <ddi/irq.h>
53
#include <ddi/device.h>
-
 
54
#include <arch/drivers/ega.h>
-
 
55
#include <arch/bootinfo.h>
53
#include <arch/bootinfo.h>
-
 
54
#include <genarch/drivers/legacy/ia32/io.h>
-
 
55
#include <genarch/drivers/ega/ega.h>
56
#include <genarch/kbd/i8042.h>
56
#include <genarch/kbrd/kbrd.h>
-
 
57
#include <genarch/srln/srln.h>
-
 
58
#include <genarch/drivers/i8042/i8042.h>
-
 
59
#include <genarch/drivers/ns16550/ns16550.h>
-
 
60
#include <arch/drivers/kbd.h>
-
 
61
#include <smp/smp.h>
-
 
62
#include <smp/ipi.h>
-
 
63
#include <arch/atomic.h>
-
 
64
#include <panic.h>
-
 
65
#include <print.h>
-
 
66
#include <sysinfo/sysinfo.h>
-
 
67
#include <string.h>
-
 
68
 
-
 
69
/* NS16550 as a COM 1 */
-
 
70
#define NS16550_IRQ  (4 + LEGACY_INTERRUPT_BASE)
57
 
71
 
58
bootinfo_t *bootinfo;
72
bootinfo_t *bootinfo;
59
 
73
 
-
 
74
static uint64_t iosapic_base = 0xfec00000;
-
 
75
 
-
 
76
/** Performs ia64-specific initialization before main_bsp() is called. */
60
void arch_pre_main(void)
77
void arch_pre_main(void)
61
{
78
{
62
    /* Setup usermode init tasks. */
79
    /* Setup usermode init tasks. */
63
 
80
 
64
//#ifdef I460GX
-
 
65
    unsigned int i;
81
    unsigned int i;
66
   
82
   
67
    init.cnt = bootinfo->taskmap.count;
83
    init.cnt = bootinfo->taskmap.count;
68
   
84
   
69
    for (i = 0; i < init.cnt; i++) {
85
    for (i = 0; i < init.cnt; i++) {
-
 
86
        init.tasks[i].addr =
70
        init.tasks[i].addr = ((unsigned long) bootinfo->taskmap.tasks[i].addr) | VRN_MASK;
87
            ((unsigned long) bootinfo->taskmap.tasks[i].addr) |
-
 
88
            VRN_MASK;
71
        init.tasks[i].size = bootinfo->taskmap.tasks[i].size;
89
        init.tasks[i].size = bootinfo->taskmap.tasks[i].size;
-
 
90
        strncpy(init.tasks[i].name, bootinfo->taskmap.tasks[i].name,
-
 
91
            CONFIG_TASK_NAME_BUFLEN);
72
    }
92
    }
73
/*
-
 
74
#else  
-
 
75
    init.cnt = 8;
-
 
76
    init.tasks[0].addr = INIT0_ADDRESS;
-
 
77
    init.tasks[0].size = INIT0_SIZE;
-
 
78
    init.tasks[1].addr = INIT0_ADDRESS + 0x400000;
-
 
79
    init.tasks[1].size = INIT0_SIZE;
-
 
80
    init.tasks[2].addr = INIT0_ADDRESS + 0x800000;
-
 
81
    init.tasks[2].size = INIT0_SIZE;
-
 
82
    init.tasks[3].addr = INIT0_ADDRESS + 0xc00000;
-
 
83
    init.tasks[3].size = INIT0_SIZE;
-
 
84
    init.tasks[4].addr = INIT0_ADDRESS + 0x1000000;
-
 
85
    init.tasks[4].size = INIT0_SIZE;
-
 
86
    init.tasks[5].addr = INIT0_ADDRESS + 0x1400000;
-
 
87
    init.tasks[5].size = INIT0_SIZE;
-
 
88
    init.tasks[6].addr = INIT0_ADDRESS + 0x1800000;
-
 
89
    init.tasks[6].size = INIT0_SIZE;
-
 
90
    init.tasks[7].addr = INIT0_ADDRESS + 0x1c00000;
-
 
91
    init.tasks[7].size = INIT0_SIZE;
-
 
92
#endif*/
-
 
93
}
93
}
94
 
94
 
95
void arch_pre_mm_init(void)
95
void arch_pre_mm_init(void)
96
{
96
{
-
 
97
    /*
97
    /* Set Interruption Vector Address (i.e. location of interruption vector table). */
98
     * Set Interruption Vector Address (i.e. location of interruption vector
-
 
99
     * table).
-
 
100
     */
98
    iva_write((uintptr_t) &ivt);
101
    iva_write((uintptr_t) &ivt);
99
    srlz_d();
102
    srlz_d();
100
   
103
   
101
}
104
}
102
 
105
 
-
 
106
static void iosapic_init(void)
-
 
107
{
-
 
108
    uint64_t IOSAPIC = PA2KA((unative_t)(iosapic_base)) | FW_OFFSET;
-
 
109
    int i;
-
 
110
   
-
 
111
    int myid, myeid;
-
 
112
   
-
 
113
    myid = ia64_get_cpu_id();
-
 
114
    myeid = ia64_get_cpu_eid();
-
 
115
 
-
 
116
    for (i = 0; i < 16; i++) {
-
 
117
        if (i == 2)
-
 
118
            continue;    /* Disable Cascade interrupt */
-
 
119
        ((uint32_t *)(IOSAPIC + 0x00))[0] = 0x10 + 2 * i;
-
 
120
        srlz_d();
-
 
121
        ((uint32_t *)(IOSAPIC + 0x10))[0] = LEGACY_INTERRUPT_BASE + i;
-
 
122
        srlz_d();
-
 
123
        ((uint32_t *)(IOSAPIC + 0x00))[0] = 0x10 + 2 * i + 1;
-
 
124
        srlz_d();
-
 
125
        ((uint32_t *)(IOSAPIC + 0x10))[0] = myid << (56 - 32) |
-
 
126
            myeid << (48 - 32);
-
 
127
        srlz_d();
-
 
128
    }
-
 
129
 
-
 
130
}
-
 
131
 
103
void arch_post_mm_init(void)
132
void arch_post_mm_init(void)
104
{
133
{
105
    irq_init(INR_COUNT, INR_COUNT);
134
    if (config.cpu_active == 1) {
106
#ifdef SKI
-
 
107
    ski_init_console();
135
        iosapic_init();
108
#else   
-
 
109
    ega_init();
136
        irq_init(INR_COUNT, INR_COUNT);
110
#endif  
137
    }
111
    it_init(); 
138
    it_init(); 
112
}
139
}
113
 
140
 
114
void arch_post_cpu_init(void)
141
void arch_post_cpu_init(void)
115
{
142
{
Line 117... Line 144...
117
 
144
 
118
void arch_pre_smp_init(void)
145
void arch_pre_smp_init(void)
119
{
146
{
120
}
147
}
121
 
148
 
122
 
-
 
123
#ifdef I460GX
-
 
124
#define POLL_INTERVAL       50000       /* 50 ms */
-
 
125
/** Kernel thread for polling keyboard. */
-
 
126
static void i8042_kkbdpoll(void *arg)
-
 
127
{
-
 
128
    while (1) {
-
 
129
        i8042_poll();
-
 
130
        thread_usleep(POLL_INTERVAL);
-
 
131
    }
-
 
132
}
-
 
133
#endif
-
 
134
 
-
 
135
void arch_post_smp_init(void)
149
void arch_post_smp_init(void)
136
{
150
{
137
 
-
 
138
    if (config.cpu_active == 1) {
-
 
139
        /*
-
 
140
         * Create thread that polls keyboard.
-
 
141
         */
-
 
142
#ifdef SKI
151
#ifdef SKI
143
        thread_t *t;
152
    indev_t *in;
144
        t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
-
 
145
        if (!t)
-
 
146
            panic("cannot create kkbdpoll\n");
-
 
147
        thread_ready(t);
153
    in = skiin_init();
148
#endif      
-
 
149
 
-
 
150
#ifdef I460GX
-
 
151
        devno_t kbd = device_assign_devno();
-
 
152
        devno_t mouse = device_assign_devno();
-
 
153
        /* keyboard controller */
-
 
154
        i8042_init(kbd, IRQ_KBD, mouse, IRQ_MOUSE);
-
 
155
 
-
 
156
        thread_t *t;
-
 
157
        t = thread_create(i8042_kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
-
 
158
        if (!t)
154
    if (in)
159
            panic("cannot create kkbdpoll\n");
155
        srln_init(in);
160
        thread_ready(t);
156
    skiout_init();
161
 
-
 
162
#endif
157
#endif
-
 
158
   
-
 
159
#ifdef CONFIG_EGA
-
 
160
    ega_init(EGA_BASE, EGA_VIDEORAM);
-
 
161
#endif
163
 
162
   
-
 
163
#ifdef CONFIG_NS16550
-
 
164
    indev_t *kbrdin_ns16550
-
 
165
        = ns16550_init((ns16550_t *) NS16550_BASE, NS16550_IRQ, NULL, NULL);
-
 
166
    if (kbrdin_ns16550)
-
 
167
        srln_init(kbrdin_ns16550);
-
 
168
   
-
 
169
    sysinfo_set_item_val("kbd", NULL, true);
-
 
170
    sysinfo_set_item_val("kbd.inr", NULL, NS16550_IRQ);
-
 
171
    sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550);
-
 
172
    sysinfo_set_item_val("kbd.address.physical", NULL,
-
 
173
        (uintptr_t) NS16550_BASE);
-
 
174
    sysinfo_set_item_val("kbd.address.kernel", NULL,
-
 
175
        (uintptr_t) NS16550_BASE);
-
 
176
#endif
-
 
177
   
-
 
178
#ifdef CONFIG_I8042
-
 
179
    indev_t *kbrdin_i8042 = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD);
-
 
180
    if (kbrdin_i8042)
-
 
181
        kbrd_init(kbrdin_i8042);
-
 
182
   
-
 
183
    sysinfo_set_item_val("kbd", NULL, true);
-
 
184
    sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD);
-
 
185
    sysinfo_set_item_val("kbd.type", NULL, KBD_LEGACY);
-
 
186
    sysinfo_set_item_val("kbd.address.physical", NULL,
-
 
187
        (uintptr_t) I8042_BASE);
-
 
188
    sysinfo_set_item_val("kbd.address.kernel", NULL,
-
 
189
        (uintptr_t) I8042_BASE);
-
 
190
#endif
164
    }
191
   
-
 
192
    sysinfo_set_item_val("ia64_iospace", NULL, true);
-
 
193
    sysinfo_set_item_val("ia64_iospace.address", NULL, true);
-
 
194
    sysinfo_set_item_val("ia64_iospace.address.virtual", NULL, IO_OFFSET);
165
}
195
}
166
 
196
 
-
 
197
 
167
/** Enter userspace and never return. */
198
/** Enter userspace and never return. */
168
void userspace(uspace_arg_t *kernel_uarg)
199
void userspace(uspace_arg_t *kernel_uarg)
169
{
200
{
170
    psr_t psr;
201
    psr_t psr;
171
    rsc_t rsc;
202
    rsc_t rsc;
172
 
203
 
173
    psr.value = psr_read();
204
    psr.value = psr_read();
174
    psr.cpl = PL_USER;
205
    psr.cpl = PL_USER;
175
    psr.i = true;               /* start with interrupts enabled */
206
    psr.i = true;           /* start with interrupts enabled */
176
    psr.ic = true;
207
    psr.ic = true;
177
    psr.ri = 0;             /* start with instruction #0 */
208
    psr.ri = 0;         /* start with instruction #0 */
178
    psr.bn = 1;             /* start in bank 0 */
209
    psr.bn = 1;         /* start in bank 0 */
179
 
210
 
180
    asm volatile ("mov %0 = ar.rsc\n" : "=r" (rsc.value));
211
    asm volatile ("mov %0 = ar.rsc\n" : "=r" (rsc.value));
181
    rsc.loadrs = 0;
212
    rsc.loadrs = 0;
182
    rsc.be = false;
213
    rsc.be = false;
183
    rsc.pl = PL_USER;
214
    rsc.pl = PL_USER;
184
    rsc.mode = 3;               /* eager mode */
215
    rsc.mode = 3;           /* eager mode */
185
 
216
 
186
    switch_to_userspace((uintptr_t) kernel_uarg->uspace_entry,
217
    switch_to_userspace((uintptr_t) kernel_uarg->uspace_entry,
187
                ((uintptr_t) kernel_uarg->uspace_stack)+PAGE_SIZE-ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT),
218
        ((uintptr_t) kernel_uarg->uspace_stack) + PAGE_SIZE -
188
                ((uintptr_t) kernel_uarg->uspace_stack)+PAGE_SIZE,
219
        ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT),
189
                (uintptr_t) kernel_uarg->uspace_uarg,
220
        ((uintptr_t) kernel_uarg->uspace_stack) + PAGE_SIZE,
190
                psr.value, rsc.value);
221
        (uintptr_t) kernel_uarg->uspace_uarg, psr.value, rsc.value);
191
 
222
 
192
    while (1) {
223
    while (1)
193
        ;
224
        ;
194
    }
-
 
195
}
225
}
196
 
226
 
197
/** Set thread-local-storage pointer.
227
/** Set thread-local-storage pointer.
198
 *
228
 *
199
 * We use r13 (a.k.a. tp) for this purpose.
229
 * We use r13 (a.k.a. tp) for this purpose.
Line 208... Line 238...
208
 */
238
 */
209
void arch_grab_console(void)
239
void arch_grab_console(void)
210
{
240
{
211
#ifdef SKI
241
#ifdef SKI
212
    ski_kbd_grab();
242
    ski_kbd_grab();
213
#endif  
243
#endif
214
}
244
}
-
 
245
 
215
/** Return console to userspace
246
/** Return console to userspace
216
 *
247
 *
217
 */
248
 */
218
void arch_release_console(void)
249
void arch_release_console(void)
219
{
250
{
Line 222... Line 253...
222
#endif
253
#endif
223
}
254
}
224
 
255
 
225
void arch_reboot(void)
256
void arch_reboot(void)
226
{
257
{
227
    // TODO
258
    pio_write_8((ioport8_t *)0x64, 0xfe);
228
    while (1);
259
    while (1)
-
 
260
        ;
-
 
261
}
-
 
262
 
-
 
263
/** Construct function pointer
-
 
264
 *
-
 
265
 * @param fptr   function pointer structure
-
 
266
 * @param addr   function address
-
 
267
 * @param caller calling function address
-
 
268
 *
-
 
269
 * @return address of the function pointer
-
 
270
 *
-
 
271
 */
-
 
272
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller)
-
 
273
{
-
 
274
    fptr->fnc = (unative_t) addr;
-
 
275
    fptr->gp = ((unative_t *) caller)[1];
-
 
276
   
-
 
277
    return (void *) fptr;
229
}
278
}
230
 
279
 
231
/** @}
280
/** @}
232
 */
281
 */