Module Name: src
Committed By: phx
Date: Tue Feb 2 19:15:33 UTC 2010
Modified Files:
src/sys/arch/amigappc/amigappc: autoconf.c machdep.c p5reg.h
pic_amiga.c
Log Message:
Rewrote the "amiga" PIC from scratch. Interrupts are based on IPL 1-6 now
and no longer on IRQ 0-13.
Fixed interrupt levels in amigappc_install_handlers() (IPL_SOFTxxx was very
bad!).
Compilation with all (most?) amiga devices was tested and fixed.
Some smaller fixes.
Status:
With Cybervision64 and A3000 SBIC SCSI (with DMA disabled) the system
reaches multiuser!
Lots of problems left...
To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/amigappc/amigappc/autoconf.c \
src/sys/arch/amigappc/amigappc/p5reg.h \
src/sys/arch/amigappc/amigappc/pic_amiga.c
cvs rdiff -u -r1.39 -r1.40 src/sys/arch/amigappc/amigappc/machdep.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/amigappc/amigappc/autoconf.c
diff -u src/sys/arch/amigappc/amigappc/autoconf.c:1.1 src/sys/arch/amigappc/amigappc/autoconf.c:1.2
--- src/sys/arch/amigappc/amigappc/autoconf.c:1.1 Tue Jul 21 09:49:15 2009
+++ src/sys/arch/amigappc/amigappc/autoconf.c Tue Feb 2 19:15:33 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: autoconf.c,v 1.1 2009/07/21 09:49:15 phx Exp $ */
+/* $NetBSD: autoconf.c,v 1.2 2010/02/02 19:15:33 phx Exp $ */
/*
* Copyright (c) 1994 Christian E. Hopps
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.1 2009/07/21 09:49:15 phx Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.2 2010/02/02 19:15:33 phx Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -66,7 +66,6 @@
*/
amiga_realconfig = 1;
custom.intena = INTF_INTEN;
- printf("spl was %d\n",splhigh()); /* XXX */
if (config_rootfound("mainbus", NULL) == NULL)
panic("configure: mainbus not configured");
@@ -75,8 +74,8 @@
printf("survived autoconf, going to enable interrupts\n");
#endif
- custom.intena = INTF_SETCLR | INTF_INTEN;
genppc_cpu_configure();
+ custom.intena = INTF_SETCLR | INTF_INTEN;
#ifdef DEBUG_KERNEL_START
printf("survived configure...\n");
Index: src/sys/arch/amigappc/amigappc/p5reg.h
diff -u src/sys/arch/amigappc/amigappc/p5reg.h:1.1 src/sys/arch/amigappc/amigappc/p5reg.h:1.2
--- src/sys/arch/amigappc/amigappc/p5reg.h:1.1 Tue Jul 21 09:49:15 2009
+++ src/sys/arch/amigappc/amigappc/p5reg.h Tue Feb 2 19:15:33 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: p5reg.h,v 1.1 2009/07/21 09:49:15 phx Exp $ */
+/* $NetBSD: p5reg.h,v 1.2 2010/02/02 19:15:33 phx Exp $ */
/*
* Copyright (C) 2000 Adam Ciarcinski.
@@ -85,6 +85,8 @@
#define P5_PPC_IPL1 0x02
#define P5_PPC_IPL0 0x01
+#define P5_IPL_MASK 0x07
+
/* INT_LVL */
#define P5_LVL7 0x40
#define P5_LVL6 0x20
@@ -98,13 +100,13 @@
#define P5read(reg, val) \
do { \
(val) = *(volatile unsigned char *)(P5BASE + (reg)); \
- __asm volatile("sync"); \
+ __asm volatile("eieio"); \
} while (0);
#define P5write(reg, val) \
do { \
*(volatile unsigned char *)(P5BASE + (reg)) = (val); \
- __asm volatile("sync"); \
+ __asm volatile("eieio"); \
} while (0);
#endif /* _P5REG_H_ */
Index: src/sys/arch/amigappc/amigappc/pic_amiga.c
diff -u src/sys/arch/amigappc/amigappc/pic_amiga.c:1.1 src/sys/arch/amigappc/amigappc/pic_amiga.c:1.2
--- src/sys/arch/amigappc/amigappc/pic_amiga.c:1.1 Tue Jul 21 09:49:15 2009
+++ src/sys/arch/amigappc/amigappc/pic_amiga.c Tue Feb 2 19:15:33 2010
@@ -1,7 +1,7 @@
-/* $NetBSD: pic_amiga.c,v 1.1 2009/07/21 09:49:15 phx Exp $ */
+/* $NetBSD: pic_amiga.c,v 1.2 2010/02/02 19:15:33 phx Exp $ */
/*-
- * Copyright (c) 2008,2009 Frank Wille.
+ * Copyright (c) 2008,2009,2010 Frank Wille.
* All rights reserved.
*
* Written by Frank Wille for The NetBSD Project.
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pic_amiga.c,v 1.1 2009/07/21 09:49:15 phx Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pic_amiga.c,v 1.2 2010/02/02 19:15:33 phx Exp $");
#include <sys/param.h>
#include <sys/malloc.h>
@@ -47,11 +47,16 @@
static void amiga_ack_irq(struct pic_ops *, int);
struct pic_ops *setup_amiga_intr(void);
-#define NIRQ 15
+/*
+ * Number of amigappc hardware interrupts, based on 68000 IPL mask.
+ * In reality 6, because level 0 means no interrupt and level 7 (NMI)
+ * should not happen.
+ */
+#define MAXIPL 7
struct amiga_ops {
struct pic_ops pic;
- int prev_level[NIRQ];
+ int disablemask;
};
struct pic_ops *
@@ -64,7 +69,7 @@
KASSERT(amipic != NULL);
pic = &amipic->pic;
- pic->pic_numintrs = NIRQ;
+ pic->pic_numintrs = MAXIPL;
pic->pic_cookie = (void *)NULL;
pic->pic_enable_irq = amiga_enable_irq;
pic->pic_reenable_irq = amiga_enable_irq;
@@ -73,66 +78,78 @@
pic->pic_ack_irq = amiga_ack_irq;
pic->pic_establish_irq = dummy_pic_establish_intr;
strcpy(pic->pic_name, "amiga");
- memset(amipic->prev_level, 0, NIRQ * sizeof(int));
+
+ /* Set PPC IPL to 7, disabling all interrupts */
+ amipic->disablemask = (1 << MAXIPL) - 1;
+ P5write(P5_IPL_EMU, P5_DISABLE_INT | 7);
+
pic_add(pic);
return pic;
}
static void
-amiga_enable_irq(struct pic_ops *pic, int irq, int type)
+amiga_enable_irq(struct pic_ops *pic, int ipl, int type)
{
+ struct amiga_ops *amipic = (struct amiga_ops *)pic;
+ int iplmask, dmask, newipl;
+
+ iplmask = 1 << ipl;
+ dmask = amipic->disablemask;
- custom.intena = INTF_SETCLR | (1 << irq);
+ if ((dmask & iplmask)) {
+
+ dmask &= ~iplmask;
+ amipic->disablemask = dmask;
+ if (!(dmask & ~(iplmask - 1))) {
+
+ /* Lower the emulated PPC IPL to the next highest */
+ newipl = 31 - cntlzw(dmask);
+ P5write(P5_IPL_EMU, P5_SET_CLEAR | P5_DISABLE_INT |
+ (newipl ^ P5_IPL_MASK));
+ P5write(P5_IPL_EMU, P5_DISABLE_INT | newipl);
+ }
+ }
}
static void
-amiga_disable_irq(struct pic_ops *pic, int irq)
+amiga_disable_irq(struct pic_ops *pic, int ipl)
{
+ struct amiga_ops *amipic = (struct amiga_ops *)pic;
+ int iplmask, dmask;
+
+ iplmask = 1 << ipl;
+ dmask = amipic->disablemask;
+
+ if (!(dmask & iplmask)) {
- custom.intena = 1 << irq;
+ if (!(dmask & ~(iplmask - 1))) {
+
+ /* Raise the emulated PPC IPL to the new ipl */
+ P5write(P5_IPL_EMU, P5_SET_CLEAR | P5_DISABLE_INT |
+ (ipl ^ P5_IPL_MASK));
+ P5write(P5_IPL_EMU, P5_DISABLE_INT | ipl);
+ }
+ amipic->disablemask |= iplmask;
+ }
}
static int
amiga_get_irq(struct pic_ops *pic, int mode)
{
- struct amiga_ops *amipic = (struct amiga_ops *)pic;
- int ipl, levels;
- uint32_t mask;
+ unsigned char ipl;
- /* Compute the interrupt's 68k IPL - the bits are active low */
- P5read(P5_IPL_EMU, levels);
- ipl = ~(levels >> 3) & 7;
-
- /* Store previous PPC IPL to restore on acknowledge */
- if (amipic->prev_level[ipl] != 0)
+ if (mode == PIC_GET_RECHECK)
return 255;
- amipic->prev_level[ipl] = ~levels & 7;
-
- mask = (uint32_t)custom.intreqr & 0x7fff;
- if (mask == 0)
- return 255; /* no interrupt pending - spurious interrupt? */
- /* Raise the emulated PPC IPL to the interrupt's IPL (active low) */
- P5write(P5_IPL_EMU, P5_SET_CLEAR | P5_DISABLE_INT | (ipl ^ 7));
- P5write(P5_IPL_EMU, P5_DISABLE_INT | ipl);
+ /* Get the interrupt's 68k IPL - the bits are active low */
+ P5read(P5_IPL_EMU, ipl);
+ ipl = ~(ipl >> 3) & P5_IPL_MASK;
- return 31 - __builtin_clz(mask);
+ return ipl == 0 ? 255 : ipl;
}
static void
-amiga_ack_irq(struct pic_ops *pic, int irq)
+amiga_ack_irq(struct pic_ops *pic, int ipl)
{
- struct amiga_ops *amipic = (struct amiga_ops *)pic;
- int ipl;
-
- ipl = amipic->prev_level[irq];
- amipic->prev_level[irq] = 0;
-
- /* Acknowledge the interrupt request */
- custom.intreq = (unsigned short)(1 << irq);
-
- /* Lower the emulated PPC IPL to the state before handling this irq */
- P5write(P5_IPL_EMU, P5_SET_CLEAR | P5_DISABLE_INT | (ipl ^ 7));
- P5write(P5_IPL_EMU, P5_DISABLE_INT | ipl);
}
Index: src/sys/arch/amigappc/amigappc/machdep.c
diff -u src/sys/arch/amigappc/amigappc/machdep.c:1.39 src/sys/arch/amigappc/amigappc/machdep.c:1.40
--- src/sys/arch/amigappc/amigappc/machdep.c:1.39 Tue Jul 21 09:49:15 2009
+++ src/sys/arch/amigappc/amigappc/machdep.c Tue Feb 2 19:15:33 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.39 2009/07/21 09:49:15 phx Exp $ */
+/* $NetBSD: machdep.c,v 1.40 2010/02/02 19:15:33 phx Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.39 2009/07/21 09:49:15 phx Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.40 2010/02/02 19:15:33 phx Exp $");
#include "opt_ddb.h"
#include "opt_ipkdb.h"
@@ -65,9 +65,6 @@
#include "fd.h"
#include "ser.h"
-/* prototypes */
-void show_me_regs(void);
-
extern void setup_amiga_intr(void);
#if NSER > 0
extern void ser_outintr(void);
@@ -77,9 +74,6 @@
extern void fdintr(int);
#endif
-/* PIC interrupt handler type */
-typedef int (*ih_t)(void *);
-
/*
* patched by some devices at attach time (currently, only the coms)
*/
@@ -112,12 +106,11 @@
p = &q->isr_forw;
isr->isr_forw = NULL;
*p = isr;
-#if 0 /* XXX always enabled */
+
/* enable interrupt */
custom.intena = isr->isr_ipl == 2 ?
INTF_SETCLR | INTF_PORTS :
INTF_SETCLR | INTF_EXTER;
-#endif
}
void
@@ -133,21 +126,22 @@
*p = q->isr_forw;
else
panic("remove_isr: handler not registered");
-#if 0 /* XXX always enabled, why disable? */
+
/* disable interrupt if no more handlers */
p = isr->isr_ipl == 6 ? &isr_exter : &isr_ports;
if (*p == NULL) {
custom.intena = isr->isr_ipl == 6 ?
INTF_EXTER : INTF_PORTS;
}
-#endif
}
-static void
-ports_intr(struct isr **p)
+static int
+ports_intr(void *arg)
{
+ struct isr **p;
struct isr *q;
+ p = (struct isr **)arg;
while ((q = *p) != NULL) {
if ((q->isr_intr)(q->isr_arg))
break;
@@ -155,22 +149,110 @@
}
if (q == NULL)
ciaa_intr(); /* ciaa handles keyboard and parallel port */
+
+ custom.intreq = INTF_PORTS;
+ return 0;
}
-static void
-exter_intr(struct isr **p)
+static int
+exter_intr(void *arg)
{
+ struct isr **p;
struct isr *q;
+ p = (struct isr **)arg;
while ((q = *p) != NULL) {
if ((q->isr_intr)(q->isr_arg))
break;
p = &q->isr_forw;
}
- /*
- * XXX ciab_intr() is not needed, neither the timers nor the
- * floppy disk FGL interrupt
- */
+ if (q == NULL)
+ ciab_intr(); /* clear ciab icr */
+
+ custom.intreq = INTF_EXTER;
+ return 0;
+}
+
+static int
+lev1_intr(void *arg)
+{
+ unsigned short ireq;
+
+ ireq = custom.intreqr;
+ if (ireq & INTF_TBE) {
+#if NSER > 0
+ ser_outintr();
+#else
+ custom.intreq = INTF_TBE;
+#endif
+ }
+ if (ireq & INTF_DSKBLK) {
+#if NFD > 0
+ fdintr(0);
+#endif
+ custom.intreq = INTF_DSKBLK;
+ }
+ if (ireq & INTF_SOFTINT) {
+#ifdef DEBUG
+ printf("intrhand: SOFTINT ignored\n");
+#endif
+ custom.intreq = INTF_SOFTINT;
+ }
+ return 0;
+}
+
+static int
+lev3_intr(void *arg)
+{
+ unsigned short ireq;
+
+ ireq = custom.intreqr;
+ if (ireq & INTF_BLIT)
+ blitter_handler();
+ if (ireq & INTF_COPER)
+ copper_handler();
+ if (ireq & INTF_VERTB)
+ vbl_handler();
+ return 0;
+}
+
+static int
+lev4_intr(void *arg)
+{
+
+ audio_handler();
+ return 0;
+}
+
+static int
+lev5_intr(void *arg)
+{
+ unsigned short ireq;
+
+ ireq = custom.intreqr;
+ if (ireq & INTF_RBF)
+ serintr();
+ if (ireq & INTF_DSKSYNC)
+ custom.intreq = INTF_DSKSYNC;
+ return 0;
+}
+
+static void
+amigappc_install_handlers(void)
+{
+
+ /* handlers for all 6 Amiga interrupt levels */
+ intr_establish(1, IST_LEVEL, IPL_BIO, lev1_intr, NULL);
+
+ intr_establish(2, IST_LEVEL, IPL_BIO, ports_intr, &isr_ports);
+
+ intr_establish(3, IST_LEVEL, IPL_TTY, lev3_intr, NULL);
+
+ intr_establish(4, IST_LEVEL, IPL_AUDIO, lev4_intr, NULL);
+
+ intr_establish(5, IST_LEVEL, IPL_SERIAL, lev5_intr, NULL);
+
+ intr_establish(6, IST_LEVEL, IPL_SERIAL, exter_intr, &isr_exter);
}
static void
@@ -305,42 +387,6 @@
}
static void
-amigappc_install_handlers(void)
-{
-
-#if NSER > 0
- intr_establish(INTB_TBE, IST_LEVEL, IPL_SOFTCLOCK, (ih_t)ser_outintr, NULL);
- intr_establish(INTB_RBF, IST_LEVEL, IPL_SERIAL, (ih_t)serintr, NULL);
-#endif
-
-#if NFD > 0
- intr_establish(INTB_DSKBLK, IST_LEVEL, IPL_SOFTCLOCK, (ih_t)fdintr, 0);
-#endif
-
- intr_establish(INTB_PORTS, IST_LEVEL, IPL_SOFTCLOCK, (ih_t)ports_intr,
- &isr_ports);
-
- intr_establish(INTB_BLIT, IST_LEVEL, IPL_BIO, (ih_t)blitter_handler,
- NULL);
- intr_establish(INTB_COPER, IST_LEVEL, IPL_BIO, (ih_t)copper_handler,
- NULL);
- intr_establish(INTB_VERTB, IST_LEVEL, IPL_BIO, (ih_t)vbl_handler,
- NULL);
-
- intr_establish(INTB_AUD0, IST_LEVEL, IPL_VM, (ih_t)audio_handler,
- NULL);
- intr_establish(INTB_AUD1, IST_LEVEL, IPL_VM, (ih_t)audio_handler,
- NULL);
- intr_establish(INTB_AUD2, IST_LEVEL, IPL_VM, (ih_t)audio_handler,
- NULL);
- intr_establish(INTB_AUD3, IST_LEVEL, IPL_VM, (ih_t)audio_handler,
- NULL);
-
- intr_establish(INTB_EXTER, IST_LEVEL, IPL_CLOCK, (ih_t)exter_intr,
- &isr_exter);
-}
-
-static void
amigappc_bat_add(paddr_t pa, register_t len, register_t prot)
{
static int ni = 0, nd = 0;
@@ -464,75 +510,6 @@
va_end(ap);
}
-#if 0
-/*
- * customized oea_startup(), supports up to 64k msgbuf at 0xfff70000
- */
-static void
-amigappc_startup(const char *model)
-{
- uintptr_t sz;
- void *v;
- vaddr_t minaddr, maxaddr;
- char pbuf[9];
-
- KASSERT(curcpu() != NULL);
- KASSERT(lwp0.l_cpu != NULL);
- KASSERT(curcpu()->ci_intstk != 0);
- KASSERT(curcpu()->ci_intrdepth == -1);
-
- sz = round_page(MSGBUFSIZE);
- v = (void *)0xfff70000;
- initmsgbuf(v, sz);
-
- printf("%s%s", copyright, version);
- if (model != NULL)
- printf("Model: %s\n", model);
- cpu_identify(NULL, 0);
-
- format_bytes(pbuf, sizeof(pbuf), ctob((u_int)physmem));
- printf("total memory = %s\n", pbuf);
-
- /*
- * Allocate away the pages that map to 0xDEA[CDE]xxxx. Do this after
- * the bufpages are allocated in case they overlap since it's not
- * fatal if we can't allocate these.
- */
- if (KERNEL_SR == 13 || KERNEL2_SR == 14) {
- int error;
- minaddr = 0xDEAC0000;
- error = uvm_map(kernel_map, &minaddr, 0x30000,
- NULL, UVM_UNKNOWN_OFFSET, 0,
- UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE,
- UVM_ADV_NORMAL, UVM_FLAG_FIXED));
- if (error != 0 || minaddr != 0xDEAC0000)
- printf("oea_startup: failed to allocate DEAD "
- "ZONE: error=%d\n", error);
- }
-
- minaddr = 0;
-
- /*
- * Allocate a submap for physio
- */
- phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
- VM_PHYS_SIZE, 0, FALSE, NULL);
-
-#ifndef PMAP_MAP_POOLPAGE
- /*
- * No need to allocate an mbuf cluster submap. Mbuf clusters
- * are allocated via the pool allocator, and we use direct-mapped
- * pool pages.
- */
- mb_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
- mclbytes*nmbclusters, VM_MAP_INTRSAFE, FALSE, NULL);
-#endif
-
- format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free));
- printf("avail memory = %s\n", pbuf);
-}
-#endif
-
void
initppc(u_int startkernel, u_int endkernel)
{
@@ -752,67 +729,3 @@
#endif
return 0;
}
-
-/* show PPC registers */
-void show_me_regs(void)
-{
- register u_long scr0, scr1, scr2, scr3;
-
- __asm volatile ("mfmsr %0" : "=r"(scr0) :);
- printf("MSR %08lx\n", scr0);
-
- __asm volatile ("mfspr %0,1; mfspr %1,8; mfspr %2,9; mfspr %3,18"
- : "=r"(scr0),"=r"(scr1),"=r"(scr2),"=r"(scr3) :);
- printf("XER %08lx\tLR %08lx\tCTR %08lx\tDSISR %08lx\n",
- scr0, scr1, scr2, scr3);
-
- __asm volatile ("mfspr %0,19; mfspr %1,22; mfspr %2,25; mfspr %3,26"
- : "=r"(scr0),"=r"(scr1),"=r"(scr2),"=r"(scr3) :);
- printf("DAR %08lx\tDEC %08lx\tSDR1 %08lx\tSRR0 %08lx\n",
- scr0, scr1, scr2, scr3);
-
- __asm volatile ("mfspr %0,27; mfspr %1,268; mfspr %2,269; mfspr %3,272"
- : "=r"(scr0),"=r"(scr1),"=r"(scr2),"=r"(scr3) :);
- printf("SRR1 %08lx\tTBL %08lx\tTBU %08lx\tSPRG0 %08lx\n",
- scr0, scr1, scr2, scr3);
-
- __asm volatile ("mfspr %0,273; mfspr %1,274; mfspr %2,275; mfspr %3,282"
- : "=r"(scr0),"=r"(scr1),"=r"(scr2),"=r"(scr3) :);
- printf("SPRG1 %08lx\tSPRG2 %08lx\tSPRG3 %08lx\tEAR %08lx\n",
- scr0, scr1, scr2, scr3);
-
- __asm volatile ("mfspr %0,528; mfspr %1,529; mfspr %2,530; mfspr %3,531"
- : "=r"(scr0),"=r"(scr1),"=r"(scr2),"=r"(scr3) :);
- printf("IBAT0U%08lx\tIBAT0L%08lx\tIBAT1U%08lx\tIBAT1L%08lx\n",
- scr0, scr1, scr2, scr3);
-
- __asm volatile ("mfspr %0,532; mfspr %1,533; mfspr %2,534; mfspr %3,535"
- : "=r"(scr0),"=r"(scr1),"=r"(scr2),"=r"(scr3) :);
- printf("IBAT2U%08lx\tIBAT2L%08lx\tIBAT3U%08lx\tIBAT3L%08lx\n",
- scr0, scr1, scr2, scr3);
-
- __asm volatile ("mfspr %0,536; mfspr %1,537; mfspr %2,538; mfspr %3,539"
- : "=r"(scr0),"=r"(scr1),"=r"(scr2),"=r"(scr3) :);
- printf("DBAT0U%08lx\tDBAT0L%08lx\tDBAT1U%08lx\tDBAT1L%08lx\n",
- scr0, scr1, scr2, scr3);
-
- __asm volatile ("mfspr %0,540; mfspr %1,541; mfspr %2,542; mfspr %3,543"
- : "=r"(scr0),"=r"(scr1),"=r"(scr2),"=r"(scr3) :);
- printf("DBAT2U%08lx\tDBAT2L%08lx\tDBAT3U%08lx\tDBAT3L%08lx\n",
- scr0, scr1, scr2, scr3);
-
- __asm volatile ("mfspr %0,1008; mfspr %1,1009; mfspr %2,1010; mfspr %3,1013"
- : "=r"(scr0),"=r"(scr1),"=r"(scr2),"=r"(scr3) :);
- printf("HID0 %08lx\tHID1 %08lx\tIABR %08lx\tDABR %08lx\n",
- scr0, scr1, scr2, scr3);
-
- __asm volatile ("mfspr %0,953; mfspr %1,954; mfspr %2,957; mfspr %3,958"
- : "=r"(scr0),"=r"(scr1),"=r"(scr2),"=r"(scr3) :);
- printf("PCM1 %08lx\tPCM2 %08lx\tPCM3 %08lx\tPCM4 %08lx\n",
- scr0, scr1, scr2, scr3);
-
- __asm volatile ("mfspr %0,952; mfspr %1,956; mfspr %2,959; mfspr %3,955"
- : "=r"(scr0),"=r"(scr1),"=r"(scr2),"=r"(scr3) :);
- printf("MMCR0 %08lx\tMMCR1 %08lx\tSDA %08lx\tSIA %08lx\n",
- scr0, scr1, scr2, scr3);
-}