Hallo everybody, I am trying to get the current git tree running on an I2 R10k, so I applied Peter Fürsts patches from http://home.alphastar.de/fuerst/download.html to it. As these are against 2.6.12-rc2, I got a bunch of rejects, which I have resolved manually, but I am stuck with the patch for include/asm-mips/stackframe.h. I would be very grateful if somebody could take a look into this and provide an updated patch against the current kernel sources. Attached to this mail is both my version of Peter Fürsts "collected.diff" (applies cleanly against current git but without the stackframe.h-patch) as well as the original stackframe.h patch. Regards, Karsten -- #include <standard_disclaimer> Nach Paragraph 28 Abs. 3 Bundesdatenschutzgesetz widerspreche ich der Nutzung oder Uebermittlung meiner Daten fuer Werbezwecke oder fuer die Markt- oder Meinungsforschung.
diff -Nur linux-git/arch/mips/Kconfig linux-git-mit-R10k-patches/arch/mips/Kconfig --- linux-git/arch/mips/Kconfig 2005-10-15 16:01:06.000000000 +0200 +++ linux-git-mit-R10k-patches/arch/mips/Kconfig 2005-10-16 13:21:56.000000000 +0200 @@ -527,6 +527,25 @@ workstations. To compile a Linux kernel that runs on these, say Y here. +config SGI_IP28 + bool "Support for SGI IP28 (Indigo2 R10k) (EXPERIMENTAL)" + depends EXPERIMENTAL + select ARC + select ARC64 + select DMA_NONCOHERENT + select IRQ_CPU + select SWAP_IO_SPACE + select HW_HAS_EISA + select CPU_R10000 + select XKPHYS_KERNEL + select BUILD_ELF64 + select BOOT_ELF64 + select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_BIG_ENDIAN + help + This is the SGI Indigo2 with R10000 processor. To compile a Linux + kernel that runs on these, say Y here. + config SGI_IP32 bool "Support for SGI IP32 (O2) (EXPERIMENTAL)" depends on EXPERIMENTAL @@ -942,7 +961,7 @@ config ARC_CONSOLE bool "ARC console support" - depends on SGI_IP22 || SNI_RM200_PCI + depends on SGI_IP22 || SNI_RM200_PCI || SGI_IP28 config ARC_MEMORY bool @@ -951,7 +970,7 @@ config ARC_PROMLIB bool - depends on MACH_JAZZ || SNI_RM200_PCI || SGI_IP22 || SGI_IP32 + depends on MACH_JAZZ || SNI_RM200_PCI || SGI_IP22 || SGI_IP28 || SGI_IP32 default y config ARC64 @@ -1319,6 +1338,14 @@ bool "Support for 64-bit physical address space" depends on (CPU_R4X00 || CPU_R5000 || CPU_RM7000 || CPU_RM9000 || CPU_R10000 || CPU_SB1 || CPU_MIPS32_R1 || CPU_MIPS64_R1) && 32BIT +config XKPHYS_KERNEL + bool "Allow kernel to run from 64-bit segments" + depends on MIPS64 + help + This option allows to locate the kernel in 64-bit unmapped memory + space (xkphys). This is required for Octane (IP30) or Indigo2 R10k + (IP28) machines. + config CPU_ADVANCED bool "Override CPU Options" depends on 32BIT @@ -1643,6 +1670,9 @@ and the task is only allowed to execute a few safe syscalls defined by each seccomp mode. +# Revision 1.145, Tue Apr 19 00:00:45 2005 +# Jun/Dec 2004 - IP28 + If unsure, say Y. Only embedded should say N here. config PM diff -Nur linux-git/arch/mips/kernel/gdb-low.S linux-git-mit-R10k-patches/arch/mips/kernel/gdb-low.S --- linux-git/arch/mips/kernel/gdb-low.S 2005-10-15 16:01:06.000000000 +0200 +++ linux-git-mit-R10k-patches/arch/mips/kernel/gdb-low.S 2005-10-16 13:21:56.000000000 +0200 @@ -52,7 +52,11 @@ /* * Called from user mode, go somewhere else. */ +#ifdef CONFIG_XKPHYS_KERNEL + dla k1, saved_vectors +#else lui k1, %hi(saved_vectors) +#endif mfc0 k0, CP0_CAUSE andi k0, k0, 0x7c add k1, k1, k0 @@ -61,7 +65,11 @@ nop 1: move k0, sp +#ifdef CONFIG_MIPS64 + dsubu sp, k1, GDB_FR_SIZE*2 # see comment above +#else subu sp, k1, GDB_FR_SIZE*2 # see comment above +#endif LONG_S k0, GDB_FR_REG29(sp) LONG_S $2, GDB_FR_REG2(sp) @@ -368,3 +376,7 @@ kgdbfault: li v0, -EFAULT jr ra .end kgdbfault +/* + * Revision 1.17, Mon Nov 17 17:19:39 2003 + * Wed May 12 21:21:49 2004 xkphys kernel addresses + */ diff -Nur linux-git/arch/mips/kernel/setup.c linux-git-mit-R10k-patches/arch/mips/kernel/setup.c --- linux-git/arch/mips/kernel/setup.c 2005-10-15 16:01:06.000000000 +0200 +++ linux-git-mit-R10k-patches/arch/mips/kernel/setup.c 2005-10-16 13:25:04.000000000 +0200 @@ -302,7 +302,7 @@ * Partially used pages are not usable - thus * we are rounding upwards. */ - start_pfn = PFN_UP(CPHYSADDR(reserved_end)); + start_pfn = PFN_UP(kernel_physaddr(reserved_end)); #ifndef CONFIG_SGI_IP27 /* Find the highest page frame number we have available. */ @@ -426,11 +426,11 @@ printk("Initial ramdisk at: 0x%p (%lu bytes)\n", (void *)initrd_start, initrd_size); - if (CPHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) { + if (kernel_physaddr(initrd_end) > PFN_PHYS(max_low_pfn)) { printk("initrd extends beyond end of memory " "(0x%0*Lx > 0x%0*Lx)\ndisabling initrd\n", sizeof(long) * 2, - (unsigned long long)CPHYSADDR(initrd_end), + (unsigned long long)kernel_physaddr(initrd_end), sizeof(long) * 2, (unsigned long long)PFN_PHYS(max_low_pfn)); initrd_start = initrd_end = 0; @@ -438,7 +438,7 @@ } if (initrd_reserve_bootmem) - reserve_bootmem(CPHYSADDR(initrd_start), initrd_size); + reserve_bootmem(kernel_physaddr(initrd_start), initrd_size); } #endif /* CONFIG_BLK_DEV_INITRD */ } @@ -452,10 +452,10 @@ * The 64bit code in 32bit object format trick can't represent * 64bit wide relocations for linker script symbols. */ - code_resource.start = CPHYSADDR(&_text); - code_resource.end = CPHYSADDR(&_etext) - 1; - data_resource.start = CPHYSADDR(&_etext); - data_resource.end = CPHYSADDR(&_edata) - 1; + code_resource.start = kernel_physaddr(&_text); + code_resource.end = kernel_physaddr(&_etext) - 1; + data_resource.start = kernel_physaddr(&_etext); + data_resource.end = kernel_physaddr(&_edata) - 1; #else code_resource.start = virt_to_phys(&_text); code_resource.end = virt_to_phys(&_etext) - 1; @@ -559,3 +559,9 @@ } __setup("nodsp", dsp_disable); + +/* + * Revision 1.179, Tue Apr 19 00:06:09 2005 + * Apr 2004/2005 pf - xkphys kernel addresses + */ + diff -Nur linux-git/arch/mips/lib/memcpy.S linux-git-mit-R10k-patches/arch/mips/lib/memcpy.S --- linux-git/arch/mips/lib/memcpy.S 2005-10-15 16:01:06.000000000 +0200 +++ linux-git-mit-R10k-patches/arch/mips/lib/memcpy.S 2005-10-16 13:21:56.000000000 +0200 @@ -17,6 +17,14 @@ #include <asm/asm-offsets.h> #include <asm/regdef.h> +#ifdef CONFIG_SGI_IP28 +/* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */ +# include <asm/cacheops.h> +# define R10KCBARRIER(addr) cache Cache_Barrier, addr; +#else +# define R10KCBARRIER(addr) +#endif + #define dst a0 #define src a1 #define len a2 @@ -180,6 +188,7 @@ */ #define rem t8 + R10KCBARRIER(0(ra)) /* hopefully inhibits speculative store prefetch */ /* * The "issue break"s below are very approximate. * Issue delays for dcache fills will perturb the schedule, as will @@ -212,6 +221,7 @@ PREF( 1, 3*32(dst) ) .align 4 1: + R10KCBARRIER(0(ra)) /* ra must be valid anyway */ EXC( LOAD t0, UNIT(0)(src), l_exc) EXC( LOAD t1, UNIT(1)(src), l_exc_copy) EXC( LOAD t2, UNIT(2)(src), l_exc_copy) @@ -253,6 +263,7 @@ EXC( LOAD t3, UNIT(3)(src), l_exc_copy) SUB len, len, 4*NBYTES ADD src, src, 4*NBYTES + R10KCBARRIER(0(ra)) EXC( STORE t0, UNIT(0)(dst), s_exc_p4u) EXC( STORE t1, UNIT(1)(dst), s_exc_p3u) EXC( STORE t2, UNIT(2)(dst), s_exc_p2u) @@ -266,6 +277,7 @@ beq rem, len, copy_bytes nop 1: + R10KCBARRIER(0(ra)) EXC( LOAD t0, 0(src), l_exc) ADD src, src, NBYTES SUB len, len, NBYTES @@ -311,6 +323,7 @@ EXC( LDREST t3, REST(0)(src), l_exc_copy) SUB t2, t2, t1 # t2 = number of bytes copied xor match, t0, t1 + R10KCBARRIER(0(ra)) EXC( STFIRST t3, FIRST(0)(dst), s_exc) beq len, t2, done SUB len, len, t2 @@ -331,6 +344,7 @@ * It's OK to load FIRST(N+1) before REST(N) because the two addresses * are to the same unit (unless src is aligned, but it's not). */ + R10KCBARRIER(0(ra)) EXC( LDFIRST t0, FIRST(0)(src), l_exc) EXC( LDFIRST t1, FIRST(1)(src), l_exc_copy) SUB len, len, 4*NBYTES @@ -359,6 +373,7 @@ beq rem, len, copy_bytes nop 1: + R10KCBARRIER(0(ra)) EXC( LDFIRST t0, FIRST(0)(src), l_exc) EXC( LDREST t0, REST(0)(src), l_exc_copy) ADD src, src, NBYTES @@ -372,6 +387,7 @@ nop copy_bytes: /* 0 < len < NBYTES */ + R10KCBARRIER(0(ra)) #define COPY_BYTE(N) \ EXC( lb t0, N(src), l_exc); \ SUB len, len, 1; \ @@ -484,6 +500,7 @@ ADD a1, a2 # src = src + len r_end_bytes: + R10KCBARRIER(0(ra)) lb t0, -1(a1) SUB a2, a2, 0x1 sb t0, -1(a0) @@ -496,6 +513,7 @@ move a2, zero r_end_bytes_up: + R10KCBARRIER(0(ra)) lb t0, (a1) SUB a2, a2, 0x1 sb t0, (a0) @@ -506,3 +524,7 @@ jr ra move a2, zero END(__rmemcpy) +/* + * Revision 1.18, Sat Jul 26 12:00:12 2003 + * Sat Aug 7 01:11:52 2004 pf - r10k cache barrier + */ diff -Nur linux-git/arch/mips/lib/strncpy_user.S linux-git-mit-R10k-patches/arch/mips/lib/strncpy_user.S --- linux-git/arch/mips/lib/strncpy_user.S 2005-10-15 16:01:06.000000000 +0200 +++ linux-git-mit-R10k-patches/arch/mips/lib/strncpy_user.S 2005-10-16 13:30:49.000000000 +0200 @@ -5,11 +5,20 @@ * * Copyright (c) 1996, 1999 by Ralf Baechle */ +#include <linux/config.h> #include <linux/errno.h> #include <asm/asm.h> #include <asm/asm-offsets.h> #include <asm/regdef.h> +#ifdef CONFIG_SGI_IP28 +/* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */ +# include <asm/cacheops.h> +# define R10KCBARRIER(addr) cache Cache_Barrier, addr; +#else +# define R10KCBARRIER(addr) +#endif + #define EX(insn,reg,addr,handler) \ 9: insn reg, addr; \ .section __ex_table,"a"; \ @@ -38,6 +47,7 @@ .set noreorder 1: EX(lbu, t0, (v1), fault) PTR_ADDIU v1, 1 + R10KCBARRIER(0(ra)) beqz t0, 2f sb t0, (a0) PTR_ADDIU v0, 1 @@ -56,3 +66,7 @@ .section __ex_table,"a" PTR 1b, fault .previous +/* + * Revision 1.9, Wed Nov 19 14:03:13 2003 + * Wed Aug 11 02:21:01 2004 pf - r10k cache barrier + */ diff -Nur linux-git/arch/mips/lib-64/memset.S linux-git-mit-R10k-patches/arch/mips/lib-64/memset.S --- linux-git/arch/mips/lib-64/memset.S 2005-10-15 16:01:06.000000000 +0200 +++ linux-git-mit-R10k-patches/arch/mips/lib-64/memset.S 2005-10-16 13:29:04.000000000 +0200 @@ -6,10 +6,19 @@ * Copyright (C) 1998, 1999, 2000 by Ralf Baechle * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ +#include <linux/config.h> #include <asm/asm.h> #include <asm/asm-offsets.h> #include <asm/regdef.h> +#ifdef CONFIG_SGI_IP28 +/* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */ +# include <asm/cacheops.h> +# define R10KCBARRIER(addr) cache Cache_Barrier, addr; +#else +# define R10KCBARRIER(addr) +#endif + #define EX(insn,reg,addr,handler) \ 9: insn reg, addr; \ .section __ex_table,"a"; \ @@ -57,6 +66,7 @@ beqz t0, 1f PTR_SUBU t0, LONGSIZE /* alignment in bytes */ + R10KCBARRIER(0(ra)) #ifdef __MIPSEB__ EX(sdl, a1, (a0), first_fixup) /* make dword aligned */ #endif @@ -74,11 +84,13 @@ PTR_ADDU t1, a0 /* end address */ .set reorder 1: PTR_ADDIU a0, 64 + R10KCBARRIER(0(ra)) f_fill64 a0, -64, a1, fwd_fixup bne t1, a0, 1b .set noreorder memset_partial: + R10KCBARRIER(0(ra)) PTR_LA t1, 2f /* where to start */ .set noat dsrl AT, t0, 1 @@ -96,6 +108,7 @@ beqz a2, 1f PTR_ADDU a0, a2 /* What's left */ + R10KCBARRIER(0(ra)) #ifdef __MIPSEB__ EX(sdr, a1, -1(a0), last_fixup) #endif @@ -110,6 +123,7 @@ PTR_ADDU t1, a0, a2 1: PTR_ADDIU a0, 1 /* fill bytewise */ + R10KCBARRIER(0(ra)) bne t1, a0, 1b sb a1, -1(a0) @@ -140,3 +154,7 @@ last_fixup: jr ra andi v1, a2, LONGMASK +/* + * Revision 1.1, Mon Jul 21 00:11:39 2003 + * Wed Aug 11 01:52:59 2004 pf - r10k cache barrier + */ diff -Nur linux-git/arch/mips/Makefile linux-git-mit-R10k-patches/arch/mips/Makefile --- linux-git/arch/mips/Makefile 2005-10-15 16:01:06.000000000 +0200 +++ linux-git-mit-R10k-patches/arch/mips/Makefile 2005-10-16 13:21:56.000000000 +0200 @@ -628,6 +628,19 @@ endif # +# SGI IP28 (Indigo2 R10k) +# +# Set the load address to >= 0xa800000020080000 if you want to leave space for +# symmon, 0xa800000020004000 for production kernels ? Note that the value must +# be 16kb aligned or the handling of the current variable will break. +# Simplified: what IP22 does at 128MB+ in ksegN, IP28 does at 512MB+ in xkphys +# +#core-$(CONFIG_SGI_IP28) += arch/mips/sgi-ip22/ arch/mips/arc/arc_con.o +core-$(CONFIG_SGI_IP28) += arch/mips/sgi-ip22/ +cflags-$(CONFIG_SGI_IP28) += -mip28-cache-barrier -Iinclude/asm-mips/mach-ip28 +load-$(CONFIG_SGI_IP28) += 0xa800000020004000 + +# # SGI-IP32 (O2) # # Set the load address to >= 80069000 if you want to leave space for symmon, @@ -814,3 +827,6 @@ CLEAN_FILES += vmlinux.32 \ vmlinux.64 \ vmlinux.ecoff + +# Revision 1.193, Tue Apr 19 00:00:49 2005 +# Jun/Dec 2004 - IP28 diff -Nur linux-git/arch/mips/mm/c-r4k.c linux-git-mit-R10k-patches/arch/mips/mm/c-r4k.c --- linux-git/arch/mips/mm/c-r4k.c 2005-10-15 16:01:07.000000000 +0200 +++ linux-git-mit-R10k-patches/arch/mips/mm/c-r4k.c 2005-10-16 13:21:56.000000000 +0200 @@ -712,6 +712,27 @@ bc_inv(addr, size); } + +#ifdef CONFIG_CPU_R10000 +static void r10k_dma_cache_inv(unsigned long addr, unsigned long size) +{ + unsigned long sc_lsize = current_cpu_data.scache.linesz; + unsigned long end, a; + + /* Catch bad driver code */ + BUG_ON(size == 0); + //BUG_ON(!cpu_has_subset_pcaches); + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + invalidate_scache_line(a); /* Hit_Invalidate_SD/S */ + if (a == end) + break; + a += sc_lsize; + } +} +#endif /* CONFIG_CPU_R10000 */ #endif /* CONFIG_DMA_NONCOHERENT */ /* @@ -1269,7 +1290,16 @@ #ifdef CONFIG_DMA_NONCOHERENT _dma_cache_wback_inv = r4k_dma_cache_wback_inv; _dma_cache_wback = r4k_dma_cache_wback_inv; - _dma_cache_inv = r4k_dma_cache_inv; + switch (current_cpu_data.cputype) { +#ifdef CONFIG_CPU_R10000 + case CPU_R10000: + case CPU_R12000: + _dma_cache_inv = r10k_dma_cache_inv; + break; +#endif + default: + _dma_cache_inv = r4k_dma_cache_inv; + } #endif build_clear_page(); @@ -1277,3 +1307,7 @@ local_r4k___flush_cache_all(NULL); coherency_setup(); } +/* + * Revision 1.107, Tue Apr 19 00:06:40 2005 + * Sat Apr 9 00:06:16 2005 pf - r10k_dma_cache_inv (really dma invalidate) + */ diff -Nur linux-git/arch/mips/mm/init.c linux-git-mit-R10k-patches/arch/mips/mm/init.c --- linux-git/arch/mips/mm/init.c 2005-10-15 16:01:07.000000000 +0200 +++ linux-git-mit-R10k-patches/arch/mips/mm/init.c 2005-10-16 13:33:09.000000000 +0200 @@ -225,6 +225,7 @@ if (PageReserved(mem_map+tmp)) reservedpages++; } + num_physpages = ram; #ifdef CONFIG_HIGHMEM for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) { @@ -241,6 +242,7 @@ set_page_count(page, 1); __free_page(page); totalhigh_pages++; + ++num_physpages; } totalram_pages += totalhigh_pages; #endif @@ -266,8 +268,8 @@ { #ifdef CONFIG_64BIT /* Switch from KSEG0 to XKPHYS addresses */ - start = (unsigned long)phys_to_virt(CPHYSADDR(start)); - end = (unsigned long)phys_to_virt(CPHYSADDR(end)); + start = (unsigned long)phys_to_virt(kernel_physaddr(start)); + end = (unsigned long)phys_to_virt(kernel_physaddr(end)); #endif if (start < end) printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", @@ -293,7 +295,7 @@ addr = (unsigned long) &__init_begin; while (addr < (unsigned long) &__init_end) { #ifdef CONFIG_64BIT - page = PAGE_OFFSET | CPHYSADDR(addr); + page = PAGE_OFFSET | kernel_physaddr(addr); #else page = addr; #endif @@ -307,3 +309,7 @@ printk(KERN_INFO "Freeing unused kernel memory: %ldk freed\n", freed >> 10); } +/* + * Revision 1.75, Tue Apr 19 00:06:47 2005 + * Jun 2004 pf - XKPHYS + */ diff -Nur linux-git/arch/mips/sgi-ip22/ip22-mc.c linux-git-mit-R10k-patches/arch/mips/sgi-ip22/ip22-mc.c --- linux-git/arch/mips/sgi-ip22/ip22-mc.c 2005-10-15 16:01:07.000000000 +0200 +++ linux-git-mit-R10k-patches/arch/mips/sgi-ip22/ip22-mc.c 2005-10-16 13:21:56.000000000 +0200 @@ -4,6 +4,7 @@ * Copyright (C) 1996 David S. Miller (dm@xxxxxxxxxxxx) * Copyright (C) 1999 Andrew R. Baker (andrewb@xxxxxxx) - Indigo2 changes * Copyright (C) 2003 Ladislav Michl (ladis@xxxxxxxxxxxxxx) + * Copyright (C) 2004 Peter Fuerst (pf@xxxxxxxxxxxxxx) - IP28 */ #include <linux/init.h> @@ -16,6 +17,8 @@ #include <asm/sgi/mc.h> #include <asm/sgi/hpc3.h> #include <asm/sgi/ip22.h> +#include <asm/system.h> +#include <asm/mipsregs.h> struct sgimc_regs *sgimc; @@ -112,6 +115,10 @@ sgimc = (struct sgimc_regs *) ioremap(SGIMC_BASE, sizeof(struct sgimc_regs)); +#ifdef CONFIG_SGI_IP28 + printk(KERN_INFO "Silicon Graphics Indigo2 R10k (IP28)" + " support: (c) 2004 peter fuerst.\n"); +#endif printk(KERN_INFO "MC: SGI memory controller Revision %d\n", (int) sgimc->systemid & SGIMC_SYSID_MASKREV); @@ -138,8 +145,21 @@ * zero. */ tmp = sgimc->cpuctrl0; - tmp |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM | - SGIMC_CCTRL0_R4KNOCHKPARR); + tmp |= SGIMC_CCTRL0_R4KNOCHKPARR; +#ifdef CONFIG_SGI_IP28 + /* IP28 prom left us cpuctrl0 set to 3d802412: + * SGIMC_CCTRL0_GIOBTOB, SGIMC_CCTRL0_R4KNOCHKPARR, + * SGIMC_CCTRL0_GFXRESET, SGIMC_CCTRL0_EREFRESH, 31800002 + * FIXME: + * We do not attempt to override IP28-prom's parity checking, + * since SGIMC_CCTRL0_EPERRGIO will trigger a CPU parity error + * (IP[6]) on reading sgioc->sysid below, while ..EPERRMEM will + * trigger the same somewhere in prom-code (ffffffff9fc431cc) + * when ArcGetEnvironmentVariable() is called :-( + */ +#else + tmp |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM); +#endif sgimc->cpuctrl0 = tmp; /* Step 3: Setup the MC write buffer depth, this is controlled @@ -147,7 +167,14 @@ */ tmp = sgimc->cpuctrl1; tmp &= ~0xf; +#ifdef CONFIG_SGI_IP28 + /* IP28 prom left us cpuctrl1 set to 00000016: + * SGIMC_CCTRL1_EGIOTIMEO | 00000006 + */ + tmp |= 0xd; /* ? 0x6:0xd */ +#else tmp |= 0xd; +#endif sgimc->cpuctrl1 = tmp; /* Step 4: Initialize the RPSS divider register to run as fast @@ -164,7 +191,12 @@ * registers value increases at each 'tick'. Thus, * for IP22 we get INCREMENT=1, DIVIDER=1 == 0x101 */ +#ifdef CONFIG_SGI_IP28 + /* IP28 prom left us divider set to 00000104 */ + sgimc->divider = 0x101; /* ? 0x104:0x101 */ +#else sgimc->divider = 0x101; +#endif /* Step 5: Initialize GIO64 arbitrator configuration register. * @@ -177,6 +209,20 @@ tmp = SGIMC_GIOPAR_HPC64; /* All 1st HPC's interface at 64bits */ tmp |= SGIMC_GIOPAR_ONEBUS; /* Only one physical GIO bus exists */ +#ifdef CONFIG_SGI_IP28 + /* IP28 prom left us giopar set to 0000ce23: + * SGIMC_GIOPAR_PLINEEXP0, SGIMC_GIOPAR_PLINEEXP1, + * SGIMC_GIOPAR_MASTERGFX, SGIMC_GIOPAR_MASTEREISA, + * SGIMC_GIOPAR_ONEBUS, SGIMC_GIOPAR_GFX64, + * SGIMC_GIOPAR_HPC264, SGIMC_GIOPAR_HPC64 + */ + tmp |= SGIMC_GIOPAR_HPC264; /* 2nd HPC at 64bits */ + tmp |= SGIMC_GIOPAR_PLINEEXP0; /* exp0 pipelines */ + tmp |= SGIMC_GIOPAR_PLINEEXP1; /* exp1 pipelines */ + tmp |= SGIMC_GIOPAR_MASTERGFX; /* GFX can act as a bus master */ + tmp |= SGIMC_GIOPAR_MASTEREISA; /* EISA bus can act as bus master */ + tmp |= SGIMC_GIOPAR_GFX64; /* GFX talks to GIO using 64-bits */ +#else if (ip22_is_fullhouse()) { /* Fullhouse specific settings. */ if (SGIOC_SYSID_BOARDREV(sgioc->sysid) < 2) { @@ -196,9 +242,14 @@ tmp |= SGIMC_GIOPAR_EISA64; /* MC talks to EISA at 64bits */ tmp |= SGIMC_GIOPAR_MASTEREISA; /* EISA bus can act as master */ } +#endif sgimc->giopar = tmp; /* poof */ + printk(KERN_INFO "MC: Boardrev. %d, Chiprev. %d\n", + SGIOC_SYSID_BOARDREV(sgioc->sysid), + SGIOC_SYSID_CHIPREV(sgioc->sysid)); probe_memory(); + ip2628_return_ucmem(0); /* see below. */ } void __init prom_meminit(void) {} @@ -206,3 +257,99 @@ { return 0; } + +#if defined(CONFIG_SGI_IP28) || defined(CONFIG_SGI_IP26) +/* + * Handling uncached writes on IP26/IP28, see IRIX man-page ip26_ucmem(D3) + * and Device Driver Programmer's Guide (007-0911-210), Chapter I.1. + */ + +static inline int _r10k_real_sync ( volatile struct sgimc_regs *sgimc ) +{ + /* See MIPS R10000 User's Manual (SGI 007-2490-001), Chapter 4.5 */ + int dummy = sgimc->cstat; + __asm__ __volatile__ ("sync"); + return dummy; +} + +static unsigned long +ip28_set_ucmem ( volatile struct sgimc_regs *sgimc, unsigned short enable ) +{ /* + * Reading `modereg' only provides random values, so we start with + * guessing (from WR_COL), which state the machine is initially in + * and do our own bookkeeping from then on. + */ + const unsigned long modereg = PHYS_TO_XKSEG_UNCACHED(0x60000000); + static unsigned oldstate = -1; + unsigned long flags; + unsigned tmp; + spinlock_t lock; + u32 mconfig1, cmacc, oldcmacc; + + if (enable == oldstate) + return (long)enable; + + /* This has to be done as early as possible ! */ + spin_lock_irqsave(&lock, flags); + + oldcmacc = sgimc->cmacc; + cmacc = (enable ? 6:4) | (oldcmacc & ~0xf); + + /* increase WR_COL before (if at all) */ + sgimc->cmacc = cmacc | 7; + + /* enable memory bank 3 at 0x60000000 */ + mconfig1 = sgimc->mconfig1; + sgimc->mconfig1 = mconfig1 & 0xffff0000 | 0x2060; + _r10k_real_sync(sgimc); + + /* set mode to "slow" or "normal" */ + *(volatile unsigned long*)modereg = enable ? 0x10000:0; + _r10k_real_sync(sgimc); + + /* restore memory bank configuration */ + sgimc->mconfig1 = mconfig1; + + /* decrease WR_COL only after */ + sgimc->cmacc = cmacc; + _r10k_real_sync(sgimc); + + if (-1 == oldstate) + oldstate = (oldcmacc & 0xf) > 4; + + tmp = oldstate; + oldstate = enable; + _r10k_real_sync(sgimc); + + spin_unlock_irqrestore(&lock, flags); + return tmp; +} +#endif + +unsigned long ip2628_enable_ucmem (void) +{ +#if defined(CONFIG_SGI_IP28) || defined(CONFIG_SGI_IP26) + if (!sgimc) + sgimc = (struct sgimc_regs *) + ioremap(SGIMC_BASE, sizeof(struct sgimc_regs)); + return ip28_set_ucmem(sgimc,1); +#else + return 0; +#endif +} + +void ip2628_return_ucmem ( unsigned long oldstate ) +{ +#if defined(CONFIG_SGI_IP28) || defined(CONFIG_SGI_IP26) + if (!sgimc) + sgimc = (struct sgimc_regs *) + ioremap(SGIMC_BASE, sizeof(struct sgimc_regs)); + ip28_set_ucmem(sgimc,!!oldstate); +#else + (void)oldstate; +#endif +} +/* + * Revision 1.12, Tue Nov 18 05:15:20 2003 + * Jun 2004/2005 pf - IP28 + */ diff -Nur linux-git/arch/mips/sgi-ip22/ip22-setup.c linux-git-mit-R10k-patches/arch/mips/sgi-ip22/ip22-setup.c --- linux-git/arch/mips/sgi-ip22/ip22-setup.c 2005-10-15 16:01:07.000000000 +0200 +++ linux-git-mit-R10k-patches/arch/mips/sgi-ip22/ip22-setup.c 2005-10-16 13:21:56.000000000 +0200 @@ -119,6 +119,34 @@ } } #endif +#if defined(CONFIG_FB_IMPACT) || defined(CONFIG_SGI_IP28) + { + /* Get graphics info before it is overwritten... + * E.g. @ 9000000020f02f78: ffffffff9fc6d770,900000001f000000 + */ + ULONG* (*__vec)(void) = (typeof(__vec)) +#ifdef CONFIG_ARC64 + ((ULONG*)PROMBLOCK->pvector)[8]; +#else + (long) ((int*)PROMBLOCK->pvector)[8]; +#endif + ULONG *gfxinfo = (*__vec)(); + ULONG a = gfxinfo[1]; + + if ((a & 0xffffffff80000000L) == 0xffffffff80000000L) + sgi_gfxaddr = a & (6L<<28) ? 0:CPHYSADDR(a); /* CKSEG[01] */ + else if ((a & (1L<<63)) && (a & 0xb80000001fffffffL) == a) + sgi_gfxaddr = XPHYSADDR(a); /* lower 512MB of XKPHYS */ + else /* rubbish... */ + sgi_gfxaddr = 0; + if (sgi_gfxaddr < 0x1f000000) + sgi_gfxaddr = 0; + + printk(KERN_DEBUG "ARCS gfx info @ %08lx: %08lx,%08lx\n", + gfxinfo, gfxinfo[0], gfxinfo[1]); + printk(KERN_INFO "SGI graphics system @ 0x%08lx\n", sgi_gfxaddr); + } +#endif #if defined(CONFIG_VT) && defined(CONFIG_SGI_NEWPORT_CONSOLE) { diff -Nur linux-git/arch/mips/sgi-ip22/ip28-berr.c linux-git-mit-R10k-patches/arch/mips/sgi-ip22/ip28-berr.c --- linux-git/arch/mips/sgi-ip22/ip28-berr.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-git-mit-R10k-patches/arch/mips/sgi-ip22/ip28-berr.c 2005-10-16 13:22:04.000000000 +0200 @@ -0,0 +1,600 @@ +/* + * ip28-berr.c: Bus error handling. + * + * Copyright (C) 2002, 2003 Ladislav Michl (ladis@xxxxxxxxxxxxxx) + * Copyright (C) 2005 Peter Fuerst (pf@xxxxxxxxxxxxxx) - IP28 + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> + +#include <asm/addrspace.h> +#include <asm/system.h> +#include <asm/traps.h> +#include <asm/branch.h> +#include <asm/sgi/mc.h> +#include <asm/sgi/hpc3.h> +#include <asm/sgi/ioc.h> +#include <asm/sgi/ip22.h> +#include <asm/r4kcache.h> +#include <asm/uaccess.h> + +static unsigned int cpu_err_stat; /* Status reg for CPU */ +static unsigned int gio_err_stat; /* Status reg for GIO */ +static unsigned int cpu_err_addr; /* Error address reg for CPU */ +static unsigned int gio_err_addr; /* Error address reg for GIO */ +static unsigned int extio_stat; +static unsigned int hpc3_berr_stat; /* Bus error interrupt status */ + +struct hpc3_stat { + unsigned int addr; + unsigned int ctrl; + unsigned int cbp; + unsigned int ndptr; +}; + +static struct { + struct hpc3_stat pbdma[8]; + struct hpc3_stat scsi[2]; + struct hpc3_stat ethrx, ethtx; +} hpc3; + +static struct { + unsigned long err_addr; + struct { unsigned lo; unsigned hi; } /* Cache tag High/Low */ + tags[1][2], tagd[4][2], tagi[4][2]; /* Way 0/1 */ +} cache_tags; + +static inline void save_cache_tags(unsigned busaddr) +{ + unsigned long addr = CAC_BASE | busaddr; + unsigned i; + cache_tags.err_addr = addr; + + /* + * Starting with a bus-address, save secondary cache (indexed by + * PA[23..18:7..6]) tags first. + */ + addr &= ~1L; + #define tag cache_tags.tags[0] + cache_op(Index_Load_Tag_S, addr); + tag[0].lo = read_c0_taglo(); /* PA[35:18], VA[13:12] */ + tag[0].hi = read_c0_taghi(); /* PA[39:36] */ + cache_op(Index_Load_Tag_S, addr | 1L); + tag[1].lo = read_c0_taglo(); /* PA[35:18], VA[13:12] */ + tag[1].hi = read_c0_taghi(); /* PA[39:36] */ + #undef tag + + /* + * Save all primary data cache (indexed by VA[13:5]) tags which + * might fit to this bus-address, knowing that VA[11:0] == PA[11:0]. + * Saving all tags and evaluating them later is easier and safer + * than relying on VA[13:12] from the secondary cache tags to pick + * matching primary tags here already. + */ + addr &= (0xffL << 56) | ((1 << 12) - 1); + #define tag cache_tags.tagd[i] + for (i = 0; i < 4; ++i, addr += (1 << 12)) + { cache_op(Index_Load_Tag_D, addr); + tag[0].lo = read_c0_taglo(); /* PA[35:12] */ + tag[0].hi = read_c0_taghi(); /* PA[39:36] */ + cache_op(Index_Load_Tag_D, addr | 1L); + tag[1].lo = read_c0_taglo(); /* PA[35:12] */ + tag[1].hi = read_c0_taghi(); /* PA[39:36] */ + } + #undef tag + + /* + * Save primary instruction cache (indexed by VA[13:6]) tags + * the same way. + */ + addr &= (0xffL << 56) | ((1 << 12) - 1); + #define tag cache_tags.tagi[i] + for (i = 0; i < 4; ++i, addr += (1 << 12)) + { cache_op(Index_Load_Tag_I, addr); + tag[0].lo = read_c0_taglo(); /* PA[35:12] */ + tag[0].hi = read_c0_taghi(); /* PA[39:36] */ + cache_op(Index_Load_Tag_I, addr | 1L); + tag[1].lo = read_c0_taglo(); /* PA[35:12] */ + tag[1].hi = read_c0_taghi(); /* PA[39:36] */ + } + #undef tag +} + +#define GIO_ERRMASK 0xff00 +#define CPU_ERRMASK 0x3f00 + +static void save_and_clear_buserr(void) +{ + unsigned i; + + /* save status registers */ + cpu_err_addr = sgimc->cerr; + cpu_err_stat = sgimc->cstat; + gio_err_addr = sgimc->gerr; + gio_err_stat = sgimc->gstat; + //BUG_ON(!ip22_is_fullhouse()); + extio_stat = sgioc->extio; + hpc3_berr_stat = hpc3c0->bestat; + + hpc3.scsi[0].addr = &hpc3c0->scsi_chan0; + hpc3.scsi[0].ctrl = hpc3c0->scsi_chan0.ctrl; /* HPC3_SCTRL_ACTIVE ? */ + hpc3.scsi[0].cbp = hpc3c0->scsi_chan0.cbptr; + hpc3.scsi[0].ndptr = hpc3c0->scsi_chan0.ndptr; + + hpc3.scsi[1].addr = &hpc3c0->scsi_chan1; + hpc3.scsi[1].ctrl = hpc3c0->scsi_chan1.ctrl; /* HPC3_SCTRL_ACTIVE ? */ + hpc3.scsi[1].cbp = hpc3c0->scsi_chan1.cbptr; + hpc3.scsi[1].ndptr = hpc3c0->scsi_chan1.ndptr; + + hpc3.ethrx.addr = &hpc3c0->ethregs.rx_cbptr; + hpc3.ethrx.ctrl = hpc3c0->ethregs.rx_ctrl; /* HPC3_ERXCTRL_ACTIVE ? */ + hpc3.ethrx.cbp = hpc3c0->ethregs.rx_cbptr; + hpc3.ethrx.ndptr = hpc3c0->ethregs.rx_ndptr; + + hpc3.ethtx.addr = &hpc3c0->ethregs.tx_cbptr; + hpc3.ethtx.ctrl = hpc3c0->ethregs.tx_ctrl; /* HPC3_ETXCTRL_ACTIVE ? */ + hpc3.ethtx.cbp = hpc3c0->ethregs.tx_cbptr; + hpc3.ethtx.ndptr = hpc3c0->ethregs.tx_ndptr; + + for (i = 0; i < 8; ++i) { + /* HPC3_PDMACTRL_ISACT ? */ + hpc3.pbdma[i].addr = &hpc3c0->pbdma[i]; + hpc3.pbdma[i].ctrl = hpc3c0->pbdma[i].pbdma_ctrl; + hpc3.pbdma[i].cbp = hpc3c0->pbdma[i].pbdma_bptr; + hpc3.pbdma[i].ndptr = hpc3c0->pbdma[i].pbdma_dptr; + } + i = 0; + if (gio_err_stat & CPU_ERRMASK) + i = gio_err_addr; + if (cpu_err_stat & CPU_ERRMASK) + i = cpu_err_addr; + save_cache_tags(i); + + sgimc->cstat = sgimc->gstat = 0; +} + +static void print_cache_tags(void) +{ + unsigned i, scb, scw; + + printk(KERN_ERR "Cache tags @ %08x:\n", (unsigned)cache_tags.err_addr); + + /* PA[31:12] shifted to PTag0 (PA[35:12]) format */ + scw = (cache_tags.err_addr >> 4) & 0x0fffff00; + + scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 5) - 1); + for (i = 0; i < 4; ++i) { /* for each possible VA[13:12] value */ + if ((cache_tags.tagd[i][0].lo & 0x0fffff00) != scw && + (cache_tags.tagd[i][1].lo & 0x0fffff00) != scw) + continue; + printk(KERN_ERR "D: 0: %08x %08x, 1: %08x %08x (VA[13:5] %04x)\n", + cache_tags.tagd[i][0].hi, cache_tags.tagd[i][0].lo, + cache_tags.tagd[i][1].hi, cache_tags.tagd[i][1].lo, + scb | (1 << 12)*i); + } + scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 6) - 1); + for (i = 0; i < 4; ++i) { /* for each possible VA[13:12] value */ + if ((cache_tags.tagi[i][0].lo & 0x0fffff00) != scw && + (cache_tags.tagi[i][1].lo & 0x0fffff00) != scw) + continue; + printk(KERN_ERR "I: 0: %08x %08x, 1: %08x %08x (VA[13:6] %04x)\n", + cache_tags.tagi[i][0].hi, cache_tags.tagi[i][0].lo, + cache_tags.tagi[i][1].hi, cache_tags.tagi[i][1].lo, + scb | (1 << 12)*i); + } + i = read_c0_config(); + scb = i & (1 << 13) ? 7:6; /* scblksize = 2^[7..6] */ + scw = ((i >> 16) & 7) + 19 - 1; /* scwaysize = 2^[24..19] / 2 */ + + i = ((1 << scw) - 1) & ~((1 << scb) - 1); + printk(KERN_ERR "S: 0: %08x %08x, 1: %08x %08x (PA[%u:%u] %05x)\n", + cache_tags.tags[0][0].hi, cache_tags.tags[0][0].lo, + cache_tags.tags[0][1].hi, cache_tags.tags[0][1].lo, + scw-1, scb, i & (unsigned)cache_tags.err_addr); +} + +static void print_buserr(void) +{ + int error = 0; + + if (extio_stat & EXTIO_MC_BUSERR) { + printk(KERN_ERR "MC Bus Error\n"); + error |= 1; + } + if (extio_stat & EXTIO_HPC3_BUSERR) { + printk(KERN_ERR "HPC3 Bus Error 0x%x:<id=0x%x,%s,lane=0x%x>\n", + hpc3_berr_stat, + (hpc3_berr_stat & HPC3_BESTAT_PIDMASK) >> + HPC3_BESTAT_PIDSHIFT, + (hpc3_berr_stat & HPC3_BESTAT_CTYPE) ? "PIO" : "DMA", + hpc3_berr_stat & HPC3_BESTAT_BLMASK); + error |= 2; + } + if (extio_stat & EXTIO_EISA_BUSERR) { + printk(KERN_ERR "EISA Bus Error\n"); + error |= 4; + } + if (cpu_err_stat & CPU_ERRMASK) { + printk(KERN_ERR "CPU error 0x%x<%s%s%s%s%s%s> @ 0x%08x\n", + cpu_err_stat, + cpu_err_stat & SGIMC_CSTAT_RD ? "RD " : "", + cpu_err_stat & SGIMC_CSTAT_PAR ? "PAR " : "", + cpu_err_stat & SGIMC_CSTAT_ADDR ? "ADDR " : "", + cpu_err_stat & SGIMC_CSTAT_SYSAD_PAR ? "SYSAD " : "", + cpu_err_stat & SGIMC_CSTAT_SYSCMD_PAR ? "SYSCMD " : "", + cpu_err_stat & SGIMC_CSTAT_BAD_DATA ? "BAD_DATA " : "", + cpu_err_addr); + error |= 8; + } + if (gio_err_stat & GIO_ERRMASK) { + printk(KERN_ERR "GIO error 0x%x:<%s%s%s%s%s%s%s%s> @ 0x%08x\n", + gio_err_stat, + gio_err_stat & SGIMC_GSTAT_RD ? "RD " : "", + gio_err_stat & SGIMC_GSTAT_WR ? "WR " : "", + gio_err_stat & SGIMC_GSTAT_TIME ? "TIME " : "", + gio_err_stat & SGIMC_GSTAT_PROM ? "PROM " : "", + gio_err_stat & SGIMC_GSTAT_ADDR ? "ADDR " : "", + gio_err_stat & SGIMC_GSTAT_BC ? "BC " : "", + gio_err_stat & SGIMC_GSTAT_PIO_RD ? "PIO_RD " : "", + gio_err_stat & SGIMC_GSTAT_PIO_WR ? "PIO_WR " : "", + gio_err_addr); + error |= 16; + } + if (!error) + printk(KERN_ERR "MC: Hmm, didn't find any error condition.\n"); + else { + printk(KERN_ERR "CP0: config %08x, " + "MC: cpuctrl0/1: %08x/%05x, giopar: %04x\n" + "MC: cpu/gio_memacc: %08x/%05x, memcfg0/1: %08x/%08x\n", + read_c0_config(), + sgimc->cpuctrl0, sgimc->cpuctrl0, sgimc->giopar, + sgimc->cmacc, sgimc->gmacc, + sgimc->mconfig0, sgimc->mconfig1); + print_cache_tags(); + } +} + +/* + * Try to find out, whether the bus error is caused by the instruction + * at EPC, otherwise we have an asynchronous error. + * + * Doc1: "MIPS IV Instruction Set", Rev 3.2 (SGI 007-2597-001) + * Doc2: "MIPS R10000 Microporcessor User's Manual", Ver 2.0 (SGI 007-2490-001) + * Doc3: "MIPS R4000 Microporcessor User's Manual", 2nd Ed. (SGI 007-2489-001) + */ + +#define JMP_INDEX26_OP 1 +#define JMP_REGISTER_OP 2 +#define JMP_PCREL16_OP 3 +#define BASE_OFFSET_OP 4 +#define BASE_IDXREG_OP 5 + +/* Match virtual address in an insn with physical error address */ + +static int match_addr(unsigned paddr, unsigned long vaddr) +{ + unsigned uaddr; + + if ((vaddr & 0xffffffff80000000L) == 0xffffffff80000000L) + uaddr = (unsigned) CPHYSADDR(vaddr); + else if ((vaddr >> 62) == 2) + uaddr = (unsigned) XPHYSADDR(vaddr); + else + { unsigned long eh = vaddr & ~0x1fffL; + eh |= read_c0_entryhi() & 0xff; + write_c0_entryhi(eh); + tlb_probe(); + if (read_c0_index() & 0x80000000) + return 0; + tlb_read(); + if (vaddr & (1L << PAGE_SHIFT)) + uaddr = (unsigned) read_c0_entrylo1(); + else + uaddr = (unsigned) read_c0_entrylo0(); + uaddr <<= 6; + uaddr &= ~PAGE_MASK; + uaddr |= vaddr & PAGE_MASK; + } + return ((uaddr & ~0x7f) == (paddr & ~0x7f)); +} + +/* Check, which kind of memory reference is triggered by `insn' */ + +static int check_special(unsigned insn) +{ + /* See Doc1, page A-180 */ + unsigned func = insn & 0x3f; + + if (8 == func || 8+1 == func) /* JR, JALR */ + return JMP_REGISTER_OP; + + return 0; +} + +static int check_regimm(unsigned insn) +{ + /* See Doc1, page A-180 */ + unsigned rt = (insn >> 19) & 3; /* bits 20..19[..16] */ + + /* BLTZ, BGEZ, BLTZL, BBGEZL || BLTZAL, BGEZAL, BLTZALL, BBGEZALL */ + if (!rt || 2 == rt) + return JMP_PCREL16_OP; + + return 0; +} + +static int check_cop0(unsigned insn) +{ + /* See Doc2, pages 287 ff., 187 ff. */ + if ((insn >> 26) == 5*8+7) /* CACHE */ + switch ((insn >> 16) & 0x1f) { + case Index_Writeback_Inv_D: + case Hit_Writeback_Inv_D: + case Index_Writeback_Inv_S: + case Hit_Writeback_Inv_S: + return BASE_OFFSET_OP; + } + return 0; +} + +static int check_cop1(unsigned insn) +{ + /* See Doc1, pages B-108 ff. */ + unsigned fmt = (insn >> 21) & 0x1f; /* bits 25..21 */ + + if (8 == fmt) /* BC1* */ + return JMP_PCREL16_OP; + + return 0; +} + +static int check_cop1x(unsigned insn) +{ + /* See Doc1, pages B-108 ff. */ + switch (insn & 0x3f) { + case 0: /* LWXC1 */ + case 1: /* LDXC1 */ + case 8: /* SWXC1 */ + case 8+1: /* SDXC1 */ + return BASE_IDXREG_OP; + } + return 0; +} + +static int check_plain(unsigned insn) +{ + /* See Doc1, page A-180 */ + unsigned opcode = insn >> 26; + + if (2 == opcode || 3 == opcode) /* J, JAL */ + return JMP_INDEX26_OP; + + if (4 <= opcode && opcode <= 7 || /* BEQ, BNE, BLEZ, BGTZ */ + 4+2*8 <= opcode && opcode <= 7+2*8) /* BEQL, BNEL, BLEZL, BGTZL */ + return JMP_PCREL16_OP; + + if (6*8+3 == opcode) /* PREF */ + return 0; + + if (3*8+2 == opcode || 3*8+3 == opcode || /* LDL, LDR */ + 4*8 <= opcode) /* misc. LOAD, STORE */ + return BASE_OFFSET_OP; + + return 0; +} + +/* Check, whether the insn at EPC causes a memory access at `paddr' */ + +static int check_addr_in_insn(unsigned paddr, struct pt_regs *regs) +{ + unsigned long epc; + unsigned insn; + int typ; + + epc = regs->cp0_cause & CAUSEF_BD ? regs->cp0_epc:regs->cp0_epc+4; + + /* show_code() from kernel/traps.c */ + if (__get_user(insn, (unsigned*) epc)) + return 1; + + /* See Doc1, pages A-180, B-108 ff. */ + switch (insn >> 26) + { case 0: + typ = check_special(insn); + break; + case 1: + typ = check_regimm(insn); + break; + case 2*8: /* COP0 */ + case 5*8+7: /* CACHE */ + typ = check_cop0(insn); + break; + case 2*8+1: + typ = check_cop1(insn); + break; + case 2*8+3: + typ = check_cop1x(insn); + break; + default: + typ = check_plain(insn); + } + switch (typ) + { unsigned long a; + case JMP_INDEX26_OP: + a = (regs->cp0_epc + 4) & ~0xfffffff; + a |= (insn & 0x3ffffff) << 2; + return match_addr(paddr, a); + case JMP_REGISTER_OP: + a = regs->regs[(insn >> 21) & 0x1f]; + return match_addr(paddr, a); + case JMP_PCREL16_OP: + a = regs->cp0_epc + 4 + ((insn & 0xffff) << 2); + return match_addr(paddr, a); + case BASE_OFFSET_OP: + a = regs->regs[(insn >> 21) & 0x1f] + (insn & 0xffff); + return match_addr(paddr, a); + case BASE_IDXREG_OP: + a = regs->regs[(insn >> 21) & 0x1f]; + a += regs->regs[(insn >> 16) & 0x1f]; + return match_addr(paddr, a); + case 0: + return 0; + } + /* Assume it would be too dangerous to continue ... */ + return 1; +} + +/* Check, whether MC's (virtual) DMA address caused the bus error. */ + +static int check_vdma_memaddr (void) +{ + /* Deferred until needed. */ + return 0; +} + +static int check_vdma_gioaddr (void) +{ + /* Deferred until needed. */ + return 0; +} + +static inline const char *cause_excode_text(int cause) +{ + static const char *txt[32] = + { "Interrupt", + "TLB modification", + "TLB (load or instruction fetch)", + "TLB (store)", + "Address error (load or instruction fetch)", + "Address error (store)", + "Bus error (instruction fetch)", + "Bus error (data: load or store)", + "Syscall", + "Breakpoint", + "Reserved instruction", + "Coprocessor unusable", + "Arithmetic Overflow", + "Trap", + "14", + "Floating-Point", + "16", "17", "18", "19", "20", "21", "22", + "Watch Hi/Lo", + "24", "25", "26", "27", "28", "29", "30", "31", + }; + return txt[(cause & 0x7c) >> 2]; +} + +/* + * MC sends an interrupt whenever bus or parity errors occur. In addition, + * if the error happened during a CPU read, it also asserts the bus error + * pin on the R4K. Code in bus error handler save the MC bus error registers + * and then clear the interrupt when this happens. + */ + +static int ip28_be_interrupt(struct pt_regs *regs) +{ + const int field = 2 * sizeof(unsigned long); + unsigned i; + + save_and_clear_buserr(); + print_buserr(); + printk(KERN_ALERT "%s, epc == %0*lx, ra == %0*lx\n", + cause_excode_text(regs->cp0_cause), + field, regs->cp0_epc, field, regs->regs[31]); + /* + * Try to find out, whether we got here by a mispredicted speculative + * load/store operation. If so, it's not fatal, we can go on. + */ + /* Any cause other than "Interrupt" (ExcCode 0) is fatal. */ + if (regs->cp0_cause & CAUSEF_EXCCODE) + return MIPS_BE_FATAL; + + /* Any cause other than "Bus error interrupt" (IP6) is weird. */ + if ((regs->cp0_cause & CAUSEF_IP6) != CAUSEF_IP6) + return MIPS_BE_FATAL; + + if (extio_stat & (EXTIO_HPC3_BUSERR | EXTIO_EISA_BUSERR)) + return MIPS_BE_FATAL; + + /* Any state other than "Memory bus error" is fatal. */ + if (cpu_err_stat & CPU_ERRMASK & ~SGIMC_CSTAT_ADDR) + return MIPS_BE_FATAL; + + /* Any state other than "GIO transaction bus timed out" is fatal. */ + if (gio_err_stat & GIO_ERRMASK & ~SGIMC_GSTAT_TIME) + return MIPS_BE_FATAL; + + /* Finding `cpu_err_addr' in the insn at EPC is fatal. */ + if ((cpu_err_stat & CPU_ERRMASK) && check_addr_in_insn(cpu_err_addr,regs)) + return MIPS_BE_FATAL; + + /* Finding `gio_err_addr' in the insn at EPC is fatal. */ + if ((gio_err_stat & GIO_ERRMASK) && check_addr_in_insn(gio_err_addr,regs)) + return MIPS_BE_FATAL; + /* + * Now we have an asynchronous bus error, speculatively or DMA caused. + * Need to search all DMA descriptors for the error address. + */ + for (i = 0; i < sizeof(hpc3)/sizeof(struct hpc3_stat); ++i) { + struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i; + if ((cpu_err_stat & CPU_ERRMASK) && + (cpu_err_addr == hp->ndptr || cpu_err_addr == hp->cbp)) + break; + if ((gio_err_stat & GIO_ERRMASK) && + (gio_err_addr == hp->ndptr || gio_err_addr == hp->cbp)) + break; + } + if (i < sizeof(hpc3)/sizeof(struct hpc3_stat)) { + struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i; + printk(KERN_ERR "at DMA addresses: HPC3 @ %08lx:" + " ctl %08x, ndp %08x, cbp %08x\n", + CPHYSADDR(hp->addr), hp->ctrl, hp->ndptr, hp->cbp); + return MIPS_BE_FATAL; + } + /* Check MC's virtual DMA stuff. */ + if ( check_vdma_memaddr() ) { + printk(KERN_ERR "at GIO DMA: mem address 0x%08x.\n", + sgimc->maddronly); + return MIPS_BE_FATAL; + } + if ( check_vdma_gioaddr() ) { + printk(KERN_ERR "at GIO DMA: gio address 0x%08x.\n", + sgimc->gmaddronly); + return MIPS_BE_FATAL; + } + /* A speculative bus error... */ + printk(KERN_ERR "discarded!\n"); + return MIPS_BE_DISCARD; +} + +void ip22_be_interrupt(int irq, struct pt_regs *regs) +{ + if (ip28_be_interrupt(regs) != MIPS_BE_DISCARD) { + /* Assume it would be too dangerous to continue ... */ + die_if_kernel("Oops", regs); + force_sig(SIGBUS, current); + } else { + show_regs(regs); + show_code((unsigned int *) regs->cp0_epc); + } +} + +static int ip28_be_handler(struct pt_regs *regs, int is_fixup) +{ + /* + * We arrive here only in the unusual case of do_be() invocation, + * i.e. by a bus error exception without a bus error interrupt. + */ + if (is_fixup) { + save_and_clear_buserr(); + return MIPS_BE_FIXUP; + } + return ip28_be_interrupt(regs); +} + +void __init ip22_be_init(void) +{ + board_be_handler = ip28_be_handler; +} diff -Nur linux-git/arch/mips/sgi-ip22/Makefile linux-git-mit-R10k-patches/arch/mips/sgi-ip22/Makefile --- linux-git/arch/mips/sgi-ip22/Makefile 2005-10-15 16:01:07.000000000 +0200 +++ linux-git-mit-R10k-patches/arch/mips/sgi-ip22/Makefile 2005-10-16 13:21:56.000000000 +0200 @@ -3,9 +3,13 @@ # under Linux. # -obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-irq.o ip22-berr.o \ +obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-irq.o \ ip22-time.o ip22-nvram.o ip22-reset.o ip22-setup.o +obj-$(CONFIG_SGI_IP28) += ip28-berr.o +obj-$(CONFIG_SGI_IP22) += ip22-berr.o obj-$(CONFIG_EISA) += ip22-eisa.o EXTRA_AFLAGS := $(CFLAGS) + +# Revision 1.19, Tue Nov 18 05:15:20 2003 diff -Nur linux-git/drivers/char/Kconfig linux-git-mit-R10k-patches/drivers/char/Kconfig --- linux-git/drivers/char/Kconfig 2005-10-15 16:01:11.000000000 +0200 +++ linux-git-mit-R10k-patches/drivers/char/Kconfig 2005-10-16 13:21:56.000000000 +0200 @@ -762,7 +762,7 @@ config SGI_DS1286 tristate "SGI DS1286 RTC support" - depends on SGI_IP22 + depends on (SGI_IP22 || SGI_IP28) help If you say Y here and create a character special file /dev/rtc with major number 10 and minor number 135 using mknod ("man mknod"), you diff -Nur linux-git/drivers/char/tty_io.c linux-git-mit-R10k-patches/drivers/char/tty_io.c --- linux-git/drivers/char/tty_io.c 2005-10-15 16:01:12.000000000 +0200 +++ linux-git-mit-R10k-patches/drivers/char/tty_io.c 2005-10-16 13:21:56.000000000 +0200 @@ -744,6 +744,7 @@ void tty_wakeup(struct tty_struct *tty) { + if (tty) { struct tty_ldisc *ld; if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) { @@ -755,6 +756,7 @@ } } wake_up_interruptible(&tty->write_wait); + } } EXPORT_SYMBOL_GPL(tty_wakeup); @@ -3014,3 +3016,7 @@ return 0; } module_init(tty_init); +/* + * Revision 1.133, Tue Apr 19 00:39:02 2005 + * Wed Jan 5 02:16:41 2005 + */ diff -Nur linux-git/drivers/char/watchdog/Kconfig linux-git-mit-R10k-patches/drivers/char/watchdog/Kconfig --- linux-git/drivers/char/watchdog/Kconfig 2005-10-15 16:01:12.000000000 +0200 +++ linux-git-mit-R10k-patches/drivers/char/watchdog/Kconfig 2005-10-16 13:21:56.000000000 +0200 @@ -427,7 +427,7 @@ config INDYDOG tristate "Indy/I2 Hardware Watchdog" - depends on WATCHDOG && SGI_IP22 + depends on WATCHDOG && (SGI_IP22 || SGI_IP28) help Hardwaredriver for the Indy's/I2's watchdog. This is a watchdog timer that will reboot the machine after a 60 second diff -Nur linux-git/drivers/input/serio/i8042.c linux-git-mit-R10k-patches/drivers/input/serio/i8042.c --- linux-git/drivers/input/serio/i8042.c 2005-10-15 16:01:13.000000000 +0200 +++ linux-git-mit-R10k-patches/drivers/input/serio/i8042.c 2005-10-16 13:21:56.000000000 +0200 @@ -656,7 +656,13 @@ if (i8042_command(¶m, I8042_CMD_AUX_ENABLE)) return -1; if (i8042_command(¶m, I8042_CMD_CTL_RCTR) || (param & I8042_CTR_AUXDIS)) +#ifdef CONFIG_SGI_IP28 + /* Seems we need to invert the CTR_AUXDIS-test on this machine: + * CMD_AUX_DISABLE -> rctr 0xcf, CMD_AUX_ENABLE -> rctr 0xef */ + printk(KERN_WARNING "Failed to enable AUX port, but continuing anyway... ;)\n"); +#else return -1; +#endif /* * Disable the interface. diff -Nur linux-git/drivers/input/serio/i8042.h linux-git-mit-R10k-patches/drivers/input/serio/i8042.h --- linux-git/drivers/input/serio/i8042.h 2005-10-15 16:01:13.000000000 +0200 +++ linux-git-mit-R10k-patches/drivers/input/serio/i8042.h 2005-10-16 13:21:56.000000000 +0200 @@ -17,7 +17,7 @@ #if defined(CONFIG_MACH_JAZZ) #include "i8042-jazzio.h" -#elif defined(CONFIG_SGI_IP22) +#elif defined(CONFIG_SGI_IP22) || defined(CONFIG_SGI_IP28) #include "i8042-ip22io.h" #elif defined(CONFIG_PPC) #include "i8042-ppcio.h" @@ -131,3 +131,7 @@ #endif #endif /* _I8042_H */ +/* + * Revision 1.10, Tue Apr 19 00:50:01 2005 + * Tue Dec 7 19:43:43 2004 - IP28 + */ diff -Nur linux-git/drivers/net/Kconfig linux-git-mit-R10k-patches/drivers/net/Kconfig --- linux-git/drivers/net/Kconfig 2005-10-15 16:01:16.000000000 +0200 +++ linux-git-mit-R10k-patches/drivers/net/Kconfig 2005-10-16 13:21:56.000000000 +0200 @@ -1728,7 +1728,7 @@ config SGISEEQ tristate "SGI Seeq ethernet controller support" - depends on NET_ETHERNET && SGI_IP22 + depends on NET_ETHERNET && (SGI_IP22 || SGI_IP26 || SGI_IP28) help Say Y here if you have an Seeq based Ethernet network card. This is used in many Silicon Graphics machines. diff -Nur linux-git/drivers/scsi/Kconfig linux-git-mit-R10k-patches/drivers/scsi/Kconfig --- linux-git/drivers/scsi/Kconfig 2005-10-15 16:01:20.000000000 +0200 +++ linux-git-mit-R10k-patches/drivers/scsi/Kconfig 2005-10-16 13:21:56.000000000 +0200 @@ -249,7 +249,7 @@ config SGIWD93_SCSI tristate "SGI WD93C93 SCSI Driver" - depends on SGI_IP22 && SCSI + depends on (SGI_IP22 || SGI_IP26 || SGI_IP28) && SCSI help If you have a Western Digital WD93 SCSI controller on an SGI MIPS system, say Y. Otherwise, say N. diff -Nur linux-git/drivers/scsi/wd33c93.c linux-git-mit-R10k-patches/drivers/scsi/wd33c93.c --- linux-git/drivers/scsi/wd33c93.c 2005-10-15 16:01:23.000000000 +0200 +++ linux-git-mit-R10k-patches/drivers/scsi/wd33c93.c 2005-10-16 13:21:56.000000000 +0200 @@ -1460,7 +1460,7 @@ const wd33c93_regs regs = hostdata->regs; uchar sr; -#ifdef CONFIG_SGI_IP22 +#if defined(CONFIG_SGI_IP22) || defined(CONFIG_SGI_IP28) { int busycount = 0; extern void sgiwd93_reset(unsigned long); diff -Nur linux-git/drivers/serial/ip22zilog.c linux-git-mit-R10k-patches/drivers/serial/ip22zilog.c --- linux-git/drivers/serial/ip22zilog.c 2005-10-15 16:01:24.000000000 +0200 +++ linux-git-mit-R10k-patches/drivers/serial/ip22zilog.c 2005-10-16 13:44:41.000000000 +0200 @@ -1015,9 +1015,9 @@ spin_lock_irqsave(&up->port.lock, flags); for (i = 0; i < count; i++, s++) { - ip22zilog_put_char(channel, *s); if (*s == 10) ip22zilog_put_char(channel, 13); + ip22zilog_put_char(channel, *s); } udelay(2); spin_unlock_irqrestore(&up->port.lock, flags); diff -Nur linux-git/drivers/serial/Kconfig linux-git-mit-R10k-patches/drivers/serial/Kconfig --- linux-git/drivers/serial/Kconfig 2005-10-15 16:01:24.000000000 +0200 +++ linux-git-mit-R10k-patches/drivers/serial/Kconfig 2005-10-16 13:21:56.000000000 +0200 @@ -555,16 +555,18 @@ config SERIAL_IP22_ZILOG tristate "IP22 Zilog8530 serial support" - depends on SGI_IP22 + depends on (SGI_IP22 || SGI_IP28) select SERIAL_CORE + default y if SGI_IP28 help - This driver supports the Zilog8530 serial ports found on SGI IP22 + This driver supports the Zilog8530 serial ports found on SGI IP22-IP28 systems. Say Y or M if you want to be able to these serial ports. config SERIAL_IP22_ZILOG_CONSOLE - bool "Console on IP22 Zilog8530 serial port" + bool "Console on IP22/28 Zilog8530 serial port" depends on SERIAL_IP22_ZILOG=y select SERIAL_CORE_CONSOLE + default y if SGI_IP28 config V850E_UART bool "NEC V850E on-chip UART support" diff -Nur linux-git/drivers/video/impact.c linux-git-mit-R10k-patches/drivers/video/impact.c --- linux-git/drivers/video/impact.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-git-mit-R10k-patches/drivers/video/impact.c 2005-10-16 13:22:04.000000000 +0200 @@ -0,0 +1,906 @@ +/* + * linux/drivers/video/impactsr.c -- SGI Octane MardiGras (IMPACTSR) graphics + * linux/drivers/video/impact.c -- SGI Indigo2 MardiGras (IMPACT) graphics + * + * Copyright (c) 2004 by Stanislaw Skowronek + * Adapted to Indigo2 by pf, 2005 + * + * Based on linux/drivers/video/skeletonfb.c + * + * This driver, as most of the IP30 (SGI Octane) port, is a result of massive + * amounts of reverse engineering and trial-and-error. If anyone is interested + * in helping with it, please contact me: <sskowron@xxxxxxxxxxxxxxxx>. + * + * The basic functions of this driver are filling and blitting rectangles. + * To achieve the latter, two DMA operations are used on Impact. It is unclear + * to me, why is it so, but even Xsgi (the IRIX X11 server) does it this way. + * It seems that fb->fb operations are not operational on these cards. + * + * For this purpose, a kernel DMA pool is allocated (pool number 0). This pool + * is (by default) 64kB in size. An ioctl could be used to set the value at + * run-time. Applications can use this pool, however proper locking has to be + * guaranteed. Kernel should be locked out from this pool by an ioctl. + * + * The IMPACTSR is quite well worked-out currently, except for the Geometry + * Engines (GE11). Any information about use of those devices would be very + * useful. It would enable a Linux OpenGL driver, as most of OpenGL calls are + * supported directly by the hardware. So far, I can't initialize the GE11. + * Verification of microcode crashes the graphics. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/mm.h> +#include <linux/tty.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include <linux/fb.h> +#include <linux/init.h> +#include <linux/vmalloc.h> +#include <linux/module.h> +#include <linux/dma-mapping.h> +#include <linux/spinlock.h> +#include <linux/font.h> +#include <asm/sgi/mc.h> + +#include <video/impact.h> + +#if defined(CONFIG_SGI_IP28)||defined(CONFIG_SGI_IP26)||defined(CONFIG_SGI_IP22) + #define INDIGO2 1 +#else + #undef INDIGO2 +#endif + +/* Some fixed register values. */ + +#ifdef INDIGO2 /* Impact (HQ3) registers */ +#define MSK_CFIFO_CNT 0x7f +#define POOLS 4 +#else /* ImpactSR (HQ4) registers */ +#define VAL_CFIFO_HW 0x47 +#define VAL_CFIFO_LW 0x14 +#define VAL_CFIFO_DELAY 0x64 +#define VAL_DFIFO_HW 0x40 +#define VAL_DFIFO_LW 0x10 +#define VAL_DFIFO_DELAY 0 +#define MSK_CFIFO_CNT 0xff +#define POOLS 5 +#endif + +#define IMPACT_KPOOL_SIZE 65536 + +struct impact_par { + /* physical mmio base in HEART XTalk space */ + unsigned long mmio_base; + /* virtual mmio base in kernel space */ + unsigned long mmio_virt; + /* DMA pool management */ + unsigned int *pool_txtbl[POOLS]; + unsigned int pool_txnum[POOLS]; + unsigned int pool_txmax[POOLS]; + unsigned long pool_txphys[POOLS]; + /* kernel DMA pools */ + unsigned long **kpool_virt[POOLS]; + unsigned long *kpool_phys[POOLS]; + unsigned int kpool_size[POOLS]; + /* locks to prevent simultaneous user and kernel access */ + int open_flag; + int mmap_flag; + spinlock_t lock; +}; + +static struct fb_fix_screeninfo impact_fix = { + .id = "Impact", + .smem_start = 0, + .smem_len = 0, + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .xpanstep = 0, + .ypanstep = 0, + .ywrapstep = 0, + .line_length = 0, + .accel = FB_ACCEL_SGI_IMPACT, +}; + +static struct fb_var_screeninfo impact_var = { + .xres = 1280, + .yres = 1024, + .xres_virtual = 1280, + .yres_virtual = 1024, + .bits_per_pixel = 24, + .red = { .offset = 0, .length = 8 }, + .green = { .offset = 8, .length = 8 }, + .blue = { .offset = 16, .length = 8 }, + .transp = { .offset = 24, .length = 8 }, +}; + +static struct fb_info info; + +static unsigned int pseudo_palette[256]; + +static struct impact_par current_par; + +int impact_init(void); + +/* --------------------- Gory Details --------------------- */ +#define MMIO (((struct impact_par *)p->par)->mmio_virt) +#define PAR (*((struct impact_par *)p->par)) + +static void impact_wait_cfifo(struct fb_info *p,int nslots) +{ + while((IMPACT_FIFOSTATUS(MMIO)&MSK_CFIFO_CNT)>(IMPACT_CFIFO_MAX-nslots)); +} +static void impact_wait_cfifo_empty(struct fb_info *p) +{ + while(IMPACT_FIFOSTATUS(MMIO)&MSK_CFIFO_CNT); +} +static void impact_wait_bfifo(struct fb_info *p,int nslots) +{ + while((IMPACT_GIOSTATUS(MMIO)&0x1f)>(IMPACT_BFIFO_MAX-nslots)); +} +static void impact_wait_bfifo_empty(struct fb_info *p) +{ + while(IMPACT_GIOSTATUS(MMIO)&0x1f); +} +static void impact_wait_dma(struct fb_info *p) +{ + while(IMPACT_DMABUSY(MMIO)&0x1f); + while(!(IMPACT_STATUS(MMIO)&1)); + while(!(IMPACT_STATUS(MMIO)&2)); + while(!(IMPACT_RESTATUS(MMIO)&0x100)); +} +static void impact_wait_dmaready(struct fb_info *p) +{ + IMPACT_CFIFOW(MMIO)=0x000e0100; + while(IMPACT_DMABUSY(MMIO)&0x1eff); + while(!(IMPACT_STATUS(MMIO)&2)); +} + +static void impact_inithq(struct fb_info *p) +{ +#ifndef INDIGO2 /* The friendly PROM did this already for us... */ + /* CFIFO parameters */ + IMPACT_CFIFO_HW(MMIO)=VAL_CFIFO_HW; + IMPACT_CFIFO_LW(MMIO)=VAL_CFIFO_LW; + IMPACT_CFIFO_DELAY(MMIO)=VAL_CFIFO_DELAY; + /* DFIFO parameters */ + IMPACT_DFIFO_HW(MMIO)=VAL_DFIFO_HW; + IMPACT_DFIFO_LW(MMIO)=VAL_DFIFO_LW; + IMPACT_DFIFO_DELAY(MMIO)=VAL_DFIFO_DELAY; +#endif +} + +static void impact_initrss(struct fb_info *p) +{ + /* transfer mask registers */ + IMPACT_CFIFO(MMIO)=IMPACT_CMD_COLORMASKLSBSA(0xffffff); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_COLORMASKLSBSB(0xffffff); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_COLORMASKMSBS(0); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XFRMASKLO(0xffffff); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XFRMASKHI(0xffffff); + /* use the main plane */ + IMPACT_CFIFO(MMIO)=IMPACT_CMD_DRBPOINTERS(0xc8240); + /* set the RE into vertical flip mode */ + IMPACT_CFIFO(MMIO)=IMPACT_CMD_CONFIG(0xcac); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XYWIN(0,0x3ff); +} + +static void impact_initxmap(struct fb_info *p) +{ + /* set XMAP into 24-bpp mode */ + IMPACT_XMAP_PP1SELECT(MMIO)=0x01; + IMPACT_XMAP_INDEX(MMIO)=0x00; + IMPACT_XMAP_MAIN_MODE(MMIO)=0x07a4; +} + +static void impact_initvc3(struct fb_info *p) +{ + /* cursor-b-gone (disable DISPLAY bit) */ + IMPACT_VC3_INDEXDATA(MMIO)=0x1d000100; +} + +static void impact_initdma(struct fb_info *p) +{ + unsigned long pool; + /* clear DMA pools */ + for(pool=0;pool<POOLS;pool++) { + impact_wait_cfifo_empty(p); + IMPACT_CFIFOPW(MMIO)=IMPACT_CMD_HQ_TXBASE(pool); + IMPACT_CFIFOP(MMIO)=0x0000000000000009; + IMPACT_CFIFOP(MMIO)=IMPACT_CMD_HQ_TXMAX(pool,0); + IMPACT_CFIFOP(MMIO)=IMPACT_CMD_HQ_PGBITS(pool,0); + IMPACT_CFIFOP(MMIO)=0x00484b0400080000|(pool<<41); + PAR.pool_txmax[pool]=0; + PAR.pool_txnum[pool]=0; + } + /* set DMA parameters */ + IMPACT_CFIFOP(MMIO)=IMPACT_CMD_HQ_PGSIZE(0); + IMPACT_CFIFOP(MMIO)=IMPACT_CMD_HQ_STACKPTR(0); + IMPACT_CFIFOP(MMIO)=0x00484a0400180000; + IMPACT_CFIFOPW(MMIO)=0x000e0100; + IMPACT_CFIFOPW(MMIO)=0x000e0100; + IMPACT_CFIFOPW(MMIO)=0x000e0100; + IMPACT_CFIFOPW(MMIO)=0x000e0100; + IMPACT_CFIFOPW(MMIO)=0x000e0100; + IMPACT_REG32(MMIO,X40918)=0x00680000; + IMPACT_REG32(MMIO,X40920)=0x80280000; + IMPACT_REG32(MMIO,X40928)=0x00000000; +} + +static void impact_alloctxtbl(struct fb_info *p,int pool,int txmax) +{ + dma_addr_t dma_handle; + int alloc_size; + if(txmax>PAR.pool_txmax[pool]) { /* grow the pool - unlikely but supported */ + alloc_size=txmax; + if(alloc_size<1024) + alloc_size=1024; + if(PAR.pool_txmax[pool]) + dma_free_coherent(NULL,PAR.pool_txmax[pool]*4, + PAR.pool_txtbl[pool],PAR.pool_txphys[pool]); + PAR.pool_txtbl[pool]= + dma_alloc_coherent(NULL,alloc_size*4,&dma_handle,GFP_KERNEL); + PAR.pool_txphys[pool]=dma_handle; + PAR.pool_txmax[pool]=alloc_size; + } + PAR.pool_txnum[pool]=txmax; +} + +static void impact_writetxtbl(struct fb_info *p,int pool) +{ + impact_wait_cfifo_empty(p); + /* inform the card about a new DMA pool */ + IMPACT_CFIFOPW(MMIO)=IMPACT_CMD_HQ_TXBASE(pool); + IMPACT_CFIFOP(MMIO)=PAR.pool_txphys[pool]; + IMPACT_CFIFOP(MMIO)=IMPACT_CMD_HQ_TXMAX(pool,PAR.pool_txnum[pool]); + IMPACT_CFIFOP(MMIO)=IMPACT_CMD_HQ_PGBITS(pool,0x0a); + IMPACT_CFIFOP(MMIO)=0x00484b0400180000|((long)pool<<41); + IMPACT_CFIFOPW(MMIO)=0x000e0100; + IMPACT_CFIFOPW(MMIO)=0x000e0100; + IMPACT_CFIFOPW(MMIO)=0x000e0100; + IMPACT_CFIFOPW(MMIO)=0x000e0100; + IMPACT_CFIFOPW(MMIO)=0x000e0100; +} + +static void impact_settxtbl(struct fb_info *p,int pool,unsigned *txtbl,int txmax) +{ + impact_alloctxtbl(p,pool,txmax); + #if defined(CONFIG_SGI_IP28)||defined(CONFIG_SGI_IP26) + { void *ca = (typeof(p)) TO_CAC((unsigned long)PAR.pool_txtbl[pool]); + memcpy(ca,txtbl,txmax*4); + dma_cache_wback_inv((unsigned long)ca, txmax*4); + } + #else + memcpy(PAR.pool_txtbl[pool],txtbl,txmax*4); + #endif + impact_writetxtbl(p,pool); +} + +static void impact_resizekpool(struct fb_info *p,int pool,int size,int growonly) +{ + typeof(PAR.pool_txtbl[pool]) txtbl; + int pages; + int i; + dma_addr_t dma_handle; + if(growonly && PAR.kpool_size[pool]>=size) + return; + if(size<8192) /* single line smallcopy (1280*4) *must* work */ + size=8192; + pages=(size+PAGE_SIZE-1)>>PAGE_SHIFT; + if(PAR.kpool_size[pool]>0) { + for(i=0;i<PAR.pool_txnum[pool];i++) { + unsigned long x=(typeof(x))PAR.kpool_virt[pool][i]; + #if defined(CONFIG_DMA_NONCOHERENT) + /* Screw it, or this damned virt_to_page() will blow up the driver. */ + x=(typeof(x))phys_to_virt(kernel_physaddr(x)); + #endif + ClearPageReserved(virt_to_page(x)); + dma_free_coherent(NULL,PAGE_SIZE,PAR.kpool_virt[pool][i], + PAR.kpool_phys[pool][i]); + } + vfree(PAR.kpool_phys[pool]); + vfree(PAR.kpool_virt[pool]); + } + impact_alloctxtbl(p,pool,pages); + txtbl = PAR.pool_txtbl[pool]; + #if defined(CONFIG_SGI_IP28)||defined(CONFIG_SGI_IP26) + txtbl = (typeof(txtbl)) TO_CAC((unsigned long) txtbl); + #endif + PAR.kpool_virt[pool]=vmalloc(pages*sizeof(unsigned long)); + PAR.kpool_phys[pool]=vmalloc(pages*sizeof(unsigned long)); + for(i=0;i<PAR.pool_txnum[pool];i++) { + unsigned long x; + PAR.kpool_virt[pool][i]= + dma_alloc_coherent(NULL,PAGE_SIZE,&dma_handle,GFP_KERNEL); + x=(typeof(x))PAR.kpool_virt[pool][i]; + #if defined(CONFIG_DMA_NONCOHERENT) + /* Screw it, or this damned virt_to_page() will blow up the driver. */ + x=(typeof(x))phys_to_virt(kernel_physaddr(x)); + #endif + SetPageReserved(virt_to_page(x)); + PAR.kpool_phys[pool][i]=dma_handle; + txtbl[i]=dma_handle>>PAGE_SHIFT; + } + #if defined(CONFIG_SGI_IP28) || defined(CONFIG_SGI_IP26) + i=sizeof(*txtbl)*PAR.pool_txnum[pool]; + dma_cache_wback_inv((unsigned long)txtbl, i); + #endif + impact_writetxtbl(p,pool); + PAR.kpool_size[pool]=pages*PAGE_SIZE; +} + +static void +impact_rect(struct fb_info *p, int x, int y, int w, int h, unsigned c, int lo) +{ + impact_wait_cfifo_empty(p); + if(lo==IMPACT_LO_COPY) + IMPACT_CFIFO(MMIO)=IMPACT_CMD_PP1FILLMODE(0x6300,lo); + else + IMPACT_CFIFO(MMIO)=IMPACT_CMD_PP1FILLMODE(0x6304,lo); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_FILLMODE(0); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_PACKEDCOLOR(c); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_BLOCKXYSTARTI(x,y); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_BLOCKXYENDI(x+w-1,y+h-1); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_IR_ALIAS(0x18); +} + +static void +impact_framerect(struct fb_info *p, int x, int y, int w, int h, unsigned c) +{ + impact_rect(p,x,y,w,1,c,IMPACT_LO_COPY); + impact_rect(p,x,y+h-1,w,1,c,IMPACT_LO_COPY); + impact_rect(p,x,y,1,h,c,IMPACT_LO_COPY); + impact_rect(p,x+w-1,y,1,h,c,IMPACT_LO_COPY); +} + +static unsigned long dcntr; +static void impact_debug(struct fb_info *p,int v) +{ + int i; + IMPACT_CFIFO(MMIO)=IMPACT_CMD_PIXCMD(3); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_HQ_PIXELFORMAT(0xe00); + switch(v) { + case 0: + for(i=0;i<64;i++) + impact_rect(p,4*(i&7),28-4*(i>>3),4,4, + (dcntr&(1L<<i))?0xa080ff:0x100030,IMPACT_LO_COPY); + break; + case 1: + dcntr++; + for(i=0;i<64;i++) + impact_rect(p,4*(i&7),28-4*(i>>3),4,4, + (dcntr&(1L<<i))?0xff80a0:0x300010,IMPACT_LO_COPY); + break; + case 2: + for(i=0;i<64;i++) + impact_rect(p,4*(i&7),28-4*(i>>3),4,4, + (dcntr&(1L<<i))?0xa0ff80:0x103000,IMPACT_LO_COPY); + } +} + +static void impact_smallcopy(struct fb_info *p,unsigned sx,unsigned sy, + unsigned dx,unsigned dy,unsigned w,unsigned h) +{ + if(w<1 || h<1) + return; + w=(w+1)&~1; + /* setup and perform DMA from RE to HOST */ + impact_wait_dma(p); +#ifndef INDIGO2 /* Beware, only MaxImpact has 2 REs, SI,HI will hang ! */ + if(sy&1) + IMPACT_CFIFO(MMIO)=IMPACT_CMD_CONFIG(0xca5); + else +#endif + IMPACT_CFIFO(MMIO)=IMPACT_CMD_CONFIG(0xca4); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_PIXCMD(2); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_PP1FILLMODE(0x2200,IMPACT_LO_COPY); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_COLORMASKLSBSA(0xffffff); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_COLORMASKLSBSB(0xffffff); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_COLORMASKMSBS(0); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_DRBPOINTERS(0xc8240); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_BLOCKXYSTARTI(sx,sy+h-1); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_BLOCKXYENDI(sx+w-1,sy); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XFRMASKLO(0xffffff); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XFRMASKHI(0xffffff); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XFRSIZE(w,h); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XFRCOUNTERS(w,h); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XFRMODE(0x00080); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_FILLMODE(0x01000000); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_HQ_PIXELFORMAT(0x200); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_HQ_SCANWIDTH(w<<2); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_HQ_DMATYPE(0x0a); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_HQ_PG_LIST_0(0x80000000); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_HQ_PG_WIDTH(w<<2); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_HQ_PG_OFFSET(0); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_HQ_PG_STARTADDR(0); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_HQ_PG_LINECNT(h); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_HQ_PG_WIDTHA(w<<2); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XFRCONTROL(8); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_GLINE_XSTARTF(1); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_IR_ALIAS(0x18); + #if 0 + IMPACT_CFIFOW(MMIO)=0x00080b04; + IMPACT_CFIFO(MMIO)=0x000000b900190204L; + IMPACT_CFIFOW(MMIO)=0x00000009; + #else + IMPACT_CFIFO(MMIO)=0x00080b04000000b9L; + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XFRCONTROL(9); + #endif + impact_wait_dmaready(p); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_GLINE_XSTARTF(0); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_RE_TOGGLECNTX(0); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XFRCOUNTERS(0,0); + /* setup and perform DMA from HOST to RE */ + impact_wait_dma(p); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_CONFIG(0xca4); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_PP1FILLMODE(0x6200,IMPACT_LO_COPY); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_BLOCKXYSTARTI(dx,dy+h-1); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_BLOCKXYENDI(dx+w-1,dy); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_FILLMODE(0x01400000); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XFRMODE(0x00080); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_HQ_PIXELFORMAT(0x600); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_HQ_SCANWIDTH(w<<2); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_HQ_DMATYPE(0x0c); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_PIXCMD(3); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XFRSIZE(w,h); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XFRCOUNTERS(w,h); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_GLINE_XSTARTF(1); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_IR_ALIAS(0x18); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XFRCONTROL(1); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_HQ_PG_LIST_0(0x80000000); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_HQ_PG_OFFSET(0); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_HQ_PG_STARTADDR(0); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_HQ_PG_LINECNT(h); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_HQ_PG_WIDTHA(w<<2); + #if 0 + IMPACT_CFIFOW(MMIO)=0x0080b04; + IMPACT_CFIFO(MMIO)=0x000000b1000e0400L; + #else + IMPACT_CFIFO(MMIO)=0x0080b04000000b1L; + IMPACT_CFIFOW(MMIO)=0x000e0400; + #endif + impact_wait_dma(p); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_GLINE_XSTARTF(0); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_RE_TOGGLECNTX(0); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XFRCOUNTERS(0,0); +} + +static unsigned impact_getpalreg(struct fb_info *p, unsigned i) +{ + return ((unsigned *)p->pseudo_palette)[i]; +} + +/* ------------ Accelerated Functions --------------------- */ + +static void impact_fillrect(struct fb_info *p, const struct fb_fillrect *region) +{ + unsigned long flags; + spin_lock_irqsave(&PAR.lock,flags); + if(!PAR.open_flag) + switch(region->rop) { + case ROP_XOR: + impact_rect(p,region->dx,region->dy,region->width,region->height, + impact_getpalreg(p,region->color),IMPACT_LO_XOR); + break; + case ROP_COPY: + default: + impact_rect(p,region->dx,region->dy,region->width,region->height, + impact_getpalreg(p,region->color),IMPACT_LO_COPY); + break; + } + spin_unlock_irqrestore(&PAR.lock,flags); +} + +static void impact_copyarea(struct fb_info *p, const struct fb_copyarea *area) +{ + unsigned sx,sy,dx,dy,w,h; + unsigned th,ah; + unsigned long flags; + w=area->width; + h=area->height; + if(w<1 || h<1) + return; + spin_lock_irqsave(&PAR.lock,flags); + if(PAR.open_flag) { + spin_unlock_irqrestore(&PAR.lock,flags); + return; + } + sx=area->sx; + sy=0x3ff-(area->sy+h-1); + dx=area->dx; + dy=0x3ff-(area->dy+h-1); + th=PAR.kpool_size[0]/(w*4); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XYWIN(0,0); + if(dy>sy) { + dy+=h; + sy+=h; + while(h>0) { + ah=th>h?h:th; + impact_smallcopy(p,sx,sy-ah,dx,dy-ah,w,ah); + dy-=ah; + sy-=ah; + h-=ah; + } + } else { + while(h>0) { + ah=th>h?h:th; + impact_smallcopy(p,sx,sy,dx,dy,w,ah); + dy+=ah; + sy+=ah; + h-=ah; + } + } + IMPACT_CFIFO(MMIO)=IMPACT_CMD_PIXCMD(0); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_HQ_PIXELFORMAT(0xe00); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_CONFIG(0xcac); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XYWIN(0,0x3ff); + spin_unlock_irqrestore(&PAR.lock,flags); +} + +/* 8-bpp blits are done as PIO draw operation; the pixels are unpacked into + 32-bpp values from the current palette in software */ +static void +impact_imageblit_8bpp(struct fb_info *p, const struct fb_image *image) +{ + int i,u,v; + const unsigned char *dp; + unsigned pix; + unsigned pal[256]; + /* setup PIO to RE */ + impact_wait_cfifo_empty(p); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_PP1FILLMODE(0x6300,IMPACT_LO_COPY); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_BLOCKXYSTARTI(image->dx,image->dy); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_BLOCKXYENDI(image->dx+image->width-1, + image->dy+image->height-1); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_FILLMODE(0x00c00000); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XFRMODE(0x00080); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XFRSIZE(image->width,image->height); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XFRCOUNTERS(image->width,image->height); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_GLINE_XSTARTF(1); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_IR_ALIAS(0x18); + /* another workaround.. 33 writes to alpha... hmm... */ + for(i=0;i<33;i++) + IMPACT_CFIFO(MMIO)=IMPACT_CMD_ALPHA(0); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XFRCONTROL(2); + /* pairs of pixels are sent in two writes to the RE */ + i=0; + dp=image->data; + for(v=0;v<256;v++) + pal[v]=impact_getpalreg(p,v); + for(v=0;v<image->height;v++) { + for(u=0;u<image->width;u++) { + pix=pal[*(dp++)]; + if(i) + IMPACT_CFIFO(MMIO)=IMPACT_CMD_CHAR_L(pix); + else + IMPACT_CFIFO(MMIO)=IMPACT_CMD_CHAR_H(pix); + i^=1; + } + } + if(i) + IMPACT_CFIFO(MMIO)=IMPACT_CMD_CHAR_L(0); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_GLINE_XSTARTF(0); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_RE_TOGGLECNTX(0); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_XFRCOUNTERS(0,0); +} + +/* 1-bpp blits are done as character drawing; the bitmaps are drawn as 8-bit wide + strips; technically, Impact supports 16-pixel wide characters, but Linux bitmap + alignment is 8 bits and most draws are 8 pixels wide (font width), anyway */ +static void impact_imageblit_1bpp(struct fb_info *p, const struct fb_image *image) +{ + int x,y,w,h,b; + int u,v,a; + const unsigned char *d; + impact_wait_cfifo_empty(p); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_PP1FILLMODE(0x6300,IMPACT_LO_COPY); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_FILLMODE(0x400018); + a=impact_getpalreg(p,image->fg_color); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_PACKEDCOLOR(a); + a=impact_getpalreg(p,image->bg_color); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_BKGRD_RG(a&0xffff); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_BKGRD_BA((a&0xff0000)>>16); + x=image->dx; + y=image->dy; + w=image->width; + h=image->height; + b=(w+7)/8; + for(u=0;u<b;u++) { + impact_wait_cfifo_empty(p); + a=(w<8)?w:8; + d=image->data+u; + IMPACT_CFIFO(MMIO)=IMPACT_CMD_BLOCKXYSTARTI(x,y); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_BLOCKXYENDI(x+a-1,y+h-1); + IMPACT_CFIFO(MMIO)=IMPACT_CMD_IR_ALIAS(0x18); + for(v=0;v<h;v++) { + IMPACT_CFIFO(MMIO)=IMPACT_CMD_CHAR((*d)<<24); + d+=b; + } + w-=a; + x+=a; + } +} + +static void impact_imageblit(struct fb_info *p, const struct fb_image *image) +{ + unsigned long flags; + spin_lock_irqsave(&PAR.lock,flags); + if(!PAR.open_flag) + switch(image->depth) { + case 1: + impact_imageblit_1bpp(p,image); + break; + case 8: + impact_imageblit_8bpp(p,image); + break; + } + spin_unlock_irqrestore(&PAR.lock,flags); +} + +static int impact_sync(struct fb_info *info) +{ + return 0; +} + +static int impact_blank(int blank_mode, struct fb_info *info) +{ + /* TODO */ + return 0; +} + +static int impact_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, struct fb_info *info) +{ + if(regno>255) + return 1; + ((unsigned *)info->pseudo_palette)[regno]= + (red>>8)|(green&0xff00)|((blue<<8)&0xff0000); + return 0; +} + +/* ------------------- Framebuffer Access -------------------- */ + +ssize_t impact_read(struct file *file, char *buf, size_t count, loff_t *ppos) +{ + return -EINVAL; +} + +ssize_t +impact_write(struct file *file, const char *buf, size_t count, loff_t *ppos) +{ + return -EINVAL; +} + +/* --------------------- Userland Access --------------------- */ + +int impact_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg, struct fb_info *info) +{ + return -EINVAL; +} + +int +impact_mmap(struct fb_info *p, struct file *file, struct vm_area_struct *vma) +{ + unsigned pool, i, n; + unsigned long size = vma->vm_end - vma->vm_start; + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + unsigned long start = vma->vm_start; + +#ifdef INDIGO2 + if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) + return -EINVAL; + if (offset + size > 0x400000) + return -EINVAL; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + vma->vm_flags |= VM_IO; + if (remap_pfn_range(vma, vma->vm_start, (offset+MMIO)>>PAGE_SHIFT, + size, vma->vm_page_prot)) + return -EAGAIN; + vma->vm_file = file; + PAR.mmap_flag = 1; +#else + switch(offset) { + case 0x0000000: + default: + if (offset+size>0x200000) /* >0x400000, >0x1000000 ? */ + return -EINVAL; + if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) + return -EINVAL; + offset += MMIO; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + vma->vm_flags |= VM_IO; + if (remap_pfn_range(vma, vma->vm_start, offset>>PAGE_SHIFT, + size, vma->vm_page_prot)) + return -EAGAIN; + vma->vm_file = file; + PAR.mmap_flag = 1; + break; + case 0x1000000: + case 0x2000000: + case 0x3000000: + case 0x8000000: + case 0x9000000: + case 0xa000000: + case 0xb000000: + if(size>0x1000000) + return EINVAL; + pool=(offset>>24)&7; + if (pool>=POOLS) + return -EINVAL; + impact_resizekpool(&info,pool,size,offset&0x8000000); + n=(size+PAGE_SIZE-1)>>PAGE_SHIFT; + for(i=0;i<n;i++) { + if (remap_pfn_range(vma, start, + PAR.kpool_phys[pool][i]>>PAGE_SHIFT, PAGE_SIZE, + vma->vm_page_prot)) + return -EAGAIN; + start += PAGE_SIZE; + } + vma->vm_file = file; + PAR.mmap_flag = 1; + } +#endif + return 0; +} + +static int impact_open(struct fb_info *p, int user) +{ + unsigned long flags; + spin_lock_irqsave(&PAR.lock,flags); + if (user) + PAR.open_flag++; + spin_unlock_irqrestore(&PAR.lock,flags); + return 0; +} + +static int impact_release(struct fb_info *p, int user) +{ + unsigned long flags; + spin_lock_irqsave(&PAR.lock,flags); + if (user && PAR.open_flag) { + PAR.open_flag--; + if (PAR.open_flag == 0) { + impact_resizekpool(&info,1,8192,0); + impact_resizekpool(&info,2,8192,0); + impact_resizekpool(&info,3,8192,0); + PAR.mmap_flag = 0; + } + } + spin_unlock_irqrestore(&PAR.lock,flags); + return 0; +} + + +/* ------------------------------------------------------------------------- */ + + /* + * Frame buffer operations + */ + +static struct fb_ops impact_ops = { + .owner = THIS_MODULE, + .fb_read = impact_read, + .fb_write = impact_write, + .fb_blank = impact_blank, + .fb_fillrect = impact_fillrect, + .fb_copyarea = impact_copyarea, + .fb_imageblit = impact_imageblit, + .fb_cursor = soft_cursor, + .fb_sync = impact_sync, + .fb_ioctl = impact_ioctl, + .fb_setcolreg = impact_setcolreg, + .fb_mmap = impact_mmap, + .fb_open = impact_open, + .fb_release = impact_release, +}; + +/* ------------------------------------------------------------------------- */ + + /* + * Initialization + */ + +static inline unsigned long gfxphysaddr(void) +{ +#ifdef INDIGO2 + extern unsigned long sgi_gfxaddr; /* provided by ARCS */ + return sgi_gfxaddr; +#else + return 0x1c000000; /* first card in Octane */ +#endif +} + +static void __init impact_hwinit(void) +{ + /* initialize hardware */ + impact_inithq(&info); + impact_initvc3(&info); + impact_initrss(&info); + impact_initxmap(&info); + impact_initdma(&info); +} + +static int __init impact_devinit(void) +{ + int i; + current_par.open_flag = 0; + current_par.mmap_flag = 0; + current_par.lock = SPIN_LOCK_UNLOCKED; + + current_par.mmio_base = gfxphysaddr(); + if (!current_par.mmio_base) { + printk(KERN_INFO "impact_devinit: !gfxaddr\n"); + return -EINVAL; + } + current_par.mmio_virt = (unsigned long) + ioremap(current_par.mmio_base,0x200000); + impact_fix.mmio_start = current_par.mmio_base; + impact_fix.mmio_len = 0x200000; + + info.flags = FBINFO_FLAG_DEFAULT; + info.screen_base = NULL; + info.fbops = &impact_ops; + info.fix = impact_fix; + info.var = impact_var; + info.par = ¤t_par; + info.pseudo_palette = pseudo_palette; + + impact_hwinit(); + /* initialize buffers */ + impact_resizekpool(&info,0,65536,0); + for (i = 1; i < POOLS; ++i) + impact_resizekpool(&info,i,8192,0); + + /* This has to been done !!! */ + fb_alloc_cmap(&info.cmap, 256, 0); + + if (register_framebuffer(&info) < 0) + return -EINVAL; + printk(KERN_INFO "fb%d: %s frame buffer device\n", info.node, + info.fix.id); + return 0; +} + +static int __init impact_probe(struct device *dev) +{ + return impact_devinit(); +} + +static struct device_driver impact_driver = { + .name = "impact", + .bus = &platform_bus_type, + .probe = impact_probe, + /* add remove someday */ +}; + +static struct platform_device impact_device = { + .name = "impact", +}; + +int __init impact_init(void) +{ + int ret = driver_register(&impact_driver); + if (!ret) { + ret = platform_device_register(&impact_device); + if (ret) + driver_unregister(&impact_driver); + } + return ret; +} + +void __exit impact_exit(void) +{ + driver_unregister(&impact_driver); +} + +module_init(impact_init); +module_exit(impact_exit); + +MODULE_LICENSE("GPL"); diff -Nur linux-git/drivers/video/Kconfig linux-git-mit-R10k-patches/drivers/video/Kconfig --- linux-git/drivers/video/Kconfig 2005-10-15 16:01:25.000000000 +0200 +++ linux-git-mit-R10k-patches/drivers/video/Kconfig 2005-10-16 13:22:04.000000000 +0200 @@ -568,6 +568,14 @@ This is the amount of memory reserved for the framebuffer, which can be any value between 1MB and 8MB. +config FB_IMPACT + tristate "SGI Octane ImpactSR / Indigo2 Impact graphics support" + depends on FB && (SGI_IP22 || SGI_IP26 || SGI_IP28 || SGI_IP30) + select FB_SOFT_CURSOR + help + SGI Octane ImpactSR (SI/SSI/MXI/SE/SSE/MXE) graphics card support. + SGI Indigo2 Impact (SI/HI/MI) graphics card support. + config BUS_I2C bool depends on (FB = y) && VISWS @@ -1609,3 +1617,5 @@ endmenu + +# Revision 1.36, Tue Apr 19 20:56:41 2005 diff -Nur linux-git/drivers/video/logo/Kconfig linux-git-mit-R10k-patches/drivers/video/logo/Kconfig --- linux-git/drivers/video/logo/Kconfig 2005-10-15 16:01:26.000000000 +0200 +++ linux-git-mit-R10k-patches/drivers/video/logo/Kconfig 2005-10-16 13:22:04.000000000 +0200 @@ -40,7 +40,7 @@ config LOGO_SGI_CLUT224 bool "224-color SGI Linux logo" - depends on LOGO && (SGI_IP22 || SGI_IP27 || SGI_IP32 || X86_VISWS) + depends on LOGO && (SGI_IP22 || SGI_IP27 || SGI_IP28 || SGI_IP32 || X86_VISWS) default y config LOGO_SUN_CLUT224 diff -Nur linux-git/drivers/video/Makefile linux-git-mit-R10k-patches/drivers/video/Makefile --- linux-git/drivers/video/Makefile 2005-10-15 16:01:25.000000000 +0200 +++ linux-git-mit-R10k-patches/drivers/video/Makefile 2005-10-16 13:45:33.000000000 +0200 @@ -94,6 +94,7 @@ obj-$(CONFIG_FB_MAXINE) += maxinefb.o obj-$(CONFIG_FB_TX3912) += tx3912fb.o obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o +obj-$(CONFIG_FB_IMPACT) += impact.o obj-$(CONFIG_FB_IMX) += imxfb.o obj-$(CONFIG_FB_SMIVGX) += smivgxfb.o obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o @@ -105,3 +106,5 @@ # the test framebuffer is last obj-$(CONFIG_FB_VIRTUAL) += vfb.o + +# Revision 1.89, Tue Apr 19 20:56:41 2005 diff -Nur linux-git/fs/partitions/Kconfig linux-git-mit-R10k-patches/fs/partitions/Kconfig --- linux-git/fs/partitions/Kconfig 2005-10-15 16:01:30.000000000 +0200 +++ linux-git-mit-R10k-patches/fs/partitions/Kconfig 2005-10-16 13:22:04.000000000 +0200 @@ -188,7 +188,7 @@ config SGI_PARTITION bool "SGI partition support" if PARTITION_ADVANCED - default y if (SGI_IP22 || SGI_IP27 || ((MACH_JAZZ || SNI_RM200_PCI) && !CPU_LITTLE_ENDIAN)) + default y if (SGI_IP22 || SGI_IP27 || SGI_IP28 || ((MACH_JAZZ || SNI_RM200_PCI) && !CPU_LITTLE_ENDIAN)) help Say Y here if you would like to be able to read the hard disk partition table format used by SGI machines. diff -Nur linux-git/include/asm-mips/addrspace.h linux-git-mit-R10k-patches/include/asm-mips/addrspace.h --- linux-git/include/asm-mips/addrspace.h 2005-10-15 16:01:33.000000000 +0200 +++ linux-git-mit-R10k-patches/include/asm-mips/addrspace.h 2005-10-16 13:58:45.000000000 +0200 @@ -53,6 +53,16 @@ #ifdef CONFIG_64BIT +static inline unsigned long kernel_physaddr(unsigned long kva) +{ + if((kva&0xffffffff80000000UL)==0xffffffff80000000UL) + return CPHYSADDR(kva); + return XPHYSADDR(kva); +} +#else +#define kernel_physaddr CPHYSADDR +#endif + /* * Memory segments (64bit kernel mode addresses) * The compatibility segments use the full 64-bit sign extended value. Note @@ -108,14 +118,14 @@ /* * Cache modes for XKPHYS address conversion macros */ -#define K_CALG_COH_EXCL1_NOL2 0 -#define K_CALG_COH_SHRL1_NOL2 1 -#define K_CALG_UNCACHED 2 -#define K_CALG_NONCOHERENT 3 -#define K_CALG_COH_EXCL 4 -#define K_CALG_COH_SHAREABLE 5 -#define K_CALG_NOTUSED 6 -#define K_CALG_UNCACHED_ACCEL 7 +#define K_CALG_COH_EXCL1_NOL2 0L +#define K_CALG_COH_SHRL1_NOL2 1L +#define K_CALG_UNCACHED 2L +#define K_CALG_NONCOHERENT 3L +#define K_CALG_COH_EXCL 4L +#define K_CALG_COH_SHAREABLE 5L +#define K_CALG_NOTUSED 6L +#define K_CALG_UNCACHED_ACCEL 7L /* * 64-bit address conversions @@ -199,3 +209,7 @@ #define PHYS_TO_K0(x) (_ACAST64_ (x) | CAC_BASE) #endif /* _ASM_ADDRSPACE_H */ +/* + * Revision 1.15, Mon Dec 27 03:16:18 2004 + * Jun/Dec 2004 + */ diff -Nur linux-git/include/asm-mips/dma.h linux-git-mit-R10k-patches/include/asm-mips/dma.h --- linux-git/include/asm-mips/dma.h 2005-10-15 16:01:33.000000000 +0200 +++ linux-git-mit-R10k-patches/include/asm-mips/dma.h 2005-10-16 13:22:04.000000000 +0200 @@ -83,10 +83,13 @@ * Deskstations or Acer PICA but not the much more versatile DMA logic used * for the local devices on Acer PICA or Magnums. */ -#ifdef CONFIG_SGI_IP22 +#if defined(CONFIG_SGI_IP22) /* Horrible hack to have a correct DMA window on IP22 */ #include <asm/sgi/mc.h> #define MAX_DMA_ADDRESS (PAGE_OFFSET + SGIMC_SEG0_BADDR + 0x01000000) +#elif defined(CONFIG_SGI_IP28) +#include <asm/sgi/mc.h> +#define MAX_DMA_ADDRESS (PAGE_OFFSET + SGIMC_SEG1_BADDR + 0x01000000) #else #define MAX_DMA_ADDRESS (PAGE_OFFSET + 0x01000000) #endif @@ -311,3 +314,7 @@ #endif #endif /* _ASM_DMA_H */ +/* + * Revision 1.14, Tue Jul 29 03:21:47 2003 + * Sun Jun 13 01:04:27 2004 - IP28 + */ diff -Nur linux-git/include/asm-mips/io.h linux-git-mit-R10k-patches/include/asm-mips/io.h --- linux-git/include/asm-mips/io.h 2005-10-15 16:01:33.000000000 +0200 +++ linux-git-mit-R10k-patches/include/asm-mips/io.h 2005-10-16 13:22:04.000000000 +0200 @@ -63,7 +63,7 @@ # define ioswabb(x) (x) # define mem_ioswabb(x) (x) -# ifdef CONFIG_SGI_IP22 +# if defined(CONFIG_SGI_IP22) || defined(CONFIG_SGI_IP28) /* * IP22 seems braindead enough to swap 16bits values in hardware, but * not 32bits. Go figure... Can't tell without documentation. diff -Nur linux-git/include/asm-mips/mach-ip28/cpu-feature-overrides.h linux-git-mit-R10k-patches/include/asm-mips/mach-ip28/cpu-feature-overrides.h --- linux-git/include/asm-mips/mach-ip28/cpu-feature-overrides.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-git-mit-R10k-patches/include/asm-mips/mach-ip28/cpu-feature-overrides.h 2005-10-16 13:22:04.000000000 +0200 @@ -0,0 +1,41 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2003 Ralf Baechle + * 6/2004 pf + */ +#ifndef __ASM_MACH_IP28_CPU_FEATURE_OVERRIDES_H +#define __ASM_MACH_IP28_CPU_FEATURE_OVERRIDES_H + +/* + * IP28 only comes with R10000 family processors all using the same config + */ +#define cpu_has_watch 1 +#define cpu_has_mips16 0 +#define cpu_has_divec 0 +#define cpu_has_vce 0 +#define cpu_has_cache_cdex_p 0 +#define cpu_has_cache_cdex_s 0 +#define cpu_has_prefetch 1 +#define cpu_has_mcheck 0 +#define cpu_has_ejtag 0 + +#define cpu_has_llsc 1 +#define cpu_has_vtag_icache 0 +#define cpu_has_dc_aliases 0 /* see probe_pcache() */ +#define cpu_has_ic_fills_f_dc 0 + +#define cpu_has_nofpuex 0 +#define cpu_has_64bits 1 + +#define cpu_has_subset_pcaches 1 + +#define cpu_dcache_line_size() 32 +#define cpu_icache_line_size() 64 +/* we better read it from COP0 $16 (SCBlkSize bit), can be 128 or 64 +#define cpu_scache_line_size() 128 +*/ + +#endif /* __ASM_MACH_IP28_CPU_FEATURE_OVERRIDES_H */ diff -Nur linux-git/include/asm-mips/mach-ip28/ds1286.h linux-git-mit-R10k-patches/include/asm-mips/mach-ip28/ds1286.h --- linux-git/include/asm-mips/mach-ip28/ds1286.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-git-mit-R10k-patches/include/asm-mips/mach-ip28/ds1286.h 2005-10-16 13:22:04.000000000 +0200 @@ -0,0 +1,4 @@ +#ifndef __ASM_MACH_IP28_DS1286_H +#define __ASM_MACH_IP28_DS1286_H +#include <asm/mach-ip22/ds1286.h> +#endif /* __ASM_MACH_IP28_DS1286_H */ diff -Nur linux-git/include/asm-mips/mach-ip28/spaces.h linux-git-mit-R10k-patches/include/asm-mips/mach-ip28/spaces.h --- linux-git/include/asm-mips/mach-ip28/spaces.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-git-mit-R10k-patches/include/asm-mips/mach-ip28/spaces.h 2005-10-16 13:22:04.000000000 +0200 @@ -0,0 +1,29 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994 - 1999, 2000, 03, 04 Ralf Baechle + * Copyright (C) 2000, 2002 Maciej W. Rozycki + * Copyright (C) 1990, 1999, 2000 Silicon Graphics, Inc. + * 2004 pf + */ +#ifndef _ASM_MACH_IP28_SPACES_H +#define _ASM_MACH_IP28_SPACES_H + +#include <linux/config.h> + +#define CAC_BASE 0xa800000000000000 +#define IO_BASE 0x9000000000000000 +#define UNCAC_BASE 0x9000000000000000 +#define MAP_BASE 0xc000000000000000 + +#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK)) +#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK)) +#define TO_UNCAC(x) (UNCAC_BASE | ((x) & TO_PHYS_MASK)) + +#define PAGE_OFFSET CAC_BASE + +#define HIGHMEM_START (~0UL) + +#endif /* _ASM_MACH_IP28_SPACES_H */ diff -Nur linux-git/include/asm-mips/sgi/ioc.h linux-git-mit-R10k-patches/include/asm-mips/sgi/ioc.h --- linux-git/include/asm-mips/sgi/ioc.h 2005-10-15 16:01:34.000000000 +0200 +++ linux-git-mit-R10k-patches/include/asm-mips/sgi/ioc.h 2005-10-16 13:48:36.000000000 +0200 @@ -138,8 +138,8 @@ u8 _sysid[3]; volatile u8 sysid; #define SGIOC_SYSID_FULLHOUSE 0x01 -#define SGIOC_SYSID_BOARDREV(x) ((x & 0xe0) > 5) -#define SGIOC_SYSID_CHIPREV(x) ((x & 0x1e) > 1) +#define SGIOC_SYSID_BOARDREV(x) (((x) & 0x1e) >> 1) +#define SGIOC_SYSID_CHIPREV(x) (((x) & 0xe0) >> 5) u32 _unused2; u8 _read[3]; volatile u8 read; @@ -198,3 +198,7 @@ extern struct sgint_regs *sgint; #endif +/* + * Revision 1.8, Sat Sep 25 14:20:00 2004 + * May 2004 pf - SYSID + */ diff -Nur linux-git/include/asm-mips/sgi/mc.h linux-git-mit-R10k-patches/include/asm-mips/sgi/mc.h --- linux-git/include/asm-mips/sgi/mc.h 2005-10-15 16:01:34.000000000 +0200 +++ linux-git-mit-R10k-patches/include/asm-mips/sgi/mc.h 2005-10-16 13:22:04.000000000 +0200 @@ -227,5 +227,11 @@ #define SGIMC_SEG1_SIZE_IP26_IP28 0x20000000 /* 512MB */ extern void sgimc_init(void); +extern unsigned long ip2628_enable_ucmem(void); +extern void ip2628_return_ucmem(unsigned long); #endif /* _SGI_MC_H */ +/* + * Revision 1.4, Mon Jun 16 13:54:54 2003 + * Wed Jun 16 13:54:54 2004 pf - IP28 + */ diff -Nur linux-git/include/asm-mips/stackframe.h linux-git-mit-R10k-patches/include/asm-mips/stackframe.h --- linux-git/include/asm-mips/stackframe.h 2005-10-15 16:01:34.000000000 +0200 +++ linux-git-mit-R10k-patches/include/asm-mips/stackframe.h 2005-10-16 13:22:04.000000000 +0200 @@ -351,3 +351,7 @@ .endm #endif /* _ASM_STACKFRAME_H */ +/* + * Revision 1.37, Tue Apr 19 21:26:28 2005 + * May 2004 pf - xkphys kernel addresses + */ Binärdateien linux-git/include/asm-mips/.stackframe.h.rej.swp and linux-git-mit-R10k-patches/include/asm-mips/.stackframe.h.rej.swp sind verschieden. diff -Nur linux-git/include/asm-mips/war.h linux-git-mit-R10k-patches/include/asm-mips/war.h --- linux-git/include/asm-mips/war.h 2005-10-15 16:01:34.000000000 +0200 +++ linux-git-mit-R10k-patches/include/asm-mips/war.h 2005-10-16 13:22:04.000000000 +0200 @@ -194,6 +194,10 @@ #ifdef CONFIG_SGI_IP27 #define R10000_LLSC_WAR 1 #endif +/* Branch-likely and friends won't hurt a weird uniprocessor system either */ +#ifdef CONFIG_SGI_IP28 +#define R10000_LLSC_WAR 1 +#endif /* * Workarounds default to off @@ -236,3 +240,7 @@ #endif #endif /* _ASM_WAR_H */ +/* + * Revision 1.19, Tue Aug 17 17:49:44 2004 + * Sun Dec 5 23:28:19 2004 - ip28 cache barrier + */ diff -Nur linux-git/include/linux/fb.h linux-git-mit-R10k-patches/include/linux/fb.h --- linux-git/include/linux/fb.h 2005-10-15 16:01:35.000000000 +0200 +++ linux-git-mit-R10k-patches/include/linux/fb.h 2005-10-16 13:22:04.000000000 +0200 @@ -118,6 +118,7 @@ #define FB_ACCEL_NEOMAGIC_NM2230 96 /* NeoMagic NM2230 */ #define FB_ACCEL_NEOMAGIC_NM2360 97 /* NeoMagic NM2360 */ #define FB_ACCEL_NEOMAGIC_NM2380 98 /* NeoMagic NM2380 */ +#define FB_ACCEL_SGI_IMPACT 333 /* SGI IMPACT graphics */ #define FB_ACCEL_SAVAGE4 0x80 /* S3 Savage4 */ #define FB_ACCEL_SAVAGE3D 0x81 /* S3 Savage3D */ @@ -948,3 +949,6 @@ #endif /* __KERNEL__ */ #endif /* _LINUX_FB_H */ +/* + * Revision 1.55, Tue Apr 19 21:33:27 2005 + */ diff -Nur linux-git/include/video/impact.h linux-git-mit-R10k-patches/include/video/impact.h --- linux-git/include/video/impact.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-git-mit-R10k-patches/include/video/impact.h 2005-10-16 13:22:04.000000000 +0200 @@ -0,0 +1,181 @@ +/* + * linux/drivers/video/impactsr.h -- SGI Octane MardiGras (IMPACTSR) graphics + * linux/include/video/impact.h -- SGI Indigo2 MardiGras (IMPACT) graphics + * + * Copyright (c) 2004 by Stanislaw Skowronek + * Hacked for Indigo2 by pf, 2005 + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#ifndef IMPACT_H +#define IMPACT_H + +/* Convenient access macros */ +#define IMPACT_REG64(vma,off) (*(volatile unsigned long *)((vma)+(off))) +#define IMPACT_REG32(vma,off) (*(volatile unsigned int *)((vma)+(off))) +#define IMPACT_REG16(vma,off) (*(volatile unsigned short *)((vma)+(off))) +#define IMPACT_REG8(vma,off) (*(volatile unsigned char *)((vma)+(off))) + +#if defined(CONFIG_SGI_IP28)||defined(CONFIG_SGI_IP26)||defined(CONFIG_SGI_IP22) +/* Impact (HQ3) register offsets */ + +#define IMPACT_CFIFO(vma) IMPACT_REG64(vma,0x70080) +#define IMPACT_CFIFOW(vma) IMPACT_REG32(vma,0x70080) +#define IMPACT_CFIFOP(vma) IMPACT_REG64(vma,0x50080) +#define IMPACT_CFIFOPW(vma) IMPACT_REG32(vma,0x50080) + +#define IMPACT_STATUS(vma) IMPACT_REG32(vma,0x70000) +#define IMPACT_FIFOSTATUS(vma) IMPACT_REG32(vma,0x70004) +#define IMPACT_GIOSTATUS(vma) IMPACT_REG32(vma,0x70100) +#define IMPACT_DMABUSY(vma) IMPACT_REG32(vma,0x70104) + +#define IMPACT_CFIFO_HW(vma) IMPACT_REG32(vma,0x50020) +#define IMPACT_CFIFO_LW(vma) IMPACT_REG32(vma,0x50024) +#define IMPACT_CFIFO_DELAY(vma) IMPACT_REG32(vma,0x50028) +#define IMPACT_DFIFO_HW(vma) IMPACT_REG32(vma,0x5002c) +#define IMPACT_DFIFO_LW(vma) IMPACT_REG32(vma,0x50030) +#define IMPACT_DFIFO_DELAY(vma) IMPACT_REG32(vma,0x50034) + +#define X40918 0x50918 +#define X40920 0x50920 +#define X40928 0x50928 +#define IMPACT_XMAP_OFF(off) (0x61c00+(off)) +#define IMPACT_VC3_OFF(off) (0x62000+(off)) +#define IMPACT_RSS_OFF(off) (0x7c000+(off)) + +#else /* ImpactSR (HQ4) register offsets */ + +#define IMPACT_CFIFO(vma) IMPACT_REG64(vma,0x20400) +#define IMPACT_CFIFOW(vma) IMPACT_REG32(vma,0x20400) +#define IMPACT_CFIFOP(vma) IMPACT_REG64(vma,0x130400) +#define IMPACT_CFIFOPW(vma) IMPACT_REG32(vma,0x130400) + +#define IMPACT_STATUS(vma) IMPACT_REG32(vma,0x20000) +#define IMPACT_FIFOSTATUS(vma) IMPACT_REG32(vma,0x20008) +#define IMPACT_GIOSTATUS(vma) IMPACT_REG32(vma,0x20100) +#define IMPACT_DMABUSY(vma) IMPACT_REG32(vma,0x20200) + +#define IMPACT_CFIFO_HW(vma) IMPACT_REG32(vma,0x40000) +#define IMPACT_CFIFO_LW(vma) IMPACT_REG32(vma,0x40008) +#define IMPACT_CFIFO_DELAY(vma) IMPACT_REG32(vma,0x40010) +#define IMPACT_DFIFO_HW(vma) IMPACT_REG32(vma,0x40020) +#define IMPACT_DFIFO_LW(vma) IMPACT_REG32(vma,0x40028) +#define IMPACT_DFIFO_DELAY(vma) IMPACT_REG32(vma,0x40030) + +#define X40918 0x40918 +#define X40920 0x40920 +#define X40928 0x40928 +#define IMPACT_XMAP_OFF(off) (0x71c00+(off)) +#define IMPACT_VC3_OFF(off) (0x72000+(off)) +#define IMPACT_RSS_OFF(off) (0x2c000+(off)) + +#endif + +#define IMPACT_RESTATUS(vma) IMPACT_REG32(vma,IMPACT_RSS_OFF(0x578)) + +#define IMPACT_XMAP_PP1SELECT(vma) IMPACT_REG8(vma,IMPACT_XMAP_OFF(0x008)) +#define IMPACT_XMAP_INDEX(vma) IMPACT_REG8(vma,IMPACT_XMAP_OFF(0x088)) +#define IMPACT_XMAP_CONFIG(vma) IMPACT_REG32(vma,IMPACT_XMAP_OFF(0x100)) +#define IMPACT_XMAP_CONFIGB(vma) IMPACT_REG8(vma,IMPACT_XMAP_OFF(0x108)) +#define IMPACT_XMAP_BUF_SELECT(vma) IMPACT_REG32(vma,IMPACT_XMAP_OFF(0x180)) +#define IMPACT_XMAP_MAIN_MODE(vma) IMPACT_REG32(vma,IMPACT_XMAP_OFF(0x200)) +#define IMPACT_XMAP_OVERLAY_MODE(vma) IMPACT_REG32(vma,IMPACT_XMAP_OFF(0x280)) +#define IMPACT_XMAP_DIB(vma) IMPACT_REG32(vma,IMPACT_XMAP_OFF(0x300)) +#define IMPACT_XMAP_DIB_DW(vma) IMPACT_REG32(vma,IMPACT_XMAP_OFF(0x340)) +#define IMPACT_XMAP_RE_RAC(vma) IMPACT_REG32(vma,IMPACT_XMAP_OFF(0x380)) + +#define IMPACT_VC3_INDEX(vma) IMPACT_REG8(vma,IMPACT_VC3_OFF(0x008)) +#define IMPACT_VC3_INDEXDATA(vma) IMPACT_REG32(vma,IMPACT_VC3_OFF(0x038)) +#define IMPACT_VC3_DATA(vma) IMPACT_REG16(vma,IMPACT_VC3_OFF(0x0b0)) +#define IMPACT_VC3_RAM(vma) IMPACT_REG16(vma,IMPACT_VC3_OFF(0x190)) + +/* FIFO status */ +#if defined(CONFIG_SGI_IP28)||defined(CONFIG_SGI_IP26)||defined(CONFIG_SGI_IP22) +#define IMPACT_CFIFO_MAX 64 +#else +#define IMPACT_CFIFO_MAX 128 +#endif +#define IMPACT_BFIFO_MAX 16 + +/* Commands for CFIFO */ +#define IMPACT_CMD_WRITERSS(reg,val)\ + (((0x00180004L|((reg)<<8))<<32)|(unsigned)(val)) +#define IMPACT_CMD_EXECRSS(reg,val)\ + (((0x001c0004L|((reg)<<8))<<32)|(unsigned)(val)) + +#define IMPACT_CMD_GLINE_XSTARTF(v) IMPACT_CMD_WRITERSS(0x00c,v) +#define IMPACT_CMD_IR_ALIAS(v) IMPACT_CMD_EXECRSS(0x045,v) +#define IMPACT_CMD_BLOCKXYSTARTI(x,y) IMPACT_CMD_WRITERSS(0x046,((x)<<16)|(y)) +#define IMPACT_CMD_BLOCKXYENDI(x,y) IMPACT_CMD_WRITERSS(0x047,((x)<<16)|(y)) +#define IMPACT_CMD_PACKEDCOLOR(v) IMPACT_CMD_WRITERSS(0x05b,v) +#define IMPACT_CMD_RED(v) IMPACT_CMD_WRITERSS(0x05c,v) +#define IMPACT_CMD_ALPHA(v) IMPACT_CMD_WRITERSS(0x05f,v) +#define IMPACT_CMD_CHAR(v) IMPACT_CMD_EXECRSS(0x070,v) +#define IMPACT_CMD_CHAR_H(v) IMPACT_CMD_WRITERSS(0x070,v) +#define IMPACT_CMD_CHAR_L(v) IMPACT_CMD_EXECRSS(0x071,v) +#define IMPACT_CMD_XFRCONTROL(v) IMPACT_CMD_WRITERSS(0x102,v) +#define IMPACT_CMD_FILLMODE(v) IMPACT_CMD_WRITERSS(0x110,v) +#define IMPACT_CMD_CONFIG(v) IMPACT_CMD_WRITERSS(0x112,v) +#define IMPACT_CMD_XYWIN(x,y) IMPACT_CMD_WRITERSS(0x115,((y)<<16)|(x)) +#define IMPACT_CMD_BKGRD_RG(v) IMPACT_CMD_WRITERSS(0x140,((v)<<8)) +#define IMPACT_CMD_BKGRD_BA(v) IMPACT_CMD_WRITERSS(0x141,((v)<<8)) +#define IMPACT_CMD_WINMODE(v) IMPACT_CMD_WRITERSS(0x14f,v) +#define IMPACT_CMD_XFRSIZE(x,y) IMPACT_CMD_WRITERSS(0x153,((y)<<16)|(x)) +#define IMPACT_CMD_XFRMASKLO(v) IMPACT_CMD_WRITERSS(0x156,v) +#define IMPACT_CMD_XFRMASKHI(v) IMPACT_CMD_WRITERSS(0x157,v) +#define IMPACT_CMD_XFRCOUNTERS(x,y) IMPACT_CMD_WRITERSS(0x158,((y)<<16)|(x)) +#define IMPACT_CMD_XFRMODE(v) IMPACT_CMD_WRITERSS(0x159,v) +#define IMPACT_CMD_RE_TOGGLECNTX(v) IMPACT_CMD_WRITERSS(0x15f,v) +#define IMPACT_CMD_PIXCMD(v) IMPACT_CMD_WRITERSS(0x160,v) +#define IMPACT_CMD_PP1FILLMODE(m,o) IMPACT_CMD_WRITERSS(0x161,(m)|(o<<26)) +#define IMPACT_CMD_COLORMASKMSBS(v) IMPACT_CMD_WRITERSS(0x162,v) +#define IMPACT_CMD_COLORMASKLSBSA(v) IMPACT_CMD_WRITERSS(0x163,v) +#define IMPACT_CMD_COLORMASKLSBSB(v) IMPACT_CMD_WRITERSS(0x164,v) +#define IMPACT_CMD_BLENDFACTOR(v) IMPACT_CMD_WRITERSS(0x165,v) +#define IMPACT_CMD_DRBPOINTERS(v) IMPACT_CMD_WRITERSS(0x16d,v) + +#define IMPACT_CMD_HQ_PIXELFORMAT(v) (0x000c000400000000L|(unsigned)(v)) +#define IMPACT_CMD_HQ_SCANWIDTH(v) (0x000a020400000000L|(unsigned)(v)) +#define IMPACT_CMD_HQ_DMATYPE(v) (0x000a060400000000L|(unsigned)(v)) +#define IMPACT_CMD_HQ_PG_LIST_0(v) (0x0008000400000000L|(unsigned)(v)) +#define IMPACT_CMD_HQ_PG_WIDTH(v) (0x0008040400000000L|(unsigned)(v)) +#define IMPACT_CMD_HQ_PG_OFFSET(v) (0x0008050400000000L|(unsigned)(v)) +#define IMPACT_CMD_HQ_PG_STARTADDR(v) (0x0008060400000000L|(unsigned)(v)) +#define IMPACT_CMD_HQ_PG_LINECNT(v) (0x0008070400000000L|(unsigned)(v)) +#define IMPACT_CMD_HQ_PG_WIDTHA(v) (0x0008080400000000L|(unsigned)(v)) +#define IMPACT_CMD_HQ_TXBASE(p) (0x00482008|((p)<<9)) +#define IMPACT_CMD_HQ_TXMAX(p,v)\ + (0x0048300400000000L|(unsigned)(v)|((unsigned long)(p)<<41)) +#define IMPACT_CMD_HQ_PGBITS(p,v)\ + (0x00482b0400000000L|(unsigned)(v)|((unsigned long)(p)<<41)) +#define IMPACT_CMD_HQ_PGSIZE(v) (0x00482a0400000000L|(unsigned)(v)) +#define IMPACT_CMD_HQ_STACKPTR(v) (0x00483a0400000000L|(unsigned)(v)) + +/* Logic operations for the PP1 (SI=source invert, DI=dest invert, RI=result invert) */ +#define IMPACT_LO_CLEAR 0 +#define IMPACT_LO_AND 1 +#define IMPACT_LO_DIAND 2 +#define IMPACT_LO_COPY 3 +#define IMPACT_LO_SIAND 4 +#define IMPACT_LO_NOP 5 +#define IMPACT_LO_XOR 6 +#define IMPACT_LO_OR 7 +#define IMPACT_LO_RIOR 8 +#define IMPACT_LO_RIXOR 9 +#define IMPACT_LO_RINOP 10 +#define IMPACT_LO_DIOR 11 +#define IMPACT_LO_RICOPY 12 +#define IMPACT_LO_SIOR 13 +#define IMPACT_LO_RIAND 14 +#define IMPACT_LO_SET 15 + +/* Blending factors */ +#define IMPACT_BLEND_ALPHA 0x0704c900 + +#endif /* IMPACT_H */ +/* + * Fri Mar 18 21:42:10 2005 + */ diff -Nur linux-git/sound/oss/Kconfig linux-git-mit-R10k-patches/sound/oss/Kconfig --- linux-git/sound/oss/Kconfig 2005-10-15 16:01:40.000000000 +0200 +++ linux-git-mit-R10k-patches/sound/oss/Kconfig 2005-10-16 19:24:17.000000000 +0200 @@ -199,10 +199,10 @@ config SOUND_HAL2 tristate "SGI HAL2 sound (EXPERIMENTAL)" - depends on SOUND_PRIME && SGI_IP22 && EXPERIMENTAL + depends on SOUND_PRIME && (SGI_IP22 || SGI_IP28) && EXPERIMENTAL help - Say Y or M if you have an SGI Indy system and want to be able to - use it's on-board A2 audio system + Say Y or M if you have an SGI Indy or Indigo2 system and want to + be able to use it's on-board A2 audio system config SOUND_IT8172 tristate "IT8172G Sound"
diff -Nau cvs-/include/asm-mips/stackframe.h ip28/include/asm-mips/stackframe.h --- cvs-/include/asm-mips/stackframe.h Tue Apr 19 21:26:28 2005 +++ ip28/include/asm-mips/stackframe.h Tue Apr 26 23:48:41 2005 @@ -107,12 +107,37 @@ .endm #else .macro get_saved_sp /* Uniprocessor variation */ +# ifdef CONFIG_XKPHYS_KERNEL + /* + * Beware! + * 1) This is called, before $at is saved, so the + * assembler MUST NOT use $at. + * 2) k1 and any implicitely used k0 are not saved. Thus + * this MUST NOT be called with interrupts enabled. + * (applies as well to the ckseg version below) + */ + .set push + .set noat + dla k1, kernelsp + LONG_L k1, (k1) + .set pop +# else lui k1, %hi(kernelsp) LONG_L k1, %lo(kernelsp)(k1) +# endif .endm .macro set_saved_sp stackp temp temp2 + /* + * Beware! This is called with interrupts enabled, so + * make sure the assembler generated code-sequence only + * uses registers ($at), that will be saved/restored + * (especially true for elf64-.. format). + */ + /* .set push */ + /* .set at */ LONG_S \stackp, kernelsp + /* .set pop */ .endm #endif @@ -349,1 +374,5 @@ #endif /* _ASM_STACKFRAME_H */ +/* + * Revision 1.37, Tue Apr 19 21:26:28 2005 + * May 2004 pf - xkphys kernel addresses + */