-+ * Linux OS Independent Layer
-+ *
-+ * Copyright 2001-2003, Broadcom Corporation
-+ * All Rights Reserved.
-+ *
-+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
-+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
-+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
-+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
-+ *
-+ * $Id: linux_osl.c,v 1.2 2005/02/28 13:34:25 jolt Exp $
-+ */
-+
-+#define LINUX_OSL
-+
-+#include <typedefs.h>
-+#include <bcmendian.h>
-+#include <linuxver.h>
-+#include <linux_osl.h>
-+#include <bcmutils.h>
-+#include <linux/delay.h>
-+#ifdef mips
-+#include <asm/paccess.h>
-+#endif
-+#include <pcicfg.h>
-+
-+#define PCI_CFG_RETRY 10
-+
-+void*
-+osl_pktget(void *drv, uint len, bool send)
-+{
-+ struct sk_buff *skb;
-+
-+ if ((skb = dev_alloc_skb(len)) == NULL)
-+ return (NULL);
-+
-+ skb_put(skb, len);
-+
-+ /* ensure the cookie field is cleared */
-+ PKTSETCOOKIE(skb, NULL);
-+
-+ return ((void*) skb);
-+}
-+
-+void
-+osl_pktfree(void *p)
-+{
-+ struct sk_buff *skb, *nskb;
-+
-+ skb = (struct sk_buff*) p;
-+
-+ /* perversion: we use skb->next to chain multi-skb packets */
-+ while (skb) {
-+ nskb = skb->next;
-+ skb->next = NULL;
-+ if (skb->destructor) {
-+ /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists */
-+ dev_kfree_skb_any(skb);
-+ } else {
-+ /* can free immediately (even in_irq()) if destructor does not exist */
-+ dev_kfree_skb(skb);
-+ }
-+ skb = nskb;
-+ }
-+}
-+
-+uint32
-+osl_pci_read_config(void *loc, uint offset, uint size)
-+{
-+ struct pci_dev *pdev;
-+ uint val;
-+ uint retry=PCI_CFG_RETRY;
-+
-+ /* only 4byte access supported */
-+ ASSERT(size == 4);
-+
-+ pdev = (struct pci_dev*)loc;
-+ do {
-+ pci_read_config_dword(pdev, offset, &val);
-+ if (val != 0xffffffff)
-+ break;
-+ } while (retry--);
-+
-+
-+ return (val);
-+}
-+
-+void
-+osl_pci_write_config(void *loc, uint offset, uint size, uint val)
-+{
-+ struct pci_dev *pdev;
-+ uint retry=PCI_CFG_RETRY;
-+
-+ /* only 4byte access supported */
-+ ASSERT(size == 4);
-+
-+ pdev = (struct pci_dev*)loc;
-+
-+ do {
-+ pci_write_config_dword(pdev, offset, val);
-+ if (offset!=PCI_BAR0_WIN)
-+ break;
-+ if (osl_pci_read_config(loc,offset,size) == val)
-+ break;
-+ } while (retry--);
-+
-+}
-+
-+void
-+osl_pcmcia_read_attr(void *osh, uint offset, void *buf, int size)
-+{
-+ ASSERT(0);
-+}
-+
-+void
-+osl_pcmcia_write_attr(void *osh, uint offset, void *buf, int size)
-+{
-+ ASSERT(0);
-+}
-+
-+void
-+osl_assert(char *exp, char *file, int line)
-+{
-+ char tempbuf[255];
-+
-+ sprintf(tempbuf, "assertion \"%s\" failed: file \"%s\", line %d\n", exp, file, line);
-+ panic(tempbuf);
-+}
-+
-+/*
-+ * BINOSL selects the slightly slower function-call-based binary compatible osl.
-+ */
-+#ifdef BINOSL
-+
-+int
-+osl_printf(const char *format, ...)
-+{
-+ va_list args;
-+ char buf[1024];
-+ int len;
-+
-+ /* sprintf into a local buffer because there *is* no "vprintk()".. */
-+ va_start(args, format);
-+ len = vsprintf(buf, format, args);
-+ va_end(args);
-+
-+ if (len > sizeof (buf)) {
-+ printk("osl_printf: buffer overrun\n");
-+ return (0);
-+ }
-+
-+ return (printk(buf));
-+}
-+
-+int
-+osl_sprintf(char *buf, const char *format, ...)
-+{
-+ va_list args;
-+ int rc;
-+
-+ va_start(args, format);
-+ rc = vsprintf(buf, format, args);
-+ va_end(args);
-+ return (rc);
-+}
-+
-+int
-+osl_strcmp(const char *s1, const char *s2)
-+{
-+ return (strcmp(s1, s2));
-+}
-+
-+int
-+osl_strncmp(const char *s1, const char *s2, uint n)
-+{
-+ return (strncmp(s1, s2, n));
-+}
-+
-+int
-+osl_strlen(char *s)
-+{
-+ return (strlen(s));
-+}
-+
-+char*
-+osl_strcpy(char *d, const char *s)
-+{
-+ return (strcpy(d, s));
-+}
-+
-+char*
-+osl_strncpy(char *d, const char *s, uint n)
-+{
-+ return (strncpy(d, s, n));
-+}
-+
-+void
-+bcopy(const void *src, void *dst, int len)
-+{
-+ memcpy(dst, src, len);
-+}
-+
-+int
-+bcmp(const void *b1, const void *b2, int len)
-+{
-+ return (memcmp(b1, b2, len));
-+}
-+
-+void
-+bzero(void *b, int len)
-+{
-+ memset(b, '\0', len);
-+}
-+
-+void*
-+osl_malloc(uint size)
-+{
-+ return (kmalloc(size, GFP_ATOMIC));
-+}
-+
-+void
-+osl_mfree(void *addr, uint size)
-+{
-+ kfree(addr);
-+}
-+
-+uint32
-+osl_readl(volatile uint32 *r)
-+{
-+ return (readl(r));
-+}
-+
-+uint16
-+osl_readw(volatile uint16 *r)
-+{
-+ return (readw(r));
-+}
-+
-+uint8
-+osl_readb(volatile uint8 *r)
-+{
-+ return (readb(r));
-+}
-+
-+void
-+osl_writel(uint32 v, volatile uint32 *r)
-+{
-+ writel(v, r);
-+}
-+
-+void
-+osl_writew(uint16 v, volatile uint16 *r)
-+{
-+ writew(v, r);
-+}
-+
-+void
-+osl_writeb(uint8 v, volatile uint8 *r)
-+{
-+ writeb(v, r);
-+}
-+
-+void *
-+osl_uncached(void *va)
-+{
-+#ifdef mips
-+ return ((void*)KSEG1ADDR(va));
-+#else
-+ return ((void*)va);
-+#endif
-+}
-+
-+uint
-+osl_getcycles(void)
-+{
-+ uint cycles;
-+
-+#if defined(mips)
-+ cycles = read_c0_count() * 2;
-+#elif defined(__i386__)
-+ rdtscl(cycles);
-+#else
-+ cycles = 0;
-+#endif
-+ return cycles;
-+}
-+
-+void *
-+osl_reg_map(uint32 pa, uint size)
-+{
-+ return (ioremap_nocache((unsigned long)pa, (unsigned long)size));
-+}
-+
-+void
-+osl_reg_unmap(void *va)
-+{
-+ iounmap(va);
-+}
-+
-+int
-+osl_busprobe(uint32 *val, uint32 addr)
-+{
-+#ifdef mips
-+ return get_dbe(*val, (uint32*)addr);
-+#else
-+ *val = readl(addr);
-+ return 0;
-+#endif
-+}
-+
-+void*
-+osl_dma_alloc_consistent(void *dev, uint size, ulong *pap)
-+{
-+ return (pci_alloc_consistent((struct pci_dev*)dev, size, (dma_addr_t*)pap));
-+}
-+
-+void
-+osl_dma_free_consistent(void *dev, void *va, uint size, ulong pa)
-+{
-+ pci_free_consistent((struct pci_dev*)dev, size, va, (dma_addr_t)pa);
-+}
-+
-+uint
-+osl_dma_map(void *dev, void *va, uint size, int direction)
-+{
-+ int dir;
-+
-+ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
-+ return (pci_map_single(dev, va, size, dir));
-+}
-+
-+void
-+osl_dma_unmap(void *dev, uint pa, uint size, int direction)
-+{
-+ int dir;
-+
-+ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
-+ pci_unmap_single(dev, (uint32)pa, size, dir);
-+}
-+
-+void
-+osl_delay(uint usec)
-+{
-+ udelay(usec);
-+}
-+
-+uchar*
-+osl_pktdata(void *drv, void *skb)
-+{
-+ return (((struct sk_buff*)skb)->data);
-+}
-+
-+uint
-+osl_pktlen(void *drv, void *skb)
-+{
-+ return (((struct sk_buff*)skb)->len);
-+}
-+
-+void*
-+osl_pktnext(void *drv, void *skb)
-+{
-+ return (((struct sk_buff*)skb)->next);
-+}
-+
-+void
-+osl_pktsetnext(void *skb, void *x)
-+{
-+ ((struct sk_buff*)skb)->next = (struct sk_buff*)x;
-+}
-+
-+void
-+osl_pktsetlen(void *drv, void *skb, uint len)
-+{
-+ __skb_trim((struct sk_buff*)skb, len);
-+}
-+
-+uchar*
-+osl_pktpush(void *drv, void *skb, int bytes)
-+{
-+ return (skb_push((struct sk_buff*)skb, bytes));
-+}
-+
-+uchar*
-+osl_pktpull(void *drv, void *skb, int bytes)
-+{
-+ return (skb_pull((struct sk_buff*)skb, bytes));
-+}
-+
-+void*
-+osl_pktdup(void *drv, void *skb)
-+{
-+ return (skb_clone((struct sk_buff*)skb, GFP_ATOMIC));
-+}
-+
-+void*
-+osl_pktcookie(void *skb)
-+{
-+ return ((void*)((struct sk_buff*)skb)->csum);
-+}
-+
-+void
-+osl_pktsetcookie(void *skb, void *x)
-+{
-+ ((struct sk_buff*)skb)->csum = (uint)x;
-+}
-+
-+void*
-+osl_pktlink(void *skb)
-+{
-+ return (((struct sk_buff*)skb)->prev);
-+}
-+
-+void
-+osl_pktsetlink(void *skb, void *x)
-+{
-+ ((struct sk_buff*)skb)->prev = (struct sk_buff*)x;
-+}
-+
-+#endif
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbmips.c
---- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbmips.c 2005-08-28 11:12:20.478851856 +0200
-@@ -0,0 +1,950 @@
-+/*
-+ * BCM47XX Sonics SiliconBackplane MIPS core routines
-+ *
-+ * Copyright 2001-2003, Broadcom Corporation
-+ * All Rights Reserved.
-+ *
-+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
-+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
-+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
-+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
-+ *
-+ * $Id: sbmips.c,v 1.1 2005/02/28 13:33:32 jolt Exp $
-+ */
-+
-+#include <typedefs.h>
-+#include <osl.h>
-+#include <sbutils.h>
-+#include <bcmdevs.h>
-+#include <bcmnvram.h>
-+#include <bcmutils.h>
-+#include <hndmips.h>
-+#include <sbconfig.h>
-+#include <sbextif.h>
-+#include <sbchipc.h>
-+#include <sbmemc.h>
-+
-+/*
-+ * Memory segments (32bit kernel mode addresses)
-+ */
-+#undef KUSEG
-+#undef KSEG0
-+#undef KSEG1
-+#undef KSEG2
-+#undef KSEG3
-+#define KUSEG 0x00000000
-+#define KSEG0 0x80000000
-+#define KSEG1 0xa0000000
-+#define KSEG2 0xc0000000
-+#define KSEG3 0xe0000000
-+
-+/*
-+ * Map an address to a certain kernel segment
-+ */
-+#undef KSEG0ADDR
-+#undef KSEG1ADDR
-+#undef KSEG2ADDR
-+#undef KSEG3ADDR
-+#define KSEG0ADDR(a) (((a) & 0x1fffffff) | KSEG0)
-+#define KSEG1ADDR(a) (((a) & 0x1fffffff) | KSEG1)
-+#define KSEG2ADDR(a) (((a) & 0x1fffffff) | KSEG2)
-+#define KSEG3ADDR(a) (((a) & 0x1fffffff) | KSEG3)
-+
-+/*
-+ * The following macros are especially useful for __asm__
-+ * inline assembler.
-+ */
-+#ifndef __STR
-+#define __STR(x) #x
-+#endif
-+#ifndef STR
-+#define STR(x) __STR(x)
-+#endif
-+
-+/* *********************************************************************
-+ * CP0 Registers
-+ ********************************************************************* */
-+
-+#define C0_INX 0 /* CP0: TLB Index */
-+#define C0_RAND 1 /* CP0: TLB Random */
-+#define C0_TLBLO0 2 /* CP0: TLB EntryLo0 */
-+#define C0_TLBLO C0_TLBLO0 /* CP0: TLB EntryLo0 */
-+#define C0_TLBLO1 3 /* CP0: TLB EntryLo1 */
-+#define C0_CTEXT 4 /* CP0: Context */
-+#define C0_PGMASK 5 /* CP0: TLB PageMask */
-+#define C0_WIRED 6 /* CP0: TLB Wired */
-+#define C0_BADVADDR 8 /* CP0: Bad Virtual Address */
-+#define C0_COUNT 9 /* CP0: Count */
-+#define C0_TLBHI 10 /* CP0: TLB EntryHi */
-+#define C0_COMPARE 11 /* CP0: Compare */
-+#define C0_SR 12 /* CP0: Processor Status */
-+#define C0_STATUS C0_SR /* CP0: Processor Status */
-+#define C0_CAUSE 13 /* CP0: Exception Cause */
-+#define C0_EPC 14 /* CP0: Exception PC */
-+#define C0_PRID 15 /* CP0: Processor Revision Indentifier */
-+#define C0_CONFIG 16 /* CP0: Config */
-+#define C0_LLADDR 17 /* CP0: LLAddr */
-+#define C0_WATCHLO 18 /* CP0: WatchpointLo */
-+#define C0_WATCHHI 19 /* CP0: WatchpointHi */
-+#define C0_XCTEXT 20 /* CP0: XContext */
-+#define C0_DIAGNOSTIC 22 /* CP0: Diagnostic */
-+#define C0_BROADCOM C0_DIAGNOSTIC /* CP0: Broadcom Register */
-+#define C0_ECC 26 /* CP0: ECC */
-+#define C0_CACHEERR 27 /* CP0: CacheErr */
-+#define C0_TAGLO 28 /* CP0: TagLo */
-+#define C0_TAGHI 29 /* CP0: TagHi */
-+#define C0_ERREPC 30 /* CP0: ErrorEPC */
-+
-+/*
-+ * Macros to access the system control coprocessor
-+ */
-+
-+#define MFC0(source, sel) \
-+({ \
-+ int __res; \
-+ __asm__ __volatile__( \
-+ ".set\tnoreorder\n\t" \
-+ ".set\tnoat\n\t" \
-+ ".word\t"STR(0x40010000 | ((source)<<11) | (sel))"\n\t" \
-+ "move\t%0,$1\n\t" \
-+ ".set\tat\n\t" \
-+ ".set\treorder" \
-+ :"=r" (__res) \
-+ : \
-+ :"$1"); \
-+ __res; \
-+})
-+
-+#define MTC0(source, sel, value) \
-+do { \
-+ __asm__ __volatile__( \
-+ ".set\tnoreorder\n\t" \
-+ ".set\tnoat\n\t" \
-+ "move\t$1,%z0\n\t" \
-+ ".word\t"STR(0x40810000 | ((source)<<11) | (sel))"\n\t" \
-+ ".set\tat\n\t" \
-+ ".set\treorder" \
-+ : \
-+ :"Jr" (value) \
-+ :"$1"); \
-+} while (0)
-+
-+/*
-+ * R4x00 interrupt enable / cause bits
-+ */
-+#undef IE_SW0
-+#undef IE_SW1
-+#undef IE_IRQ0
-+#undef IE_IRQ1
-+#undef IE_IRQ2
-+#undef IE_IRQ3
-+#undef IE_IRQ4
-+#undef IE_IRQ5
-+#define IE_SW0 (1<< 8)
-+#define IE_SW1 (1<< 9)
-+#define IE_IRQ0 (1<<10)
-+#define IE_IRQ1 (1<<11)
-+#define IE_IRQ2 (1<<12)
-+#define IE_IRQ3 (1<<13)
-+#define IE_IRQ4 (1<<14)
-+#define IE_IRQ5 (1<<15)
-+
-+/*
-+ * Bitfields in the R4xx0 cp0 status register
-+ */
-+#define ST0_IE 0x00000001
-+#define ST0_EXL 0x00000002
-+#define ST0_ERL 0x00000004
-+#define ST0_KSU 0x00000018
-+# define KSU_USER 0x00000010
-+# define KSU_SUPERVISOR 0x00000008
-+# define KSU_KERNEL 0x00000000
-+#define ST0_UX 0x00000020
-+#define ST0_SX 0x00000040
-+#define ST0_KX 0x00000080
-+#define ST0_DE 0x00010000
-+#define ST0_CE 0x00020000
-+
-+/*
-+ * Status register bits available in all MIPS CPUs.
-+ */
-+#define ST0_IM 0x0000ff00
-+#define ST0_CH 0x00040000
-+#define ST0_SR 0x00100000
-+#define ST0_TS 0x00200000
-+#define ST0_BEV 0x00400000
-+#define ST0_RE 0x02000000
-+#define ST0_FR 0x04000000
-+#define ST0_CU 0xf0000000
-+#define ST0_CU0 0x10000000
-+#define ST0_CU1 0x20000000
-+#define ST0_CU2 0x40000000
-+#define ST0_CU3 0x80000000
-+#define ST0_XX 0x80000000 /* MIPS IV naming */
-+
-+/*
-+ * Cache Operations
-+ */
-+
-+#ifndef Fill_I
-+#define Fill_I 0x14
-+#endif
-+
-+#define cache_unroll(base,op) \
-+ __asm__ __volatile__(" \
-+ .set noreorder; \
-+ .set mips3; \
-+ cache %1, (%0); \
-+ .set mips0; \
-+ .set reorder" \
-+ : \
-+ : "r" (base), \
-+ "i" (op));
-+
-+/*
-+ * These are the UART port assignments, expressed as offsets from the base
-+ * register. These assignments should hold for any serial port based on
-+ * a 8250, 16450, or 16550(A).
-+ */
-+
-+#define UART_MCR 4 /* Out: Modem Control Register */
-+#define UART_MSR 6 /* In: Modem Status Register */
-+#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
-+
-+/*
-+ * Returns TRUE if an external UART exists at the given base
-+ * register.
-+ */
-+static bool
-+serial_exists(uint8 *regs)
-+{
-+ uint8 save_mcr, status1;
-+
-+ save_mcr = R_REG(®s[UART_MCR]);
-+ W_REG(®s[UART_MCR], UART_MCR_LOOP | 0x0a);
-+ status1 = R_REG(®s[UART_MSR]) & 0xf0;
-+ W_REG(®s[UART_MCR], save_mcr);
-+
-+ return (status1 == 0x90);
-+}
-+
-+/*
-+ * Initializes UART access. The callback function will be called once
-+ * per found UART.
-+*/
-+void
-+sb_serial_init(void *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift))
-+{
-+ void *regs;
-+ ulong base;
-+ uint irq;
-+ int i, n;
-+
-+ if ((regs = sb_setcore(sbh, SB_EXTIF, 0))) {
-+ extifregs_t *eir = (extifregs_t *) regs;
-+ sbconfig_t *sb;
-+
-+ /* Determine external UART register base */
-+ sb = (sbconfig_t *)((ulong) eir + SBCONFIGOFF);
-+ base = EXTIF_CFGIF_BASE(sb_base(R_REG(&sb->sbadmatch1)));
-+
-+ /* Determine IRQ */
-+ irq = sb_irq(sbh);
-+
-+ /* Disable GPIO interrupt initially */
-+ W_REG(&eir->gpiointpolarity, 0);
-+ W_REG(&eir->gpiointmask, 0);
-+
-+ /* Search for external UARTs */
-+ n = 2;
-+ for (i = 0; i < 2; i++) {
-+ regs = (void *) REG_MAP(base + (i * 8), 8);
-+ if (serial_exists(regs)) {
-+ /* Set GPIO 1 to be the external UART IRQ */
-+ W_REG(&eir->gpiointmask, 2);
-+ if (add)
-+ add(regs, irq, 13500000, 0);
-+ }
-+ }
-+
-+ /* Add internal UART if enabled */
-+ if (R_REG(&eir->corecontrol) & CC_UE)
-+ if (add)
-+ add((void *) &eir->uartdata, irq, sb_clock(sbh), 2);
-+ } else if ((regs = sb_setcore(sbh, SB_CC, 0))) {
-+ chipcregs_t *cc = (chipcregs_t *) regs;
-+ uint32 rev, cap, pll, baud_base, div;
-+
-+ /* Determine core revision and capabilities */
-+ rev = sb_corerev(sbh);
-+ cap = R_REG(&cc->capabilities);
-+ pll = cap & CAP_PLL_MASK;
-+
-+ /* Determine IRQ */
-+ irq = sb_irq(sbh);
-+
-+ if (pll == PLL_TYPE1) {
-+ /* PLL clock */
-+ baud_base = sb_clock_rate(pll,
-+ R_REG(&cc->clockcontrol_n),
-+ R_REG(&cc->clockcontrol_m2));
-+ div = 1;
-+ } else if (rev >= 3) {
-+ /* Internal backplane clock */
-+ baud_base = sb_clock_rate(pll,
-+ R_REG(&cc->clockcontrol_n),
-+ R_REG(&cc->clockcontrol_sb));
-+ div = 2; /* Minimum divisor */
-+ W_REG(&cc->uart_clkdiv, div);
-+ } else {
-+ /* Fixed internal backplane clock */
-+ baud_base = 88000000;
-+ div = 48;
-+ }
-+
-+ /* Clock source depends on strapping if UartClkOverride is unset */
-+ if ((rev > 0) && ((R_REG(&cc->corecontrol) & CC_UARTCLKO) == 0)) {
-+ if ((cap & CAP_UCLKSEL) == CAP_UINTCLK) {
-+ /* Internal divided backplane clock */
-+ baud_base /= div;
-+ } else {
-+ /* Assume external clock of 1.8432 MHz */
-+ baud_base = 1843200;
-+ }
-+ }
-+
-+ /* Add internal UARTs */
-+ n = cap & CAP_UARTS_MASK;
-+ for (i = 0; i < n; i++) {
-+ /* Register offset changed after revision 0 */
-+ if (rev)
-+ regs = (void *)((ulong) &cc->uart0data + (i * 256));
-+ else
-+ regs = (void *)((ulong) &cc->uart0data + (i * 8));
-+
-+ if (add)
-+ add(regs, irq, baud_base, 0);
-+ }
-+ }
-+}
-+
-+/* Returns the SB interrupt flag of the current core. */
-+uint32
-+sb_flag(void *sbh)
-+{
-+ void *regs;
-+ sbconfig_t *sb;
-+
-+ regs = sb_coreregs(sbh);
-+ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
-+
-+ return (R_REG(&sb->sbtpsflag) & SBTPS_NUM0_MASK);
-+}
-+
-+static const uint32 sbips_int_mask[] = {
-+ 0,
-+ SBIPS_INT1_MASK,
-+ SBIPS_INT2_MASK,
-+ SBIPS_INT3_MASK,
-+ SBIPS_INT4_MASK
-+};
-+
-+static const uint32 sbips_int_shift[] = {
-+ 0,
-+ 0,
-+ SBIPS_INT2_SHIFT,
-+ SBIPS_INT3_SHIFT,
-+ SBIPS_INT4_SHIFT
-+};
-+
-+/*
-+ * Returns the MIPS IRQ assignment of the current core. If unassigned,
-+ * 0 is returned.
-+ */
-+uint
-+sb_irq(void *sbh)
-+{
-+ uint idx;
-+ void *regs;
-+ sbconfig_t *sb;
-+ uint32 flag, sbipsflag;
-+ uint irq = 0;
-+
-+ flag = sb_flag(sbh);
-+
-+ idx = sb_coreidx(sbh);
-+
-+ if ((regs = sb_setcore(sbh, SB_MIPS, 0)) ||
-+ (regs = sb_setcore(sbh, SB_MIPS33, 0))) {
-+ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
-+
-+ /* sbipsflag specifies which core is routed to interrupts 1 to 4 */
-+ sbipsflag = R_REG(&sb->sbipsflag);
-+ for (irq = 1; irq <= 4; irq++) {
-+ if (((sbipsflag & sbips_int_mask[irq]) >> sbips_int_shift[irq]) == flag)
-+ break;
-+ }
-+ if (irq == 5)
-+ irq = 0;
-+ }
-+
-+ sb_setcoreidx(sbh, idx);
-+
-+ return irq;
-+}
-+
-+/* Clears the specified MIPS IRQ. */
-+static void
-+sb_clearirq(void *sbh, uint irq)
-+{
-+ void *regs;
-+ sbconfig_t *sb;
-+
-+ if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) &&
-+ !(regs = sb_setcore(sbh, SB_MIPS33, 0)))
-+ ASSERT(regs);
-+ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
-+
-+ if (irq == 0)
-+ W_REG(&sb->sbintvec, 0);
-+ else
-+ OR_REG(&sb->sbipsflag, sbips_int_mask[irq]);
-+}
-+
-+/*
-+ * Assigns the specified MIPS IRQ to the specified core. Shared MIPS
-+ * IRQ 0 may be assigned more than once.
-+ */
-+static void
-+sb_setirq(void *sbh, uint irq, uint coreid, uint coreunit)
-+{
-+ void *regs;
-+ sbconfig_t *sb;
-+ uint32 flag;
-+
-+ regs = sb_setcore(sbh, coreid, coreunit);
-+ ASSERT(regs);
-+ flag = sb_flag(sbh);
-+
-+ if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) &&
-+ !(regs = sb_setcore(sbh, SB_MIPS33, 0)))
-+ ASSERT(regs);
-+ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
-+
-+ if (irq == 0)
-+ OR_REG(&sb->sbintvec, 1 << flag);
-+ else {
-+ flag <<= sbips_int_shift[irq];
-+ ASSERT(!(flag & ~sbips_int_mask[irq]));
-+ flag |= R_REG(&sb->sbipsflag) & ~sbips_int_mask[irq];
-+ W_REG(&sb->sbipsflag, flag);
-+ }
-+}
-+
-+/*
-+ * Initializes clocks and interrupts. SB and NVRAM access must be
-+ * initialized prior to calling.
-+ */
-+void
-+sb_mips_init(void *sbh)
-+{
-+ ulong hz, ns, tmp;
-+ extifregs_t *eir;
-+ chipcregs_t *cc;
-+ char *value;
-+ uint irq;
-+
-+ /* Figure out current SB clock speed */
-+ if ((hz = sb_clock(sbh)) == 0)
-+ hz = 100000000;
-+ ns = 1000000000 / hz;
-+
-+ /* Setup external interface timing */
-+ if ((eir = sb_setcore(sbh, SB_EXTIF, 0))) {
-+ /* Initialize extif so we can get to the LEDs and external UART */
-+ W_REG(&eir->prog_config, CF_EN);
-+
-+ /* Set timing for the flash */
-+ tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */
-+ tmp = tmp | (CEIL(40, ns) << FW_W1_SHIFT); /* W1 = 40nS */
-+ tmp = tmp | CEIL(120, ns); /* W0 = 120nS */
-+ W_REG(&eir->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */
-+
-+ /* Set programmable interface timing for external uart */
-+ tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */
-+ tmp = tmp | (CEIL(20, ns) << FW_W2_SHIFT); /* W2 = 20nS */
-+ tmp = tmp | (CEIL(100, ns) << FW_W1_SHIFT); /* W1 = 100nS */
-+ tmp = tmp | CEIL(120, ns); /* W0 = 120nS */
-+ W_REG(&eir->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */
-+ } else if ((cc = sb_setcore(sbh, SB_CC, 0))) {
-+ /* Set timing for the flash */
-+ tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */
-+ tmp |= CEIL(10, ns) << FW_W1_SHIFT; /* W1 = 10nS */
-+ tmp |= CEIL(120, ns); /* W0 = 120nS */
-+ W_REG(&cc->parallelflashwaitcnt, tmp);
-+
-+ W_REG(&cc->cs01memwaitcnt, tmp);
-+ }
-+
-+ /* Chip specific initialization */
-+ switch (sb_chip(sbh)) {
-+ case BCM4710_DEVICE_ID:
-+ /* Clear interrupt map */
-+ for (irq = 0; irq <= 4; irq++)
-+ sb_clearirq(sbh, irq);
-+ sb_setirq(sbh, 0, SB_CODEC, 0);
-+ sb_setirq(sbh, 0, SB_EXTIF, 0);
-+ sb_setirq(sbh, 2, SB_ENET, 1);
-+ sb_setirq(sbh, 3, SB_ILINE20, 0);
-+ sb_setirq(sbh, 4, SB_PCI, 0);
-+ ASSERT(eir);
-+ value = nvram_get("et0phyaddr");
-+ if (value && !strcmp(value, "31")) {
-+ /* Enable internal UART */
-+ W_REG(&eir->corecontrol, CC_UE);
-+ /* Give USB its own interrupt */
-+ sb_setirq(sbh, 1, SB_USB, 0);
-+ } else {
-+ /* Disable internal UART */
-+ W_REG(&eir->corecontrol, 0);
-+ /* Give Ethernet its own interrupt */
-+ sb_setirq(sbh, 1, SB_ENET, 0);
-+ sb_setirq(sbh, 0, SB_USB, 0);
-+ }
-+ break;
-+ case BCM4310_DEVICE_ID:
-+ MTC0(C0_BROADCOM, 0, MFC0(C0_BROADCOM, 0) & ~(1 << 22));
-+ break;
-+ }
-+}
-+
-+uint32
-+sb_mips_clock(void *sbh)
-+{
-+ extifregs_t *eir;
-+ chipcregs_t *cc;
-+ uint32 n, m;
-+ uint idx;
-+ uint32 pll_type, rate = 0;
-+
-+ /* get index of the current core */
-+ idx = sb_coreidx(sbh);
-+ pll_type = PLL_TYPE1;
-+
-+ /* switch to extif or chipc core */
-+ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) {
-+ n = R_REG(&eir->clockcontrol_n);
-+ m = R_REG(&eir->clockcontrol_sb);
-+ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) {
-+ pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK;
-+ n = R_REG(&cc->clockcontrol_n);
-+ if ((pll_type == PLL_TYPE2) || (pll_type == PLL_TYPE4))
-+ m = R_REG(&cc->clockcontrol_mips);
-+ else if (pll_type == PLL_TYPE3) {
-+ rate = 200000000;
-+ goto out;
-+ } else
-+ m = R_REG(&cc->clockcontrol_sb);
-+ } else
-+ goto out;
-+
-+ /* calculate rate */
-+ rate = sb_clock_rate(pll_type, n, m);
-+
-+out:
-+ /* switch back to previous core */
-+ sb_setcoreidx(sbh, idx);
-+
-+ return rate;
-+}
-+
-+static void
-+icache_probe(int *size, int *lsize)
-+{
-+ uint32 config1;
-+ uint sets, ways;
-+
-+ config1 = MFC0(C0_CONFIG, 1);
-+
-+ /* Instruction Cache Size = Associativity * Line Size * Sets Per Way */
-+ if ((*lsize = ((config1 >> 19) & 7)))
-+ *lsize = 2 << *lsize;
-+ sets = 64 << ((config1 >> 22) & 7);
-+ ways = 1 + ((config1 >> 16) & 7);
-+ *size = *lsize * sets * ways;
-+}
-+
-+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4)
-+
-+static void
-+handler(void)
-+{
-+ /* Step 11 */
-+ __asm__ (
-+ ".set\tmips32\n\t"
-+ "ssnop\n\t"
-+ "ssnop\n\t"
-+ /* Disable interrupts */
-+ /* MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~(ALLINTS | STO_IE)); */
-+ "mfc0 $15, $12\n\t"
-+ "and $15, $15, -31746\n\t"
-+ "mtc0 $15, $12\n\t"
-+ "eret\n\t"
-+ "nop\n\t"
-+ "nop\n\t"
-+ ".set\tmips0"
-+ );
-+}
-+
-+/* The following MUST come right after handler() */
-+static void
-+afterhandler(void)
-+{
-+}
-+
-+/*
-+ * Set the MIPS, backplane and PCI clocks as closely as possible.