Ok yet again. Sorry for the semi-profuse emailing. I think the problem 
is that Linux doesn't recognize an external interrupt, aka from an 
external (to the I/O APIC) interrupt controller like an 8259, as being 
from an 8259 and representing the 8254 timer unless it's specified as 
belonging to the ISA bus in the MP tables. Fun fun. I'm taking a break 
and then I'll give that a shot.

Gabe

Gabe Black wrote:
> Gabe Black wrote:
>   
>>     I'm trying to figure out why the kernel isn't unmasking an IRQ it's 
>> trying to wait for, and it would really help if I could get a source and 
>> disassembly listing from objdump. I've tried it with the kernel I've 
>> been running, but for some reason it doesn't include any source lines. 
>> If somebody knows how to get this to work please let me know.
>>
>> Gabe
>> _______________________________________________
>> m5-dev mailing list
>> [email protected]
>> http://m5sim.org/mailman/listinfo/m5-dev
>>   
>>     
> Ok, I figured out what line the problem is on. It's line 675 of 
> arch/x86_64/kernel/io_apic.c in function __assign_irq_vector. It looks 
> like it's comparing the mask of processors that could accept the 
> interrupt (I think) with the "domain" member of the irq configuration. I 
> don't know what that "domain" is or why it's set. It also only seems to 
> need to check the domain if old_vector is set to something, so I think 
> what it's doing is checking if the irq already has a vector assigned to 
> it, and if so then bailing out. Unfortunately, that means that it never 
> unmasks the redirection table entry in the I/O APIC that would let the 
> timer interrupt through, and then it waits for it until it dies. The 
> interrupt wouldn't get through anyway because I haven't built that yet, 
> but the interrupt never tries to get through because the APIC is set to 
> mask it. Does anybody know what it's trying to do in that function and 
> what that domain member is/is for? The function is below.
>
> Once I get that figured out, I'll immediately be blocked by needing to 
> figure out how the various APICs will communicate over the memory 
> system, namely how the local APIC in the CPU will be exposed to the 
> outside world. I'll also eventually need a better way of assigning APIC 
> ids and figuring out what the system configuration looks like to install 
> in the MP configuration table.
>
> Gabe
>
>
>
> static int __assign_irq_vector(int irq, cpumask_t mask)
> {
>     /*
>      * NOTE! The local APIC isn't very good at handling
>      * multiple interrupts at the same interrupt level.
>      * As the interrupt level is determined by taking the
>      * vector number and shifting that right by 4, we
>      * want to spread these out a bit so that they don't
>      * all fall in the same interrupt level.
>      *
>      * Also, we've got to be careful not to trash gate
>      * 0x80, because int 0x80 is hm, kind of importantish. ;)
>      */
>     static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0;
>     unsigned int old_vector;
>     int cpu;
>     struct irq_cfg *cfg;
>
>     BUG_ON((unsigned)irq >= NR_IRQS);
>     cfg = &irq_cfg[irq];
>
>     /* Only try and allocate irqs on cpus that are present */
>     cpus_and(mask, mask, cpu_online_map);
>
>     if ((cfg->move_in_progress) || cfg->move_cleanup_count)
>         return -EBUSY;
>
>     old_vector = cfg->vector;
>     if (old_vector) {
>         cpumask_t tmp;
>         cpus_and(tmp, cfg->domain, mask);
>         if (!cpus_empty(tmp))
>             return 0;
>     }
>
>     for_each_cpu_mask(cpu, mask) {
>         cpumask_t domain, new_mask;
>         int new_cpu;
>         int vector, offset;
>
>         domain = vector_allocation_domain(cpu);
>         cpus_and(new_mask, domain, cpu_online_map);
>
>         vector = current_vector;
>         offset = current_offset;
> next:
>         vector += 8;
>         if (vector >= FIRST_SYSTEM_VECTOR) {
>             /* If we run out of vectors on large boxen, must share them. */
>             offset = (offset + 1) % 8;
>             vector = FIRST_DEVICE_VECTOR + offset;
>         }
>         if (unlikely(current_vector == vector))
>             continue;
>         if (vector == IA32_SYSCALL_VECTOR)
>             goto next;
>         for_each_cpu_mask(new_cpu, new_mask)
>             if (per_cpu(vector_irq, new_cpu)[vector] != -1)
>                 goto next;
>         /* Found one! */
>         current_vector = vector;
>         current_offset = offset;
>         if (old_vector) {
>             cfg->move_in_progress = 1;
>             cfg->old_domain = cfg->domain;
>         }
>         for_each_cpu_mask(new_cpu, new_mask)
>             per_cpu(vector_irq, new_cpu)[vector] = irq;
>         cfg->vector = vector;
>         cfg->domain = domain;
>         return 0;
>     }
>     return -ENOSPC;
> }
>
> _______________________________________________
> m5-dev mailing list
> [email protected]
> http://m5sim.org/mailman/listinfo/m5-dev
>   

_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to