Subversion Repositories HelenOS

Rev

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

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