--- 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 <asm/macints.h>

-/* FIXME: should go into <asm/macints.h> */
-#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<<i)) {
                               if (irq_flags[*viaidx].disabled & (1<<i)) {
                                       /* irq disabled -> 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<<i);
                               } else {
                                       /* irq enabled -> 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<<i))
                           && !(irq_flags[*viaidx].disabled & (1<<i)) ) {
                               /* call handler for re-enabled irq */
-#ifdef DEBUG_VIA
-                               printk("via_irq: irq %d pending %d -> %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<<i);
@@ -588,7 +629,7 @@
               ct++;
               if(events && ct>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<<i)) {
@@ -723,7 +759,7 @@
                                       printk("rbv - bashing source %d\n",
                                               i);
                                       via_write(via, rIER, 1<<i);
-                                       via_write(via, rIFR, 1<<i|0x80);
+                                       via_write(via, rIFR, (1<<i) | rbv_clear);
                               }
                       }
                       break;
@@ -841,6 +877,9 @@
               else
                       map = ~via_read(via2_regp, vBufA);

+#ifdef DEBUG_VIA
+               printk("nubus_irq: map %x mask %x\n", map, nubus_active);
+#endif
               if( (map = (map&nubus_active)) ==0 )
                       break;

@@ -849,6 +888,7 @@
                       printk("nubus stuck events - %d/%d\n", map, nubus_active);
                       return;
               }
+
               for(i=0;i<7;i++)
               {
                       if(map&(1<<i))
--- linux-2.0.29/drivers/nubus/nubus.c.270897-1 Mon Sep 22 05:44:45 1997
+++ linux-2.0.29/drivers/nubus/nubus.c  Mon Sep 22 04:26:27 1997
@@ -14,6 +14,10 @@
#include <asm/setup.h>
#include <asm/system.h>
#include <asm/page.h>
+/* for LCIII stuff; better find a general way like MACH_HAS_NUBUS */
+#include <asm/macintosh.h>
+
+#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);