--- 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);