diff -ur LINUX/linux-2.4.10/arch/alpha/kernel/setup.c PATCH/linux-2.4.10/arch/alpha/kernel/setup.c --- LINUX/linux-2.4.10/arch/alpha/kernel/setup.c Thu Aug 16 23:48:33 2001 +++ PATCH/linux-2.4.10/arch/alpha/kernel/setup.c Thu Sep 27 17:45:08 2001 @@ -85,7 +93,7 @@ static struct alpha_machine_vector *get_sysvec(long, long, long); static struct alpha_machine_vector *get_sysvec_byname(const char *); -static void get_sysnames(long, long, char **, char **); +static void get_sysnames(long, long, long, char **, char **); static char command_line[COMMAND_LINE_SIZE]; char saved_command_line[COMMAND_LINE_SIZE]; @@ -537,14 +545,14 @@ /* * Indentify and reconfigure for the current system. */ + cpu = (struct percpu_struct*)((char*)hwrpb + hwrpb->processor_offset); + get_sysnames(hwrpb->sys_type, hwrpb->sys_variation, - &type_name, &var_name); + cpu->type, &type_name, &var_name); if (*var_name == '0') var_name = ""; if (!vec) { - cpu = (struct percpu_struct*) - ((char*)hwrpb + hwrpb->processor_offset); vec = get_sysvec(hwrpb->sys_type, hwrpb->sys_variation, cpu->type); } @@ -801,6 +809,8 @@ /* Member ID is a bit-field. */ long member = (variation >> 10) & 0x3f; + cpu &= 0xffffffff; /* make it usable */ + switch (type) { case ST_DEC_ALCOR: if (member < N(alcor_indices)) @@ -809,6 +819,10 @@ case ST_DEC_EB164: if (member < N(eb164_indices)) vec = eb164_vecs[eb164_indices[member]]; + /* PC164 may show as EB164 variation with EV56 CPU, + but, since no true EB164 had anything but EV5... */ + if (vec == &eb164_mv && cpu == EV56_CPU) + vec = &pc164_mv; break; case ST_DEC_EB64P: if (member < N(eb64p_indices)) @@ -827,21 +841,18 @@ vec = tsunami_vecs[tsunami_indices[member]]; break; case ST_DEC_1000: - cpu &= 0xffffffff; if (cpu == EV5_CPU || cpu == EV56_CPU) vec = &mikasa_primo_mv; else vec = &mikasa_mv; break; case ST_DEC_NORITAKE: - cpu &= 0xffffffff; if (cpu == EV5_CPU || cpu == EV56_CPU) vec = &noritake_primo_mv; else vec = &noritake_mv; break; case ST_DEC_2100_A500: - cpu &= 0xffffffff; if (cpu == EV5_CPU || cpu == EV56_CPU) vec = &sable_gamma_mv; else @@ -905,7 +916,7 @@ } static void -get_sysnames(long type, long variation, +get_sysnames(long type, long variation, long cpu, char **type_name, char **variation_name) { long member; @@ -938,12 +949,18 @@ member = (variation >> 10) & 0x3f; /* member ID is a bit-field */ + cpu &= 0xffffffff; /* make it usable */ + switch (type) { /* select by family */ default: /* default to variation "0" for now */ break; case ST_DEC_EB164: if (member < N(eb164_indices)) *variation_name = eb164_names[eb164_indices[member]]; + /* PC164 may show as EB164 variation, but with EV56 CPU, + so, since no true EB164 had anything but EV5... */ + if (eb164_indices[member] == 0 && cpu == EV56_CPU) + *variation_name = eb164_names[1]; /* make it PC164 */ break; case ST_DEC_ALCOR: if (member < N(alcor_indices)) @@ -1054,7 +1071,7 @@ cpu_name = cpu_names[cpu_index]; get_sysnames(hwrpb->sys_type, hwrpb->sys_variation, - &systype_name, &sysvariation_name); + cpu->type, &systype_name, &sysvariation_name); nr_processors = get_nr_processors(cpu, hwrpb->nr_processors); diff -ur LINUX/linux-2.4.10/arch/alpha/kernel/sys_cabriolet.c PATCH/linux-2.4.10/arch/alpha/kernel/sys_cabriolet.c --- LINUX/linux-2.4.10/arch/alpha/kernel/sys_cabriolet.c Sat Feb 24 22:54:55 2001 +++ PATCH/linux-2.4.10/arch/alpha/kernel/sys_cabriolet.c Fri Sep 28 10:34:51 2001 @@ -106,12 +106,12 @@ } static void __init -cabriolet_init_irq(void) +common_init_irq(void (*srm_dev_int)(unsigned long v, struct pt_regs *r)) { init_i8259a_irqs(); if (alpha_using_srm) { - alpha_mv.device_interrupt = srm_device_interrupt; + alpha_mv.device_interrupt = srm_dev_int; init_srm_irqs(35, 0); } else { @@ -131,8 +131,43 @@ setup_irq(16+4, &isa_cascade_irqaction); } +static void __init +cabriolet_init_irq(void) +{ + common_init_irq(srm_device_interrupt); +} + #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_PC164) static void +pc164_srm_device_interrupt(unsigned long v, struct pt_regs *r) +{ + /* In theory, the PC164 has the same interrupt hardware as + the other Cabriolet based systems. However, something + got screwed up late in the development cycle which broke + the interrupt masking hardware. Repeat, it is not + possible to mask and ack interrupts. At all. + + In an attempt to work around this, while processing + interrupts, we do not allow the IPL to drop below what + it is currently. This prevents the possibility of + recursion. + + ??? Another option might be to force all PCI devices + to use edge triggered rather than level triggered + interrupts. That might be too invasive though. */ + + __min_ipl = getipl(); + srm_device_interrupt(v, r); + __min_ipl = 0; +} + +static void __init +pc164_init_irq(void) +{ + common_init_irq(pc164_srm_device_interrupt); +} + +static void pc164_device_interrupt(unsigned long v, struct pt_regs *r) { /* In theory, the PC164 has the same interrupt hardware as @@ -419,7 +454,7 @@ device_interrupt: pc164_device_interrupt, init_arch: cia_init_arch, - init_irq: cabriolet_init_irq, + init_irq: pc164_init_irq, init_rtc: common_init_rtc, init_pci: alphapc164_init_pci, pci_map_irq: alphapc164_map_irq,