--- linux-2.0.29/arch/m68k/kernel/head.S.270897-1 Sun Sep 21 18:55:48 1997 +++ linux-2.0.29/arch/m68k/kernel/head.S Sun Sep 21 19:01:49 1997 @@ -160,14 +160,12 @@ #define is_060(lab) btst &D6B_060,%d6; jne lab #define is_not_060(lab) btst &D6B_060,%d6; jeq lab -/* - * misc defines for test hacks - */ #define CONFIG_MAC -/*#define DEBUG_MAC*/ + /*#define CONFIG_MAC_ONLY*/ #define FPU -#define MACSERIAL + +#undef MACSERIAL ENTRY(_stext) /* @@ -214,7 +212,6 @@ /* * Copy bootinfo from position after BSS to final resting place - * (regardless if it makes sense; i.e. for the NetBSD booter) */ lea %pc@(SYMBOL_NAME(_end)),%a0 lea %pc@(SYMBOL_NAME(boot_info)),%a1 @@ -288,7 +285,6 @@ cmpl #0x50656e00,%d1 jeq Ltest_penguin - /* okay, so it's the MacBSD booter, not Penguin */ /* @@ -377,14 +373,22 @@ */ Ltest_penguin: +#if 0 + jbsr Lserial_init + + putr() + putc('L') + putc('i') + putc('n') + putc('u') + putc('x') + putc('.') + putr() +#endif + /* * Yes this isnt the clean way to do it. I need to revise * my 68k asm. - * MS: No sweat, Alan. I learned a lot from it :-) - */ - - /* - * clear screen (first write to screen!) .... */ lea %pc@(SYMBOL_NAME(boot_info)),%a0 movel %a0@(BI_videoaddr), %a1 @@ -398,10 +402,7 @@ dbra %d1,loopy /* - * 5 rows white at the top ... - * - plus a few more bytes, which get partially overwritten as - * the boot proceeds, black and white in turn. - * Crude hack, but I need some kind of process indicator ... + * check how far we got ... */ movel %a0@(BI_videoaddr),%a1 movel %a0@(BI_videorow),%d0 @@ -414,33 +415,26 @@ moveb #0x00, %a1@+ dbra %d0,loopw /* white + 9 bytes */ - /* - * write what we determined to be the videoaddr to the screen - * Note: if we got this wrong enough, we won't see it anyway. - */ movel %a0@(BI_videoaddr), %a1@+ /* video addr. */ - moveb #0xFF, %a1@+ - moveb #0x00, %a1@+ /* b/w: spacer */ - - /* - * write kernel start address to the screen - */ + moveb #0x00, %a1@+ /* b/w */ +#if 0 /* don't clobber videoaddr!! */ + movel %a1, %a0@(BI_videoaddr) /* save screen pointer */ +#endif lea %pc@(SYMBOL_NAME(_stext):w),%a0 movel %a0,%d0 /* get start addr. */ + + lea %pc@(SYMBOL_NAME(boot_info)),%a0 +#if 0 /* a1 preserved */ + movel %a0@(BI_videoaddr), %a1 /* restore screen pointer */ +#endif movel %d0, %a1@+ /* write start addr. */ moveb #0xFF, %a1@+ - moveb #0x00, %a1@+ /* b/w: spacer */ - - /* - * restore register a0 (used for accessing bootinfo below) - */ - lea %pc@(SYMBOL_NAME(boot_info)),%a0 + moveb #0x00, %a1@+ /* b/w */ Ltest_notmac: - /* * Re-record the CPU and machine type (we just clobbered d0 and d4 :=( if * booting with NetBSD ...). @@ -454,19 +448,6 @@ */ #endif - jbsr Lserial_init - -#ifdef SERIAL_DEBUG - putr() - putc('L') - putc('i') - putc('n') - putc('u') - putc('x') - putc('.') - putr() -#endif - btst #CPUB_68060,%d0 jeq 1f /* '060: d6 := BIT0460|BIT060, cache mode 0x60 (no-cache/non-ser) */ @@ -479,6 +460,7 @@ jra 2f 1: /* '020 or '030: d6 := no CPU bit, cache mode unused */ moveq #0,%d6 + 2: lea %pc@(SYMBOL_NAME(m68k_pgtable_cachemode)),%a0 moveq #0,%d0 movew %d6,%d0 @@ -536,9 +518,7 @@ * Initialize serial port */ jbsr Lserial_init -#endif -#ifdef SERIAL_DEBUG putr() putc('A') #endif @@ -591,7 +571,7 @@ 2: #endif -#ifdef SERIAL_DEBUG +#ifndef CONFIG_MAC putc('B') #endif @@ -615,16 +595,9 @@ addl %d0,%d0 /* 7 rows */ movel %d5,%a0@(%d0) -#endif -#ifdef MAC_HARDCODE_START - /* - * XXX: This is a bummer - without DEBUG_MAC defined never seen before! - */ movel #0,%d5 -#endif -#ifdef DEBUG_MAC /* just testing if we arrived here ... pattern interrupted if not! */ lea %pc@(SYMBOL_NAME(boot_info)),%a0 movel %a0@(BI_videorow),%d0 /* rowbytes */ @@ -701,7 +674,7 @@ 2: #endif -#ifdef SERIAL_DEBUG +#if 0 putc('C') #endif @@ -772,7 +745,7 @@ 2: #endif -#ifdef SERIAL_DEBUG +#if 0 putc('D') #endif @@ -785,7 +758,7 @@ */ is_not_040_or_060(Lnot040) -#ifdef SERIAL_DEBUG +#if 0 putc('F') #endif @@ -855,7 +828,7 @@ * non-cacheable. */ -#ifdef SERIAL_DEBUG +#if 0 putc('H') #endif @@ -867,7 +840,7 @@ * using an early termination page descriptor. */ -#ifdef SERIAL_DEBUG +#if 0 putc('I') #endif @@ -952,7 +925,7 @@ * as non-cacheable. (040/060 one still wrong XXX) */ -#ifdef SERIAL_DEBUG +#if 0 putc('H') #endif @@ -979,7 +952,7 @@ * using an early termination page descriptor. */ -#ifdef SERIAL_DEBUG +#if 0 putc('I') #endif @@ -1024,7 +997,6 @@ orl #0x60000000,%d0 movel %d0,%a5@(0x4F<<2) -#if 1 /* * MAC RAM identity at 0x00000000 - required for SE/30 and IIcx * syntax: physbase | _PAGE_NOCACHE030 | _PAGE_PRESENT @@ -1034,17 +1006,6 @@ moveq #_PAGE_NOCACHE030+_PAGE_PRESENT,%d0 orl #0x00000000,%d0 movel %d0,%a5@(0x00<<2) -#endif - -#if 0 - /* - * MAC RAM 0x80000000 -> 0x00000000 - doesn't help :-( - */ - - moveq #_PAGE_NOCACHE030+_PAGE_PRESENT,%d0 - orl #0x00000000,%d0 - movel %d0,%a5@(0x40<<2) -#endif #ifdef DEBUG_MAC lea %pc@(SYMBOL_NAME(boot_info)),%a0 @@ -1260,7 +1221,7 @@ */ Lmapphys: -#ifdef SERIAL_DEBUG +#if 0 putc('J') #endif @@ -1286,7 +1247,7 @@ * setup translation register contents and enable translation. */ -#ifdef SERIAL_DEBUG +#if 0 putc('K') #endif @@ -1363,7 +1324,7 @@ * transparent translation where the kernel is executing. */ -#ifdef SERIAL_DEBUG +#if 0 putc('L') #endif @@ -1468,7 +1429,7 @@ dbra %d0,1b #endif -#ifdef SERIAL_DEBUG +#if 0 putc('L') #endif @@ -1514,11 +1475,10 @@ tstl %a1 jra LdoneMMUenable - /* NOT reached (and if we would try to write to screenmem after MMU + /* NOT reached (and if we try to write to screenmem after MMU * enable - what happens??) */ -#if 0 #ifdef DEBUG_MAC lea %pc@(SYMBOL_NAME(boot_info)),%a0 movel %a0@(BI_videorow),%d0 /* rowbytes */ @@ -1533,7 +1493,6 @@ moveb #0xF0,%a0@+ /* white/black - 3 bytes */ dbra %d0,1b #endif -#endif Lmapphysnotmac: #endif @@ -1562,9 +1521,8 @@ 2: #endif -#ifdef SERIAL_DEBUG - putc('M') -#endif +/* putc('M')*/ + /* * d5 contains physaddr of kernel start */ @@ -1577,9 +1535,7 @@ subl %d5,%a6 movel %a6,SYMBOL_NAME(availmem) /* first available memory address */ -#ifdef SERIAL_DEBUG - putc('N') -#endif +/* putc('N')*/ #if 0 putr() @@ -1605,7 +1561,6 @@ putr() dbra %d0,1b #endif - /* * Enable caches */ @@ -1864,9 +1819,8 @@ moveb %d0,%a0@ moveb %a1@+,%a0@ jra 2b -3: clrb %a0@ +3: #endif /* MACSERIAL */ - #endif 9: rts --- linux-2.0.29/arch/m68k/mac/macints.c.270897-1 Mon Sep 22 05:44:45 1997 +++ linux-2.0.29/arch/m68k/mac/macints.c Mon Sep 22 05:51:26 1997 @@ -6,22 +6,27 @@ * exclusively use the autovector interrupts (the 'generic level0-level7' * interrupts with exception vectors 0x19-0x1f). The following interrupt levels * are used: - * 1 - VIA1 ??? + * 1 - VIA1 * - slot 0: one second interrupt * - slot 1: VBlank * - slot 2: ADB data ready * - slot 3: ADB data * - slot 4: ADB clock + * - slot 5: timer 2 * - slot 6: timer 1 - * - slot 7: timer 2 + * - slot 7: status of IRQ; signals 'any enabled int.' * * 2 - VIA2, RBV or OSS * - slot 0: SCSI DRQ * - slot 1: NUBUS IRQ * - slot 3: SCSI IRQ + * * 4 - SCC + * * 6 - Off switch (??) * + * 7 - Debug output + * * Using the autovector irq numbers for Linux/m68k hardware interrupts without * the IRQ_MACHSPEC bit set would interfere with the general m68k interrupt * handling in kernel versions 2.0.x, so the following strategy is used: @@ -67,17 +72,6 @@ #include -/* FIXME: should go into */ -#if 0 -extern void via1_irq(int irq, void *dev_id, struct pt_regs *regs); -extern void via2_irq(int irq, void *dev_id, struct pt_regs *regs); -static void via_do_nubus(int slot, volatile void *via, struct pt_regs *regs); -extern void mac_bang(int irq, void *dev_id, struct pt_regs *regs); - -asmlinkage void bad_interrupt(void); -#endif -void nubus_wtf(int slot, void *via, struct pt_regs *regs); - /* * Interrupt handler and parameter types */ @@ -132,17 +126,40 @@ static volatile unsigned char *via_table[8]; +#ifdef VIABASE_WEIRDNESS /* - * Flag to control via2 behaviour + * VIA2 / RBV default base address + */ + +volatile unsigned char *via2_regp = ((volatile unsigned char *)VIA2_BAS); +volatile unsigned char *rbv_regp = ((volatile unsigned char *)VIA2_BAS_IIci); +#endif + +/* + * Flags to control via2 / rbv behaviour */ static int via2_is_rbv = 0; +static int rbv_clear = 0; + +/* + * console_loglevel determines NMI handler function + */ + +extern int console_loglevel; /* Defined in entry.S; only increments 'num_spurious' */ asmlinkage void bad_interrupt(void); +void nubus_wtf(int slot, void *via, struct pt_regs *regs); + +void mac_nmi_handler(int irq, void *dev_id, struct pt_regs *regs); +void mac_debug_handler(int irq, void *dev_id, struct pt_regs *regs); + static void via_do_nubus(int slot, void *via, struct pt_regs *regs); +#define DEBUG_VIA + void mac_init_IRQ(void) { int i; @@ -159,20 +176,32 @@ /* via2 or rbv?? */ if (macintosh_config->via_type == MAC_VIA_IIci) { + /* VIA2 is part of the RBV: different base, other offsets */ via2_is_rbv = 1; + /* LC III weirdness: IFR seems to behave like VIA2 */ + /* FIXME: maybe also for LC II ?? */ + if (macintosh_config->ident == MAC_MODEL_LCIII) { + rbv_clear = 0x0; + } else { + rbv_clear = 0x80; + } /* level 2 IRQ: RBV/OSS; we only care about RBV for now */ request_irq(2, rbv_irq, IRQ_FLG_LOCK, "rbv", rbv_irq); } else - /* level 2 IRQ: VIA2; we only care about VIA2 for now */ + /* level 2 IRQ: VIA2 */ request_irq(2, via2_irq, IRQ_FLG_LOCK, "via2", via2_irq); -#if 0 +#if 1 /* level 4 IRQ: SCC - what's the interrupt routine there??*/ /* moved to the SCC code anyway */ - request_irq(4, bad_interrupt, IRQ_FLG_STD, "via2", via2_irq); + request_irq(4, mac_debug_handler, IRQ_FLG_STD, "INT4", mac_debug_handler); + request_irq(5, mac_debug_handler, IRQ_FLG_STD, "INT5", mac_debug_handler); #endif - /* level 6 (or 7??) */ + /* level 6 */ request_irq(6, mac_bang, IRQ_FLG_LOCK, "offswitch", mac_bang); + /* level 7 (or NMI) */ + request_irq(7, mac_nmi_handler, IRQ_FLG_STD, "NMI", mac_nmi_handler); + /* initialize the handler tables for VIAs */ for (i = 0; i < 8; i++) { via1_handler[i].handler = mac_default_handler; @@ -254,18 +283,11 @@ return -EINVAL; } -#if 0 - if (irq >= IRQ_IDX(IRQ_SCC)) { - /* ?? do nothing */ - return 0; - } -#endif - /* figure out what VIA is handling this irq */ if (irq >= IRQ_IDX(IRQ_SCC) || irq < IRQ_IDX(IRQ_VIA1_1)) { - /* via = rbv etc.; unimplemented */ + /* non-via irqs unimplemented */ printk ("%s: Bad irq source %d on VIA %d requested from %s\n", - __FUNCTION__, irq, srcidx+1, devname); + __FUNCTION__, irq, srcidx, devname); return -EINVAL; } @@ -296,7 +318,6 @@ * Set vPCR for SCSI interrupts. (what about RBV here?) */ via_write(via, vPCR, 0x66); - } return 0; @@ -316,13 +337,9 @@ __FUNCTION__, irq, srcidx+1, irqidx); #endif - if (irq >= IRQ_IDX(IRQ_SCC)) - /* ?? do nothing */ - return 0; - /* figure out what VIA is handling this irq */ - if (irq >= IRQ_IDX(IRQ_RBV_1) || irq < IRQ_IDX(IRQ_VIA1_1)) { - /* via = rbv etc.; unimplemented */ + if (irq >= IRQ_IDX(IRQ_SCC) || irq < IRQ_IDX(IRQ_VIA1_1)) { + /* non-via irqs unimplemented */ return -EINVAL; } @@ -370,6 +387,9 @@ * by the VIA interrupt routine which should ignore requests for masked IRQs * (after possibly ack'ing them). * + * On second thought: some of the IRQ sources _can_ be turned off via bits + * in the VIA output registers. Need to check this ... + * * TBI: According to the VIA docs, clearing a bit in the IER has the effect of * blocking generation of the interrupt, but the internal interrupt condition * is preserved. So the IER might be used as mask register here, and turnon_irq @@ -478,7 +498,7 @@ { volatile unsigned char deep_magic; if (via2_is_rbv) - via_write(via2_regp, rIFR, (1<<3)|(1<<0)|0x80); + via_write(rbv_regp, rIFR, (1<<3)|(1<<0)|0x80); deep_magic = via_read(via2_regp, vBufB); mac_enable_irq( IRQ_IDX(IRQ_MAC_SCSI) ); } @@ -486,11 +506,44 @@ void mac_default_handler(int irq, void *dev_id, struct pt_regs *regs) { -#ifdef DEBUG_MACINTS +#ifdef DEBUG_VIA printk("Unexpected IRQ %d\n", irq); #endif } +static int num_debug[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + +void mac_debug_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + if (num_debug[irq] < 10) { + printk("DEBUG: Unexpected IRQ %d\n", irq); + num_debug[irq]++; + } +} + + +void mac_nmi_handler(int irq, void *dev_id, struct pt_regs *fp) +{ + /* + * generate debug output on NMI switch if 'debug' kernel option given + * (only works with Penguin!) + */ + if ( console_loglevel == 10 ) { + show_state(); + printk("PC: %08lx\nSR: %04x SP: %p\n", fp->pc, fp->sr, fp); + printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n", + fp->d0, fp->d1, fp->d2, fp->d3); + printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n", + fp->d4, fp->d5, fp->a0, fp->a1); + + if (STACK_MAGIC != *(unsigned long *)current->kernel_stack_page) + printk("Corrupted stack page\n"); + printk("Process %s (pid: %d, stackpage=%08lx)\n", + current->comm, current->pid, current->kernel_stack_page); + dump_stack((struct frame *)fp); + } +} + /* * The generic VIA interrupt routines (shamelessly stolen from Alan Cox's * via6522.c :-), disable/pending masks added. @@ -525,6 +578,11 @@ } #ifdef DEBUG_VIA + /* + * limited verbosity for VIA interrupts + */ + if ( (*viaidx == 0 && events != 1<<6) /* timer int */ + || (*viaidx == 1 && events != 1<<3) ) /* SCSI IRQ */ printk("via_irq: irq %d events %x !\n", *viaidx, events); #endif @@ -547,20 +605,9 @@ if (events&(1< mark pending */ -#ifdef DEBUG_VIA - printk("via_irq: irq %d(%d) disabled %d -> %p\n", - *viaidx, i, irq, - *via_handler->handler[i]); -#endif irq_flags[*viaidx].pending |= (1< call handler */ -#ifdef DEBUG_VIA - printk("via_irq: irq %d(%d) source %d -> %p\n", - *viaidx, i, irq, - via_handler[i].handler); -#endif - (via_handler[i].handler)(irq, via, regs); } } @@ -568,12 +615,6 @@ if ( (irq_flags[*viaidx].pending & (1< %p -> %p\n", - *viaidx, i, - via_handler->handler[i], - *via_handler[i].handler); -#endif (via_handler[i].handler)(irq, via, regs); /* and clear pending flag :-) */ irq_flags[*viaidx].pending &= ~(1<8) { - printk("via: stuck events %x\n",events); + printk("via%d: stuck events %x\n", (*viaidx)+1, events); break; } } @@ -614,9 +655,6 @@ void via1_irq(int irq, void *dev_id, struct pt_regs *regs) { int srcidx = IRQ_IDX(irq) - 1; -#ifdef DEBUG_VIA - printk("via1_irq: irq %d srcidx %d !\n", irq, srcidx); -#endif via_irq((unsigned char *)via1_regp, &srcidx, regs); } @@ -629,9 +667,6 @@ void via2_irq(int irq, void *dev_id, struct pt_regs *regs) { int srcidx = IRQ_IDX(irq) - 1; -#ifdef DEBUG_VIA - printk("via2_irq: irq %d srcidx %d !\n", irq, srcidx); -#endif via_irq((unsigned char *)via2_regp, &srcidx, regs); } @@ -679,7 +714,7 @@ * Clear the pending flag */ - via_write(via, rIFR, events|0x80); + via_write(via, rIFR, events | rbv_clear); /* * Now see what bits are raised @@ -687,6 +722,7 @@ for(i=0;i<7;i++) { + /* determine machspec. irq no. */ int irq = (srcidx+1)* 8 + i; /* call corresponding handlers */ if (events&(1< #include #include +/* for LCIII stuff; better find a general way like MACH_HAS_NUBUS */ +#include + +#define LCIII_WEIRDNESS static struct nubus_slot nubus_slots[16]; @@ -520,6 +524,7 @@ int i; for(i=9;i<15;i++) { + printk("nubus: probing slot %d !\n", i); nubus_probe_slot(i, 0); } } @@ -590,8 +595,6 @@ return ng; } - - void nubus_init(void) { /* @@ -603,6 +606,13 @@ printk("ERROR: not a Mac, skipping nubus_init!\n"); return; } + +#ifdef LCIII_WEIRDNESS + if (macintosh_config->ident == MAC_MODEL_LCIII) { + printk("nubus init: LCIII has no nubus!\n"); + return; + } +#endif #ifdef CONFIG_DAYNAPORT register_nubus_device(&nubus_8390);