Subversion Repositories HelenOS-historic

Rev

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

Rev 501 Rev 512
Line 38... Line 38...
38
#include <arch.h>
38
#include <arch.h>
39
 
39
 
40
#ifdef CONFIG_SMP
40
#ifdef CONFIG_SMP
41
 
41
 
42
/*
42
/*
43
 * This is functional, far-from-general-enough interface to the APIC.
-
 
44
 * Advanced Programmable Interrupt Controller for MP systems.
43
 * Advanced Programmable Interrupt Controller for SMP systems.
45
 * Tested on:
44
 * Tested on:
46
 *  Bochs 2.0.2 - Bochs 2.2 with 2-8 CPUs
45
 *  Bochs 2.0.2 - Bochs 2.2 with 2-8 CPUs
47
 *  Simics 2.0.28 - Simics 2.2.14 2-4 CPUs
46
 *  Simics 2.0.28 - Simics 2.2.14 2-4 CPUs
48
 *  ASUS P/I-P65UP5 + ASUS C-P55T2D REV. 1.41 with 2x 200Mhz Pentium CPUs
47
 *  ASUS P/I-P65UP5 + ASUS C-P55T2D REV. 1.41 with 2x 200Mhz Pentium CPUs
49
 *  ASUS PCH-DL with 2x 3000Mhz Pentium 4 Xeon (HT) CPUs
48
 *  ASUS PCH-DL with 2x 3000Mhz Pentium 4 Xeon (HT) CPUs
Line 80... Line 79...
80
     * IRQ 0 remains masked as the time signal is generated by l_apic's themselves.
79
     * IRQ 0 remains masked as the time signal is generated by l_apic's themselves.
81
     * Other interrupts will be forwarded to the lowest priority CPU.
80
     * Other interrupts will be forwarded to the lowest priority CPU.
82
     */
81
     */
83
    io_apic_disable_irqs(0xffff);
82
    io_apic_disable_irqs(0xffff);
84
    trap_register(VECTOR_CLK, l_apic_timer_interrupt);
83
    trap_register(VECTOR_CLK, l_apic_timer_interrupt);
85
    for (i=1; i<16; i++) {
84
    for (i=0; i<16; i++) {
86
        int pin;
85
        int pin;
87
   
86
   
88
        if ((pin = mps_irq_to_pin(i)) != -1)
87
        if ((pin = smp_irq_to_pin(i)) != -1) {
89
        io_apic_change_ioredtbl(pin,0xf,IVT_IRQBASE+i,LOPRI);
88
            io_apic_change_ioredtbl(pin,0xff,IVT_IRQBASE+i,LOPRI);
-
 
89
        }
90
    }
90
    }
91
   
91
   
92
 
92
 
93
    /*
93
    /*
94
     * Ensure that io_apic has unique ID.
94
     * Ensure that io_apic has unique ID.
Line 350... Line 350...
350
    io_apic[IOWIN] = x;
350
    io_apic[IOWIN] = x;
351
}
351
}
352
 
352
 
353
void io_apic_change_ioredtbl(int signal, int dest, __u8 v, int flags)
353
void io_apic_change_ioredtbl(int signal, int dest, __u8 v, int flags)
354
{
354
{
355
    __u32 reglo, reghi;
355
    io_redirection_reg_t reg;
356
    int dlvr = 0;
356
    int dlvr = 0;
357
   
357
   
358
    if (flags & LOPRI)
358
    if (flags & LOPRI)
359
        dlvr = 1;
359
        dlvr = DELMOD_LOWPRI;
-
 
360
 
360
   
361
   
361
    reglo = io_apic_read(IOREDTBL + signal*2);
362
    reg.lo = io_apic_read(IOREDTBL + signal*2);
362
    reghi = io_apic_read(IOREDTBL + signal*2 + 1);
363
    reg.hi = io_apic_read(IOREDTBL + signal*2 + 1);
363
   
364
   
364
    reghi &= ~0x0f000000;
365
    reg.dest =  dest;
365
    reghi |= (dest<<24);
366
    reg.destmod = DESTMOD_LOGIC;
366
 
-
 
367
    reglo &= (~0x1ffff) | (1<<16); /* don't touch the mask */
367
    reg.trigger_mode = TRIGMOD_EDGE;
368
    reglo |= (0<<15) | (0<<13) | (0<<11) | (dlvr<<8) | v;
368
    reg.intpol = POLARITY_HIGH;
-
 
369
    reg.delmod = dlvr;
-
 
370
    reg.intvec = v;
369
 
371
 
370
    io_apic_write(IOREDTBL + signal*2, reglo);     
372
    io_apic_write(IOREDTBL + signal*2, reg.lo);
371
    io_apic_write(IOREDTBL + signal*2 + 1, reghi);
373
    io_apic_write(IOREDTBL + signal*2 + 1, reg.hi);
372
}
374
}
373
 
375
 
374
void io_apic_disable_irqs(__u16 irqmask)
376
void io_apic_disable_irqs(__u16 irqmask)
375
{
377
{
-
 
378
    io_redirection_reg_t reg;
376
    int i,pin;
379
    int i, pin;
377
    __u32 reglo;
-
 
378
   
380
   
379
    for (i=0;i<16;i++) {
381
    for (i=0;i<16;i++) {
380
        if ((irqmask>>i) & 1) {
382
        if ((irqmask>>i) & 1) {
381
            /*
383
            /*
382
             * Mask the signal input in IO APIC if there is a
384
             * Mask the signal input in IO APIC if there is a
383
             * mapping for the respective IRQ number.
385
             * mapping for the respective IRQ number.
384
             */
386
             */
385
            pin = mps_irq_to_pin(i);
387
            pin = smp_irq_to_pin(i);
386
            if (pin != -1) {
388
            if (pin != -1) {
387
                reglo = io_apic_read(IOREDTBL + pin*2);
389
                reg.lo = io_apic_read(IOREDTBL + pin*2);
388
                reglo |= (1<<16);
390
                reg.masked = true;
389
                io_apic_write(IOREDTBL + pin*2,reglo);
391
                io_apic_write(IOREDTBL + pin*2, reg.lo);
390
            }
392
            }
391
           
393
           
392
        }
394
        }
393
    }
395
    }
394
}
396
}
395
 
397
 
396
void io_apic_enable_irqs(__u16 irqmask)
398
void io_apic_enable_irqs(__u16 irqmask)
397
{
399
{
398
    int i,pin;
400
    int i, pin;
399
    __u32 reglo;
401
    io_redirection_reg_t reg;  
400
   
402
   
401
    for (i=0;i<16;i++) {
403
    for (i=0;i<16;i++) {
402
        if ((irqmask>>i) & 1) {
404
        if ((irqmask>>i) & 1) {
403
            /*
405
            /*
404
             * Unmask the signal input in IO APIC if there is a
406
             * Unmask the signal input in IO APIC if there is a
405
             * mapping for the respective IRQ number.
407
             * mapping for the respective IRQ number.
406
             */
408
             */
407
            pin = mps_irq_to_pin(i);
409
            pin = smp_irq_to_pin(i);
408
            if (pin != -1) {
410
            if (pin != -1) {
409
                reglo = io_apic_read(IOREDTBL + pin*2);
411
                reg.lo = io_apic_read(IOREDTBL + pin*2);
410
                reglo &= ~(1<<16);
412
                reg.masked = false;
411
                io_apic_write(IOREDTBL + pin*2,reglo);
413
                io_apic_write(IOREDTBL + pin*2, reg.lo);
412
            }
414
            }
413
           
415
           
414
        }
416
        }
415
    }
417
    }
416
 
418