From 372dd7234251bf38fa44a7388ab90a3d3a799b27 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sun, 18 Jan 2009 23:49:02 +0000 Subject: [PATCH 001/380] - Move Silicon Backplanes code out to system-wide level (dev/siba) as it's going to be used not only for siba5 devices. --- sys/conf/files.mips | 4 ++++ sys/{mips/sentry5 => dev/siba}/siba_cc.c | 0 sys/{mips/sentry5 => dev/siba}/siba_mips.c | 0 sys/{mips/sentry5 => dev/siba}/siba_sdram.c | 0 sys/mips/conf/SENTRY5 | 4 ++-- sys/mips/sentry5/files.sentry5 | 7 ------- 6 files changed, 6 insertions(+), 9 deletions(-) rename sys/{mips/sentry5 => dev/siba}/siba_cc.c (100%) rename sys/{mips/sentry5 => dev/siba}/siba_mips.c (100%) rename sys/{mips/sentry5 => dev/siba}/siba_sdram.c (100%) diff --git a/sys/conf/files.mips b/sys/conf/files.mips index 7fa0172c942..f3c2a0db0ec 100644 --- a/sys/conf/files.mips +++ b/sys/conf/files.mips @@ -95,3 +95,7 @@ dev/cfe/cfe_api.c optional cfe dev/cfe/cfe_console.c optional cfe_console #dev/cfe/cfe_resource.c optional cfe # not yet needed +dev/siba/siba.c optional siba +dev/siba/siba_pcib.c optional siba pci +dev/siba/siba_cc.c optional siba +#mips/sentry5/siba_mips.c optional siba # not yet diff --git a/sys/mips/sentry5/siba_cc.c b/sys/dev/siba/siba_cc.c similarity index 100% rename from sys/mips/sentry5/siba_cc.c rename to sys/dev/siba/siba_cc.c diff --git a/sys/mips/sentry5/siba_mips.c b/sys/dev/siba/siba_mips.c similarity index 100% rename from sys/mips/sentry5/siba_mips.c rename to sys/dev/siba/siba_mips.c diff --git a/sys/mips/sentry5/siba_sdram.c b/sys/dev/siba/siba_sdram.c similarity index 100% rename from sys/mips/sentry5/siba_sdram.c rename to sys/dev/siba/siba_sdram.c diff --git a/sys/mips/conf/SENTRY5 b/sys/mips/conf/SENTRY5 index 7611e44bb7e..5b37e9783d8 100644 --- a/sys/mips/conf/SENTRY5 +++ b/sys/mips/conf/SENTRY5 @@ -73,8 +73,8 @@ options INVARIANT_SUPPORT device siba # Sonics SiliconBackplane device pci # siba_pcib -device bfe # XXX will build both pci and siba -device miibus # attachments +# device bfe # XXX will build both pci and siba +# device miibus # attachments # pci devices # notyet: diff --git a/sys/mips/sentry5/files.sentry5 b/sys/mips/sentry5/files.sentry5 index 61038e035df..79925094a2d 100644 --- a/sys/mips/sentry5/files.sentry5 +++ b/sys/mips/sentry5/files.sentry5 @@ -4,11 +4,4 @@ # for USB 1.1 OHCI, Ethernet and IPSEC cores # which are believed to be devices we have drivers for # which just need to be tweaked for attachment to an SSB system bus. - mips/sentry5/s5_machdep.c standard -dev/siba/siba.c optional siba -dev/siba/siba_pcib.c optional siba pci -mips/sentry5/siba_cc.c optional siba - -# notyet -#mips/sentry5/siba_mips.c optional siba From f8865fd78d2fe3858a1cf5ed7329c4248423f0be Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 19 Jan 2009 02:37:10 +0000 Subject: [PATCH 002/380] - Add trampoline stuff for bootloaders that do not support ELF - Replace arm'ish KERNPHYSADDR/KERNVIRTADDR with KERNLOADADDR/TRAMPLOADADDR and clean configs --- sys/conf/Makefile.mips | 48 +++++++++++- sys/conf/ldscript.mips | 2 +- sys/conf/options.mips | 4 +- sys/mips/conf/ADM5120 | 1 - sys/mips/conf/MALTA | 1 - sys/mips/conf/QEMU | 1 - sys/mips/conf/SENTRY5 | 7 -- sys/mips/mips/elf_trampoline.c | 133 +++++++++++++++++++++++++++++++++ sys/mips/mips/inckern.S | 34 +++++++++ 9 files changed, 216 insertions(+), 15 deletions(-) create mode 100644 sys/mips/mips/elf_trampoline.c create mode 100644 sys/mips/mips/inckern.S diff --git a/sys/conf/Makefile.mips b/sys/conf/Makefile.mips index 443065aaafc..e03432c9edf 100644 --- a/sys/conf/Makefile.mips +++ b/sys/conf/Makefile.mips @@ -28,35 +28,73 @@ S= ../../.. .endif .include "$S/conf/kern.pre.mk" +SYSTEM_LD:= ${SYSTEM_LD:$S/conf/ldscript.$M=ldscript.$M} +SYSTEM_DEP:= ${SYSTEM_DEP:$S/conf/ldscript.$M=ldscript.$M} + # XXX: Such sweeping assumptions... MACHINE=mips MACHINE_ARCH=mips +KERNLOADADDR?=0x80001000 +# This obscure value is defined by CFE for WR160N +# To be changed later +TRAMPLOADADDR?=0x807963c0 MKMODULESENV+= MACHINE=${MACHINE} MACHINE_ARCH=${MACHINE_ARCH} # We default to the MIPS32 ISA, if none specified in the # kernel configuration file. ARCH_FLAGS?=-march=mips32 +EXTRA_FLAGS=-fno-pic -mno-abicalls -mno-dsp -G0 HACK_EXTRA_FLAGS=-shared .if defined(TARGET_BIG_ENDIAN) CFLAGS+=-EB SYSTEM_LD+=-EB +EXTRA_FLAGS+=-EB +TRAMP_LDFLAGS+=-Wl,-EB HACK_EXTRA_FLAGS+=-EB -Wl,-EB .else CFLAGS+=-EL SYSTEM_LD+=-EL +EXTRA_FLAGS+=-EL +TRAMP_LDFLAGS+=-Wl,-EL HACK_EXTRA_FLAGS+=-EL -Wl,-EL .endif # We add the -fno-pic flag to kernels because otherwise performance # is extremely poor, as well as -mno-abicalls to force no ABI usage. -CFLAGS+=-fno-pic -mno-abicalls -G0 $(ARCH_FLAGS) -HACK_EXTRA_FLAGS+=-fno-pic -mno-abicalls -G0 $(ARCH_FLAGS) +CFLAGS+=${EXTRA_FLAGS} $(ARCH_FLAGS) +HACK_EXTRA_FLAGS+=${EXTRA_FLAGS} $(ARCH_FLAGS) # XXX hardcoded kernel entry point ASM_CFLAGS+=${CFLAGS} -D_LOCORE -DLOCORE +KERNEL_EXTRA=trampoline +trampoline: ${KERNEL_KO}.tramp.bin +${KERNEL_KO}.tramp.bin: ${KERNEL_KO} $S/$M/$M/elf_trampoline.c \ + $S/$M/$M/inckern.S + ${OBJCOPY} --strip-symbol '$$d' --strip-symbol '$$a' \ + -g --strip-symbol '$$t' ${FULLKERNEL} ${KERNEL_KO}.tmp + sed s/${KERNLOADADDR}/${TRAMPLOADADDR}/ ldscript.$M | \ + sed s/" + SIZEOF_HEADERS"// > ldscript.$M.tramp.noheader + # Generate .S file that setups stack and jumps to trampoline + echo "#include " >tmphack.S + echo "ENTRY(_start)" >>tmphack.S + echo "la t0, kernel_end" >>tmphack.S + echo "move sp, t0" >>tmphack.S + echo "add sp, 0x2000" >>tmphack.S + echo "and sp, ~0x7" >>tmphack.S + echo "la t0, _startC" >>tmphack.S + echo "j t0" >>tmphack.S + echo "END(_start)" >>tmphack.S + echo "#define KERNNAME \"${KERNEL_KO}.tmp\"" >opt_kernname.h + ${CC} -O -nostdlib -I. -I$S ${EXTRA_FLAGS} ${TRAMP_LDFLAGS} -Xlinker \ + -T -Xlinker ldscript.$M.tramp.noheader tmphack.S \ + $S/$M/$M/elf_trampoline.c $S/$M/$M/inckern.S \ + -o ${KERNEL_KO}.tramp.noheader + ${OBJCOPY} -S -O binary ${KERNEL_KO}.tramp.noheader \ + ${KERNEL_KO}.tramp.bin \ + %BEFORE_DEPEND %OBJS @@ -69,6 +107,12 @@ ASM_CFLAGS+=${CFLAGS} -D_LOCORE -DLOCORE %CLEAN +CLEAN+= ldscript.$M ldscript.$M.tramp.noheader \ + ${KERNEL_KO}.tramp.noheader ${KERNEL_KO}.tramp.bin + +ldscript.$M: $S/conf/ldscript.$M + cat $S/conf/ldscript.$M|sed s/KERNLOADADDR/${KERNLOADADDR}/g \ + > ldscript.$M %RULES .include "$S/conf/kern.post.mk" diff --git a/sys/conf/ldscript.mips b/sys/conf/ldscript.mips index ca4a70bd32e..3e55dba46d8 100644 --- a/sys/conf/ldscript.mips +++ b/sys/conf/ldscript.mips @@ -43,7 +43,7 @@ PROVIDE (_DYNAMIC = 0); SECTIONS { /* Read-only sections, merged into text segment: */ - . = 0x80100000 + SIZEOF_HEADERS; + . = KERNLOADADDR + SIZEOF_HEADERS; .interp : { *(.interp) } .hash : { *(.hash) } .dynsym : { *(.dynsym) } diff --git a/sys/conf/options.mips b/sys/conf/options.mips index 757993ff91a..abbc700c799 100644 --- a/sys/conf/options.mips +++ b/sys/conf/options.mips @@ -45,8 +45,8 @@ YAMON opt_global.h CFE opt_global.h CFE_CONSOLE opt_global.h -KERNPHYSADDR opt_global.h -KERNVIRTADDR opt_global.h +KERNLOADADDR opt_global.h +TRAMPLOADADDR opt_global.h PHYSADDR opt_global.h SOFTFLOAT opt_global.h diff --git a/sys/mips/conf/ADM5120 b/sys/mips/conf/ADM5120 index a03d102251c..7a47abed107 100644 --- a/sys/mips/conf/ADM5120 +++ b/sys/mips/conf/ADM5120 @@ -25,7 +25,6 @@ makeoptions MIPS_LITTLE_ENDIAN=defined # Don't build any modules yet. makeoptions MODULES_OVERRIDE="" -options KERNVIRTADDR=0x80100000 include "../adm5120/std.adm5120" hints "ADM5120.hints" #Default places to look for devices. diff --git a/sys/mips/conf/MALTA b/sys/mips/conf/MALTA index 9771c55351e..022cc5245c8 100644 --- a/sys/mips/conf/MALTA +++ b/sys/mips/conf/MALTA @@ -27,7 +27,6 @@ options YAMON # Don't build any modules yet. makeoptions MODULES_OVERRIDE="" -options KERNVIRTADDR=0x80100000 options TICK_USE_YAMON_FREQ=defined #options TICK_USE_MALTA_RTC=defined diff --git a/sys/mips/conf/QEMU b/sys/mips/conf/QEMU index 0a2b122570b..bc7d64951b1 100644 --- a/sys/mips/conf/QEMU +++ b/sys/mips/conf/QEMU @@ -27,7 +27,6 @@ makeoptions ARCH_FLAGS=-march=mips32 # Don't build any modules yet. makeoptions MODULES_OVERRIDE="" -options KERNVIRTADDR=0x80100000 include "../adm5120/std.adm5120" #hints "GENERIC.hints" #Default places to look for devices. diff --git a/sys/mips/conf/SENTRY5 b/sys/mips/conf/SENTRY5 index 5b37e9783d8..c3918e2e35c 100644 --- a/sys/mips/conf/SENTRY5 +++ b/sys/mips/conf/SENTRY5 @@ -41,13 +41,6 @@ options CFE options CFE_CONSOLE options ALT_BREAK_TO_DEBUGGER -# cfe loader expects kernel at 0x80001000 for mips32 w/o backwards -# offsets in the linked elf image (see ldscript hack) -# XXX can we conditionalize the linker stuff on options CFE? -options KERNVIRTADDR=0x80001000 - -makeoptions LDSCRIPT_NAME= ldscript.mips.cfe - #makeoptions ARCH_FLAGS=-march=mips32 makeoptions MIPS_LITTLE_ENDIAN=defined makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols diff --git a/sys/mips/mips/elf_trampoline.c b/sys/mips/mips/elf_trampoline.c new file mode 100644 index 00000000000..0f2ccc95e31 --- /dev/null +++ b/sys/mips/mips/elf_trampoline.c @@ -0,0 +1,133 @@ +/*- + * Copyright (c) 2005 Olivier Houchard. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); +#include +#include +#include +#include +#include +#include +#include + +/* + * Since we are compiled outside of the normal kernel build process, we + * need to include opt_global.h manually. + */ +#include "opt_global.h" +#include "opt_kernname.h" + +extern char kernel_start[]; +extern char kernel_end[]; + +static __inline void * +memcpy(void *dst, const void *src, int len) +{ + const char *s = src; + char *d = dst; + + while (len) { + if (0 && len >= 4 && !((vm_offset_t)d & 3) && + !((vm_offset_t)s & 3)) { + *(uint32_t *)d = *(uint32_t *)s; + s += 4; + d += 4; + len -= 4; + } else { + *d++ = *s++; + len--; + } + } + return (dst); +} + +static __inline void +bzero(void *addr, int count) +{ + char *tmp = (char *)addr; + + while (count > 0) { + if (count >= 4 && !((vm_offset_t)tmp & 3)) { + *(uint32_t *)tmp = 0; + tmp += 4; + count -= 4; + } else { + *tmp = 0; + tmp++; + count--; + } + } +} + +/* + * Relocate PT_LOAD segements of kernel ELF image to their respective + * virtual addresses and return entry point + */ +void * +load_kernel(void * kstart) +{ + Elf32_Ehdr *eh; + Elf32_Phdr phdr[64] /* XXX */; + int i; + void *entry_point; + + eh = (Elf32_Ehdr *)kstart; + entry_point = (void*)eh->e_entry; + memcpy(phdr, (void *)(kstart + eh->e_phoff ), + eh->e_phnum * sizeof(phdr[0])); + + for (i = 0; i < eh->e_phnum; i++) { + volatile char c; + + if (phdr[i].p_type != PT_LOAD) + continue; + + memcpy((void *)(phdr[i].p_vaddr), + (void*)(kstart + phdr[i].p_offset), phdr[i].p_filesz); + /* Clean space from oversized segments, eg: bss. */ + if (phdr[i].p_filesz < phdr[i].p_memsz) + bzero((void *)(phdr[i].p_vaddr + phdr[i].p_filesz), + phdr[i].p_memsz - phdr[i].p_filesz); + } + + return entry_point; +} + +void +_startC(register_t a0, register_t a1, register_t a2, register_t a3) +{ + unsigned int * code; + int i; + void (*entry_point)(register_t, register_t, register_t, register_t); + + /* + * Relocate segment to the predefined memory location + * Most likely it will be KSEG0/KSEG1 address + */ + entry_point = load_kernel(kernel_start); + + /* Pass saved registers to original _start */ + entry_point(a0, a1, a2, a3); +} diff --git a/sys/mips/mips/inckern.S b/sys/mips/mips/inckern.S new file mode 100644 index 00000000000..8610196d204 --- /dev/null +++ b/sys/mips/mips/inckern.S @@ -0,0 +1,34 @@ +/*- + * Copyright (c) 2005 Olivier Houchard. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "opt_kernname.h" + +#include +__FBSDID("$FreeBSD$") +.section ".real_kernel","aw" +.globl kernel_start; +kernel_start: +.incbin KERNNAME +.globl kernel_end; +kernel_end: From 68d46a5406d4b483df2132d53b320b432fd3062a Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 19 Jan 2009 06:32:30 +0000 Subject: [PATCH 003/380] - First bits of Atheros' AR71XX port. Only UART supported ATM. --- sys/mips/ar71xx/ar71xx_machdep.c | 138 ++++++++++++++++++++++++++++++ sys/mips/ar71xx/ar71xxreg.h | 36 ++++++++ sys/mips/ar71xx/files.ar71xx | 4 + sys/mips/ar71xx/uart_cpu_ar71xx.c | 71 +++++++++++++++ sys/mips/conf/AR71XX | 35 ++++++++ 5 files changed, 284 insertions(+) create mode 100644 sys/mips/ar71xx/ar71xx_machdep.c create mode 100644 sys/mips/ar71xx/ar71xxreg.h create mode 100644 sys/mips/ar71xx/files.ar71xx create mode 100644 sys/mips/ar71xx/uart_cpu_ar71xx.c create mode 100644 sys/mips/conf/AR71XX diff --git a/sys/mips/ar71xx/ar71xx_machdep.c b/sys/mips/ar71xx/ar71xx_machdep.c new file mode 100644 index 00000000000..01f7762faa8 --- /dev/null +++ b/sys/mips/ar71xx/ar71xx_machdep.c @@ -0,0 +1,138 @@ +/*- + * Copyright (c) 2009 Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include + +#include "opt_ddb.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +extern int *edata; +extern int *end; + +void +platform_halt(void) +{ + +} + +void +platform_identify(void) +{ + +} + +void +platform_reset(void) +{ + volatile unsigned int * p = + (void *)MIPS_PHYS_TO_KSEG1(AR71XX_RST_RESET); + + *p = RST_RESET_CPU_COLD_RESET; +} + +void +platform_trap_enter(void) +{ + +} + +void +platform_trap_exit(void) +{ + +} + +void +platform_start(__register_t a0 __unused, __register_t a1 __unused, + __register_t a2 __unused, __register_t a3 __unused) +{ + vm_offset_t kernend; + uint64_t platform_counter_freq; + + /* clear the BSS and SBSS segments */ + kernend = round_page((vm_offset_t)&end); + memset(&edata, 0, kernend - (vm_offset_t)(&edata)); + + /* TODO: Get available memory from RedBoot. Is it possible? */ + realmem = btoc(64*1024*1024); + /* phys_avail regions are in bytes */ + phys_avail[0] = MIPS_KSEG0_TO_PHYS((vm_offset_t)&end); + phys_avail[1] = ctob(realmem); + + physmem = realmem; + + /* + * ns8250 uart code uses DELAY so ticker should be inititalized + * before cninit. And tick_init_params refers to hz, so * init_param1 + * should be called first. + */ + init_param1(); + /* TODO: Get CPU freq from RedBoot. Is it possible? */ + platform_counter_freq = 680000000UL; + mips_timer_init_params(platform_counter_freq, 0); + cninit(); + + printf("arguments: \n"); + printf(" a0 = %08x\n", a0); + printf(" a1 = %08x\n", a1); + printf(" a2 = %08x\n", a2); + printf(" a3 = %08x\n", a3); + + init_param2(physmem); + mips_cpu_init(); + pmap_bootstrap(); + mips_proc0_init(); + mutex_init(); + +#ifdef DDB + kdb_init(); +#endif +} diff --git a/sys/mips/ar71xx/ar71xxreg.h b/sys/mips/ar71xx/ar71xxreg.h new file mode 100644 index 00000000000..ce5e1ccc415 --- /dev/null +++ b/sys/mips/ar71xx/ar71xxreg.h @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2009 Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#ifndef _AR71XX_REG_H_ +#define _AR71XX_REG_H_ + +#define AR71XX_UART_ADDR 0x18020000 + +#define AR71XX_RST_RESET 0x18060024 +#define RST_RESET_CPU_COLD_RESET (1 << 20) /* Cold reset */ +#define RST_RESET_FULL_CHIP_RESET (1 << 24) /* Same as pulling + the reset pin */ + +#endif /* _AR71XX_REG_H_ */ diff --git a/sys/mips/ar71xx/files.ar71xx b/sys/mips/ar71xx/files.ar71xx new file mode 100644 index 00000000000..1563092d56c --- /dev/null +++ b/sys/mips/ar71xx/files.ar71xx @@ -0,0 +1,4 @@ +# $FreeBSD$ + +mips/ar71xx/ar71xx_machdep.c standard +mips/ar71xx/uart_cpu_ar71xx.c optional uart diff --git a/sys/mips/ar71xx/uart_cpu_ar71xx.c b/sys/mips/ar71xx/uart_cpu_ar71xx.c new file mode 100644 index 00000000000..18b5b07577c --- /dev/null +++ b/sys/mips/ar71xx/uart_cpu_ar71xx.c @@ -0,0 +1,71 @@ +/*- + * Copyright (c) 2009 Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +#include "opt_uart.h" + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include + +#include +#include + +#include + +bus_space_tag_t uart_bus_space_io; +bus_space_tag_t uart_bus_space_mem; + +int +uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) +{ + return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0); +} + +int +uart_cpu_getdev(int devtype, struct uart_devinfo *di) +{ + di->ops = uart_getops(&uart_ns8250_class); + di->bas.chan = 0; + di->bas.bst = 0; + di->bas.regshft = 2; + /* TODO: calculate proper AHB freq using PLL registers */ + di->bas.rclk = 85000000; + di->baudrate = 115200; + di->databits = 8; + di->stopbits = 1; + di->parity = UART_PARITY_NONE; + + /* Bad MIPS, no IO for MIPS */ + uart_bus_space_io = 0; + uart_bus_space_mem = MIPS_PHYS_TO_KSEG1(AR71XX_UART_ADDR) + 3; + di->bas.bsh = MIPS_PHYS_TO_KSEG1(AR71XX_UART_ADDR) + 3; + return (0); +} diff --git a/sys/mips/conf/AR71XX b/sys/mips/conf/AR71XX new file mode 100644 index 00000000000..1c54d8dfd0a --- /dev/null +++ b/sys/mips/conf/AR71XX @@ -0,0 +1,35 @@ +# +# $FreeBSD$ +# + +ident AR71XX +cpu CPU_MIPS4KC +options CPU_NOFPU +options ISA_MIPS32 +makeoptions TARGET_BIG_ENDIAN +options KERNLOADADDR=0x80100000 + +files "../ar71xx/files.ar71xx" + +makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols +makeoptions MODULES_OVERRIDE="" + +options DDB +options KDB + +options SCHED_4BSD #4BSD scheduler +options INET #InterNETworking +options NFSCLIENT #Network Filesystem Client +options NFS_ROOT #NFS usable as /, requires NFSCLIENT +options PSEUDOFS #Pseudo-filesystem framework +options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions + +# Debugging for use in -current +options INVARIANTS +options INVARIANT_SUPPORT + +device uart + +device loop +device ether +device md From 45f80db0d589135f445f9e1b47a256f347d65096 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 19 Jan 2009 06:42:44 +0000 Subject: [PATCH 004/380] - style(9) fix: replace spaces with tabs --- sys/mips/ar71xx/ar71xx_machdep.c | 42 ++++++++++++++++---------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/sys/mips/ar71xx/ar71xx_machdep.c b/sys/mips/ar71xx/ar71xx_machdep.c index 01f7762faa8..88aaf1550de 100644 --- a/sys/mips/ar71xx/ar71xx_machdep.c +++ b/sys/mips/ar71xx/ar71xx_machdep.c @@ -72,10 +72,10 @@ platform_identify(void) void platform_reset(void) { - volatile unsigned int * p = + volatile unsigned int * p = (void *)MIPS_PHYS_TO_KSEG1(AR71XX_RST_RESET); - *p = RST_RESET_CPU_COLD_RESET; + *p = RST_RESET_CPU_COLD_RESET; } void @@ -103,36 +103,36 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, /* TODO: Get available memory from RedBoot. Is it possible? */ realmem = btoc(64*1024*1024); - /* phys_avail regions are in bytes */ - phys_avail[0] = MIPS_KSEG0_TO_PHYS((vm_offset_t)&end); - phys_avail[1] = ctob(realmem); + /* phys_avail regions are in bytes */ + phys_avail[0] = MIPS_KSEG0_TO_PHYS((vm_offset_t)&end); + phys_avail[1] = ctob(realmem); - physmem = realmem; + physmem = realmem; /* - * ns8250 uart code uses DELAY so ticker should be inititalized - * before cninit. And tick_init_params refers to hz, so * init_param1 - * should be called first. - */ - init_param1(); + * ns8250 uart code uses DELAY so ticker should be inititalized + * before cninit. And tick_init_params refers to hz, so * init_param1 + * should be called first. + */ + init_param1(); /* TODO: Get CPU freq from RedBoot. Is it possible? */ - platform_counter_freq = 680000000UL; - mips_timer_init_params(platform_counter_freq, 0); - cninit(); + platform_counter_freq = 680000000UL; + mips_timer_init_params(platform_counter_freq, 0); + cninit(); - printf("arguments: \n"); + printf("arguments: \n"); printf(" a0 = %08x\n", a0); printf(" a1 = %08x\n", a1); printf(" a2 = %08x\n", a2); printf(" a3 = %08x\n", a3); - init_param2(physmem); - mips_cpu_init(); - pmap_bootstrap(); - mips_proc0_init(); - mutex_init(); + init_param2(physmem); + mips_cpu_init(); + pmap_bootstrap(); + mips_proc0_init(); + mutex_init(); #ifdef DDB - kdb_init(); + kdb_init(); #endif } From 14fccbfcc3d0a6148a57551bda6314f1654f14f1 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 20 Jan 2009 00:03:52 +0000 Subject: [PATCH 005/380] - Use more generic name for atheros-based devices subdirectory. Keep old naming scheme for files until we'll figure out common parts. Suggested by: imp@ --- sys/mips/ar71xx/files.ar71xx | 4 ---- sys/mips/{ar71xx => atheros}/ar71xx_machdep.c | 2 +- sys/mips/{ar71xx => atheros}/ar71xxreg.h | 0 sys/mips/atheros/files.ar71xx | 4 ++++ sys/mips/{ar71xx => atheros}/uart_cpu_ar71xx.c | 2 +- sys/mips/conf/AR71XX | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) delete mode 100644 sys/mips/ar71xx/files.ar71xx rename sys/mips/{ar71xx => atheros}/ar71xx_machdep.c (98%) rename sys/mips/{ar71xx => atheros}/ar71xxreg.h (100%) create mode 100644 sys/mips/atheros/files.ar71xx rename sys/mips/{ar71xx => atheros}/uart_cpu_ar71xx.c (98%) diff --git a/sys/mips/ar71xx/files.ar71xx b/sys/mips/ar71xx/files.ar71xx deleted file mode 100644 index 1563092d56c..00000000000 --- a/sys/mips/ar71xx/files.ar71xx +++ /dev/null @@ -1,4 +0,0 @@ -# $FreeBSD$ - -mips/ar71xx/ar71xx_machdep.c standard -mips/ar71xx/uart_cpu_ar71xx.c optional uart diff --git a/sys/mips/ar71xx/ar71xx_machdep.c b/sys/mips/atheros/ar71xx_machdep.c similarity index 98% rename from sys/mips/ar71xx/ar71xx_machdep.c rename to sys/mips/atheros/ar71xx_machdep.c index 88aaf1550de..a5aa2b213e0 100644 --- a/sys/mips/ar71xx/ar71xx_machdep.c +++ b/sys/mips/atheros/ar71xx_machdep.c @@ -52,7 +52,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include +#include extern int *edata; extern int *end; diff --git a/sys/mips/ar71xx/ar71xxreg.h b/sys/mips/atheros/ar71xxreg.h similarity index 100% rename from sys/mips/ar71xx/ar71xxreg.h rename to sys/mips/atheros/ar71xxreg.h diff --git a/sys/mips/atheros/files.ar71xx b/sys/mips/atheros/files.ar71xx new file mode 100644 index 00000000000..14e7f9c471e --- /dev/null +++ b/sys/mips/atheros/files.ar71xx @@ -0,0 +1,4 @@ +# $FreeBSD$ + +mips/atheros/ar71xx_machdep.c standard +mips/atheros/uart_cpu_ar71xx.c optional uart diff --git a/sys/mips/ar71xx/uart_cpu_ar71xx.c b/sys/mips/atheros/uart_cpu_ar71xx.c similarity index 98% rename from sys/mips/ar71xx/uart_cpu_ar71xx.c rename to sys/mips/atheros/uart_cpu_ar71xx.c index 18b5b07577c..739ecf50e8b 100644 --- a/sys/mips/ar71xx/uart_cpu_ar71xx.c +++ b/sys/mips/atheros/uart_cpu_ar71xx.c @@ -38,7 +38,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include +#include bus_space_tag_t uart_bus_space_io; bus_space_tag_t uart_bus_space_mem; diff --git a/sys/mips/conf/AR71XX b/sys/mips/conf/AR71XX index 1c54d8dfd0a..d87b0bb7001 100644 --- a/sys/mips/conf/AR71XX +++ b/sys/mips/conf/AR71XX @@ -9,7 +9,7 @@ options ISA_MIPS32 makeoptions TARGET_BIG_ENDIAN options KERNLOADADDR=0x80100000 -files "../ar71xx/files.ar71xx" +files "../atheros/files.ar71xx" makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols makeoptions MODULES_OVERRIDE="" From c5c94e1e1b2ccf3575222bee40c905dfdb50867f Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 20 Jan 2009 04:24:03 +0000 Subject: [PATCH 006/380] - KERNLOADADDR should be defined with makeoption. Redboot loads kernel now --- sys/mips/conf/AR71XX | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/conf/AR71XX b/sys/mips/conf/AR71XX index d87b0bb7001..a373fb93613 100644 --- a/sys/mips/conf/AR71XX +++ b/sys/mips/conf/AR71XX @@ -7,7 +7,7 @@ cpu CPU_MIPS4KC options CPU_NOFPU options ISA_MIPS32 makeoptions TARGET_BIG_ENDIAN -options KERNLOADADDR=0x80100000 +makeoptions KERNLOADADDR=0x80050000 files "../atheros/files.ar71xx" From 452c36d15b052550aa7309931ef03cd4096b7172 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 20 Jan 2009 04:31:12 +0000 Subject: [PATCH 007/380] - Use more generic prefix for register names (ATH instead of AR71XX --- sys/mips/atheros/ar71xxreg.h | 27 ++++++++++++++++++++++++--- sys/mips/atheros/uart_cpu_ar71xx.c | 4 ++-- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/sys/mips/atheros/ar71xxreg.h b/sys/mips/atheros/ar71xxreg.h index ce5e1ccc415..f6ccdb7903f 100644 --- a/sys/mips/atheros/ar71xxreg.h +++ b/sys/mips/atheros/ar71xxreg.h @@ -26,11 +26,32 @@ #ifndef _AR71XX_REG_H_ #define _AR71XX_REG_H_ -#define AR71XX_UART_ADDR 0x18020000 +#define ATH_READ_REG(reg) \ + *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((reg))) -#define AR71XX_RST_RESET 0x18060024 +#define ATH_WRITE_REG(reg, val) \ + *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((reg))) = (val) + +#define ATH_UART_ADDR 0x18020000 + +/* APB registers */ +/* + * APB interrupt status and mask register and interrupt bit numbers for + */ +#define ATH_MISC_INTR_STATUS 0x18060010 +#define ATH_MISC_INTR_MASK 0x18060014 +#define ATH_INT_MISC_TIMER 0 +#define ATH_INT_MISC_ERROR 1 +#define ATH_INT_MISC_GPIO 2 +#define ATH_INT_MISC_UART 3 +#define ATH_INT_MISC_WATCHDOG 4 +#define ATH_INT_MISC_PERF 5 +#define ATH_INT_MISC_OHCI 6 +#define ATH_INT_MISC_DMA 7 + + +#define ATH_RST_RESET 0x18060024 #define RST_RESET_CPU_COLD_RESET (1 << 20) /* Cold reset */ #define RST_RESET_FULL_CHIP_RESET (1 << 24) /* Same as pulling the reset pin */ - #endif /* _AR71XX_REG_H_ */ diff --git a/sys/mips/atheros/uart_cpu_ar71xx.c b/sys/mips/atheros/uart_cpu_ar71xx.c index 739ecf50e8b..97cb1293d9d 100644 --- a/sys/mips/atheros/uart_cpu_ar71xx.c +++ b/sys/mips/atheros/uart_cpu_ar71xx.c @@ -65,7 +65,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) /* Bad MIPS, no IO for MIPS */ uart_bus_space_io = 0; - uart_bus_space_mem = MIPS_PHYS_TO_KSEG1(AR71XX_UART_ADDR) + 3; - di->bas.bsh = MIPS_PHYS_TO_KSEG1(AR71XX_UART_ADDR) + 3; + uart_bus_space_mem = MIPS_PHYS_TO_KSEG1(ATH_UART_ADDR) + 3; + di->bas.bsh = MIPS_PHYS_TO_KSEG1(ATH_UART_ADDR) + 3; return (0); } From ab93ec40cf900e296d0ed72a5de722413dcca09d Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 20 Jan 2009 04:31:45 +0000 Subject: [PATCH 008/380] - Fix platform_reset function --- sys/mips/atheros/ar71xx_machdep.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sys/mips/atheros/ar71xx_machdep.c b/sys/mips/atheros/ar71xx_machdep.c index a5aa2b213e0..9aee3bb5e3e 100644 --- a/sys/mips/atheros/ar71xx_machdep.c +++ b/sys/mips/atheros/ar71xx_machdep.c @@ -72,10 +72,14 @@ platform_identify(void) void platform_reset(void) { - volatile unsigned int * p = - (void *)MIPS_PHYS_TO_KSEG1(AR71XX_RST_RESET); + volatile uint32_t * p = + (void *)MIPS_PHYS_TO_KSEG1(ATH_RST_RESET); + uint32_t reg = *p; - *p = RST_RESET_CPU_COLD_RESET; + *p = reg | RST_RESET_FULL_CHIP_RESET; + /* Wait for reset */ + while(1) + ; } void From eed8ee1f6c360eb1a0d80056e39d304c9c645ae5 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 20 Jan 2009 22:42:37 +0000 Subject: [PATCH 009/380] First milestone on Alchemy port: Simplest kernel now compiles. --- sys/mips/alchemy/alchemy_machdep.c | 157 ++++++++++++++++++++++++++++ sys/mips/alchemy/files.alchemy | 7 ++ sys/mips/alchemy/std.alchemy | 10 ++ sys/mips/alchemy/uart_bus_alchemy.c | 87 +++++++++++++++ sys/mips/alchemy/uart_cpu_alchemy.c | 79 ++++++++++++++ 5 files changed, 340 insertions(+) create mode 100644 sys/mips/alchemy/alchemy_machdep.c create mode 100644 sys/mips/alchemy/files.alchemy create mode 100644 sys/mips/alchemy/std.alchemy create mode 100644 sys/mips/alchemy/uart_bus_alchemy.c create mode 100644 sys/mips/alchemy/uart_cpu_alchemy.c diff --git a/sys/mips/alchemy/alchemy_machdep.c b/sys/mips/alchemy/alchemy_machdep.c new file mode 100644 index 00000000000..eca9b18ae0d --- /dev/null +++ b/sys/mips/alchemy/alchemy_machdep.c @@ -0,0 +1,157 @@ +/*- + * Copyright (C) 2007 by Oleksandr Tymoshenko. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "opt_ddb.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern int *edata; +extern int *end; + +static void +mips_init(void) +{ + int i; + + printf("entry: mips_init()\n"); + + bootverbose = 1; + realmem = btoc(16 << 20); + + for (i = 0; i < 10; i++) { + phys_avail[i] = 0; + } + + /* phys_avail regions are in bytes */ + phys_avail[0] = MIPS_KSEG0_TO_PHYS((vm_offset_t)&end); + phys_avail[1] = ctob(realmem); + + physmem = realmem; + + init_param1(); + init_param2(physmem); + mips_cpu_init(); + pmap_bootstrap(); + mips_proc0_init(); + mutex_init(); +#ifdef DDB + kdb_init(); +#endif +} + +void +platform_halt(void) +{ + +} + + +void +platform_identify(void) +{ + +} + +void +platform_reset(void) +{ + + __asm __volatile("li $25, 0xbfc00000"); + __asm __volatile("j $25"); +} + +void +platform_trap_enter(void) +{ + +} + +void +platform_trap_exit(void) +{ + +} + +void +platform_start(__register_t a0 __unused, __register_t a1 __unused, + __register_t a2 __unused, __register_t a3 __unused) +{ + vm_offset_t kernend; + uint64_t platform_counter_freq = 175 * 1000 * 1000; + + /* clear the BSS and SBSS segments */ + kernend = round_page((vm_offset_t)&end); + memset(&edata, 0, kernend - (vm_offset_t)(&edata)); + + cninit(); + mips_init(); + /* Set counter_freq for tick_init_params() */ + platform_counter_freq = 175 * 1000 * 1000; + + mips_timer_init_params(platform_counter_freq, 0); +} diff --git a/sys/mips/alchemy/files.alchemy b/sys/mips/alchemy/files.alchemy new file mode 100644 index 00000000000..8534431d020 --- /dev/null +++ b/sys/mips/alchemy/files.alchemy @@ -0,0 +1,7 @@ +# $FreeBSD$ +# Alchmy on-board devices +# mips/alchemy/console.c standard +mips/alchemy/alchemy_machdep.c standard +mips/alchemy/obio.c standard +mips/alchemy/uart_bus_alchemy.c optional uart +mips/alchemy/uart_cpu_alchemy.c optional uart diff --git a/sys/mips/alchemy/std.alchemy b/sys/mips/alchemy/std.alchemy new file mode 100644 index 00000000000..c06d02c979f --- /dev/null +++ b/sys/mips/alchemy/std.alchemy @@ -0,0 +1,10 @@ +# $FreeBSD$ +# Standard include file for Alchemy Au1xxx CPUs: +# Au1000, Au1200, Au1250, Au1500 and Au1550 + +files "../alchemy/files.alchemy" + +cpu CPU_MIPS4KC +options ISA_MIPS32 + +device uart diff --git a/sys/mips/alchemy/uart_bus_alchemy.c b/sys/mips/alchemy/uart_bus_alchemy.c new file mode 100644 index 00000000000..5c2315b8b7c --- /dev/null +++ b/sys/mips/alchemy/uart_bus_alchemy.c @@ -0,0 +1,87 @@ +/*- + * Copyright (c) 2007 Bruce M. Simpson. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * $Id$ + */ +/* + * Skeleton of this file was based on respective code for ARM + * code written by Olivier Houchard. + */ + +#include "opt_uart.h" + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include "uart_if.h" + +static int uart_alchemy_probe(device_t dev); + +static device_method_t uart_alchemy_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, uart_alchemy_probe), + DEVMETHOD(device_attach, uart_bus_attach), + DEVMETHOD(device_detach, uart_bus_detach), + { 0, 0 } +}; + +static driver_t uart_alchemy_driver = { + uart_driver_name, + uart_alchemy_methods, + sizeof(struct uart_softc), +}; + +extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; + +static int +uart_alchemy_probe(device_t dev) +{ + struct uart_softc *sc; + + sc = device_get_softc(dev); + sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); + sc->sc_class = &uart_ns8250_class; + bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); + + return (uart_bus_probe(dev, 0, 0, 0, 0)); +} + +DRIVER_MODULE(uart, obio, uart_alchemy_driver, uart_devclass, 0, 0); diff --git a/sys/mips/alchemy/uart_cpu_alchemy.c b/sys/mips/alchemy/uart_cpu_alchemy.c new file mode 100644 index 00000000000..931aed63126 --- /dev/null +++ b/sys/mips/alchemy/uart_cpu_alchemy.c @@ -0,0 +1,79 @@ +/*- + * Copyright (c) 2006 Wojciech A. Koszek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ +/* + * Skeleton of this file was based on respective code for ARM + * code written by Olivier Houchard. + */ + +#include "opt_uart.h" + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include + +#include +#include + +#include + +bus_space_tag_t uart_bus_space_io; +bus_space_tag_t uart_bus_space_mem; + +int +uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) +{ + + return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0); +} + +int +uart_cpu_getdev(int devtype, struct uart_devinfo *di) +{ + + di->ops = uart_getops(&uart_ns8250_class); + di->bas.chan = 0; + di->bas.bst = 0; + di->bas.regshft = 0; + di->bas.rclk = 0; + di->baudrate = 115200; + di->databits = 8; + di->stopbits = 1; + di->parity = UART_PARITY_NONE; + + uart_bus_space_io = 0; + uart_bus_space_mem = MIPS_PHYS_TO_KSEG1(UART0_BASE); + di->bas.bsh = MIPS_PHYS_TO_KSEG1(UART0_BASE); + + return (0); +} From 80c7df029fb598b81a93626b0fbddedf6bf0c406 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 20 Jan 2009 22:48:14 +0000 Subject: [PATCH 010/380] Au1xxx registers from NetBSD. Obtained from: NetBSD --- sys/mips/alchemy/aureg.h | 373 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 373 insertions(+) create mode 100644 sys/mips/alchemy/aureg.h diff --git a/sys/mips/alchemy/aureg.h b/sys/mips/alchemy/aureg.h new file mode 100644 index 00000000000..dfa21032763 --- /dev/null +++ b/sys/mips/alchemy/aureg.h @@ -0,0 +1,373 @@ +/* $NetBSD: aureg.h,v 1.18 2006/10/02 06:44:00 gdamore Exp $ */ + +/* + * Copyright 2002 Wasabi Systems, Inc. + * All rights reserved. + * + * Written by Simon Burge for Wasabi Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project by + * Wasabi Systems, Inc. + * 4. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _MIPS_ALCHEMY_AUREG_H +#define _MIPS_ALCHEMY_AUREG_H + +/************************************************************************/ +/******************** AC97 Controller registers *********************/ +/************************************************************************/ +#define AC97_BASE 0x10000000 + +/************************************************************************/ +/*********************** USB Host registers *************************/ +/************************************************************************/ +#define USBH_BASE 0x10100000 +#define AU1550_USBH_BASE 0x14020000 + +#define USBH_ENABLE 0x7fffc +#define USBH_SIZE 0x100000 + +#define AU1550_USBH_ENABLE 0x7ffc +#define AU1550_USBH_SIZE 0x60000 + +/************************************************************************/ +/********************** USB Device registers ************************/ +/************************************************************************/ +#define USBD_BASE 0x10200000 + +/************************************************************************/ +/************************* IRDA registers ***************************/ +/************************************************************************/ +#define IRDA_BASE 0x10300000 + +/************************************************************************/ +/****************** Interrupt Controller registers ******************/ +/************************************************************************/ + +#define IC0_BASE 0x10400000 +#define IC1_BASE 0x11800000 + +/* + * The *_READ registers read the current value of the register + * The *_SET registers set to 1 all bits that are written 1 + * The *_CLEAR registers clear to zero all bits that are written as 1 + */ +#define IC_CONFIG0_READ 0x40 /* See table below */ +#define IC_CONFIG0_SET 0x40 +#define IC_CONFIG0_CLEAR 0x44 + +#define IC_CONFIG1_READ 0x48 /* See table below */ +#define IC_CONFIG1_SET 0x48 +#define IC_CONFIG1_CLEAR 0x4c + +#define IC_CONFIG2_READ 0x50 /* See table below */ +#define IC_CONFIG2_SET 0x50 +#define IC_CONFIG2_CLEAR 0x54 + +#define IC_REQUEST0_INT 0x54 /* Show active interrupts on request 0 */ + +#define IC_SOURCE_READ 0x58 /* Interrupt source */ +#define IC_SOURCE_SET 0x58 /* 0 - test bit used as source */ +#define IC_SOURCE_CLEAR 0x5c /* 1 - peripheral/GPIO used as source */ + +#define IC_REQUEST1_INT 0x5c /* Show active interrupts on request 1 */ + +#define IC_ASSIGN_REQUEST_READ 0x60 /* Assigns the interrupt to one of the */ +#define IC_ASSIGN_REQUEST_SET 0x60 /* CPU requests (0 - assign to request 1, */ +#define IC_ASSIGN_REQUEST_CLEAR 0x64 /* 1 - assign to request 0) */ + +#define IC_WAKEUP_READ 0x68 /* Controls whether the interrupt can */ +#define IC_WAKEUP_SET 0x68 /* cause a wakeup from IDLE */ +#define IC_WAKEUP_CLEAR 0x6c + +#define IC_MASK_READ 0x70 /* Enables/Disables the interrupt */ +#define IC_MASK_SET 0x70 +#define IC_MASK_CLEAR 0x74 + +#define IC_RISING_EDGE 0x78 /* Check/clear rising edge */ + +#define IC_FALLING_EDGE 0x7c /* Check/clear falling edge */ + +#define IC_TEST_BIT 0x80 /* single bit source select */ + +/* + * Interrupt Configuration Register Functions + * + * Cfg2[n] Cfg1[n] Cfg0[n] Function + * 0 0 0 Interrupts Disabled + * 0 0 1 Rising Edge Enabled + * 0 1 0 Falling Edge Enabled + * 0 1 1 Rising and Falling Edge Enabled + * 1 0 0 Interrupts Disabled + * 1 0 1 High Level Enabled + * 1 1 0 Low Level Enabled + * 1 1 1 Both Levels and Both Edges Enabled + */ + +/************************************************************************/ +/************* Programable Serial Controller registers **************/ +/************************************************************************/ + +#define PSC0_BASE 0x11A00000 +#define PSC1_BASE 0x11B00000 +#define PSC2_BASE 0x10A00000 +#define PSC3_BASE 0x10B00000 + + +/************************************************************************/ +/********************** Ethernet MAC registers **********************/ +/************************************************************************/ + +#define MAC0_BASE 0x10500000 +#define MAC1_BASE 0x10510000 +#define MACx_SIZE 0x28 + +#define AU1500_MAC0_BASE 0x11500000 /* Grr, different on Au1500 */ +#define AU1500_MAC1_BASE 0x11510000 /* Grr, different on Au1500 */ + +#define MAC0_ENABLE 0x10520000 +#define MAC1_ENABLE 0x10520004 +#define MACENx_SIZE 0x04 + +#define AU1500_MAC0_ENABLE 0x11520000 /* Grr, different on Au1500 */ +#define AU1500_MAC1_ENABLE 0x11520004 /* Grr, different on Au1500 */ + +#define MAC0_DMA_BASE 0x14004000 +#define MAC1_DMA_BASE 0x14004200 +#define MACx_DMA_SIZE 0x140 + +/************************************************************************/ +/********************** Static Bus registers ************************/ +/************************************************************************/ +#define STATIC_BUS_BASE 0x14001000 + +/************************************************************************/ +/******************** Secure Digital registers **********************/ +/************************************************************************/ +#define SD0_BASE 0x10600000 +#define SD1_BASE 0x10680000 + +/************************************************************************/ +/************************* I^2S registers ***************************/ +/************************************************************************/ +#define I2S_BASE 0x11000000 + +/************************************************************************/ +/************************** UART registers **************************/ +/************************************************************************/ + +#define UART0_BASE 0x11100000 +#define UART1_BASE 0x11200000 +#define UART2_BASE 0x11300000 +#define UART3_BASE 0x11400000 + +/************************************************************************/ +/************************* SSI registers ****************************/ +/************************************************************************/ +#define SSI0_BASE 0x11600000 +#define SSI1_BASE 0x11680000 + +/************************************************************************/ +/************************ GPIO2 registers ***************************/ +/************************************************************************/ +#define GPIO_BASE 0x11900100 + +/************************************************************************/ +/************************ GPIO2 registers ***************************/ +/************************************************************************/ +#define GPIO2_BASE 0x11700000 + +/************************************************************************/ +/************************* PCI registers ****************************/ +/************************************************************************/ +#define PCI_BASE 0x14005000 +#define PCI_HEADER 0x14005100 +#define PCI_MEM_BASE 0x400000000ULL +#define PCI_IO_BASE 0x500000000ULL +#define PCI_CONFIG_BASE 0x600000000ULL + +/************************************************************************/ +/*********************** PCMCIA registers ***************************/ +/************************************************************************/ +#define PCMCIA_BASE 0xF00000000ULL + +/************************************************************************/ +/****************** Programmable Counter registers ******************/ +/************************************************************************/ + +#define SYS_BASE 0x11900000 + +#define PC_BASE SYS_BASE + +#define PC_TRIM0 0x00 /* PC0 Divide (16 bits) */ +#define PC_COUNTER_WRITE0 0x04 /* set PC0 */ +#define PC_MATCH0_0 0x08 /* match counter & interrupt */ +#define PC_MATCH1_0 0x0c /* match counter & interrupt */ +#define PC_MATCH2_0 0x10 /* match counter & interrupt */ +#define PC_COUNTER_CONTROL 0x14 /* Programmable Counter Control */ +#define CC_E1S 0x00800000 /* Enable PC1 write status */ +#define CC_T1S 0x00100000 /* Trim PC1 write status */ +#define CC_M21 0x00080000 /* Match 2 of PC1 write status */ +#define CC_M11 0x00040000 /* Match 1 of PC1 write status */ +#define CC_M01 0x00020000 /* Match 0 of PC1 write status */ +#define CC_C1S 0x00010000 /* PC1 write status */ +#define CC_BP 0x00004000 /* Bypass OSC (use GPIO1) */ +#define CC_EN1 0x00002000 /* Enable PC1 */ +#define CC_BT1 0x00001000 /* Bypass Trim on PC1 */ +#define CC_EN0 0x00000800 /* Enable PC0 */ +#define CC_BT0 0x00000400 /* Bypass Trim on PC0 */ +#define CC_EO 0x00000100 /* Enable Oscillator */ +#define CC_E0S 0x00000080 /* Enable PC0 write status */ +#define CC_32S 0x00000020 /* 32.768kHz OSC status */ +#define CC_T0S 0x00000010 /* Trim PC0 write status */ +#define CC_M20 0x00000008 /* Match 2 of PC0 write status */ +#define CC_M10 0x00000004 /* Match 1 of PC0 write status */ +#define CC_M00 0x00000002 /* Match 0 of PC0 write status */ +#define CC_C0S 0x00000001 /* PC0 write status */ +#define PC_COUNTER_READ_0 0x40 /* get PC0 */ +#define PC_TRIM1 0x44 /* PC1 Divide (16 bits) */ +#define PC_COUNTER_WRITE1 0x48 /* set PC1 */ +#define PC_MATCH0_1 0x4c /* match counter & interrupt */ +#define PC_MATCH1_1 0x50 /* match counter & interrupt */ +#define PC_MATCH2_1 0x54 /* match counter & interrupt */ +#define PC_COUNTER_READ_1 0x58 /* get PC1 */ + +#define PC_SIZE 0x5c /* size of register set */ +#define PC_RATE 32768 /* counter rate is 32.768kHz */ + +/************************************************************************/ +/******************* Frequency Generator Registers ******************/ +/************************************************************************/ + +#define SYS_FREQCTRL0 (SYS_BASE + 0x20) +#define SFC_FRDIV2(f) (f<<22) /* 29:22. Freq Divider 2 */ +#define SFC_FE2 (1<<21) /* Freq generator output enable 2 */ +#define SFC_FS2 (1<<20) /* Freq generator source 2 */ +#define SFC_FRDIV1(f) (f<<12) /* 19:12. Freq Divider 1 */ +#define SFC_FE1 (1<<11) /* Freq generator output enable 1 */ +#define SFC_FS1 (1<<10) /* Freq generator source 1 */ +#define SFC_FRDIV0(f) (f<<2) /* 9:2. Freq Divider 0 */ +#define SFC_FE0 2 /* Freq generator output enable 0 */ +#define SFC_FS0 1 /* Freq generator source 0 */ + +#define SYS_FREQCTRL1 (SYS_BASE + 0x24) +#define SFC_FRDIV5(f) (f<<22) /* 29:22. Freq Divider 5 */ +#define SFC_FE5 (1<<21) /* Freq generator output enable 5 */ +#define SFC_FS5 (1<<20) /* Freq generator source 5 */ +#define SFC_FRDIV4(f) (f<<12) /* 19:12. Freq Divider 4 */ +#define SFC_FE4 (1<<11) /* Freq generator output enable 4 */ +#define SFC_FS4 (1<<10) /* Freq generator source 4 */ +#define SFC_FRDIV3(f) (f<<2) /* 9:2. Freq Divider 3 */ +#define SFC_FE3 2 /* Freq generator output enable 3 */ +#define SFC_FS3 1 /* Freq generator source 3 */ + +/************************************************************************/ +/****************** Clock Source Control Registers ******************/ +/************************************************************************/ + +#define SYS_CLKSRC (SYS_BASE + 0x28) +#define SCS_ME1(n) (n<<27) /* EXTCLK1 Clock Mux input select */ +#define SCS_ME0(n) (n<<22) /* EXTCLK0 Clock Mux input select */ +#define SCS_MPC(n) (n<<17) /* PCI clock mux input select */ +#define SCS_MUH(n) (n<<12) /* USB Host clock mux input select */ +#define SCS_MUD(n) (n<<7) /* USB Device clock mux input select */ +#define SCS_MEx_AUX 0x1 /* Aux clock */ +#define SCS_MEx_FREQ0 0x2 /* FREQ0 */ +#define SCS_MEx_FREQ1 0x3 /* FREQ1 */ +#define SCS_MEx_FREQ2 0x4 /* FREQ2 */ +#define SCS_MEx_FREQ3 0x5 /* FREQ3 */ +#define SCS_MEx_FREQ4 0x6 /* FREQ4 */ +#define SCS_MEx_FREQ5 0x7 /* FREQ5 */ +#define SCS_DE1 (1<<26) /* EXTCLK1 clock divider select */ +#define SCS_CE1 (1<<25) /* EXTCLK1 clock select */ +#define SCS_DE0 (1<<21) /* EXTCLK0 clock divider select */ +#define SCS_CE0 (1<<20) /* EXTCLK0 clock select */ +#define SCS_DPC (1<<16) /* PCI clock divider select */ +#define SCS_CPC (1<<15) /* PCI clock select */ +#define SCS_DUH (1<<11) /* USB Host clock divider select */ +#define SCS_CUH (1<<10) /* USB Host clock select */ +#define SCS_DUD (1<<6) /* USB Device clock divider select */ +#define SCS_CUD (1<<5) /* USB Device clock select */ +/* + * Au1550 bits, needed for PSCs. Note that some bits collide with + * earlier parts. On Au1550, USB clocks (both device and host) are + * shared with PSC2, and must be configured for 48MHz. DBAU1550 YAMON + * does this by default. Also, EXTCLK0 is shared with PSC3. DBAU1550 + * YAMON does not configure any clocks besides PSC2. + */ +#define SCS_MP3(n) (n<<22) /* psc3_intclock mux */ +#define SCS_DP3 (1<<21) /* psc3_intclock divider */ +#define SCS_CP3 (1<<20) /* psc3_intclock select */ +#define SCS_MP1(n) (n<<12) /* psc1_intclock mux */ +#define SCS_DP1 (1<<11) /* psc1_intclock divider */ +#define SCS_CP1 (1<<10) /* psc1_intclock select */ +#define SCS_MP0(n) (n<<7) /* psc0_intclock mux */ +#define SCS_DP0 (1<<6) /* psc0_intclock divider */ +#define SCS_CP0 (1<<5) /* psc0_intclock seelct */ +#define SCS_MP2(n) (n<<2) /* psc2_intclock mux */ +#define SCS_DP2 (1<<1) /* psc2_intclock divider */ +#define SCS_CP2 (1<<0) /* psc2_intclock select */ + +/************************************************************************/ +/*************************** PIN Function *****************************/ +/************************************************************************/ + +#define SYS_PINFUNC (SYS_BASE + 0x2c) +#define SPF_PSC3_MASK (7<<20) +#define SPF_PSC3_AC97 (0<<17) /* select AC97/SPI */ +#define SPF_PSC3_I2S (1<<17) /* select I2S */ +#define SPF_PSC3_SMBUS (3<<17) /* select SMbus */ +#define SPF_PSC3_GPIO (7<<17) /* select gpio215:211 */ +#define SPF_PSC2_MASK (7<<17) +#define SPF_PSC2_AC97 (0<<17) /* select AC97/SPI */ +#define SPF_PSC2_I2S (1<<17) /* select I2S */ +#define SPF_PSC2_SMBUS (3<<17) /* select SMbus */ +#define SPF_PSC2_GPIO (7<<17) /* select gpio210:206*/ +#define SPF_CS (1<<16) /* extclk0 or 32kHz osc */ +#define SPF_USB (1<<15) /* host or device usb otg */ +#define SPF_U3T (1<<14) /* uart3 tx or gpio23 */ +#define SPF_U1R (1<<13) /* uart1 rx or gpio22 */ +#define SPF_U1T (1<<12) /* uart1 tx or gpio21 */ +#define SPF_EX1 (1<<10) /* gpio3 or extclk1 */ +#define SPF_EX0 (1<<9) /* gpio2 or extclk0/32kHz osc*/ +#define SPF_U3 (1<<7) /* gpio14:9 or uart3 */ +#define SPF_MBSa (1<<5) /* must be set */ +#define SPF_NI2 (1<<4) /* enet1 or gpio28:24 */ +#define SPF_U0 (1<<3) /* uart0 or gpio20 */ +#define SPF_MBSb (1<<2) /* must be set */ +#define SPF_S1 (1<<1) /* gpio17 or psc1_sync1 */ +#define SPF_S0 (1<<0) /* gpio16 or psc0_sync1 */ + +/************************************************************************/ +/*************************** PLL Control *****************************/ +/************************************************************************/ + +#define SYS_CPUPLL (SYS_BASE + 0x60) +#define SYS_AUXPLL (SYS_BASE + 0x64) + +#endif /* _MIPS_ALCHEMY_AUREG_H */ From 15ec9f628a0b7dfec02f32f32dc7d59462ef9957 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 20 Jan 2009 22:48:52 +0000 Subject: [PATCH 011/380] Dummy obio driver. --- sys/mips/alchemy/obio.c | 501 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 501 insertions(+) create mode 100644 sys/mips/alchemy/obio.c diff --git a/sys/mips/alchemy/obio.c b/sys/mips/alchemy/obio.c new file mode 100644 index 00000000000..03e098d42ba --- /dev/null +++ b/sys/mips/alchemy/obio.c @@ -0,0 +1,501 @@ +/* $NetBSD: obio.c,v 1.11 2003/07/15 00:25:05 lukem Exp $ */ + +/*- + * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc. + * All rights reserved. + * + * Written by Jason R. Thorpe for Wasabi Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project by + * Wasabi Systems, Inc. + * 4. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +/* MIPS HW interrupts of IRQ/FIQ respectively */ +#define ADM5120_INTR 0 +#define ADM5120_FAST_INTR 1 + +/* Interrupt levels */ +#define INTR_IRQ 0 +#define INTR_FIQ 1 + +int irq_priorities[NIRQS] = { + INTR_IRQ, /* flash */ + INTR_FIQ, /* uart0 */ + INTR_FIQ, /* uart1 */ + INTR_IRQ, /* ahci */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* admsw */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ +}; + + +#define REG_READ(o) *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1(ADM5120_BASE_ICU + (o))) +#define REG_WRITE(o,v) (REG_READ(o)) = (v) + +static int obio_activate_resource(device_t, device_t, int, int, + struct resource *); +static device_t obio_add_child(device_t, int, const char *, int); +static struct resource * + obio_alloc_resource(device_t, device_t, int, int *, u_long, + u_long, u_long, u_int); +static int obio_attach(device_t); +static int obio_deactivate_resource(device_t, device_t, int, int, + struct resource *); +static struct resource_list * + obio_get_resource_list(device_t, device_t); +static void obio_hinted_child(device_t, const char *, int); +static int obio_intr(void *); +static int obio_probe(device_t); +static int obio_release_resource(device_t, device_t, int, int, + struct resource *); +static int obio_setup_intr(device_t, device_t, struct resource *, int, + driver_filter_t *, driver_intr_t *, void *, void **); +static int obio_teardown_intr(device_t, device_t, struct resource *, + void *); + +static int +obio_probe(device_t dev) +{ + + return (0); +} + +static int +obio_attach(device_t dev) +{ + struct obio_softc *sc = device_get_softc(dev); + int rid; + + sc->oba_mem_rman.rm_type = RMAN_ARRAY; + sc->oba_mem_rman.rm_descr = "OBIO memeory"; + if (rman_init(&sc->oba_mem_rman) != 0 || + rman_manage_region(&sc->oba_mem_rman, OBIO_MEM_START, + OBIO_MEM_START + OBIO_MEM_SIZE) != 0) + panic("obio_attach: failed to set up I/O rman"); + + sc->oba_irq_rman.rm_type = RMAN_ARRAY; + sc->oba_irq_rman.rm_descr = "OBIO IRQ"; + + if (rman_init(&sc->oba_irq_rman) != 0 || + rman_manage_region(&sc->oba_irq_rman, 0, NIRQS-1) != 0) + panic("obio_attach: failed to set up IRQ rman"); + + /* Hook up our interrupt handler. */ + if ((sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, + ADM5120_INTR, ADM5120_INTR, 1, + RF_SHAREABLE | RF_ACTIVE)) == NULL) { + device_printf(dev, "unable to allocate IRQ resource\n"); + return (ENXIO); + } + + if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC, obio_intr, NULL, + sc, &sc->sc_ih))) { + device_printf(dev, + "WARNING: unable to register interrupt handler\n"); + return (ENXIO); + } + + /* Hook up our FAST interrupt handler. */ + if ((sc->sc_fast_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, + ADM5120_FAST_INTR, ADM5120_FAST_INTR, 1, + RF_SHAREABLE | RF_ACTIVE)) == NULL) { + device_printf(dev, "unable to allocate IRQ resource\n"); + return (ENXIO); + } + + if ((bus_setup_intr(dev, sc->sc_fast_irq, INTR_TYPE_MISC, obio_intr, + NULL, sc, &sc->sc_fast_ih))) { + device_printf(dev, + "WARNING: unable to register interrupt handler\n"); + return (ENXIO); + } + + /* disable all interrupts */ + REG_WRITE(ICU_ENABLE_REG, ICU_INT_MASK); + + bus_generic_probe(dev); + bus_enumerate_hinted_children(dev); + bus_generic_attach(dev); + + return (0); +} + +static struct resource * +obio_alloc_resource(device_t bus, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + struct obio_softc *sc = device_get_softc(bus); + struct obio_ivar *ivar = device_get_ivars(child); + struct resource *rv; + struct resource_list_entry *rle; + struct rman *rm; + int isdefault, needactivate, passthrough; + + isdefault = (start == 0UL && end == ~0UL && count == 1); + needactivate = flags & RF_ACTIVE; + passthrough = (device_get_parent(child) != bus); + rle = NULL; + + if (passthrough) + return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, + rid, start, end, count, flags)); + + /* + * If this is an allocation of the "default" range for a given RID, + * and we know what the resources for this device are (ie. they aren't + * maintained by a child bus), then work out the start/end values. + */ + if (isdefault) { + rle = resource_list_find(&ivar->resources, type, *rid); + if (rle == NULL) + return (NULL); + if (rle->res != NULL) { + panic("%s: resource entry is busy", __func__); + } + start = rle->start; + end = rle->end; + count = rle->count; + } + + switch (type) { + case SYS_RES_IRQ: + rm = &sc->oba_irq_rman; + break; + case SYS_RES_MEMORY: + rm = &sc->oba_mem_rman; + break; + default: + printf("%s: unknown resource type %d\n", __func__, type); + return (0); + } + + rv = rman_reserve_resource(rm, start, end, count, flags, child); + if (rv == 0) { + printf("%s: could not reserve resource\n", __func__); + return (0); + } + + rman_set_rid(rv, *rid); + + if (needactivate) { + if (bus_activate_resource(child, type, *rid, rv)) { + printf("%s: could not activate resource\n", __func__); + rman_release_resource(rv); + return (0); + } + } + + return (rv); +} + +static int +obio_activate_resource(device_t bus, device_t child, int type, int rid, + struct resource *r) +{ + + /* + * If this is a memory resource, track the direct mapping + * in the uncached MIPS KSEG1 segment. + */ + if (type == SYS_RES_MEMORY) { + void *vaddr; + + vaddr = (void *)MIPS_PHYS_TO_KSEG1((intptr_t)rman_get_start(r)); + rman_set_virtual(r, vaddr); + rman_set_bustag(r, MIPS_BUS_SPACE_MEM); + rman_set_bushandle(r, (bus_space_handle_t)vaddr); + } + + return (rman_activate_resource(r)); +} + +static int +obio_deactivate_resource(device_t bus, device_t child, int type, int rid, + struct resource *r) +{ + + return (rman_deactivate_resource(r)); +} + +static int +obio_release_resource(device_t dev, device_t child, int type, + int rid, struct resource *r) +{ + struct resource_list *rl; + struct resource_list_entry *rle; + + rl = obio_get_resource_list(dev, child); + if (rl == NULL) + return (EINVAL); + rle = resource_list_find(rl, type, rid); + if (rle == NULL) + return (EINVAL); + rman_release_resource(r); + rle->res = NULL; + + return (0); +} + +static int +obio_setup_intr(device_t dev, device_t child, struct resource *ires, + int flags, driver_filter_t *filt, driver_intr_t *handler, + void *arg, void **cookiep) +{ + struct obio_softc *sc = device_get_softc(dev); + struct intr_event *event; + int irq, error, priority; + uint32_t irqmask; + + irq = rman_get_start(ires); + + if (irq >= NIRQS) + panic("%s: bad irq %d", __func__, irq); + + event = sc->sc_eventstab[irq]; + if (event == NULL) { + error = intr_event_create(&event, (void *)irq, 0, irq, + (mask_fn)mips_mask_irq, (mask_fn)mips_unmask_irq, + NULL, NULL, "obio intr%d:", irq); + + sc->sc_eventstab[irq] = event; + } + else + panic("obio: Can't share IRQs"); + + intr_event_add_handler(event, device_get_nameunit(child), filt, + handler, arg, intr_priority(flags), flags, cookiep); + + irqmask = 1 << irq; + priority = irq_priorities[irq]; + + if (priority == INTR_FIQ) + REG_WRITE(ICU_MODE_REG, REG_READ(ICU_MODE_REG) | irqmask); + else + REG_WRITE(ICU_MODE_REG, REG_READ(ICU_MODE_REG) & ~irqmask); + + /* enable */ + REG_WRITE(ICU_ENABLE_REG, irqmask); + + return (0); +} + +static int +obio_teardown_intr(device_t dev, device_t child, struct resource *ires, + void *cookie) +{ + struct obio_softc *sc = device_get_softc(dev); + int irq, result; + uint32_t irqmask; + + irq = rman_get_start(ires); + if (irq >= NIRQS) + panic("%s: bad irq %d", __func__, irq); + + if (sc->sc_eventstab[irq] == NULL) + panic("Trying to teardown unoccupied IRQ"); + + irqmask = 1 << irq; /* only used as a mask from here on */ + + /* disable this irq in HW */ + REG_WRITE(ICU_DISABLE_REG, irqmask); + + result = intr_event_remove_handler(cookie); + if (!result) { + sc->sc_eventstab[irq] = NULL; + } + + return (result); +} + +static int +obio_intr(void *arg) +{ + struct obio_softc *sc = arg; + struct intr_event *event; + uint32_t irqstat; + int irq; + + irqstat = REG_READ(ICU_FIQ_STATUS_REG); + irqstat |= REG_READ(ICU_STATUS_REG); + + irq = 0; + while (irqstat != 0) { + if ((irqstat & 1) == 1) { + event = sc->sc_eventstab[irq]; + if (!event || TAILQ_EMPTY(&event->ie_handlers)) + continue; + + /* TODO: pass frame as an argument*/ + /* TODO: log stray interrupt */ + intr_event_handle(event, NULL); + } + + irq++; + irqstat >>= 1; + } + + return (FILTER_HANDLED); +} + +static void +obio_hinted_child(device_t bus, const char *dname, int dunit) +{ + device_t child; + long maddr; + int msize; + int irq; + int result; + + child = BUS_ADD_CHILD(bus, 0, dname, dunit); + + /* + * Set hard-wired resources for hinted child using + * specific RIDs. + */ + resource_long_value(dname, dunit, "maddr", &maddr); + resource_int_value(dname, dunit, "msize", &msize); + + + result = bus_set_resource(child, SYS_RES_MEMORY, 0, + maddr, msize); + if (result != 0) + device_printf(bus, "warning: bus_set_resource() failed\n"); + + if (resource_int_value(dname, dunit, "irq", &irq) == 0) { + result = bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1); + if (result != 0) + device_printf(bus, + "warning: bus_set_resource() failed\n"); + } +} + +static device_t +obio_add_child(device_t bus, int order, const char *name, int unit) +{ + device_t child; + struct obio_ivar *ivar; + + ivar = malloc(sizeof(struct obio_ivar), M_DEVBUF, M_WAITOK | M_ZERO); + if (ivar == NULL) { + printf("Failed to allocate ivar\n"); + return (0); + } + resource_list_init(&ivar->resources); + + child = device_add_child_ordered(bus, order, name, unit); + if (child == NULL) { + printf("Can't add child %s%d ordered\n", name, unit); + return (0); + } + + device_set_ivars(child, ivar); + + return (child); +} + +/* + * Helper routine for bus_generic_rl_get_resource/bus_generic_rl_set_resource + * Provides pointer to resource_list for these routines + */ +static struct resource_list * +obio_get_resource_list(device_t dev, device_t child) +{ + struct obio_ivar *ivar; + + ivar = device_get_ivars(child); + return (&(ivar->resources)); +} + +static device_method_t obio_methods[] = { + DEVMETHOD(bus_activate_resource, obio_activate_resource), + DEVMETHOD(bus_add_child, obio_add_child), + DEVMETHOD(bus_alloc_resource, obio_alloc_resource), + DEVMETHOD(bus_deactivate_resource, obio_deactivate_resource), + DEVMETHOD(bus_get_resource_list, obio_get_resource_list), + DEVMETHOD(bus_hinted_child, obio_hinted_child), + DEVMETHOD(bus_release_resource, obio_release_resource), + DEVMETHOD(bus_setup_intr, obio_setup_intr), + DEVMETHOD(bus_teardown_intr, obio_teardown_intr), + DEVMETHOD(device_attach, obio_attach), + DEVMETHOD(device_probe, obio_probe), + DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), + DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), + + {0, 0}, +}; + +static driver_t obio_driver = { + "obio", + obio_methods, + sizeof(struct obio_softc), +}; +static devclass_t obio_devclass; + +DRIVER_MODULE(obio, nexus, obio_driver, obio_devclass, 0, 0); From 34eb00b1446df80b7adb1a1b5809fd8e65c55a5a Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 21 Jan 2009 05:49:30 +0000 Subject: [PATCH 012/380] - Check if maddr/msize hints are there before setting hinted resources to device - Check for irq hint too --- sys/mips/mips/nexus.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/sys/mips/mips/nexus.c b/sys/mips/mips/nexus.c index 64cba66d181..e96eeab34ff 100644 --- a/sys/mips/mips/nexus.c +++ b/sys/mips/mips/nexus.c @@ -249,6 +249,8 @@ nexus_hinted_child(device_t bus, const char *dname, int dunit) long maddr; int msize; int result; + int irq; + int mem_hints_count; child = BUS_ADD_CHILD(bus, 0, dname, dunit); @@ -256,17 +258,34 @@ nexus_hinted_child(device_t bus, const char *dname, int dunit) * Set hard-wired resources for hinted child using * specific RIDs. */ - resource_long_value(dname, dunit, "maddr", &maddr); - resource_int_value(dname, dunit, "msize", &msize); + mem_hints_count = 0; + if (resource_long_value(dname, dunit, "maddr", &maddr) == 0) + mem_hints_count++; + if (resource_int_value(dname, dunit, "msize", &msize) == 0) + mem_hints_count++; - dprintf("%s: discovered hinted child %s at maddr %p(%d)\n", - __func__, device_get_nameunit(child), - (void *)(intptr_t)maddr, msize); + /* check if all info for mem resource has been provided */ + if ((mem_hints_count > 0) && (mem_hints_count < 2)) { + printf("Either maddr or msize hint is missing for %s%d\n", + dname, dunit); + } else if (mem_hints_count) { + dprintf("%s: discovered hinted child %s at maddr %p(%d)\n", + __func__, device_get_nameunit(child), + (void *)(intptr_t)maddr, msize); - result = bus_set_resource(child, SYS_RES_MEMORY, MIPS_MEM_RID, - maddr, msize); - if (result != 0) { - device_printf(bus, "warning: bus_set_resource() failed\n"); + result = bus_set_resource(child, SYS_RES_MEMORY, MIPS_MEM_RID, + maddr, msize); + if (result != 0) { + device_printf(bus, + "warning: bus_set_resource() failed\n"); + } + } + + if (resource_int_value(dname, dunit, "irq", &irq) == 0) { + result = bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1); + if (result != 0) + device_printf(bus, + "warning: bus_set_resource() failed\n"); } } From 3eeb7260ff13ea65ba98af11c5e954ac0f891b2f Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 21 Jan 2009 05:52:30 +0000 Subject: [PATCH 013/380] - Use ATH_READ_REG/ATH_WRITE_REG instead of direct memory access --- sys/mips/atheros/ar71xx_machdep.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sys/mips/atheros/ar71xx_machdep.c b/sys/mips/atheros/ar71xx_machdep.c index 9aee3bb5e3e..74ba0a17fb4 100644 --- a/sys/mips/atheros/ar71xx_machdep.c +++ b/sys/mips/atheros/ar71xx_machdep.c @@ -72,11 +72,9 @@ platform_identify(void) void platform_reset(void) { - volatile uint32_t * p = - (void *)MIPS_PHYS_TO_KSEG1(ATH_RST_RESET); - uint32_t reg = *p; + uint32_t reg = ATH_READ_REG(APB_RST_RESET); - *p = reg | RST_RESET_FULL_CHIP_RESET; + ATH_WRITE_REG(APB_RST_RESET, reg | RST_RESET_FULL_CHIP_RESET); /* Wait for reset */ while(1) ; From a1cbd4c2143b4024985a23f18ba97576c4ee882d Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 21 Jan 2009 05:54:00 +0000 Subject: [PATCH 014/380] - Add newbus uart driver implementation --- sys/mips/atheros/uart_bus_ar71xx.c | 79 ++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 sys/mips/atheros/uart_bus_ar71xx.c diff --git a/sys/mips/atheros/uart_bus_ar71xx.c b/sys/mips/atheros/uart_bus_ar71xx.c new file mode 100644 index 00000000000..1cb611ce092 --- /dev/null +++ b/sys/mips/atheros/uart_bus_ar71xx.c @@ -0,0 +1,79 @@ +/*- + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + */ +#include "opt_uart.h" + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include "uart_if.h" + +static int uart_ar71xx_probe(device_t dev); +extern struct uart_class uart_ar71xx_uart_class; + +static device_method_t uart_ar71xx_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, uart_ar71xx_probe), + DEVMETHOD(device_attach, uart_bus_attach), + DEVMETHOD(device_detach, uart_bus_detach), + { 0, 0 } +}; + +static driver_t uart_ar71xx_driver = { + uart_driver_name, + uart_ar71xx_methods, + sizeof(struct uart_softc), +}; + +extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; + +static int +uart_ar71xx_probe(device_t dev) +{ + struct uart_softc *sc; + + sc = device_get_softc(dev); + sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); + sc->sc_class = &uart_ns8250_class; + bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); + + return (uart_bus_probe(dev, 2, 85000000, 0, 0)); +} + +DRIVER_MODULE(uart, apb, uart_ar71xx_driver, uart_devclass, 0, 0); From 1c5953e278eed346d1e90a9ee4429207c2377ca1 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 21 Jan 2009 06:17:01 +0000 Subject: [PATCH 015/380] - Change register/bitnumber/masks naming convention (again) o For register names use AR71XX_REGISTER_NAME (prefix varies depending on platform AR71XX/AR91XX/... Yes, let's hope other families are on their way to tree, they call it positive thinking) o For bit number use REGISTER_NAME_FIELD_NAME o For field mask use REGISTER_NAME_FIELD_NAME_MASK --- sys/mips/atheros/ar71xxreg.h | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/sys/mips/atheros/ar71xxreg.h b/sys/mips/atheros/ar71xxreg.h index f6ccdb7903f..91d162db613 100644 --- a/sys/mips/atheros/ar71xxreg.h +++ b/sys/mips/atheros/ar71xxreg.h @@ -32,25 +32,24 @@ #define ATH_WRITE_REG(reg, val) \ *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((reg))) = (val) -#define ATH_UART_ADDR 0x18020000 +#define AR71XX_UART_ADDR 0x18020000 /* APB registers */ /* * APB interrupt status and mask register and interrupt bit numbers for */ -#define ATH_MISC_INTR_STATUS 0x18060010 -#define ATH_MISC_INTR_MASK 0x18060014 -#define ATH_INT_MISC_TIMER 0 -#define ATH_INT_MISC_ERROR 1 -#define ATH_INT_MISC_GPIO 2 -#define ATH_INT_MISC_UART 3 -#define ATH_INT_MISC_WATCHDOG 4 -#define ATH_INT_MISC_PERF 5 -#define ATH_INT_MISC_OHCI 6 -#define ATH_INT_MISC_DMA 7 +#define AR71XX_MISC_INTR_STATUS 0x18060010 +#define AR71XX_MISC_INTR_MASK 0x18060014 +#define MISC_INTR_TIMER 0 +#define MISC_INTR_ERROR 1 +#define MISC_INTR_GPIO 2 +#define MISC_INTR_UART 3 +#define MISC_INTR_WATCHDOG 4 +#define MISC_INTR_PERF 5 +#define MISC_INTR_OHCI 6 +#define MISC_INTR_DMA 7 - -#define ATH_RST_RESET 0x18060024 +#define AR71XX_RST_RESET 0x18060024 #define RST_RESET_CPU_COLD_RESET (1 << 20) /* Cold reset */ #define RST_RESET_FULL_CHIP_RESET (1 << 24) /* Same as pulling the reset pin */ From 6ccd3c9a8a216ff9f841fe8b0509e280966c0b4f Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 21 Jan 2009 06:20:56 +0000 Subject: [PATCH 016/380] - Use new register naming convention - Properly initialize bus_space tags for uart --- sys/mips/atheros/uart_cpu_ar71xx.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/sys/mips/atheros/uart_cpu_ar71xx.c b/sys/mips/atheros/uart_cpu_ar71xx.c index 97cb1293d9d..4d6b7e79ed1 100644 --- a/sys/mips/atheros/uart_cpu_ar71xx.c +++ b/sys/mips/atheros/uart_cpu_ar71xx.c @@ -54,7 +54,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) { di->ops = uart_getops(&uart_ns8250_class); di->bas.chan = 0; - di->bas.bst = 0; + di->bas.bst = MIPS_BUS_SPACE_MEM; di->bas.regshft = 2; /* TODO: calculate proper AHB freq using PLL registers */ di->bas.rclk = 85000000; @@ -63,9 +63,16 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) di->stopbits = 1; di->parity = UART_PARITY_NONE; - /* Bad MIPS, no IO for MIPS */ - uart_bus_space_io = 0; - uart_bus_space_mem = MIPS_PHYS_TO_KSEG1(ATH_UART_ADDR) + 3; - di->bas.bsh = MIPS_PHYS_TO_KSEG1(ATH_UART_ADDR) + 3; + /* TODO: check if uart_bus_space_io mandatory to set */ + uart_bus_space_io = MIPS_BUS_SPACE_IO; + uart_bus_space_mem = MIPS_BUS_SPACE_MEM; + /* + * FIXME: + * 3 is to compensate big endian, uart operates + * with bus_space_read_1/bus_space_write_1 and hence gets + * highest byte instead of lowest one. Actual fix will involve + * MIPS bus_space fixing. + */ + di->bas.bsh = MIPS_PHYS_TO_KSEG1(AR71XX_UART_ADDR) + 3; return (0); } From fa79281fa8f22652990ea33de5b190f0f1e395ab Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 21 Jan 2009 06:26:22 +0000 Subject: [PATCH 017/380] - Add apb device. apb is bridge that connects UART, GPIO, I2S and PCM to main bus - Connect apb and uart_bus to build --- sys/mips/atheros/apb.c | 424 ++++++++++++++++++++++++++++++++++ sys/mips/atheros/apbvar.h | 52 +++++ sys/mips/atheros/files.ar71xx | 2 + 3 files changed, 478 insertions(+) create mode 100644 sys/mips/atheros/apb.c create mode 100644 sys/mips/atheros/apbvar.h diff --git a/sys/mips/atheros/apb.c b/sys/mips/atheros/apb.c new file mode 100644 index 00000000000..f1393423387 --- /dev/null +++ b/sys/mips/atheros/apb.c @@ -0,0 +1,424 @@ +/*- + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +static int apb_activate_resource(device_t, device_t, int, int, + struct resource *); +static device_t apb_add_child(device_t, int, const char *, int); +static struct resource * + apb_alloc_resource(device_t, device_t, int, int *, u_long, + u_long, u_long, u_int); +static int apb_attach(device_t); +static int apb_deactivate_resource(device_t, device_t, int, int, + struct resource *); +static struct resource_list * + apb_get_resource_list(device_t, device_t); +static void apb_hinted_child(device_t, const char *, int); +static int apb_intr(void *); +static int apb_probe(device_t); +static int apb_release_resource(device_t, device_t, int, int, + struct resource *); +static int apb_setup_intr(device_t, device_t, struct resource *, int, + driver_filter_t *, driver_intr_t *, void *, void **); +static int apb_teardown_intr(device_t, device_t, struct resource *, + void *); + +static void apb_mask_irq(unsigned int irq) +{ + uint32_t reg; + + reg = ATH_READ_REG(AR71XX_MISC_INTR_MASK); + ATH_WRITE_REG(AR71XX_MISC_INTR_MASK, reg & ~(1 << irq)); + +} + +static void apb_unmask_irq(unsigned int irq) +{ + uint32_t reg; + + reg = ATH_READ_REG(AR71XX_MISC_INTR_MASK); + ATH_WRITE_REG(AR71XX_MISC_INTR_MASK, reg | (1 << irq)); +} + +static int +apb_probe(device_t dev) +{ + + return (0); +} + +static int +apb_attach(device_t dev) +{ + struct apb_softc *sc = device_get_softc(dev); + int rid = 0; + + device_set_desc(dev, "APB Bus bridge"); + sc->apb_mem_rman.rm_type = RMAN_ARRAY; + sc->apb_mem_rman.rm_descr = "APB memory"; + if (rman_init(&sc->apb_mem_rman) != 0 || + rman_manage_region(&sc->apb_mem_rman, APB_MEM_START, + APB_MEM_END) != 0) + panic("apb_attach: failed to set up I/O rman"); + + sc->apb_irq_rman.rm_type = RMAN_ARRAY; + sc->apb_irq_rman.rm_descr = "APB IRQ"; + + if (rman_init(&sc->apb_irq_rman) != 0 || + rman_manage_region(&sc->apb_irq_rman, + APB_IRQ_BASE, APB_IRQ_END) != 0) + panic("apb_attach: failed to set up IRQ rman"); + + if ((sc->sc_misc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_SHAREABLE | RF_ACTIVE)) == NULL) { + device_printf(dev, "unable to allocate IRQ resource\n"); + return (ENXIO); + } + + if ((bus_setup_intr(dev, sc->sc_misc_irq, INTR_TYPE_MISC, + apb_intr, NULL, sc, &sc->sc_misc_ih))) { + device_printf(dev, + "WARNING: unable to register interrupt handler\n"); + return (ENXIO); + } + + bus_generic_probe(dev); + bus_enumerate_hinted_children(dev); + bus_generic_attach(dev); + + return (0); +} + +static struct resource * +apb_alloc_resource(device_t bus, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + struct apb_softc *sc = device_get_softc(bus); + struct apb_ivar *ivar = device_get_ivars(child); + struct resource *rv; + struct resource_list_entry *rle; + struct rman *rm; + int isdefault, needactivate, passthrough; + + isdefault = (start == 0UL && end == ~0UL); + needactivate = flags & RF_ACTIVE; + passthrough = (device_get_parent(child) != bus); + rle = NULL; + + if (passthrough) + return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, + rid, start, end, count, flags)); + + /* + * If this is an allocation of the "default" range for a given RID, + * and we know what the resources for this device are (ie. they aren't + * maintained by a child bus), then work out the start/end values. + */ + + if (isdefault) { + rle = resource_list_find(&ivar->resources, type, *rid); + if (rle == NULL) { + return (NULL); + } + + if (rle->res != NULL) { + panic("%s: resource entry is busy", __func__); + } + start = rle->start; + end = rle->end; + count = rle->count; + } + + switch (type) { + case SYS_RES_IRQ: + rm = &sc->apb_irq_rman; + break; + case SYS_RES_MEMORY: + rm = &sc->apb_mem_rman; + break; + default: + printf("%s: unknown resource type %d\n", __func__, type); + return (0); + } + + rv = rman_reserve_resource(rm, start, end, count, flags, child); + if (rv == 0) { + printf("%s: could not reserve resource\n", __func__); + return (0); + } + + rman_set_rid(rv, *rid); + + if (needactivate) { + if (bus_activate_resource(child, type, *rid, rv)) { + printf("%s: could not activate resource\n", __func__); + rman_release_resource(rv); + return (0); + } + } + + return (rv); +} + +static int +apb_activate_resource(device_t bus, device_t child, int type, int rid, + struct resource *r) +{ + + /* XXX: should we mask/unmask IRQ here? */ + return (BUS_ACTIVATE_RESOURCE(device_get_parent(bus), child, + type, rid, r)); +} + +static int +apb_deactivate_resource(device_t bus, device_t child, int type, int rid, + struct resource *r) +{ + + /* XXX: should we mask/unmask IRQ here? */ + return (BUS_DEACTIVATE_RESOURCE(device_get_parent(bus), child, + type, rid, r)); +} + +static int +apb_release_resource(device_t dev, device_t child, int type, + int rid, struct resource *r) +{ + struct resource_list *rl; + struct resource_list_entry *rle; + + rl = apb_get_resource_list(dev, child); + if (rl == NULL) + return (EINVAL); + rle = resource_list_find(rl, type, rid); + if (rle == NULL) + return (EINVAL); + rman_release_resource(r); + rle->res = NULL; + + return (0); +} + +static int +apb_setup_intr(device_t bus, device_t child, struct resource *ires, + int flags, driver_filter_t *filt, driver_intr_t *handler, + void *arg, void **cookiep) +{ + struct apb_softc *sc = device_get_softc(bus); + struct intr_event *event; + int irq, error; + + irq = rman_get_start(ires); + + if (irq > APB_IRQ_END) + panic("%s: bad irq %d", __func__, irq); + + event = sc->sc_eventstab[irq]; + if (event == NULL) { + error = intr_event_create(&event, (void *)irq, 0, irq, + (mask_fn)apb_mask_irq, (mask_fn)apb_unmask_irq, + NULL, NULL, + "apb intr%d:", irq); + + sc->sc_eventstab[irq] = event; + } + + intr_event_add_handler(event, device_get_nameunit(child), filt, + handler, arg, intr_priority(flags), flags, cookiep); + + return (0); +} + +static int +apb_teardown_intr(device_t dev, device_t child, struct resource *ires, + void *cookie) +{ + struct apb_softc *sc = device_get_softc(dev); + int irq, result; + + irq = rman_get_start(ires); + if (irq > APB_IRQ_END) + panic("%s: bad irq %d", __func__, irq); + + if (sc->sc_eventstab[irq] == NULL) + panic("Trying to teardown unoccupied IRQ"); + + apb_mask_irq(irq); + + result = intr_event_remove_handler(cookie); + if (!result) + sc->sc_eventstab[irq] = NULL; + + return (result); +} + +static int +apb_intr(void *arg) +{ + struct apb_softc *sc = arg; + struct intr_event *event; + uint32_t reg, irq; + + reg = ATH_READ_REG(AR71XX_MISC_INTR_STATUS); + for (irq = 0; irq < APB_NIRQS; irq++) { + if (reg & (1 << irq)) { + event = sc->sc_eventstab[irq]; + if (!event || TAILQ_EMPTY(&event->ie_handlers)) { + printf("Stray IRQ %d\n", irq); + continue; + } + + /* TODO: frame instead of NULL? */ + intr_event_handle(event, NULL); + } + } + + return (FILTER_HANDLED); +} + +static void +apb_hinted_child(device_t bus, const char *dname, int dunit) +{ + device_t child; + long maddr; + int msize; + int irq; + int result; + int mem_hints_count; + + child = BUS_ADD_CHILD(bus, 0, dname, dunit); + + /* + * Set hard-wired resources for hinted child using + * specific RIDs. + */ + mem_hints_count = 0; + if (resource_long_value(dname, dunit, "maddr", &maddr) == 0) + mem_hints_count++; + if (resource_int_value(dname, dunit, "msize", &msize) == 0) + mem_hints_count++; + + /* check if all info for mem resource has been provided */ + if ((mem_hints_count > 0) && (mem_hints_count < 2)) { + printf("Either maddr or msize hint is missing for %s%d\n", + dname, dunit); + } else if (mem_hints_count) { + result = bus_set_resource(child, SYS_RES_MEMORY, 0, + maddr, msize); + if (result != 0) + device_printf(bus, + "warning: bus_set_resource() failed\n"); + } + + if (resource_int_value(dname, dunit, "irq", &irq) == 0) { + result = bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1); + if (result != 0) + device_printf(bus, + "warning: bus_set_resource() failed\n"); + } +} + +static device_t +apb_add_child(device_t bus, int order, const char *name, int unit) +{ + device_t child; + struct apb_ivar *ivar; + + ivar = malloc(sizeof(struct apb_ivar), M_DEVBUF, M_WAITOK | M_ZERO); + if (ivar == NULL) { + printf("Failed to allocate ivar\n"); + return (0); + } + resource_list_init(&ivar->resources); + + child = device_add_child_ordered(bus, order, name, unit); + if (child == NULL) { + printf("Can't add child %s%d ordered\n", name, unit); + return (0); + } + + device_set_ivars(child, ivar); + + return (child); +} + +/* + * Helper routine for bus_generic_rl_get_resource/bus_generic_rl_set_resource + * Provides pointer to resource_list for these routines + */ +static struct resource_list * +apb_get_resource_list(device_t dev, device_t child) +{ + struct apb_ivar *ivar; + + ivar = device_get_ivars(child); + return (&(ivar->resources)); +} + +static device_method_t apb_methods[] = { + DEVMETHOD(bus_activate_resource, apb_activate_resource), + DEVMETHOD(bus_add_child, apb_add_child), + DEVMETHOD(bus_alloc_resource, apb_alloc_resource), + DEVMETHOD(bus_deactivate_resource, apb_deactivate_resource), + DEVMETHOD(bus_get_resource_list, apb_get_resource_list), + DEVMETHOD(bus_hinted_child, apb_hinted_child), + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_release_resource, apb_release_resource), + DEVMETHOD(bus_setup_intr, apb_setup_intr), + DEVMETHOD(bus_teardown_intr, apb_teardown_intr), + DEVMETHOD(device_attach, apb_attach), + DEVMETHOD(device_probe, apb_probe), + DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), + DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), + + {0, 0}, +}; + +static driver_t apb_driver = { + "apb", + apb_methods, + sizeof(struct apb_softc), +}; +static devclass_t apb_devclass; + +DRIVER_MODULE(apb, nexus, apb_driver, apb_devclass, 0, 0); diff --git a/sys/mips/atheros/apbvar.h b/sys/mips/atheros/apbvar.h new file mode 100644 index 00000000000..5ffdfd43e38 --- /dev/null +++ b/sys/mips/atheros/apbvar.h @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _APBVAR_H_ +#define _APBVAR_H_ + +#define APB_MEM_START 0x18000000 +#define APB_MEM_END 0x18ffffff + +#define APB_IRQ_BASE 0 +#define APB_IRQ_END 7 +#define APB_NIRQS 8 + +struct apb_softc { + struct rman apb_mem_rman; + struct rman apb_irq_rman; + /* IRQ events structs for child devices */ + struct intr_event *sc_eventstab[APB_NIRQS]; + /* Resources and cookies for MIPS CPU INTs */ + struct resource *sc_misc_irq; + void *sc_misc_ih; +}; + +struct apb_ivar { + struct resource_list resources; +}; + +#endif /* _APBVAR_H_ */ diff --git a/sys/mips/atheros/files.ar71xx b/sys/mips/atheros/files.ar71xx index 14e7f9c471e..174043b2682 100644 --- a/sys/mips/atheros/files.ar71xx +++ b/sys/mips/atheros/files.ar71xx @@ -1,4 +1,6 @@ # $FreeBSD$ mips/atheros/ar71xx_machdep.c standard +mips/atheros/apb.c standard +mips/atheros/uart_bus_ar71xx.c optional uart mips/atheros/uart_cpu_ar71xx.c optional uart From 07a28a812004780e4ac76b4175b9319fe5f2a83a Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 21 Jan 2009 06:29:41 +0000 Subject: [PATCH 018/380] - Forgot to add this file to r187515 --- sys/mips/atheros/ar71xx_machdep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/mips/atheros/ar71xx_machdep.c b/sys/mips/atheros/ar71xx_machdep.c index 74ba0a17fb4..33ae7ddec16 100644 --- a/sys/mips/atheros/ar71xx_machdep.c +++ b/sys/mips/atheros/ar71xx_machdep.c @@ -72,9 +72,9 @@ platform_identify(void) void platform_reset(void) { - uint32_t reg = ATH_READ_REG(APB_RST_RESET); + uint32_t reg = ATH_READ_REG(AR71XX_RST_RESET); - ATH_WRITE_REG(APB_RST_RESET, reg | RST_RESET_FULL_CHIP_RESET); + ATH_WRITE_REG(AR71XX_RST_RESET, reg | RST_RESET_FULL_CHIP_RESET); /* Wait for reset */ while(1) ; From 8efb13fc48198a809602497c0c845baec485c8de Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 21 Jan 2009 06:30:53 +0000 Subject: [PATCH 019/380] - Add apb and uart hints for AR71XX kernel --- sys/mips/conf/AR71XX | 1 + sys/mips/conf/AR71XX.hints | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 sys/mips/conf/AR71XX.hints diff --git a/sys/mips/conf/AR71XX b/sys/mips/conf/AR71XX index a373fb93613..c655f990f98 100644 --- a/sys/mips/conf/AR71XX +++ b/sys/mips/conf/AR71XX @@ -10,6 +10,7 @@ makeoptions TARGET_BIG_ENDIAN makeoptions KERNLOADADDR=0x80050000 files "../atheros/files.ar71xx" +hints "AR71XX.hints" makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols makeoptions MODULES_OVERRIDE="" diff --git a/sys/mips/conf/AR71XX.hints b/sys/mips/conf/AR71XX.hints new file mode 100644 index 00000000000..821ee0c7cef --- /dev/null +++ b/sys/mips/conf/AR71XX.hints @@ -0,0 +1,12 @@ +# $FreeBSD$ +hint.apb.0.at="nexus0" +hint.apb.0.maddr=0x18000000 +hint.apb.0.msize=0x01000000 +hint.apb.0.irq=4 + +# uart0 +hint.uart.0.at="apb0" +# see atheros/uart_cpu_ar71xx.c why +3 +hint.uart.0.maddr=0x18020003 +hint.uart.0.msize=0x18 +hint.uart.0.irq=3 From a43957fea2a1e31efa4cd816d3d292fb4ff04793 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 26 Jan 2009 06:13:09 +0000 Subject: [PATCH 020/380] - Rename RESET-related registers - Add PCI registers --- sys/mips/atheros/ar71xx_machdep.c | 2 +- sys/mips/atheros/ar71xxreg.h | 80 +++++++++++++++++++++++++++++-- 2 files changed, 77 insertions(+), 5 deletions(-) diff --git a/sys/mips/atheros/ar71xx_machdep.c b/sys/mips/atheros/ar71xx_machdep.c index 33ae7ddec16..eac159a83a2 100644 --- a/sys/mips/atheros/ar71xx_machdep.c +++ b/sys/mips/atheros/ar71xx_machdep.c @@ -74,7 +74,7 @@ platform_reset(void) { uint32_t reg = ATH_READ_REG(AR71XX_RST_RESET); - ATH_WRITE_REG(AR71XX_RST_RESET, reg | RST_RESET_FULL_CHIP_RESET); + ATH_WRITE_REG(AR71XX_RST_RESET, reg | RST_RESET_FULL_CHIP); /* Wait for reset */ while(1) ; diff --git a/sys/mips/atheros/ar71xxreg.h b/sys/mips/atheros/ar71xxreg.h index 91d162db613..825a9461c71 100644 --- a/sys/mips/atheros/ar71xxreg.h +++ b/sys/mips/atheros/ar71xxreg.h @@ -32,9 +32,75 @@ #define ATH_WRITE_REG(reg, val) \ *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((reg))) = (val) -#define AR71XX_UART_ADDR 0x18020000 +/* PCI region */ +#define AR71XX_PCI_MEM_BASE 0x10000000 +/* + * PCI mem windows is 0x08000000 bytes long but we exclude control + * region from the resource manager + */ +#define AR71XX_PCI_MEM_SIZE 0x07000000 +#define AR71XX_PCI_IRQ_START 0 +#define AR71XX_PCI_IRQ_END 2 + +/* PCI config registers */ +#define AR71XX_PCI_LCONF_CMD 0x17010000 +#define PCI_LCONF_CMD_READ 0x00000000 +#define PCI_LCONF_CMD_WRITE 0x00010000 +#define AR71XX_PCI_LCONF_WRITE_DATA 0x17010004 +#define AR71XX_PCI_LCONF_READ_DATA 0x17010008 +#define AR71XX_PCI_CONF_ADDR 0x1701000C +#define AR71XX_PCI_CONF_CMD 0x17010010 +#define PCI_CONF_CMD_READ 0x0000000A +#define PCI_CONF_CMD_WRITE 0x0000000B +#define AR71XX_PCI_CONF_WRITE_DATA 0x17010014 +#define AR71XX_PCI_CONF_READ_DATA 0x17010018 +#define AR71XX_PCI_ERROR 0x1701001C +#define AR71XX_PCI_ERROR_ADDR 0x17010020 +#define AR71XX_PCI_AHB_ERROR 0x17010024 +#define AR71XX_PCI_AHB_ERROR_ADDR 0x17010028 + +/* APB region */ +/* DDR registers */ +#define AR71XX_DDR_CONFIG 0x18000000 +#define AR71XX_DDR_CONFIG2 0x18000004 +#define AR71XX_DDR_MODE_REGISTER 0x18000008 +#define AR71XX_DDR_EXT_MODE_REGISTER 0x1800000C +#define AR71XX_DDR_CONTROL 0x18000010 +#define AR71XX_DDR_REFRESH 0x18000014 +#define AR71XX_DDR_RD_DATA_THIS_CYCLE 0x18000018 +#define AR71XX_TAP_CONTROL0 0x1800001C +#define AR71XX_TAP_CONTROL1 0x18000020 +#define AR71XX_TAP_CONTROL2 0x18000024 +#define AR71XX_TAP_CONTROL3 0x18000028 +#define AR71XX_PCI_WINDOW0 0x1800007C +#define AR71XX_PCI_WINDOW1 0x18000080 +#define AR71XX_PCI_WINDOW2 0x18000084 +#define AR71XX_PCI_WINDOW3 0x18000088 +#define AR71XX_PCI_WINDOW4 0x1800008C +#define AR71XX_PCI_WINDOW5 0x18000090 +#define AR71XX_PCI_WINDOW6 0x18000094 +#define AR71XX_PCI_WINDOW7 0x18000098 +#define AR71XX_WB_FLUSH_GE0 0x1800009C +#define AR71XX_WB_FLUSH_GE1 0x180000A0 +#define AR71XX_WB_FLUSH_USB 0x180000A4 +#define AR71XX_WB_FLUSH_PCI 0x180000A8 + +/* + * Values for PCI_WINDOW_X registers + */ +#define PCI_WINDOW0_ADDR 0x10000000 +#define PCI_WINDOW1_ADDR 0x11000000 +#define PCI_WINDOW2_ADDR 0x12000000 +#define PCI_WINDOW3_ADDR 0x13000000 +#define PCI_WINDOW4_ADDR 0x14000000 +#define PCI_WINDOW5_ADDR 0x15000000 +#define PCI_WINDOW6_ADDR 0x16000000 +#define PCI_WINDOW7_ADDR 0x17000000 +/* This value enables acces to PCI config registers */ +#define PCI_WINDOW7_CONF_ADDR 0x07000000 + +#define AR71XX_UART_ADDR 0x18020000 -/* APB registers */ /* * APB interrupt status and mask register and interrupt bit numbers for */ @@ -49,8 +115,14 @@ #define MISC_INTR_OHCI 6 #define MISC_INTR_DMA 7 +#define AR71XX_PCI_INTR_STATUS 0x18060018 +#define AR71XX_PCI_INTR_MASK 0x1806001C +#define PCI_INTR_CORE (1 << 4) + #define AR71XX_RST_RESET 0x18060024 -#define RST_RESET_CPU_COLD_RESET (1 << 20) /* Cold reset */ -#define RST_RESET_FULL_CHIP_RESET (1 << 24) /* Same as pulling +#define RST_RESET_PCI_CORE (1 << 0) +#define RST_RESET_PCI_BUS (1 << 1) +#define RST_RESET_CPU_COLD (1 << 20) /* Cold reset */ +#define RST_RESET_FULL_CHIP (1 << 24) /* Same as pulling the reset pin */ #endif /* _AR71XX_REG_H_ */ From 2c2becc103094e7aed6f1d7f5ee406d82708b807 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 26 Jan 2009 06:14:42 +0000 Subject: [PATCH 021/380] - Add ar71xx PCI bridge implementation and link it to the build --- sys/mips/atheros/ar71xx_pci.c | 429 ++++++++++++++++++++++++++++++++++ sys/mips/atheros/files.ar71xx | 3 +- sys/mips/conf/AR71XX | 1 + sys/mips/conf/AR71XX.hints | 4 + 4 files changed, 436 insertions(+), 1 deletion(-) create mode 100644 sys/mips/atheros/ar71xx_pci.c diff --git a/sys/mips/atheros/ar71xx_pci.c b/sys/mips/atheros/ar71xx_pci.c new file mode 100644 index 00000000000..d3a9295d7aa --- /dev/null +++ b/sys/mips/atheros/ar71xx_pci.c @@ -0,0 +1,429 @@ +/*- + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include "pcib_if.h" + +#include "mips/atheros/ar71xxreg.h" + +#undef AR71XX_PCI_DEBUG +#ifdef AR71XX_PCI_DEBUG +#define dprintf printf +#else +#define dprintf(x, arg...) +#endif + +struct ar71xx_pci_softc { + device_t sc_dev; + + int sc_busno; + struct rman sc_mem_rman; + struct rman sc_irq_rman; + + struct resource *sc_irq; + void *sc_ih; +}; + +/* + * get bitmask for bytes of interest: + * 0 - we want this byte, 1 - ignore it. e.g: we read 1 byte + * from register 7. Bitmask would be: 0111 + */ +static uint32_t +ar71xx_get_bytes_to_read(int reg, int bytes) +{ + uint32_t bytes_to_read = 0; + if ((bytes % 4) == 0) + bytes_to_read = 0; + else if ((bytes % 4) == 1) + bytes_to_read = (~(1 << (reg % 4))) & 0xf; + else if ((bytes % 4) == 2) + bytes_to_read = (~(3 << (reg % 4))) & 0xf; + else + panic("%s: wrong combination", __func__); + + return (bytes_to_read); +} + +static int +ar71xx_pci_check_bus_error(void) +{ + uint32_t error, addr, has_errors = 0; + error = ATH_READ_REG(AR71XX_PCI_ERROR) & 0x3; + dprintf("%s: PCI error = %02x\n", __func__, error); + if (error) { + addr = ATH_READ_REG(AR71XX_PCI_ERROR_ADDR); + + /* Do not report it yet */ +#if 0 + printf("PCI bus error %d at addr 0x%08x\n", error, addr); +#endif + ATH_WRITE_REG(AR71XX_PCI_ERROR, error); + has_errors = 1; + } + + error = ATH_READ_REG(AR71XX_PCI_AHB_ERROR) & 0x1; + dprintf("%s: AHB error = %02x\n", __func__, error); + if (error) { + addr = ATH_READ_REG(AR71XX_PCI_AHB_ERROR_ADDR); + /* Do not report it yet */ +#if 0 + printf("AHB bus error %d at addr 0x%08x\n", error, addr); +#endif + ATH_WRITE_REG(AR71XX_PCI_AHB_ERROR, error); + has_errors = 1; + } + + return (has_errors); +} + +static uint32_t +ar71xx_pci_make_addr(int bus, int slot, int func, int reg) +{ + if (bus == 0) { + return ((1 << slot) | (func << 8) | (reg & ~3)); + } else { + return ((bus << 16) | (slot << 11) | (func << 8) + | (reg & ~3) | 1); + } +} + +static int +ar71xx_pci_conf_setup(int bus, int slot, int func, int reg, int bytes, + uint32_t cmd) +{ + uint32_t addr = ar71xx_pci_make_addr(bus, slot, func, (reg & ~3)); + cmd |= (ar71xx_get_bytes_to_read(reg, bytes) << 4); + + ATH_WRITE_REG(AR71XX_PCI_CONF_ADDR, addr); + ATH_WRITE_REG(AR71XX_PCI_CONF_CMD, cmd); + + dprintf("%s: tag (%x, %x, %x) %d/%d addr=%08x, cmd=%08x\n", __func__, + bus, slot, func, reg, bytes, addr, cmd); + + return ar71xx_pci_check_bus_error(); +} + +static uint32_t +ar71xx_pci_read_config(device_t dev, int bus, int slot, int func, int reg, + int bytes) +{ + uint32_t data; + uint32_t cmd, shift, mask; + + /* register access is 32-bit aligned */ + shift = (reg & 3) * 8; + if (shift) + mask = (1 << shift) - 1; + else + mask = 0xffffffff; + + dprintf("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, bus, slot, + func, reg, bytes); + + if ((bus == 0) && (slot == 0) && (func == 0)) { + cmd = PCI_LCONF_CMD_READ | (reg & ~3); + ATH_WRITE_REG(AR71XX_PCI_LCONF_CMD, cmd); + data = ATH_READ_REG(AR71XX_PCI_LCONF_READ_DATA); + } else { + if (ar71xx_pci_conf_setup(bus, slot, func, reg, bytes, + PCI_CONF_CMD_READ) == 0) + data = ATH_READ_REG(AR71XX_PCI_CONF_READ_DATA); + else + data = -1; + } + + /* get request bytes from 32-bit word */ + data = (data >> shift) & mask; + + dprintf("%s: read 0x%x\n", __func__, data); + + return (data); +} + +static void +ar71xx_pci_write_config(device_t dev, int bus, int slot, int func, int reg, + uint32_t data, int bytes) +{ + uint32_t cmd; + + dprintf("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, bus, slot, + func, reg, bytes); + + data = data << (8*(reg % 4)); + + if ((bus == 0) && (slot == 0) && (func == 0)) { + cmd = PCI_LCONF_CMD_WRITE | (reg & ~3); + cmd |= ar71xx_get_bytes_to_read(reg, bytes) << 20; + ATH_WRITE_REG(AR71XX_PCI_LCONF_CMD, cmd); + ATH_WRITE_REG(AR71XX_PCI_LCONF_WRITE_DATA, data); + } else { + if (ar71xx_pci_conf_setup(bus, slot, func, reg, bytes, + PCI_CONF_CMD_WRITE) == 0) + ATH_WRITE_REG(AR71XX_PCI_CONF_WRITE_DATA, data); + } +} + +static int +at71xx_pci_intr(void *v) +{ + panic("Implement me: %s\n", __func__); + return FILTER_HANDLED; +} + +static int +ar71xx_pci_probe(device_t dev) +{ + + return (0); +} + +static int +ar71xx_pci_attach(device_t dev) +{ + int busno = 0; + int rid = 0; + uint32_t reset; + struct ar71xx_pci_softc *sc = device_get_softc(dev); + + sc->sc_mem_rman.rm_type = RMAN_ARRAY; + sc->sc_mem_rman.rm_descr = "ar71xx PCI memory window"; + if (rman_init(&sc->sc_mem_rman) != 0 || + rman_manage_region(&sc->sc_mem_rman, AR71XX_PCI_MEM_BASE, + AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1) != 0) { + panic("ar71xx_pci_attach: failed to set up I/O rman"); + } + + sc->sc_irq_rman.rm_type = RMAN_ARRAY; + sc->sc_irq_rman.rm_descr = "ar71xx PCI IRQs"; + if (rman_init(&sc->sc_irq_rman) != 0 || + rman_manage_region(&sc->sc_irq_rman, AR71XX_PCI_IRQ_START, + AR71XX_PCI_IRQ_END) != 0) + panic("ar71xx_pci_attach: failed to set up IRQ rman"); + + + ATH_WRITE_REG(AR71XX_PCI_INTR_STATUS, 0); + ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, 0); + + /* Hook up our interrupt handler. */ + if ((sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_SHAREABLE | RF_ACTIVE)) == NULL) { + device_printf(dev, "unable to allocate IRQ resource\n"); + return ENXIO; + } + + if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC, + at71xx_pci_intr, NULL, sc, &sc->sc_ih))) { + device_printf(dev, + "WARNING: unable to register interrupt handler\n"); + return ENXIO; + } + + /* reset PCI core and PCI bus */ + reset = ATH_READ_REG(AR71XX_RST_RESET); + reset |= (RST_RESET_PCI_CORE | RST_RESET_PCI_BUS); + ATH_WRITE_REG(AR71XX_RST_RESET, reset); + DELAY(1000); + + reset &= ~(RST_RESET_PCI_CORE | RST_RESET_PCI_BUS); + ATH_WRITE_REG(AR71XX_RST_RESET, reset); + DELAY(1000); + + /* Init PCI windows */ + ATH_WRITE_REG(AR71XX_PCI_WINDOW0, PCI_WINDOW0_ADDR); + ATH_WRITE_REG(AR71XX_PCI_WINDOW1, PCI_WINDOW1_ADDR); + ATH_WRITE_REG(AR71XX_PCI_WINDOW2, PCI_WINDOW2_ADDR); + ATH_WRITE_REG(AR71XX_PCI_WINDOW3, PCI_WINDOW3_ADDR); + ATH_WRITE_REG(AR71XX_PCI_WINDOW4, PCI_WINDOW4_ADDR); + ATH_WRITE_REG(AR71XX_PCI_WINDOW5, PCI_WINDOW5_ADDR); + ATH_WRITE_REG(AR71XX_PCI_WINDOW6, PCI_WINDOW6_ADDR); + ATH_WRITE_REG(AR71XX_PCI_WINDOW7, PCI_WINDOW7_CONF_ADDR); + DELAY(1000); + + ar71xx_pci_check_bus_error(); + + /* Fixup internal PCI bridge */ + ar71xx_pci_write_config(dev, 0, 0, 0, PCIR_COMMAND, + PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN + | PCIM_CMD_SERRESPEN | PCIM_CMD_BACKTOBACK + | PCIM_CMD_PERRESPEN | PCIM_CMD_MWRICEN, 2); + + device_add_child(dev, "pci", busno); + return (bus_generic_attach(dev)); +} + +static int +ar71xx_pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) +{ + struct ar71xx_pci_softc *sc = device_get_softc(dev); + + switch (which) { + case PCIB_IVAR_DOMAIN: + *result = 0; + return (0); + case PCIB_IVAR_BUS: + *result = sc->sc_busno; + return (0); + } + + return (ENOENT); +} + +static int +ar71xx_pci_write_ivar(device_t dev, device_t child, int which, uintptr_t result) +{ + struct ar71xx_pci_softc * sc = device_get_softc(dev); + + switch (which) { + case PCIB_IVAR_BUS: + sc->sc_busno = result; + return (0); + } + + return (ENOENT); +} + +static struct resource * +ar71xx_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + + struct ar71xx_pci_softc *sc = device_get_softc(bus); + struct resource *rv = NULL; + struct rman *rm; + + switch (type) { + case SYS_RES_IRQ: + rm = &sc->sc_irq_rman; + break; + case SYS_RES_MEMORY: + rm = &sc->sc_mem_rman; + break; + default: + return (NULL); + } + + rv = rman_reserve_resource(rm, start, end, count, flags, child); + + if (rv == NULL) + return (NULL); + + rman_set_rid(rv, *rid); + + if (flags & RF_ACTIVE) { + if (bus_activate_resource(child, type, *rid, rv)) { + rman_release_resource(rv); + return (NULL); + } + } + + return (rv); +} + +static int +ar71xx_pci_teardown_intr(device_t dev, device_t child, struct resource *res, + void *cookie) +{ + + return (intr_event_remove_handler(cookie)); +} + +static int +ar71xx_pci_maxslots(device_t dev) +{ + + return (PCI_SLOTMAX); +} + +static int +ar71xx_pci_route_interrupt(device_t pcib, device_t device, int pin) +{ + + return (pin); +} + +static device_method_t ar71xx_pci_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, ar71xx_pci_probe), + DEVMETHOD(device_attach, ar71xx_pci_attach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(device_suspend, bus_generic_suspend), + DEVMETHOD(device_resume, bus_generic_resume), + + /* Bus interface */ + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_read_ivar, ar71xx_pci_read_ivar), + DEVMETHOD(bus_write_ivar, ar71xx_pci_write_ivar), + DEVMETHOD(bus_alloc_resource, ar71xx_pci_alloc_resource), + DEVMETHOD(bus_release_resource, bus_generic_release_resource), + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_teardown_intr, ar71xx_pci_teardown_intr), + + /* pcib interface */ + DEVMETHOD(pcib_maxslots, ar71xx_pci_maxslots), + DEVMETHOD(pcib_read_config, ar71xx_pci_read_config), + DEVMETHOD(pcib_write_config, ar71xx_pci_write_config), + DEVMETHOD(pcib_route_interrupt, ar71xx_pci_route_interrupt), + + {0, 0} +}; + +static driver_t ar71xx_pci_driver = { + "pcib", + ar71xx_pci_methods, + sizeof(struct ar71xx_pci_softc), +}; + +static devclass_t ar71xx_pci_devclass; + +DRIVER_MODULE(ar71xx_pci, nexus, ar71xx_pci_driver, ar71xx_pci_devclass, 0, 0); diff --git a/sys/mips/atheros/files.ar71xx b/sys/mips/atheros/files.ar71xx index 174043b2682..4eba2487b26 100644 --- a/sys/mips/atheros/files.ar71xx +++ b/sys/mips/atheros/files.ar71xx @@ -1,6 +1,7 @@ # $FreeBSD$ -mips/atheros/ar71xx_machdep.c standard mips/atheros/apb.c standard +mips/atheros/ar71xx_machdep.c standard +mips/atheros/ar71xx_pci.c optional pci mips/atheros/uart_bus_ar71xx.c optional uart mips/atheros/uart_cpu_ar71xx.c optional uart diff --git a/sys/mips/conf/AR71XX b/sys/mips/conf/AR71XX index c655f990f98..936d0f1f88d 100644 --- a/sys/mips/conf/AR71XX +++ b/sys/mips/conf/AR71XX @@ -29,6 +29,7 @@ options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions options INVARIANTS options INVARIANT_SUPPORT +device pci device uart device loop diff --git a/sys/mips/conf/AR71XX.hints b/sys/mips/conf/AR71XX.hints index 821ee0c7cef..f05995850c0 100644 --- a/sys/mips/conf/AR71XX.hints +++ b/sys/mips/conf/AR71XX.hints @@ -10,3 +10,7 @@ hint.uart.0.at="apb0" hint.uart.0.maddr=0x18020003 hint.uart.0.msize=0x18 hint.uart.0.irq=3 + +# pci +hint.pcib.0.at="nexus0" +hint.pcib.0.irq=0 From b76b7cf82b28d3a5cd499f517738c2712a612892 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 19 Feb 2009 06:20:30 +0000 Subject: [PATCH 022/380] - Add PLL, reset, ethernet and DMA registers/values --- sys/mips/atheros/ar71xxreg.h | 167 ++++++++++++++++++++++++++++++++++- 1 file changed, 164 insertions(+), 3 deletions(-) diff --git a/sys/mips/atheros/ar71xxreg.h b/sys/mips/atheros/ar71xxreg.h index 825a9461c71..ab653e13c31 100644 --- a/sys/mips/atheros/ar71xxreg.h +++ b/sys/mips/atheros/ar71xxreg.h @@ -101,6 +101,21 @@ #define AR71XX_UART_ADDR 0x18020000 +#define AR71XX_PLL_CPU_CONFIG 0x18050000 +#define AR71XX_PLL_SEC_CONFIG 0x18050004 +#define AR71XX_PLL_CPU_CLK_CTRL 0x18050008 +#define AR71XX_PLL_ETH_INT0_CLK 0x18050010 +#define AR71XX_PLL_ETH_INT1_CLK 0x18050014 +#define XPLL_ETH_INT_CLK_10 0x00991099 +#define XPLL_ETH_INT_CLK_100 0x00441011 +#define XPLL_ETH_INT_CLK_1000 0x13110000 +#define XPLL_ETH_INT_CLK_1000_GMII 0x14110000 +#define PLL_ETH_INT_CLK_10 0x00991099 +#define PLL_ETH_INT_CLK_100 0x00001099 +#define PLL_ETH_INT_CLK_1000 0x00110000 +#define AR71XX_PLL_ETH_EXT_CLK 0x18050018 +#define AR71XX_PLL_PCI_CLK 0x1805001C + /* * APB interrupt status and mask register and interrupt bit numbers for */ @@ -120,9 +135,155 @@ #define PCI_INTR_CORE (1 << 4) #define AR71XX_RST_RESET 0x18060024 -#define RST_RESET_PCI_CORE (1 << 0) -#define RST_RESET_PCI_BUS (1 << 1) -#define RST_RESET_CPU_COLD (1 << 20) /* Cold reset */ #define RST_RESET_FULL_CHIP (1 << 24) /* Same as pulling the reset pin */ +#define RST_RESET_CPU_COLD (1 << 20) /* Cold reset */ +#define RST_RESET_GE1_MAC (1 << 13) +#define RST_RESET_GE1_PHY (1 << 12) +#define RST_RESET_GE0_MAC (1 << 9) +#define RST_RESET_GE0_PHY (1 << 8) +#define RST_RESET_PCI_BUS (1 << 1) +#define RST_RESET_PCI_CORE (1 << 0) + +/* + * GigE adapters region + */ +#define AR71XX_MAC0_BASE 0x19000000 +#define AR71XX_MAC1_BASE 0x1A000000 + +#define AR71XX_MAC_CFG1 0x00 +#define MAC_CFG1_SOFT_RESET (1 << 31) +#define MAC_CFG1_SIMUL_RESET (1 << 30) +#define MAC_CFG1_MAC_RX_BLOCK_RESET (1 << 19) +#define MAC_CFG1_MAC_TX_BLOCK_RESET (1 << 18) +#define MAC_CFG1_RX_FUNC_RESET (1 << 17) +#define MAC_CFG1_TX_FUNC_RESET (1 << 16) +#define MAC_CFG1_LOOPBACK (1 << 8) +#define MAC_CFG1_RXFLOW_CTRL (1 << 5) +#define MAC_CFG1_TXFLOW_CTRL (1 << 4) +#define MAC_CFG1_SYNC_RX (1 << 3) +#define MAC_CFG1_RX_ENABLE (1 << 2) +#define MAC_CFG1_SYNC_TX (1 << 1) +#define MAC_CFG1_TX_ENABLE (1 << 0) +#define AR71XX_MAC_CFG2 0x04 +#define MAC_CFG2_PREAMBLE_LEN_MASK 0xf +#define MAC_CFG2_PREAMBLE_LEN_SHIFT 12 +#define MAC_CFG2_IFACE_MODE_1000 (2 << 8) +#define MAC_CFG2_IFACE_MODE_10_100 (1 << 8) +#define MAC_CFG2_IFACE_MODE_SHIFT 8 +#define MAC_CFG2_IFACE_MODE_MASK 3 +#define MAC_CFG2_HUGE_FRAME (1 << 5) +#define MAC_CFG2_LENGTH_FIELD (1 << 4) +#define MAC_CFG2_ENABLE_PADCRC (1 << 2) +#define MAC_CFG2_ENABLE_CRC (1 << 1) +#define MAC_CFG2_FULL_DUPLEX (1 << 0) +#define AR71XX_MAC_IFG 0x08 +#define AR71XX_MAC_HDUPLEX 0x0C +#define AR71XX_MAC_MAX_FRAME_LEN 0x10 +#define AR71XX_MAC_MII_CFG 0x20 +#define MAC_MII_CFG_RESET (1 << 31) +#define MAC_MII_CFG_SCAN_AUTO_INC (1 << 5) +#define MAC_MII_CFG_PREAMBLE_SUP (1 << 4) +#define MAC_MII_CFG_CLOCK_SELECT_MASK 0x7 +#define MAC_MII_CFG_CLOCK_DIV_4 0 +#define MAC_MII_CFG_CLOCK_DIV_6 2 +#define MAC_MII_CFG_CLOCK_DIV_8 3 +#define MAC_MII_CFG_CLOCK_DIV_10 4 +#define MAC_MII_CFG_CLOCK_DIV_14 5 +#define MAC_MII_CFG_CLOCK_DIV_20 6 +#define MAC_MII_CFG_CLOCK_DIV_28 7 +#define AR71XX_MAC_MII_CMD 0x24 +#define MAC_MII_CMD_SCAN_CYCLE (1 << 1) +#define MAC_MII_CMD_READ 1 +#define MAC_MII_CMD_WRITE 0 +#define AR71XX_MAC_MII_ADDR 0x28 +#define MAC_MII_PHY_ADDR_SHIFT 8 +#define MAC_MII_PHY_ADDR_MASK 0xff +#define MAC_MII_REG_MASK 0x1f +#define AR71XX_MAC_MII_CONTROL 0x2C +#define MAC_MII_CONTROL_MASK 0xffff +#define AR71XX_MAC_MII_STATUS 0x30 +#define MAC_MII_STATUS_MASK 0xffff +#define AR71XX_MAC_MII_INDICATOR 0x34 +#define MAC_MII_INDICATOR_NOT_VALID (1 << 2) +#define MAC_MII_INDICATOR_SCANNING (1 << 1) +#define MAC_MII_INDICATOR_BUSY (1 << 0) +#define AR71XX_MAC_IFCONTROL 0x38 +#define MAC_IFCONTROL_SPEED (1 << 16) +#define AR71XX_MAC_STA_ADDR1 0x40 +#define AR71XX_MAC_STA_ADDR2 0x44 +#define AR71XX_MAC_FIFO_CFG0 0x48 +#define FIFO_CFG0_TX_FABRIC (1 << 4) +#define FIFO_CFG0_TX_SYSTEM (1 << 3) +#define FIFO_CFG0_RX_FABRIC (1 << 2) +#define FIFO_CFG0_RX_SYSTEM (1 << 1) +#define FIFO_CFG0_WATERMARK (1 << 0) +#define FIFO_CFG0_ALL ((1 << 5) - 1) +#define FIFO_CFG0_ENABLE_SHIFT 8 +#define AR71XX_MAC_FIFO_CFG1 0x4C +#define AR71XX_MAC_FIFO_CFG2 0x50 +#define AR71XX_MAC_FIFO_TX_THRESHOLD 0x54 +#define AR71XX_MAC_FIFO_RX_FILTMATCH 0x58 +#define FIFO_RX_FILTMATCH_ALL ((1 << 18) - 1) +#define AR71XX_MAC_FIFO_RX_FILTMASK 0x5C +#define FIFO_RX_FILTMASK_BYTE_MODE (1 << 19) +#define FIFO_RX_FILTMASK_NO_SHORT_FRAME (1 << 18) +#define FIFO_RX_FILTMASK_ALL ((1 << 20) - 1) +/* + * These flags applicable both to AR71XX_MAC_FIFO_RX_FILTMASK and + * to AR71XX_MAC_FIFO_RX_FILTMATCH + */ +#define FIFO_RX_FILT_UNICAST (1 << 17) +#define FIFO_RX_FILT_TRUNC_FRAME (1 << 16) +#define FIFO_RX_FILT_VLAN_TAG (1 << 15) +#define FIFO_RX_FILT_UNSUP_OPCODE (1 << 14) +#define FIFO_RX_FILT_PAUSE_FRAME (1 << 13) +#define FIFO_RX_FILT_CTRL_FRAME (1 << 12) +#define FIFO_RX_FILT_LONG_EVENT (1 << 11) +#define FIFO_RX_FILT_DRIBBLE_NIBBLE (1 << 10) +#define FIFO_RX_FILT_BCAST (1 << 9) +#define FIFO_RX_FILT_MCAST (1 << 8) +#define FIFO_RX_FILT_OK (1 << 7) +#define FIFO_RX_FILT_OORANGE (1 << 6) +#define FIFO_RX_FILT_LEN_MSMTCH (1 << 5) +#define FIFO_RX_FILT_CRC_ERROR (1 << 4) +#define FIFO_RX_FILT_CODE_ERROR (1 << 3) +#define FIFO_RX_FILT_FALSE_CARRIER (1 << 2) +#define FIFO_RX_FILT_RX_DV_EVENT (1 << 1) +#define FIFO_RX_FILT_DROP_EVENT (1 << 0) +#define AR71XX_MAC_FIFO_RAM0 0x60 +#define AR71XX_MAC_FIFO_RAM1 0x64 +#define AR71XX_MAC_FIFO_RAM2 0x68 +#define AR71XX_MAC_FIFO_RAM3 0x6C +#define AR71XX_MAC_FIFO_RAM4 0x70 +#define AR71XX_MAC_FIFO_RAM5 0x74 +#define AR71XX_MAC_FIFO_RAM6 0x78 +#define AR71XX_DMA_TX_CONTROL 0x180 +#define DMA_TX_CONTROL_EN (1 << 0) +#define AR71XX_DMA_TX_DESC 0x184 +#define AR71XX_DMA_TX_STATUS 0x188 +#define DMA_TX_STATUS_PCOUNT_MASK 0xff +#define DMA_TX_STATUS_PCOUNT_SHIFT 16 +#define DMA_TX_STATUS_BUS_ERROR (1 << 3) +#define DMA_TX_STATUS_UNDERRUN (1 << 1) +#define DMA_TX_STATUS_PKT_SENT (1 << 0) +#define AR71XX_DMA_RX_CONTROL 0x18C +#define DMA_RX_CONTROL_EN (1 << 0) +#define AR71XX_DMA_RX_DESC 0x190 +#define AR71XX_DMA_RX_STATUS 0x194 +#define DMA_RX_STATUS_PCOUNT_MASK 0xff +#define DMA_RX_STATUS_PCOUNT_SHIFT 16 +#define DMA_RX_STATUS_BUS_ERROR (1 << 3) +#define DMA_RX_STATUS_OVERFLOW (1 << 1) +#define DMA_RX_STATUS_PKT_RECVD (1 << 0) +#define AR71XX_DMA_INTR 0x198 +#define AR71XX_DMA_INTR_STATUS 0x19C +#define DMA_INTR_ALL ((1 << 8) - 1) +#define DMA_INTR_RX_BUS_ERROR (1 << 7) +#define DMA_INTR_RX_OVERFLOW (1 << 6) +#define DMA_INTR_RX_PKT_RCVD (1 << 4) +#define DMA_INTR_TX_BUS_ERROR (1 << 3) +#define DMA_INTR_TX_UNDERRUN (1 << 1) +#define DMA_INTR_TX_PKT_SENT (1 << 0) + #endif /* _AR71XX_REG_H_ */ From 2739312579a01b2b0e3d7c95b136cad7d1fda219 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 19 Feb 2009 06:23:56 +0000 Subject: [PATCH 023/380] - Driver for on-board AR71XX ethernet --- sys/mips/atheros/if_arge.c | 1657 +++++++++++++++++++++++++++++++++ sys/mips/atheros/if_argevar.h | 138 +++ 2 files changed, 1795 insertions(+) create mode 100644 sys/mips/atheros/if_arge.c create mode 100644 sys/mips/atheros/if_argevar.h diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c new file mode 100644 index 00000000000..7dbfe70fb29 --- /dev/null +++ b/sys/mips/atheros/if_arge.c @@ -0,0 +1,1657 @@ +/*- + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +/* + * AR71XX gigabit ethernet driver + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +MODULE_DEPEND(arge, ether, 1, 1, 1); +MODULE_DEPEND(arge, miibus, 1, 1, 1); + +#include "miibus_if.h" + +#include +#include + +#undef ARGE_DEBUG +#ifdef ARGE_DEBUG +#define dprintf printf +#else +#define dprintf(x, arg...) +#endif + +static int arge_attach(device_t); +static int arge_detach(device_t); +static int arge_fix_chain(struct mbuf **mp); +static void arge_flush_ddr(struct arge_softc *); +static int arge_ifmedia_upd(struct ifnet *); +static void arge_ifmedia_sts(struct ifnet *, struct ifmediareq *); +static int arge_ioctl(struct ifnet *, u_long, caddr_t); +static void arge_init(void *); +static void arge_init_locked(struct arge_softc *); +static void arge_link_task(void *, int); +static int arge_miibus_readreg(device_t, int, int); +static void arge_miibus_statchg(device_t); +static int arge_miibus_writereg(device_t, int, int, int); +static int arge_probe(device_t); +static void arge_reset_dma(struct arge_softc *); +static int arge_resume(device_t); +static int arge_rx_ring_init(struct arge_softc *); +static int arge_tx_ring_init(struct arge_softc *); +static void arge_shutdown(device_t); +static void arge_start(struct ifnet *); +static void arge_start_locked(struct ifnet *); +static void arge_stop(struct arge_softc *); +static int arge_suspend(device_t); + +static void arge_rx_locked(struct arge_softc *); +static void arge_tx_locked(struct arge_softc *); +static void arge_intr(void *); +static int arge_intr_filter(void *); +static void arge_tx_intr(struct arge_softc *, uint32_t); +static void arge_rx_intr(struct arge_softc *, uint32_t); +static void arge_tick(void *); + +static void arge_dmamap_cb(void *, bus_dma_segment_t *, int, int); +static int arge_dma_alloc(struct arge_softc *); +static void arge_dma_free(struct arge_softc *); +static int arge_newbuf(struct arge_softc *, int); +static __inline void arge_fixup_rx(struct mbuf *); + +static device_method_t arge_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, arge_probe), + DEVMETHOD(device_attach, arge_attach), + DEVMETHOD(device_detach, arge_detach), + DEVMETHOD(device_suspend, arge_suspend), + DEVMETHOD(device_resume, arge_resume), + DEVMETHOD(device_shutdown, arge_shutdown), + + /* bus interface */ + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_driver_added, bus_generic_driver_added), + + /* MII interface */ + DEVMETHOD(miibus_readreg, arge_miibus_readreg), + DEVMETHOD(miibus_writereg, arge_miibus_writereg), + DEVMETHOD(miibus_statchg, arge_miibus_statchg), + + { 0, 0 } +}; + +static driver_t arge_driver = { + "arge", + arge_methods, + sizeof(struct arge_softc) +}; + +static devclass_t arge_devclass; + +DRIVER_MODULE(arge, nexus, arge_driver, arge_devclass, 0, 0); +DRIVER_MODULE(miibus, arge, miibus_driver, miibus_devclass, 0, 0); + +/* + * Flushes all + */ +static void +arge_flush_ddr(struct arge_softc *sc) +{ + + ATH_WRITE_REG(sc->arge_ddr_flush_reg, 1); + while (ATH_READ_REG(sc->arge_ddr_flush_reg) & 1) + ; + + ATH_WRITE_REG(sc->arge_ddr_flush_reg, 1); + while (ATH_READ_REG(sc->arge_ddr_flush_reg) & 1) + ; +} + +static int +arge_probe(device_t dev) +{ + + device_set_desc(dev, "Atheros AR71xx built-in ethernet interface"); + return (0); +} + +static int +arge_attach(device_t dev) +{ + uint8_t eaddr[ETHER_ADDR_LEN]; + struct ifnet *ifp; + struct arge_softc *sc; + int error = 0, rid, phynum; + uint32_t reg; + + sc = device_get_softc(dev); + sc->arge_dev = dev; + sc->arge_mac_unit = device_get_unit(dev); + + KASSERT(((sc->arge_mac_unit == 0) || (sc->arge_mac_unit == 1)), + ("if_arge: Only MAC0 and MAC1 supported")); + if (sc->arge_mac_unit == 0) { + sc->arge_ddr_flush_reg = AR71XX_WB_FLUSH_GE0; + sc->arge_pll_reg = AR71XX_PLL_ETH_INT0_CLK; + } else { + sc->arge_ddr_flush_reg = AR71XX_WB_FLUSH_GE1; + sc->arge_pll_reg = AR71XX_PLL_ETH_INT1_CLK; + } + + /* + * Get which PHY of 5 available we should use for this unit + */ + if (resource_int_value(device_get_name(dev), device_get_unit(dev), + "phy", &phynum) != 0) { + /* + * Use port 4 (WAN) for GE0. For any other port use + * its PHY the same as its unit number + */ + if (sc->arge_mac_unit == 0) + phynum = 4; + else + phynum = sc->arge_mac_unit; + + device_printf(dev, "No PHY specified, using %d\n", phynum); + } + + sc->arge_phy_num = phynum; + + + mtx_init(&sc->arge_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, + MTX_DEF); + callout_init_mtx(&sc->arge_stat_callout, &sc->arge_mtx, 0); + TASK_INIT(&sc->arge_link_task, 0, arge_link_task, sc); + + /* Map control/status registers. */ + sc->arge_rid = 0; + sc->arge_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &sc->arge_rid, RF_ACTIVE); + + if (sc->arge_res == NULL) { + device_printf(dev, "couldn't map memory\n"); + error = ENXIO; + goto fail; + } + + /* Allocate interrupts */ + rid = 0; + sc->arge_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_SHAREABLE | RF_ACTIVE); + + if (sc->arge_irq == NULL) { + device_printf(dev, "couldn't map interrupt\n"); + error = ENXIO; + goto fail; + } + + /* Allocate ifnet structure. */ + ifp = sc->arge_ifp = if_alloc(IFT_ETHER); + + if (ifp == NULL) { + device_printf(dev, "couldn't allocate ifnet structure\n"); + error = ENOSPC; + goto fail; + } + + ifp->if_softc = sc; + if_initname(ifp, device_get_name(dev), device_get_unit(dev)); + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_ioctl = arge_ioctl; + ifp->if_start = arge_start; + ifp->if_init = arge_init; + + /* XXX: add real size */ + IFQ_SET_MAXLEN(&ifp->if_snd, 9); + ifp->if_snd.ifq_maxlen = 9; + IFQ_SET_READY(&ifp->if_snd); + + ifp->if_capenable = ifp->if_capabilities; + + eaddr[0] = 0x00; + eaddr[1] = 0x15; + eaddr[2] = 0x6d; + eaddr[3] = 0xc1; + eaddr[4] = 0x28; + eaddr[5] = 0x2e; + + if (arge_dma_alloc(sc) != 0) { + error = ENXIO; + goto fail; + } + + ARGE_WRITE(sc, AR71XX_MAC_CFG1, + MAC_CFG1_SYNC_RX | MAC_CFG1_RX_ENABLE | + MAC_CFG1_SYNC_TX | MAC_CFG1_TX_ENABLE); + + reg = ARGE_READ(sc, AR71XX_MAC_CFG2); + reg |= MAC_CFG2_ENABLE_PADCRC | MAC_CFG2_LENGTH_FIELD ; + ARGE_WRITE(sc, AR71XX_MAC_CFG2, reg); + + ARGE_WRITE(sc, AR71XX_MAC_MAX_FRAME_LEN, 1536); + + /* Reset MII bus */ + ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_RESET); + DELAY(100); + ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_CLOCK_DIV_28); + DELAY(100); + + /* + * Set all Ethernet address registers to the same initial values + * set all four addresses to 66-88-aa-cc-dd-ee + */ + ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR1, 0x6dc1282e); + ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR2, 0x00000015); + + ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG0, + FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT); + ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG1, 0x0fff0000); + ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG2, 0x00001fff); + + reg = FIFO_RX_FILTMATCH_ALL; + ARGE_WRITE(sc, AR71XX_MAC_FIFO_RX_FILTMATCH, reg); + + reg = FIFO_RX_FILTMASK_ALL; + reg &= ~FIFO_RX_FILTMASK_BYTE_MODE; + ARGE_WRITE(sc, AR71XX_MAC_FIFO_RX_FILTMASK, reg); + + /* Do MII setup. */ + if (mii_phy_probe(dev, &sc->arge_miibus, + arge_ifmedia_upd, arge_ifmedia_sts)) { + device_printf(dev, "MII without any phy!\n"); + error = ENXIO; + goto fail; + } + + /* Call MI attach routine. */ + ether_ifattach(ifp, eaddr); + + /* Hook interrupt last to avoid having to lock softc */ + error = bus_setup_intr(dev, sc->arge_irq, INTR_TYPE_NET | INTR_MPSAFE, + arge_intr_filter, arge_intr, sc, &sc->arge_intrhand); + + if (error) { + device_printf(dev, "couldn't set up irq\n"); + ether_ifdetach(ifp); + goto fail; + } + +fail: + if (error) + arge_detach(dev); + + return (error); +} + +static int +arge_detach(device_t dev) +{ + struct arge_softc *sc = device_get_softc(dev); + struct ifnet *ifp = sc->arge_ifp; + + KASSERT(mtx_initialized(&sc->arge_mtx), ("arge mutex not initialized")); + + /* These should only be active if attach succeeded */ + if (device_is_attached(dev)) { + ARGE_LOCK(sc); + sc->arge_detach = 1; + arge_stop(sc); + ARGE_UNLOCK(sc); + taskqueue_drain(taskqueue_swi, &sc->arge_link_task); + ether_ifdetach(ifp); + } + + if (sc->arge_miibus) + device_delete_child(dev, sc->arge_miibus); + bus_generic_detach(dev); + + if (sc->arge_intrhand) + bus_teardown_intr(dev, sc->arge_irq, sc->arge_intrhand); + + if (sc->arge_res) + bus_release_resource(dev, SYS_RES_MEMORY, sc->arge_rid, + sc->arge_res); + + if (ifp) + if_free(ifp); + + arge_dma_free(sc); + + mtx_destroy(&sc->arge_mtx); + + return (0); + +} + +static int +arge_suspend(device_t dev) +{ + + panic("%s", __func__); + return 0; +} + +static int +arge_resume(device_t dev) +{ + + panic("%s", __func__); + return 0; +} + +static void +arge_shutdown(device_t dev) +{ + struct arge_softc *sc; + + sc = device_get_softc(dev); + + ARGE_LOCK(sc); + arge_stop(sc); + ARGE_UNLOCK(sc); +} + +static int +arge_miibus_readreg(device_t dev, int phy, int reg) +{ + struct arge_softc * sc = device_get_softc(dev); + int i, result; + uint32_t addr = 0x1000 | (phy << MAC_MII_PHY_ADDR_SHIFT) + | (reg & MAC_MII_REG_MASK); + + if (phy != sc->arge_phy_num) + return (0); + + ARGE_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); + ARGE_WRITE(sc, AR71XX_MAC_MII_ADDR, addr); + ARGE_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_READ); + + i = ARGE_MII_TIMEOUT; + while ((ARGE_READ(sc, AR71XX_MAC_MII_INDICATOR) & + MAC_MII_INDICATOR_BUSY) && (i--)) + DELAY(5); + + if (i < 0) { + dprintf("%s timedout\n", __func__); + /* XXX: return ERRNO istead? */ + return (-1); + } + + result = ARGE_READ(sc, AR71XX_MAC_MII_STATUS) & MAC_MII_STATUS_MASK; + ARGE_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); + dprintf("%s: phy=%d, reg=%02x, value[%08x]=%04x\n", __func__, + phy, reg, addr, result); + + return (result); +} + +static int +arge_miibus_writereg(device_t dev, int phy, int reg, int data) +{ + struct arge_softc * sc = device_get_softc(dev); + int i; + uint32_t addr = 0x1000 + | (phy << MAC_MII_PHY_ADDR_SHIFT) | (reg & MAC_MII_REG_MASK); + + dprintf("%s: phy=%d, reg=%02x, value=%04x\n", __func__, + phy, reg, data); + + ARGE_WRITE(sc, AR71XX_MAC_MII_ADDR, addr); + ARGE_WRITE(sc, AR71XX_MAC_MII_CONTROL, data); + + i = ARGE_MII_TIMEOUT; + while ((ARGE_READ(sc, AR71XX_MAC_MII_INDICATOR) & + MAC_MII_INDICATOR_BUSY) && (i--)) + DELAY(5); + + if (i < 0) { + dprintf("%s timedout\n", __func__); + /* XXX: return ERRNO istead? */ + return (-1); + } + + return (0); +} + +static void +arge_miibus_statchg(device_t dev) +{ + struct arge_softc *sc; + + sc = device_get_softc(dev); + taskqueue_enqueue(taskqueue_swi, &sc->arge_link_task); +} + +static void +arge_link_task(void *arg, int pending) +{ + struct arge_softc *sc; + struct mii_data *mii; + struct ifnet *ifp; + uint32_t media; + uint32_t cfg, ifcontrol, rx_filtmask, pll, sec_cfg; + + sc = (struct arge_softc *)arg; + + ARGE_LOCK(sc); + mii = device_get_softc(sc->arge_miibus); + ifp = sc->arge_ifp; + if (mii == NULL || ifp == NULL || + (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + ARGE_UNLOCK(sc); + return; + } + + if (mii->mii_media_status & IFM_ACTIVE) { + + media = IFM_SUBTYPE(mii->mii_media_active); + + if (media != IFM_NONE) { + sc->arge_link_status = 1; + + cfg = ARGE_READ(sc, AR71XX_MAC_CFG2); + ifcontrol = ARGE_READ(sc, AR71XX_MAC_IFCONTROL); + rx_filtmask = + ARGE_READ(sc, AR71XX_MAC_FIFO_RX_FILTMASK); + + cfg &= ~(MAC_CFG2_IFACE_MODE_1000 + | MAC_CFG2_IFACE_MODE_10_100 + | MAC_CFG2_FULL_DUPLEX); + ifcontrol &= ~MAC_IFCONTROL_SPEED; + rx_filtmask &= ~FIFO_RX_FILTMASK_BYTE_MODE; + + switch(media) { + case IFM_10_T: + cfg |= MAC_CFG2_IFACE_MODE_10_100; + pll = PLL_ETH_INT_CLK_10; + break; + case IFM_100_TX: + cfg |= MAC_CFG2_IFACE_MODE_10_100; + ifcontrol |= MAC_IFCONTROL_SPEED; + pll = PLL_ETH_INT_CLK_100; + break; + case IFM_1000_T: + case IFM_1000_SX: + cfg |= MAC_CFG2_IFACE_MODE_1000; + rx_filtmask |= FIFO_RX_FILTMASK_BYTE_MODE; + pll = PLL_ETH_INT_CLK_1000; + break; + default: + pll = PLL_ETH_INT_CLK_100; + device_printf(sc->arge_dev, + "Unknown media %d\n", media); + } + + ARGE_WRITE(sc, AR71XX_MAC_FIFO_TX_THRESHOLD, + 0x008001ff); + + ARGE_WRITE(sc, AR71XX_MAC_CFG2, cfg); + ARGE_WRITE(sc, AR71XX_MAC_IFCONTROL, ifcontrol); + ARGE_WRITE(sc, AR71XX_MAC_FIFO_RX_FILTMASK, + rx_filtmask); + + /* set PLL registers */ + sec_cfg = ATH_READ_REG(AR71XX_PLL_CPU_CONFIG); + sec_cfg &= ~(3 << 17); + sec_cfg |= (2 << 17); + + ATH_WRITE_REG(AR71XX_PLL_CPU_CONFIG, sec_cfg); + DELAY(100); + + ATH_WRITE_REG(sc->arge_pll_reg, pll); + + sec_cfg |= (3 << 17); + ATH_WRITE_REG(AR71XX_PLL_CPU_CONFIG, sec_cfg); + DELAY(100); + + sec_cfg &= ~(3 << 17); + ATH_WRITE_REG(AR71XX_PLL_CPU_CONFIG, sec_cfg); + DELAY(100); + } + } else + sc->arge_link_status = 0; + + ARGE_UNLOCK(sc); +} + +static void +arge_reset_dma(struct arge_softc *sc) +{ + unsigned int i; + + ARGE_WRITE(sc, AR71XX_DMA_RX_CONTROL, 0); + ARGE_WRITE(sc, AR71XX_DMA_TX_CONTROL, 0); + + ARGE_WRITE(sc, AR71XX_DMA_RX_DESC, 0); + ARGE_WRITE(sc, AR71XX_DMA_TX_DESC, 0); + + /* Clear all possible RX interrupts */ + for (i = 0; i < ARGE_RX_RING_COUNT; i++) + ARGE_WRITE(sc, AR71XX_DMA_RX_STATUS, DMA_RX_STATUS_PKT_RECVD); + + /* + * Clear all possible TX interrupts + */ + for (i = 0; i < ARGE_TX_RING_COUNT; i++) + ARGE_WRITE(sc, AR71XX_DMA_TX_STATUS, DMA_TX_STATUS_PKT_SENT); + + /* + * Now Rx/Tx errors + */ + ARGE_WRITE(sc, AR71XX_DMA_RX_STATUS, + DMA_RX_STATUS_BUS_ERROR | DMA_RX_STATUS_OVERFLOW); + ARGE_WRITE(sc, AR71XX_DMA_TX_STATUS, + DMA_TX_STATUS_BUS_ERROR | DMA_TX_STATUS_UNDERRUN); +} + + + +static void +arge_init(void *xsc) +{ + struct arge_softc *sc = xsc; + + ARGE_LOCK(sc); + arge_init_locked(sc); + ARGE_UNLOCK(sc); +} + +static void +arge_init_locked(struct arge_softc *sc) +{ + struct ifnet *ifp = sc->arge_ifp; + struct mii_data *mii; + + ARGE_LOCK_ASSERT(sc); + + mii = device_get_softc(sc->arge_miibus); + + arge_stop(sc); + + /* Init circular RX list. */ + if (arge_rx_ring_init(sc) != 0) { + device_printf(sc->arge_dev, + "initialization failed: no memory for rx buffers\n"); + arge_stop(sc); + return; + } + + /* Init tx descriptors. */ + arge_tx_ring_init(sc); + + arge_reset_dma(sc); + + sc->arge_link_status = 0; + mii_mediachg(mii); + + ifp->if_drv_flags |= IFF_DRV_RUNNING; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + + callout_reset(&sc->arge_stat_callout, hz, arge_tick, sc); + ARGE_WRITE(sc, AR71XX_DMA_TX_DESC, ARGE_TX_RING_ADDR(sc, 0)); + ARGE_WRITE(sc, AR71XX_DMA_RX_DESC, ARGE_RX_RING_ADDR(sc, 0)); + + /* Start listening */ + ARGE_WRITE(sc, AR71XX_DMA_RX_CONTROL, DMA_RX_CONTROL_EN); + + /* Enable interrupts */ + ARGE_WRITE(sc, AR71XX_DMA_INTR, DMA_INTR_ALL); +} + +/* + * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data + * pointers to the fragment pointers. + */ +static int +arge_encap(struct arge_softc *sc, struct mbuf **m_head) +{ + struct arge_txdesc *txd; + struct arge_desc *desc, *prev_desc; + bus_dma_segment_t txsegs[ARGE_MAXFRAGS]; + int error, i, nsegs, prod, si, prev_prod; + + ARGE_LOCK_ASSERT(sc); + + prod = sc->arge_cdata.arge_tx_prod; + txd = &sc->arge_cdata.arge_txdesc[prod]; + error = bus_dmamap_load_mbuf_sg(sc->arge_cdata.arge_tx_tag, + txd->tx_dmamap, *m_head, txsegs, &nsegs, BUS_DMA_NOWAIT); + + if (error == EFBIG) { + panic("EFBIG"); + } else if (error != 0) + return (error); + + if (nsegs == 0) { + m_freem(*m_head); + *m_head = NULL; + return (EIO); + } + + /* Check number of available descriptors. */ + if (sc->arge_cdata.arge_tx_cnt + nsegs >= (ARGE_TX_RING_COUNT - 1)) { + bus_dmamap_unload(sc->arge_cdata.arge_tx_tag, txd->tx_dmamap); + return (ENOBUFS); + } + + txd->tx_m = *m_head; + bus_dmamap_sync(sc->arge_cdata.arge_tx_tag, txd->tx_dmamap, + BUS_DMASYNC_PREWRITE); + + si = prod; + + /* + * Make a list of descriptors for this packet. DMA controller will + * walk through it while arge_link is not zero. + */ + prev_prod = prod; + desc = prev_desc = NULL; + for (i = 0; i < nsegs; i++) { + desc = &sc->arge_rdata.arge_tx_ring[prod]; + desc->packet_ctrl = ARGE_DMASIZE(txsegs[i].ds_len); + + desc->packet_addr = txsegs[i].ds_addr; + /* link with previous descriptor */ + if (prev_desc) + prev_desc->packet_ctrl |= ARGE_DESC_MORE; + + sc->arge_cdata.arge_tx_cnt++; + prev_desc = desc; + ARGE_INC(prod, ARGE_TX_RING_COUNT); + } + + /* Update producer index. */ + sc->arge_cdata.arge_tx_prod = prod; + + /* Sync descriptors. */ + bus_dmamap_sync(sc->arge_cdata.arge_tx_ring_tag, + sc->arge_cdata.arge_tx_ring_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + + /* Start transmitting */ + ARGE_WRITE(sc, AR71XX_DMA_TX_CONTROL, DMA_TX_CONTROL_EN); + return (0); +} + +static void +arge_start(struct ifnet *ifp) +{ + struct arge_softc *sc; + + sc = ifp->if_softc; + + ARGE_LOCK(sc); + arge_start_locked(ifp); + ARGE_UNLOCK(sc); +} + +static void +arge_start_locked(struct ifnet *ifp) +{ + struct arge_softc *sc; + struct mbuf *m_head; + int enq; + + sc = ifp->if_softc; + + ARGE_LOCK_ASSERT(sc); + + if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != + IFF_DRV_RUNNING || sc->arge_link_status == 0 ) + return; + + arge_flush_ddr(sc); + + for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) && + sc->arge_cdata.arge_tx_cnt < ARGE_TX_RING_COUNT - 2; ) { + IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); + if (m_head == NULL) + break; + + /* + * Fix mbuf chain, all fragments should be 4 bytes aligned and + * even 4 bytes + */ + arge_fix_chain(&m_head); + + if (m_head == NULL) { + dprintf("failed to adjust mbuf chain\n"); + } + + /* + * Pack the data into the transmit ring. + */ + if (arge_encap(sc, &m_head)) { + if (m_head == NULL) + break; + IFQ_DRV_PREPEND(&ifp->if_snd, m_head); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } + + enq++; + /* + * If there's a BPF listener, bounce a copy of this frame + * to him. + */ + ETHER_BPF_MTAP(ifp, m_head); + } +} + +static void +arge_stop(struct arge_softc *sc) +{ + struct ifnet *ifp; + + ARGE_LOCK_ASSERT(sc); + + ifp = sc->arge_ifp; + ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + callout_stop(&sc->arge_stat_callout); + + /* mask out interrupts */ + ARGE_WRITE(sc, AR71XX_DMA_INTR, 0); + + arge_reset_dma(sc); +} + + +static int +arge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) +{ + struct arge_softc *sc = ifp->if_softc; + struct ifreq *ifr = (struct ifreq *) data; + struct mii_data *mii; + int error; + + switch (command) { + case SIOCSIFFLAGS: + printf("Implement me: SIOCSIFFLAGS\n"); + error = 0; + break; + case SIOCADDMULTI: + case SIOCDELMULTI: + printf("Implement me: SIOCDELMULTI\n"); + error = 0; + break; + case SIOCGIFMEDIA: + case SIOCSIFMEDIA: + printf("Implement me: SIOCSIFMEDIA\n"); + mii = device_get_softc(sc->arge_miibus); + error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); + break; + case SIOCSIFCAP: + error = 0; + ifp->if_hwassist = 0; + printf("Implement me: SIOCSIFCAP\n"); + break; + default: + error = ether_ioctl(ifp, command, data); + break; + } + + return (error); +} + +/* + * Set media options. + */ +static int +arge_ifmedia_upd(struct ifnet *ifp) +{ + struct arge_softc *sc; + struct mii_data *mii; + struct mii_softc *miisc; + int error; + + sc = ifp->if_softc; + ARGE_LOCK(sc); + mii = device_get_softc(sc->arge_miibus); + if (mii->mii_instance) { + LIST_FOREACH(miisc, &mii->mii_phys, mii_list) + mii_phy_reset(miisc); + } + error = mii_mediachg(mii); + ARGE_UNLOCK(sc); + + return (error); +} + +/* + * Report current media status. + */ +static void +arge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) +{ + struct arge_softc *sc = ifp->if_softc; + struct mii_data *mii; + + mii = device_get_softc(sc->arge_miibus); + ARGE_LOCK(sc); + mii_pollstat(mii); + ARGE_UNLOCK(sc); + ifmr->ifm_active = mii->mii_media_active; + ifmr->ifm_status = mii->mii_media_status; +} + +struct arge_dmamap_arg { + bus_addr_t arge_busaddr; +}; + +static void +arge_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) +{ + struct arge_dmamap_arg *ctx; + + if (error != 0) + return; + ctx = arg; + ctx->arge_busaddr = segs[0].ds_addr; +} + +static int +arge_dma_alloc(struct arge_softc *sc) +{ + struct arge_dmamap_arg ctx; + struct arge_txdesc *txd; + struct arge_rxdesc *rxd; + int error, i; + + /* Create parent DMA tag. */ + error = bus_dma_tag_create( + bus_get_dma_tag(sc->arge_dev), /* parent */ + 1, 0, /* alignment, boundary */ + BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + BUS_SPACE_MAXSIZE_32BIT, /* maxsize */ + 0, /* nsegments */ + BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ + 0, /* flags */ + NULL, NULL, /* lockfunc, lockarg */ + &sc->arge_cdata.arge_parent_tag); + if (error != 0) { + device_printf(sc->arge_dev, "failed to create parent DMA tag\n"); + goto fail; + } + /* Create tag for Tx ring. */ + error = bus_dma_tag_create( + sc->arge_cdata.arge_parent_tag, /* parent */ + ARGE_RING_ALIGN, 0, /* alignment, boundary */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + ARGE_TX_DMA_SIZE, /* maxsize */ + 1, /* nsegments */ + ARGE_TX_DMA_SIZE, /* maxsegsize */ + 0, /* flags */ + NULL, NULL, /* lockfunc, lockarg */ + &sc->arge_cdata.arge_tx_ring_tag); + if (error != 0) { + device_printf(sc->arge_dev, "failed to create Tx ring DMA tag\n"); + goto fail; + } + + /* Create tag for Rx ring. */ + error = bus_dma_tag_create( + sc->arge_cdata.arge_parent_tag, /* parent */ + ARGE_RING_ALIGN, 0, /* alignment, boundary */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + ARGE_RX_DMA_SIZE, /* maxsize */ + 1, /* nsegments */ + ARGE_RX_DMA_SIZE, /* maxsegsize */ + 0, /* flags */ + NULL, NULL, /* lockfunc, lockarg */ + &sc->arge_cdata.arge_rx_ring_tag); + if (error != 0) { + device_printf(sc->arge_dev, "failed to create Rx ring DMA tag\n"); + goto fail; + } + + /* Create tag for Tx buffers. */ + error = bus_dma_tag_create( + sc->arge_cdata.arge_parent_tag, /* parent */ + sizeof(uint32_t), 0, /* alignment, boundary */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + MCLBYTES * ARGE_MAXFRAGS, /* maxsize */ + ARGE_MAXFRAGS, /* nsegments */ + MCLBYTES, /* maxsegsize */ + 0, /* flags */ + NULL, NULL, /* lockfunc, lockarg */ + &sc->arge_cdata.arge_tx_tag); + if (error != 0) { + device_printf(sc->arge_dev, "failed to create Tx DMA tag\n"); + goto fail; + } + + /* Create tag for Rx buffers. */ + error = bus_dma_tag_create( + sc->arge_cdata.arge_parent_tag, /* parent */ + ARGE_RX_ALIGN, 0, /* alignment, boundary */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + MCLBYTES, /* maxsize */ + 1, /* nsegments */ + MCLBYTES, /* maxsegsize */ + 0, /* flags */ + NULL, NULL, /* lockfunc, lockarg */ + &sc->arge_cdata.arge_rx_tag); + if (error != 0) { + device_printf(sc->arge_dev, "failed to create Rx DMA tag\n"); + goto fail; + } + + /* Allocate DMA'able memory and load the DMA map for Tx ring. */ + error = bus_dmamem_alloc(sc->arge_cdata.arge_tx_ring_tag, + (void **)&sc->arge_rdata.arge_tx_ring, BUS_DMA_WAITOK | + BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->arge_cdata.arge_tx_ring_map); + if (error != 0) { + device_printf(sc->arge_dev, + "failed to allocate DMA'able memory for Tx ring\n"); + goto fail; + } + + ctx.arge_busaddr = 0; + error = bus_dmamap_load(sc->arge_cdata.arge_tx_ring_tag, + sc->arge_cdata.arge_tx_ring_map, sc->arge_rdata.arge_tx_ring, + ARGE_TX_DMA_SIZE, arge_dmamap_cb, &ctx, 0); + if (error != 0 || ctx.arge_busaddr == 0) { + device_printf(sc->arge_dev, + "failed to load DMA'able memory for Tx ring\n"); + goto fail; + } + sc->arge_rdata.arge_tx_ring_paddr = ctx.arge_busaddr; + + /* Allocate DMA'able memory and load the DMA map for Rx ring. */ + error = bus_dmamem_alloc(sc->arge_cdata.arge_rx_ring_tag, + (void **)&sc->arge_rdata.arge_rx_ring, BUS_DMA_WAITOK | + BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->arge_cdata.arge_rx_ring_map); + if (error != 0) { + device_printf(sc->arge_dev, + "failed to allocate DMA'able memory for Rx ring\n"); + goto fail; + } + + ctx.arge_busaddr = 0; + error = bus_dmamap_load(sc->arge_cdata.arge_rx_ring_tag, + sc->arge_cdata.arge_rx_ring_map, sc->arge_rdata.arge_rx_ring, + ARGE_RX_DMA_SIZE, arge_dmamap_cb, &ctx, 0); + if (error != 0 || ctx.arge_busaddr == 0) { + device_printf(sc->arge_dev, + "failed to load DMA'able memory for Rx ring\n"); + goto fail; + } + sc->arge_rdata.arge_rx_ring_paddr = ctx.arge_busaddr; + + /* Create DMA maps for Tx buffers. */ + for (i = 0; i < ARGE_TX_RING_COUNT; i++) { + txd = &sc->arge_cdata.arge_txdesc[i]; + txd->tx_m = NULL; + txd->tx_dmamap = NULL; + error = bus_dmamap_create(sc->arge_cdata.arge_tx_tag, 0, + &txd->tx_dmamap); + if (error != 0) { + device_printf(sc->arge_dev, + "failed to create Tx dmamap\n"); + goto fail; + } + } + /* Create DMA maps for Rx buffers. */ + if ((error = bus_dmamap_create(sc->arge_cdata.arge_rx_tag, 0, + &sc->arge_cdata.arge_rx_sparemap)) != 0) { + device_printf(sc->arge_dev, + "failed to create spare Rx dmamap\n"); + goto fail; + } + for (i = 0; i < ARGE_RX_RING_COUNT; i++) { + rxd = &sc->arge_cdata.arge_rxdesc[i]; + rxd->rx_m = NULL; + rxd->rx_dmamap = NULL; + error = bus_dmamap_create(sc->arge_cdata.arge_rx_tag, 0, + &rxd->rx_dmamap); + if (error != 0) { + device_printf(sc->arge_dev, + "failed to create Rx dmamap\n"); + goto fail; + } + } + +fail: + return (error); +} + +static void +arge_dma_free(struct arge_softc *sc) +{ + struct arge_txdesc *txd; + struct arge_rxdesc *rxd; + int i; + + /* Tx ring. */ + if (sc->arge_cdata.arge_tx_ring_tag) { + if (sc->arge_cdata.arge_tx_ring_map) + bus_dmamap_unload(sc->arge_cdata.arge_tx_ring_tag, + sc->arge_cdata.arge_tx_ring_map); + if (sc->arge_cdata.arge_tx_ring_map && + sc->arge_rdata.arge_tx_ring) + bus_dmamem_free(sc->arge_cdata.arge_tx_ring_tag, + sc->arge_rdata.arge_tx_ring, + sc->arge_cdata.arge_tx_ring_map); + sc->arge_rdata.arge_tx_ring = NULL; + sc->arge_cdata.arge_tx_ring_map = NULL; + bus_dma_tag_destroy(sc->arge_cdata.arge_tx_ring_tag); + sc->arge_cdata.arge_tx_ring_tag = NULL; + } + /* Rx ring. */ + if (sc->arge_cdata.arge_rx_ring_tag) { + if (sc->arge_cdata.arge_rx_ring_map) + bus_dmamap_unload(sc->arge_cdata.arge_rx_ring_tag, + sc->arge_cdata.arge_rx_ring_map); + if (sc->arge_cdata.arge_rx_ring_map && + sc->arge_rdata.arge_rx_ring) + bus_dmamem_free(sc->arge_cdata.arge_rx_ring_tag, + sc->arge_rdata.arge_rx_ring, + sc->arge_cdata.arge_rx_ring_map); + sc->arge_rdata.arge_rx_ring = NULL; + sc->arge_cdata.arge_rx_ring_map = NULL; + bus_dma_tag_destroy(sc->arge_cdata.arge_rx_ring_tag); + sc->arge_cdata.arge_rx_ring_tag = NULL; + } + /* Tx buffers. */ + if (sc->arge_cdata.arge_tx_tag) { + for (i = 0; i < ARGE_TX_RING_COUNT; i++) { + txd = &sc->arge_cdata.arge_txdesc[i]; + if (txd->tx_dmamap) { + bus_dmamap_destroy(sc->arge_cdata.arge_tx_tag, + txd->tx_dmamap); + txd->tx_dmamap = NULL; + } + } + bus_dma_tag_destroy(sc->arge_cdata.arge_tx_tag); + sc->arge_cdata.arge_tx_tag = NULL; + } + /* Rx buffers. */ + if (sc->arge_cdata.arge_rx_tag) { + for (i = 0; i < ARGE_RX_RING_COUNT; i++) { + rxd = &sc->arge_cdata.arge_rxdesc[i]; + if (rxd->rx_dmamap) { + bus_dmamap_destroy(sc->arge_cdata.arge_rx_tag, + rxd->rx_dmamap); + rxd->rx_dmamap = NULL; + } + } + if (sc->arge_cdata.arge_rx_sparemap) { + bus_dmamap_destroy(sc->arge_cdata.arge_rx_tag, + sc->arge_cdata.arge_rx_sparemap); + sc->arge_cdata.arge_rx_sparemap = 0; + } + bus_dma_tag_destroy(sc->arge_cdata.arge_rx_tag); + sc->arge_cdata.arge_rx_tag = NULL; + } + + if (sc->arge_cdata.arge_parent_tag) { + bus_dma_tag_destroy(sc->arge_cdata.arge_parent_tag); + sc->arge_cdata.arge_parent_tag = NULL; + } +} + +/* + * Initialize the transmit descriptors. + */ +static int +arge_tx_ring_init(struct arge_softc *sc) +{ + struct arge_ring_data *rd; + struct arge_txdesc *txd; + bus_addr_t addr; + int i; + + sc->arge_cdata.arge_tx_prod = 0; + sc->arge_cdata.arge_tx_cons = 0; + sc->arge_cdata.arge_tx_cnt = 0; + sc->arge_cdata.arge_tx_pkts = 0; + + rd = &sc->arge_rdata; + bzero(rd->arge_tx_ring, sizeof(rd->arge_tx_ring)); + for (i = 0; i < ARGE_TX_RING_COUNT; i++) { + if (i == ARGE_TX_RING_COUNT - 1) + addr = ARGE_TX_RING_ADDR(sc, 0); + else + addr = ARGE_TX_RING_ADDR(sc, i + 1); + rd->arge_tx_ring[i].packet_ctrl = ARGE_DESC_EMPTY; + rd->arge_tx_ring[i].next_desc = addr; + txd = &sc->arge_cdata.arge_txdesc[i]; + txd->tx_m = NULL; + } + + bus_dmamap_sync(sc->arge_cdata.arge_tx_ring_tag, + sc->arge_cdata.arge_tx_ring_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + + return (0); +} + +/* + * Initialize the RX descriptors and allocate mbufs for them. Note that + * we arrange the descriptors in a closed ring, so that the last descriptor + * points back to the first. + */ +static int +arge_rx_ring_init(struct arge_softc *sc) +{ + struct arge_ring_data *rd; + struct arge_rxdesc *rxd; + bus_addr_t addr; + int i; + + sc->arge_cdata.arge_rx_cons = 0; + + rd = &sc->arge_rdata; + bzero(rd->arge_rx_ring, sizeof(rd->arge_rx_ring)); + for (i = 0; i < ARGE_RX_RING_COUNT; i++) { + rxd = &sc->arge_cdata.arge_rxdesc[i]; + rxd->rx_m = NULL; + rxd->desc = &rd->arge_rx_ring[i]; + if (i == ARGE_RX_RING_COUNT - 1) + addr = ARGE_RX_RING_ADDR(sc, 0); + else + addr = ARGE_RX_RING_ADDR(sc, i + 1); + rd->arge_rx_ring[i].packet_ctrl = ARGE_DESC_EMPTY; + rd->arge_rx_ring[i].next_desc = addr; + if (arge_newbuf(sc, i) != 0) + return (ENOBUFS); + } + + bus_dmamap_sync(sc->arge_cdata.arge_rx_ring_tag, + sc->arge_cdata.arge_rx_ring_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + + return (0); +} + +/* + * Initialize an RX descriptor and attach an MBUF cluster. + */ +static int +arge_newbuf(struct arge_softc *sc, int idx) +{ + struct arge_desc *desc; + struct arge_rxdesc *rxd; + struct mbuf *m; + bus_dma_segment_t segs[1]; + bus_dmamap_t map; + int nsegs; + + m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); + if (m == NULL) + return (ENOBUFS); + m->m_len = m->m_pkthdr.len = MCLBYTES; + m_adj(m, sizeof(uint64_t)); + + if (bus_dmamap_load_mbuf_sg(sc->arge_cdata.arge_rx_tag, + sc->arge_cdata.arge_rx_sparemap, m, segs, &nsegs, 0) != 0) { + m_freem(m); + return (ENOBUFS); + } + KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs)); + + rxd = &sc->arge_cdata.arge_rxdesc[idx]; + if (rxd->rx_m != NULL) { + bus_dmamap_sync(sc->arge_cdata.arge_rx_tag, rxd->rx_dmamap, + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->arge_cdata.arge_rx_tag, rxd->rx_dmamap); + } + map = rxd->rx_dmamap; + rxd->rx_dmamap = sc->arge_cdata.arge_rx_sparemap; + sc->arge_cdata.arge_rx_sparemap = map; + bus_dmamap_sync(sc->arge_cdata.arge_rx_tag, rxd->rx_dmamap, + BUS_DMASYNC_PREREAD); + rxd->rx_m = m; + desc = rxd->desc; + desc->packet_addr = segs[0].ds_addr; + desc->packet_ctrl = (desc->packet_ctrl & ~ARGE_DESC_SIZE_MASK) + | ARGE_DMASIZE(segs[0].ds_len); + + return (0); +} + +static __inline void +arge_fixup_rx(struct mbuf *m) +{ + int i; + uint16_t *src, *dst; + + src = mtod(m, uint16_t *); + dst = src - 1; + + for (i = 0; i < (m->m_len / sizeof(uint16_t) + 1); i++) + *dst++ = *src++; + + m->m_data -= ETHER_ALIGN; +} + + +static void +arge_tx_locked(struct arge_softc *sc) +{ + struct arge_txdesc *txd; + struct arge_desc *cur_tx; + struct ifnet *ifp; + uint32_t ctrl; + int cons, prod; + + ARGE_LOCK_ASSERT(sc); + + cons = sc->arge_cdata.arge_tx_cons; + prod = sc->arge_cdata.arge_tx_prod; + if (cons == prod) + return; + + bus_dmamap_sync(sc->arge_cdata.arge_tx_ring_tag, + sc->arge_cdata.arge_tx_ring_map, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + + ifp = sc->arge_ifp; + /* + * Go through our tx list and free mbufs for those + * frames that have been transmitted. + */ + for (; cons != prod; ARGE_INC(cons, ARGE_TX_RING_COUNT)) { + cur_tx = &sc->arge_rdata.arge_tx_ring[cons]; + ctrl = cur_tx->packet_ctrl; + /* Check if descriptor has "finished" flag */ + if ((ctrl & ARGE_DESC_EMPTY) == 0) + break; + + ARGE_WRITE(sc, AR71XX_DMA_TX_STATUS, DMA_TX_STATUS_PKT_SENT); + + sc->arge_cdata.arge_tx_cnt--; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + + txd = &sc->arge_cdata.arge_txdesc[cons]; + + cur_tx->packet_ctrl = ARGE_DESC_EMPTY; + + ifp->if_opackets++; + + bus_dmamap_sync(sc->arge_cdata.arge_tx_tag, txd->tx_dmamap, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->arge_cdata.arge_tx_tag, txd->tx_dmamap); + + /* Free only if it's first descriptor in list */ + if (txd->tx_m) + m_freem(txd->tx_m); + txd->tx_m = NULL; + + /* reset descriptor */ + cur_tx->packet_ctrl = ARGE_DESC_EMPTY; + cur_tx->packet_addr = 0; + } + + sc->arge_cdata.arge_tx_cons = cons; + + bus_dmamap_sync(sc->arge_cdata.arge_tx_ring_tag, + sc->arge_cdata.arge_tx_ring_map, BUS_DMASYNC_PREWRITE); +} + + +static void +arge_rx_locked(struct arge_softc *sc) +{ + struct arge_rxdesc *rxd; + struct ifnet *ifp = sc->arge_ifp; + int cons, prog, packet_len; + struct arge_desc *cur_rx; + struct mbuf *m; + + ARGE_LOCK_ASSERT(sc); + + cons = sc->arge_cdata.arge_rx_cons; + + bus_dmamap_sync(sc->arge_cdata.arge_rx_ring_tag, + sc->arge_cdata.arge_rx_ring_map, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + + for (prog = 0; prog < ARGE_RX_RING_COUNT; + ARGE_INC(cons, ARGE_RX_RING_COUNT)) { + cur_rx = &sc->arge_rdata.arge_rx_ring[cons]; + rxd = &sc->arge_cdata.arge_rxdesc[cons]; + m = rxd->rx_m; + + if ((cur_rx->packet_ctrl & ARGE_DESC_EMPTY) != 0) + break; + + ARGE_WRITE(sc, AR71XX_DMA_RX_STATUS, DMA_RX_STATUS_PKT_RECVD); + + prog++; + + packet_len = ARGE_DMASIZE(cur_rx->packet_ctrl); + bus_dmamap_sync(sc->arge_cdata.arge_rx_tag, rxd->rx_dmamap, + BUS_DMASYNC_PREREAD); + m = rxd->rx_m; + + arge_fixup_rx(m); + m->m_pkthdr.rcvif = ifp; + /* Skip 4 bytes of CRC */ + m->m_pkthdr.len = m->m_len = packet_len - ETHER_CRC_LEN; + ifp->if_ipackets++; + + ARGE_UNLOCK(sc); + (*ifp->if_input)(ifp, m); + ARGE_LOCK(sc); + + /* Reinit descriptor */ + cur_rx->packet_ctrl = ARGE_DESC_EMPTY; + cur_rx->packet_addr = 0; + if (arge_newbuf(sc, cons) != 0) { + device_printf(sc->arge_dev, + "Failed to allocate buffer\n"); + break; + } + + bus_dmamap_sync(sc->arge_cdata.arge_rx_ring_tag, + sc->arge_cdata.arge_rx_ring_map, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + + } + + if (prog > 0) { + sc->arge_cdata.arge_rx_cons = cons; + + bus_dmamap_sync(sc->arge_cdata.arge_rx_ring_tag, + sc->arge_cdata.arge_rx_ring_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + } +} + +static void +arge_rx_intr(struct arge_softc *sc, uint32_t status) +{ + + ARGE_LOCK(sc); + /* interrupts are masked by filter */ + arge_rx_locked(sc); + + /* unmask interrupts */ + ARGE_SET_BITS(sc, + AR71XX_DMA_INTR, DMA_INTR_RX_OVERFLOW | DMA_INTR_RX_PKT_RCVD); + ARGE_UNLOCK(sc); +} + +static int +arge_intr_filter(void *arg) +{ + struct arge_softc *sc = arg; + uint32_t status, ints; + + status = ARGE_READ(sc, AR71XX_DMA_INTR_STATUS); + ints = ARGE_READ(sc, AR71XX_DMA_INTR); + +#if 0 + dprintf("int mask(filter) = %b\n", ints, + "\20\10RX_BUS_ERROR\7RX_OVERFLOW\5RX_PKT_RCVD" + "\4TX_BUS_ERROR\2TX_UNDERRUN\1TX_PKT_SENT"); + dprintf("status(filter) = %b\n", status, + "\20\10RX_BUS_ERROR\7RX_OVERFLOW\5RX_PKT_RCVD" + "\4TX_BUS_ERROR\2TX_UNDERRUN\1TX_PKT_SENT"); +#endif + + if (status & DMA_INTR_ALL) { + if (status & (DMA_INTR_RX_PKT_RCVD | DMA_INTR_RX_OVERFLOW)) + ARGE_CLEAR_BITS(sc, AR71XX_DMA_INTR, + DMA_INTR_RX_OVERFLOW | DMA_INTR_RX_PKT_RCVD); + + if (status & (DMA_INTR_TX_PKT_SENT | DMA_INTR_TX_UNDERRUN)) + ARGE_CLEAR_BITS(sc, AR71XX_DMA_INTR, + DMA_INTR_TX_UNDERRUN | DMA_INTR_TX_PKT_SENT); + + sc->arge_intr_status = status; + return (FILTER_SCHEDULE_THREAD); + } + + sc->arge_intr_status = 0; + return (FILTER_STRAY); +} + +static void +arge_intr(void *arg) +{ + struct arge_softc *sc = arg; + uint32_t status; + + status = sc->arge_intr_status; + +#if 0 + dprintf("int status(intr) = %b\n", status, + "\20\10\7RX_OVERFLOW\5RX_PKT_RCVD" + "\4TX_BUS_ERROR\2TX_UNDERRUN\1TX_PKT_SENT"); +#endif + + /* + * Is it our interrupt at all? + */ + if (status == 0) + return; + + if (status & DMA_INTR_RX_BUS_ERROR) { + ARGE_WRITE(sc, AR71XX_DMA_RX_STATUS, DMA_RX_STATUS_BUS_ERROR); + device_printf(sc->arge_dev, "RX bus error"); + return; + } + + if (status & DMA_INTR_TX_BUS_ERROR) { + ARGE_WRITE(sc, AR71XX_DMA_TX_STATUS, DMA_TX_STATUS_BUS_ERROR); + device_printf(sc->arge_dev, "TX bus error"); + return; + } + + if (status & (DMA_INTR_RX_PKT_RCVD | DMA_INTR_RX_OVERFLOW)) + arge_rx_intr(sc, status); + + if (status & (DMA_INTR_TX_PKT_SENT | DMA_INTR_TX_UNDERRUN)) + arge_tx_intr(sc, status); +} + +static void +arge_tx_intr(struct arge_softc *sc, uint32_t status) +{ + ARGE_LOCK(sc); + + /* Interrupts are masked by filter */ + arge_tx_locked(sc); + + ARGE_UNLOCK(sc); +} + +static void +arge_tick(void *xsc) +{ + struct arge_softc *sc = xsc; + struct mii_data *mii; + + ARGE_LOCK_ASSERT(sc); + + mii = device_get_softc(sc->arge_miibus); + mii_tick(mii); + callout_reset(&sc->arge_stat_callout, hz, arge_tick, sc); +} + +/* + * Create a copy of a single mbuf. It can have either internal or + * external data, it may have a packet header. External data is really + * copied, so the new buffer is writeable. + */ +static struct mbuf * +copy_mbuf(struct mbuf *m) +{ + struct mbuf *new; + + MGET(new, M_DONTWAIT, MT_DATA); + if (new == NULL) + return (NULL); + + if (m->m_flags & M_PKTHDR) { + M_MOVE_PKTHDR(new, m); + if (m->m_len > MHLEN) + MCLGET(new, M_WAIT); + } else { + if (m->m_len > MLEN) + MCLGET(new, M_WAIT); + } + + bcopy(m->m_data, new->m_data, m->m_len); + new->m_len = m->m_len; + new->m_flags &= ~M_RDONLY; + + return (new); +} + + + +static int +arge_fix_chain(struct mbuf **mp) +{ + struct mbuf *m = *mp, *prev = NULL, *next, *new; + u_int mlen = 0, fill = 0; + int first, off; + u_char *d, *cp; + + do { + next = m->m_next; + + if ((uintptr_t)mtod(m, void *) % 4 != 0 || + (m->m_len % 4 != 0 && next)) { + /* + * Needs fixing + */ + first = (m == *mp); + + d = mtod(m, u_char *); + if ((off = (uintptr_t)(void *)d % 4) != 0) { + if (M_WRITABLE(m)) { + bcopy(d, d - off, m->m_len); + m->m_data = (caddr_t)(d - off); + } else { + if ((new = copy_mbuf(m)) == NULL) { + goto fail; + } + if (prev) + prev->m_next = new; + new->m_next = next; + m_free(m); + m = new; + } + } + + if ((off = m->m_len % 4) != 0) { + if (!M_WRITABLE(m)) { + if ((new = copy_mbuf(m)) == NULL) { + goto fail; + } + if (prev) + prev->m_next = new; + new->m_next = next; + m_free(m); + m = new; + } + d = mtod(m, u_char *) + m->m_len; + off = 4 - off; + while (off) { + if (next == NULL) { + *d++ = 0; + fill++; + } else if (next->m_len == 0) { + next = m_free(next); + continue; + } else { + cp = mtod(next, u_char *); + *d++ = *cp++; + next->m_len--; + next->m_data = (caddr_t)cp; + } + off--; + m->m_len++; + } + } + + if (first) + *mp = m; + } + + mlen += m->m_len; + prev = m; + } while ((m = next) != NULL); + + return (mlen - fill); + + fail: + m_freem(*mp); + *mp = NULL; + return (0); +} diff --git a/sys/mips/atheros/if_argevar.h b/sys/mips/atheros/if_argevar.h new file mode 100644 index 00000000000..1966e61aeec --- /dev/null +++ b/sys/mips/atheros/if_argevar.h @@ -0,0 +1,138 @@ +/*- + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __IF_ARGEVAR_H__ +#define __IF_ARGEVAR_H__ + +#define ARGE_TX_RING_COUNT 128 +#define ARGE_RX_RING_COUNT 128 +#define ARGE_RX_DMA_SIZE ARGE_RX_RING_COUNT * sizeof(struct arge_desc) +#define ARGE_TX_DMA_SIZE ARGE_TX_RING_COUNT * sizeof(struct arge_desc) +#define ARGE_MAXFRAGS 8 +#define ARGE_RING_ALIGN sizeof(struct arge_desc) +#define ARGE_RX_ALIGN sizeof(uint32_t) +#define ARGE_MAXFRAGS 8 +#define ARGE_TX_RING_ADDR(sc, i) \ + ((sc)->arge_rdata.arge_tx_ring_paddr + sizeof(struct arge_desc) * (i)) +#define ARGE_RX_RING_ADDR(sc, i) \ + ((sc)->arge_rdata.arge_rx_ring_paddr + sizeof(struct arge_desc) * (i)) +#define ARGE_INC(x,y) (x) = (((x) + 1) % y) + + +#define ARGE_MII_TIMEOUT 1000 + +#define ARGE_LOCK(_sc) mtx_lock(&(_sc)->arge_mtx) +#define ARGE_UNLOCK(_sc) mtx_unlock(&(_sc)->arge_mtx) +#define ARGE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->arge_mtx, MA_OWNED) + +/* + * register space access macros + */ +#define ARGE_WRITE(sc, reg, val) do { \ + bus_write_4(sc->arge_res, (reg), (val)); \ + } while (0) + +#define ARGE_READ(sc, reg) bus_read_4(sc->arge_res, (reg)) + +#define ARGE_SET_BITS(sc, reg, bits) \ + ARGE_WRITE(sc, reg, ARGE_READ(sc, (reg)) | (bits)) + +#define ARGE_CLEAR_BITS(sc, reg, bits) \ + ARGE_WRITE(sc, reg, ARGE_READ(sc, (reg)) & ~(bits)) + +#define ARGE_DESC_EMPTY (1 << 31) +#define ARGE_DESC_MORE (1 << 24) +#define ARGE_DESC_SIZE_MASK ((1 << 12) - 1) +#define ARGE_DMASIZE(len) ((len) & ARGE_DESC_SIZE_MASK) +struct arge_desc { + uint32_t packet_addr; + uint32_t packet_ctrl; + uint32_t next_desc; + uint32_t padding; +}; + +struct arge_txdesc { + struct mbuf *tx_m; + bus_dmamap_t tx_dmamap; +}; + +struct arge_rxdesc { + struct mbuf *rx_m; + bus_dmamap_t rx_dmamap; + struct arge_desc *desc; +}; + +struct arge_chain_data { + bus_dma_tag_t arge_parent_tag; + bus_dma_tag_t arge_tx_tag; + struct arge_txdesc arge_txdesc[ARGE_TX_RING_COUNT]; + bus_dma_tag_t arge_rx_tag; + struct arge_rxdesc arge_rxdesc[ARGE_RX_RING_COUNT]; + bus_dma_tag_t arge_tx_ring_tag; + bus_dma_tag_t arge_rx_ring_tag; + bus_dmamap_t arge_tx_ring_map; + bus_dmamap_t arge_rx_ring_map; + bus_dmamap_t arge_rx_sparemap; + int arge_tx_pkts; + int arge_tx_prod; + int arge_tx_cons; + int arge_tx_cnt; + int arge_rx_cons; +}; + +struct arge_ring_data { + struct arge_desc *arge_rx_ring; + struct arge_desc *arge_tx_ring; + bus_addr_t arge_rx_ring_paddr; + bus_addr_t arge_tx_ring_paddr; +}; + +struct arge_softc { + struct ifnet *arge_ifp; /* interface info */ + device_t arge_dev; + struct resource *arge_res; + int arge_rid; + struct resource *arge_irq; + void *arge_intrhand; + device_t arge_miibus; + bus_dma_tag_t arge_parent_tag; + bus_dma_tag_t arge_tag; + struct mtx arge_mtx; + struct callout arge_stat_callout; + struct task arge_link_task; + struct arge_chain_data arge_cdata; + struct arge_ring_data arge_rdata; + int arge_link_status; + int arge_detach; + uint32_t arge_intr_status; + int arge_mac_unit; + int arge_phy_num; + uint32_t arge_ddr_flush_reg; + uint32_t arge_pll_reg; +}; + +#endif /* __IF_ARGEVAR_H__ */ From 245d4a9491d3dce059eba381a04f6d163488441f Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 19 Feb 2009 06:24:33 +0000 Subject: [PATCH 024/380] - Add if_arge to build --- sys/mips/atheros/files.ar71xx | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/mips/atheros/files.ar71xx b/sys/mips/atheros/files.ar71xx index 4eba2487b26..586bf7a98e4 100644 --- a/sys/mips/atheros/files.ar71xx +++ b/sys/mips/atheros/files.ar71xx @@ -3,5 +3,6 @@ mips/atheros/apb.c standard mips/atheros/ar71xx_machdep.c standard mips/atheros/ar71xx_pci.c optional pci +mips/atheros/if_arge.c optional arge mips/atheros/uart_bus_ar71xx.c optional uart mips/atheros/uart_cpu_ar71xx.c optional uart From 65ccb832d5bc8cb29baf741a960740e74b236938 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 19 Feb 2009 06:25:29 +0000 Subject: [PATCH 025/380] - Add GE0 port to hinted devices, GE1 will stay commented for a while --- sys/mips/conf/AR71XX.hints | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sys/mips/conf/AR71XX.hints b/sys/mips/conf/AR71XX.hints index f05995850c0..58fbddec01a 100644 --- a/sys/mips/conf/AR71XX.hints +++ b/sys/mips/conf/AR71XX.hints @@ -14,3 +14,12 @@ hint.uart.0.irq=3 # pci hint.pcib.0.at="nexus0" hint.pcib.0.irq=0 + +hint.arge.0.at="nexus0" +hint.arge.0.maddr=0x19000000 +hint.arge.0.msize=0x1000 +hint.arge.0.irq=2 +# hint.arge.1.at="nexus0" +# hint.arge.1.maddr=0x1A000000 +# hint.arge.1.msize=0x1000 +# hint.arge.1.irq=3 From 319ecb038d28e826c51dc1d1b4bc09fd9baaf5ee Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sat, 21 Feb 2009 03:11:43 +0000 Subject: [PATCH 026/380] - Add USB-related registers --- sys/mips/atheros/ar71xxreg.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/sys/mips/atheros/ar71xxreg.h b/sys/mips/atheros/ar71xxreg.h index ab653e13c31..93677922463 100644 --- a/sys/mips/atheros/ar71xxreg.h +++ b/sys/mips/atheros/ar71xxreg.h @@ -101,6 +101,31 @@ #define AR71XX_UART_ADDR 0x18020000 +#define AR71XX_USB_CTRL_FLADJ 0x18030000 +#define USB_CTRL_FLADJ_HOST_SHIFT 12 +#define USB_CTRL_FLADJ_A5_SHIFT 10 +#define USB_CTRL_FLADJ_A4_SHIFT 8 +#define USB_CTRL_FLADJ_A3_SHIFT 6 +#define USB_CTRL_FLADJ_A2_SHIFT 4 +#define USB_CTRL_FLADJ_A1_SHIFT 2 +#define USB_CTRL_FLADJ_A0_SHIFT 0 +#define AR71XX_USB_CTRL_CONFIG 0x18030004 +#define USB_CTRL_CONFIG_OHCI_DES_SWAP (1 << 19) +#define USB_CTRL_CONFIG_OHCI_BUF_SWAP (1 << 18) +#define USB_CTRL_CONFIG_EHCI_DES_SWAP (1 << 17) +#define USB_CTRL_CONFIG_EHCI_BUF_SWAP (1 << 16) +#define USB_CTRL_CONFIG_DISABLE_XTL (1 << 13) +#define USB_CTRL_CONFIG_OVERRIDE_XTL (1 << 12) +#define USB_CTRL_CONFIG_CLK_SEL_SHIFT 4 +#define USB_CTRL_CONFIG_CLK_SEL_MASK 3 +#define USB_CTRL_CONFIG_CLK_SEL_12 0 +#define USB_CTRL_CONFIG_CLK_SEL_24 1 +#define USB_CTRL_CONFIG_CLK_SEL_48 2 +#define USB_CTRL_CONFIG_OVER_CURRENT_AS_GPIO (1 << 8) +#define USB_CTRL_CONFIG_SS_SIMULATION_MODE (1 << 2) +#define USB_CTRL_CONFIG_RESUME_UTMI_PLS_DIS (1 << 1) +#define USB_CTRL_CONFIG_UTMI_BACKWARD_ENB (1 << 0) + #define AR71XX_PLL_CPU_CONFIG 0x18050000 #define AR71XX_PLL_SEC_CONFIG 0x18050004 #define AR71XX_PLL_CPU_CLK_CTRL 0x18050008 @@ -142,6 +167,9 @@ #define RST_RESET_GE1_PHY (1 << 12) #define RST_RESET_GE0_MAC (1 << 9) #define RST_RESET_GE0_PHY (1 << 8) +#define RST_RESET_USB_OHCI_DLL (1 << 6) +#define RST_RESET_USB_HOST (1 << 5) +#define RST_RESET_USB_PHY (1 << 4) #define RST_RESET_PCI_BUS (1 << 1) #define RST_RESET_PCI_CORE (1 << 0) From ce6abcd404a10b2553e1d4c3f69807c1460d4249 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sat, 21 Feb 2009 03:13:10 +0000 Subject: [PATCH 027/380] - Reset USB chip and init control registers --- sys/mips/atheros/ar71xx_machdep.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/sys/mips/atheros/ar71xx_machdep.c b/sys/mips/atheros/ar71xx_machdep.c index eac159a83a2..a5699edb7ee 100644 --- a/sys/mips/atheros/ar71xx_machdep.c +++ b/sys/mips/atheros/ar71xx_machdep.c @@ -98,6 +98,7 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, { vm_offset_t kernend; uint64_t platform_counter_freq; + uint32_t reg; /* clear the BSS and SBSS segments */ kernend = round_page((vm_offset_t)&end); @@ -134,6 +135,26 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, mips_proc0_init(); mutex_init(); + /* + * Reset USB devices + */ + reg = ATH_READ_REG(AR71XX_RST_RESET); + reg |= + RST_RESET_USB_OHCI_DLL | RST_RESET_USB_HOST | RST_RESET_USB_PHY; + ATH_WRITE_REG(AR71XX_RST_RESET, reg); + DELAY(1000); + reg &= + ~(RST_RESET_USB_OHCI_DLL | RST_RESET_USB_HOST | RST_RESET_USB_PHY); + ATH_WRITE_REG(AR71XX_RST_RESET, reg); + + ATH_WRITE_REG(AR71XX_USB_CTRL_CONFIG, + USB_CTRL_CONFIG_OHCI_DES_SWAP | USB_CTRL_CONFIG_OHCI_BUF_SWAP | + USB_CTRL_CONFIG_EHCI_DES_SWAP | USB_CTRL_CONFIG_EHCI_BUF_SWAP); + + ATH_WRITE_REG(AR71XX_USB_CTRL_FLADJ, + (32 << USB_CTRL_FLADJ_HOST_SHIFT) | (3 << USB_CTRL_FLADJ_A5_SHIFT)); + DELAY(1000); + #ifdef DDB kdb_init(); #endif From 03a7d33247cf987f3c69eea1567606e0bb396322 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sat, 21 Feb 2009 03:14:44 +0000 Subject: [PATCH 028/380] - Add some debug output - Do not manage memory, it's not neccessary. Just pass request up to nexus to map it to KSEG1 --- sys/mips/atheros/apb.c | 32 +++++++++++++++++++++----------- sys/mips/atheros/apbvar.h | 4 ---- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/sys/mips/atheros/apb.c b/sys/mips/atheros/apb.c index f1393423387..458a48cc302 100644 --- a/sys/mips/atheros/apb.c +++ b/sys/mips/atheros/apb.c @@ -42,6 +42,13 @@ __FBSDID("$FreeBSD$"); #include #include +#undef APB_DEBUG +#ifdef APB_DEBUG +#define dprintf printf +#else +#define dprintf(x, arg...) +#endif /* APB_DEBUG */ + static int apb_activate_resource(device_t, device_t, int, int, struct resource *); static device_t apb_add_child(device_t, int, const char *, int); @@ -94,13 +101,6 @@ apb_attach(device_t dev) int rid = 0; device_set_desc(dev, "APB Bus bridge"); - sc->apb_mem_rman.rm_type = RMAN_ARRAY; - sc->apb_mem_rman.rm_descr = "APB memory"; - if (rman_init(&sc->apb_mem_rman) != 0 || - rman_manage_region(&sc->apb_mem_rman, APB_MEM_START, - APB_MEM_END) != 0) - panic("apb_attach: failed to set up I/O rman"); - sc->apb_irq_rman.rm_type = RMAN_ARRAY; sc->apb_irq_rman.rm_descr = "APB IRQ"; @@ -142,9 +142,17 @@ apb_alloc_resource(device_t bus, device_t child, int type, int *rid, isdefault = (start == 0UL && end == ~0UL); needactivate = flags & RF_ACTIVE; - passthrough = (device_get_parent(child) != bus); + /* + * Pass memory requests to nexus device + */ + passthrough = (device_get_parent(child) != bus) || + (type == SYS_RES_MEMORY); rle = NULL; + dprintf("%s: entry (%p, %p, %d, %p, %p, %p, %ld, %d)\n", + __func__, bus, child, type, rid, (void *)(intptr_t)start, + (void *)(intptr_t)end, count, flags); + if (passthrough) return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, rid, start, end, count, flags)); @@ -157,6 +165,7 @@ apb_alloc_resource(device_t bus, device_t child, int type, int *rid, if (isdefault) { rle = resource_list_find(&ivar->resources, type, *rid); + printf("DEFAULT: %d, %p\n", *rid, rle); if (rle == NULL) { return (NULL); } @@ -167,15 +176,16 @@ apb_alloc_resource(device_t bus, device_t child, int type, int *rid, start = rle->start; end = rle->end; count = rle->count; + + dprintf("%s: default resource (%p, %p, %ld)\n", + __func__, (void *)(intptr_t)start, + (void *)(intptr_t)end, count); } switch (type) { case SYS_RES_IRQ: rm = &sc->apb_irq_rman; break; - case SYS_RES_MEMORY: - rm = &sc->apb_mem_rman; - break; default: printf("%s: unknown resource type %d\n", __func__, type); return (0); diff --git a/sys/mips/atheros/apbvar.h b/sys/mips/atheros/apbvar.h index 5ffdfd43e38..e1d29f4a662 100644 --- a/sys/mips/atheros/apbvar.h +++ b/sys/mips/atheros/apbvar.h @@ -28,15 +28,11 @@ #ifndef _APBVAR_H_ #define _APBVAR_H_ -#define APB_MEM_START 0x18000000 -#define APB_MEM_END 0x18ffffff - #define APB_IRQ_BASE 0 #define APB_IRQ_END 7 #define APB_NIRQS 8 struct apb_softc { - struct rman apb_mem_rman; struct rman apb_irq_rman; /* IRQ events structs for child devices */ struct intr_event *sc_eventstab[APB_NIRQS]; From 166d0cb71527dad06f781ccce917346a03acf7f9 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sat, 21 Feb 2009 03:36:43 +0000 Subject: [PATCH 029/380] - Add integrated OHCI controller driver, just a wrapper around generic ohci driver --- sys/mips/atheros/ar71xx_ohci.c | 205 +++++++++++++++++++++++++++++++++ sys/mips/atheros/files.ar71xx | 1 + 2 files changed, 206 insertions(+) create mode 100644 sys/mips/atheros/ar71xx_ohci.c diff --git a/sys/mips/atheros/ar71xx_ohci.c b/sys/mips/atheros/ar71xx_ohci.c new file mode 100644 index 00000000000..b7adc617b9c --- /dev/null +++ b/sys/mips/atheros/ar71xx_ohci.c @@ -0,0 +1,205 @@ +/*- + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +static int ar71xx_ohci_attach(device_t dev); +static int ar71xx_ohci_detach(device_t dev); +static int ar71xx_ohci_probe(device_t dev); + +struct ar71xx_ohci_softc +{ + struct ohci_softc sc_ohci; +}; + +static int +ar71xx_ohci_probe(device_t dev) +{ + device_set_desc(dev, "AR71XX integrated OHCI controller"); + return (BUS_PROBE_DEFAULT); +} + +static int +ar71xx_ohci_attach(device_t dev) +{ + struct ar71xx_ohci_softc *sc = device_get_softc(dev); + int err; + int rid; + + rid = 0; + sc->sc_ohci.io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (sc->sc_ohci.io_res == NULL) { + err = ENOMEM; + goto error; + } + sc->sc_ohci.iot = rman_get_bustag(sc->sc_ohci.io_res); + sc->sc_ohci.ioh = rman_get_bushandle(sc->sc_ohci.io_res); + + rid = 0; + sc->sc_ohci.irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_ACTIVE); + if (sc->sc_ohci.irq_res == NULL) { + err = ENOMEM; + goto error; + } + sc->sc_ohci.sc_bus.bdev = device_add_child(dev, "usb", -1); + if (sc->sc_ohci.sc_bus.bdev == NULL) { + err = ENOMEM; + goto error; + } + device_set_ivars(sc->sc_ohci.sc_bus.bdev, &sc->sc_ohci.sc_bus); + + /* Allocate a parent dma tag for DMA maps */ + err = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, + BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0, + NULL, NULL, &sc->sc_ohci.sc_bus.parent_dmatag); + if (err) { + device_printf(dev, "Could not allocate parent DMA tag (%d)\n", + err); + err = ENXIO; + goto error; + } + + /* Allocate a dma tag for transfer buffers */ + err = bus_dma_tag_create(sc->sc_ohci.sc_bus.parent_dmatag, 1, 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, + BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0, + busdma_lock_mutex, &Giant, &sc->sc_ohci.sc_bus.buffer_dmatag); + if (err) { + device_printf(dev, "Could not allocate transfer tag (%d)\n", + err); + err = ENXIO; + goto error; + } + + err = bus_setup_intr(dev, sc->sc_ohci.irq_res, INTR_TYPE_BIO, NULL, + ohci_intr, sc, &sc->sc_ohci.ih); + if (err) { + err = ENXIO; + goto error; + } + strlcpy(sc->sc_ohci.sc_vendor, "Atheros", + sizeof(sc->sc_ohci.sc_vendor)); + + bus_space_write_4(sc->sc_ohci.iot, sc->sc_ohci.ioh, OHCI_CONTROL, 0); + + err = ohci_init(&sc->sc_ohci); + if (!err) { + sc->sc_ohci.sc_flags |= OHCI_SCFLG_DONEINIT; + err = device_probe_and_attach(sc->sc_ohci.sc_bus.bdev); + } + +error: + if (err) { + ar71xx_ohci_detach(dev); + return (err); + } + return (err); +} + +static int +ar71xx_ohci_detach(device_t dev) +{ + struct ar71xx_ohci_softc *sc = device_get_softc(dev); + + if (sc->sc_ohci.sc_flags & OHCI_SCFLG_DONEINIT) { + ohci_detach(&sc->sc_ohci, 0); + sc->sc_ohci.sc_flags &= ~OHCI_SCFLG_DONEINIT; + } + + if (sc->sc_ohci.ih) { + bus_teardown_intr(dev, sc->sc_ohci.irq_res, sc->sc_ohci.ih); + sc->sc_ohci.ih = NULL; + } + + if (sc->sc_ohci.sc_bus.parent_dmatag != NULL) + bus_dma_tag_destroy(sc->sc_ohci.sc_bus.parent_dmatag); + if (sc->sc_ohci.sc_bus.buffer_dmatag != NULL) + bus_dma_tag_destroy(sc->sc_ohci.sc_bus.buffer_dmatag); + + if (sc->sc_ohci.sc_bus.bdev) { + device_delete_child(dev, sc->sc_ohci.sc_bus.bdev); + sc->sc_ohci.sc_bus.bdev = NULL; + } + if (sc->sc_ohci.irq_res) { + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_ohci.irq_res); + sc->sc_ohci.irq_res = NULL; + } + if (sc->sc_ohci.io_res) { + bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_ohci.io_res); + sc->sc_ohci.io_res = NULL; + sc->sc_ohci.iot = 0; + sc->sc_ohci.ioh = 0; + } + return (0); +} + +static device_method_t ohci_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, ar71xx_ohci_probe), + DEVMETHOD(device_attach, ar71xx_ohci_attach), + DEVMETHOD(device_detach, ar71xx_ohci_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + + /* Bus interface */ + DEVMETHOD(bus_print_child, bus_generic_print_child), + + {0, 0} +}; + +static driver_t ohci_driver = { + "ohci", + ohci_methods, + sizeof(struct ar71xx_ohci_softc), +}; + +static devclass_t ohci_devclass; + +DRIVER_MODULE(ohci, apb, ohci_driver, ohci_devclass, 0, 0); diff --git a/sys/mips/atheros/files.ar71xx b/sys/mips/atheros/files.ar71xx index 586bf7a98e4..78e1d9ce177 100644 --- a/sys/mips/atheros/files.ar71xx +++ b/sys/mips/atheros/files.ar71xx @@ -2,6 +2,7 @@ mips/atheros/apb.c standard mips/atheros/ar71xx_machdep.c standard +mips/atheros/ar71xx_ohci.c optional ohci mips/atheros/ar71xx_pci.c optional pci mips/atheros/if_arge.c optional arge mips/atheros/uart_bus_ar71xx.c optional uart From 0c23f7044e516f4bfc5b4d417e8110f2e9d9e8f4 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sat, 21 Feb 2009 03:37:10 +0000 Subject: [PATCH 030/380] - Remove some garbage output --- sys/mips/atheros/apb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/mips/atheros/apb.c b/sys/mips/atheros/apb.c index 458a48cc302..d53408c3b07 100644 --- a/sys/mips/atheros/apb.c +++ b/sys/mips/atheros/apb.c @@ -165,7 +165,6 @@ apb_alloc_resource(device_t bus, device_t child, int type, int *rid, if (isdefault) { rle = resource_list_find(&ivar->resources, type, *rid); - printf("DEFAULT: %d, %p\n", *rid, rle); if (rle == NULL) { return (NULL); } From 56c1ff198be378afedecb2c96d780157a1ae7ea3 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 13 Mar 2009 03:00:38 +0000 Subject: [PATCH 031/380] First cut at config file for mips alchemy based systems. --- sys/mips/alchemy/std.alchemy | 2 -- sys/mips/conf/ALCHEMY | 66 ++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 sys/mips/conf/ALCHEMY diff --git a/sys/mips/alchemy/std.alchemy b/sys/mips/alchemy/std.alchemy index c06d02c979f..a955b6765c4 100644 --- a/sys/mips/alchemy/std.alchemy +++ b/sys/mips/alchemy/std.alchemy @@ -6,5 +6,3 @@ files "../alchemy/files.alchemy" cpu CPU_MIPS4KC options ISA_MIPS32 - -device uart diff --git a/sys/mips/conf/ALCHEMY b/sys/mips/conf/ALCHEMY new file mode 100644 index 00000000000..c1fb59a11de --- /dev/null +++ b/sys/mips/conf/ALCHEMY @@ -0,0 +1,66 @@ +# ALCHEMY -- Generic kernel for Alchemy Au1xxx CPUs. +# +# For more information on this file, please read the handbook section on +# Kernel Configuration Files: +# +# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# +# The handbook is also available locally in /usr/share/doc/handbook +# if you've installed the doc distribution, otherwise always see the +# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# latest information. +# +# An exhaustive list of options and more detailed explanations of the +# device lines is also present in the ../../conf/NOTES and NOTES files. +# If you are in doubt as to the purpose or necessity of a line, check first +# in NOTES. +# +# $FreeBSD$ + +ident ALCHEMY + +makeoptions ARCH_FLAGS=-march=mips32 +makeoptions MIPS_LITTLE_ENDIAN=defined + +# Don't build any modules yet. +makeoptions MODULES_OVERRIDE="" + +include "../alchemy/std.alchemy" + +hints "ALCHEMY.hints" #Default places to look for devices. + +makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols + +options DDB +options KDB + +options SCHED_4BSD #4BSD scheduler +options INET #InterNETworking +options NFSCLIENT #Network Filesystem Client +options NFS_ROOT #NFS usable as /, requires NFSCLIENT +options PSEUDOFS #Pseudo-filesystem framework +# options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions + +options BOOTP +options BOOTP_NFSROOT +options BOOTP_NFSV3 +options BOOTP_WIRED_TO=admsw0 +options BOOTP_COMPAT + +# options FFS #Berkeley Fast Filesystem +# options SOFTUPDATES #Enable FFS soft updates support +# options UFS_ACL #Support for access control lists +# options UFS_DIRHASH #Improve performance on big directories +options ROOTDEVNAME=\"nfs:10.0.0.1:/mnt/bsd\" + + +# Debugging for use in -current +options INVARIANTS #Enable calls of extra sanity checking +options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS +#options WITNESS #Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed + +device loop +device ether +device uart +# device md From fd7391fc0cd3840d3f6301706737f65ea4b8ca40 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 14 Apr 2009 22:53:22 +0000 Subject: [PATCH 032/380] - Revert changes accidentally killed by merge operation --- sys/conf/Makefile.mips | 48 +- sys/conf/files.mips | 4 + sys/conf/ldscript.mips | 2 +- sys/{mips/sentry5 => dev/siba}/siba_cc.c | 0 sys/{mips/sentry5 => dev/siba}/siba_mips.c | 0 sys/{mips/sentry5 => dev/siba}/siba_sdram.c | 0 sys/mips/alchemy/alchemy_machdep.c | 157 ++ sys/mips/alchemy/aureg.h | 373 +++++ sys/mips/alchemy/files.alchemy | 7 + sys/mips/alchemy/obio.c | 501 ++++++ sys/mips/alchemy/std.alchemy | 8 + sys/mips/alchemy/uart_bus_alchemy.c | 87 + sys/mips/alchemy/uart_cpu_alchemy.c | 79 + sys/mips/atheros/apb.c | 433 +++++ sys/mips/atheros/apbvar.h | 48 + sys/mips/atheros/ar71xx_machdep.c | 161 ++ sys/mips/atheros/ar71xx_ohci.c | 205 +++ sys/mips/atheros/ar71xx_pci.c | 429 +++++ sys/mips/atheros/ar71xxreg.h | 317 ++++ sys/mips/atheros/files.ar71xx | 9 + sys/mips/atheros/if_arge.c | 1657 +++++++++++++++++++ sys/mips/atheros/if_argevar.h | 138 ++ sys/mips/atheros/uart_bus_ar71xx.c | 79 + sys/mips/atheros/uart_cpu_ar71xx.c | 78 + sys/mips/conf/ADM5120 | 1 - sys/mips/conf/ALCHEMY | 66 + sys/mips/conf/AR71XX | 37 + sys/mips/conf/AR71XX.hints | 25 + sys/mips/conf/MALTA | 1 - sys/mips/conf/QEMU | 1 - sys/mips/conf/SENTRY5 | 11 +- sys/mips/include/bus.h | 5 +- sys/mips/mips/elf_machdep.c | 3 +- sys/mips/mips/elf_trampoline.c | 133 ++ sys/mips/mips/inckern.S | 34 + sys/mips/mips/nexus.c | 37 +- sys/mips/sentry5/files.sentry5 | 7 - 37 files changed, 5145 insertions(+), 36 deletions(-) rename sys/{mips/sentry5 => dev/siba}/siba_cc.c (100%) rename sys/{mips/sentry5 => dev/siba}/siba_mips.c (100%) rename sys/{mips/sentry5 => dev/siba}/siba_sdram.c (100%) create mode 100644 sys/mips/alchemy/alchemy_machdep.c create mode 100644 sys/mips/alchemy/aureg.h create mode 100644 sys/mips/alchemy/files.alchemy create mode 100644 sys/mips/alchemy/obio.c create mode 100644 sys/mips/alchemy/std.alchemy create mode 100644 sys/mips/alchemy/uart_bus_alchemy.c create mode 100644 sys/mips/alchemy/uart_cpu_alchemy.c create mode 100644 sys/mips/atheros/apb.c create mode 100644 sys/mips/atheros/apbvar.h create mode 100644 sys/mips/atheros/ar71xx_machdep.c create mode 100644 sys/mips/atheros/ar71xx_ohci.c create mode 100644 sys/mips/atheros/ar71xx_pci.c create mode 100644 sys/mips/atheros/ar71xxreg.h create mode 100644 sys/mips/atheros/files.ar71xx create mode 100644 sys/mips/atheros/if_arge.c create mode 100644 sys/mips/atheros/if_argevar.h create mode 100644 sys/mips/atheros/uart_bus_ar71xx.c create mode 100644 sys/mips/atheros/uart_cpu_ar71xx.c create mode 100644 sys/mips/conf/ALCHEMY create mode 100644 sys/mips/conf/AR71XX create mode 100644 sys/mips/conf/AR71XX.hints create mode 100644 sys/mips/mips/elf_trampoline.c create mode 100644 sys/mips/mips/inckern.S diff --git a/sys/conf/Makefile.mips b/sys/conf/Makefile.mips index 443065aaafc..e03432c9edf 100644 --- a/sys/conf/Makefile.mips +++ b/sys/conf/Makefile.mips @@ -28,35 +28,73 @@ S= ../../.. .endif .include "$S/conf/kern.pre.mk" +SYSTEM_LD:= ${SYSTEM_LD:$S/conf/ldscript.$M=ldscript.$M} +SYSTEM_DEP:= ${SYSTEM_DEP:$S/conf/ldscript.$M=ldscript.$M} + # XXX: Such sweeping assumptions... MACHINE=mips MACHINE_ARCH=mips +KERNLOADADDR?=0x80001000 +# This obscure value is defined by CFE for WR160N +# To be changed later +TRAMPLOADADDR?=0x807963c0 MKMODULESENV+= MACHINE=${MACHINE} MACHINE_ARCH=${MACHINE_ARCH} # We default to the MIPS32 ISA, if none specified in the # kernel configuration file. ARCH_FLAGS?=-march=mips32 +EXTRA_FLAGS=-fno-pic -mno-abicalls -mno-dsp -G0 HACK_EXTRA_FLAGS=-shared .if defined(TARGET_BIG_ENDIAN) CFLAGS+=-EB SYSTEM_LD+=-EB +EXTRA_FLAGS+=-EB +TRAMP_LDFLAGS+=-Wl,-EB HACK_EXTRA_FLAGS+=-EB -Wl,-EB .else CFLAGS+=-EL SYSTEM_LD+=-EL +EXTRA_FLAGS+=-EL +TRAMP_LDFLAGS+=-Wl,-EL HACK_EXTRA_FLAGS+=-EL -Wl,-EL .endif # We add the -fno-pic flag to kernels because otherwise performance # is extremely poor, as well as -mno-abicalls to force no ABI usage. -CFLAGS+=-fno-pic -mno-abicalls -G0 $(ARCH_FLAGS) -HACK_EXTRA_FLAGS+=-fno-pic -mno-abicalls -G0 $(ARCH_FLAGS) +CFLAGS+=${EXTRA_FLAGS} $(ARCH_FLAGS) +HACK_EXTRA_FLAGS+=${EXTRA_FLAGS} $(ARCH_FLAGS) # XXX hardcoded kernel entry point ASM_CFLAGS+=${CFLAGS} -D_LOCORE -DLOCORE +KERNEL_EXTRA=trampoline +trampoline: ${KERNEL_KO}.tramp.bin +${KERNEL_KO}.tramp.bin: ${KERNEL_KO} $S/$M/$M/elf_trampoline.c \ + $S/$M/$M/inckern.S + ${OBJCOPY} --strip-symbol '$$d' --strip-symbol '$$a' \ + -g --strip-symbol '$$t' ${FULLKERNEL} ${KERNEL_KO}.tmp + sed s/${KERNLOADADDR}/${TRAMPLOADADDR}/ ldscript.$M | \ + sed s/" + SIZEOF_HEADERS"// > ldscript.$M.tramp.noheader + # Generate .S file that setups stack and jumps to trampoline + echo "#include " >tmphack.S + echo "ENTRY(_start)" >>tmphack.S + echo "la t0, kernel_end" >>tmphack.S + echo "move sp, t0" >>tmphack.S + echo "add sp, 0x2000" >>tmphack.S + echo "and sp, ~0x7" >>tmphack.S + echo "la t0, _startC" >>tmphack.S + echo "j t0" >>tmphack.S + echo "END(_start)" >>tmphack.S + echo "#define KERNNAME \"${KERNEL_KO}.tmp\"" >opt_kernname.h + ${CC} -O -nostdlib -I. -I$S ${EXTRA_FLAGS} ${TRAMP_LDFLAGS} -Xlinker \ + -T -Xlinker ldscript.$M.tramp.noheader tmphack.S \ + $S/$M/$M/elf_trampoline.c $S/$M/$M/inckern.S \ + -o ${KERNEL_KO}.tramp.noheader + ${OBJCOPY} -S -O binary ${KERNEL_KO}.tramp.noheader \ + ${KERNEL_KO}.tramp.bin \ + %BEFORE_DEPEND %OBJS @@ -69,6 +107,12 @@ ASM_CFLAGS+=${CFLAGS} -D_LOCORE -DLOCORE %CLEAN +CLEAN+= ldscript.$M ldscript.$M.tramp.noheader \ + ${KERNEL_KO}.tramp.noheader ${KERNEL_KO}.tramp.bin + +ldscript.$M: $S/conf/ldscript.$M + cat $S/conf/ldscript.$M|sed s/KERNLOADADDR/${KERNLOADADDR}/g \ + > ldscript.$M %RULES .include "$S/conf/kern.post.mk" diff --git a/sys/conf/files.mips b/sys/conf/files.mips index 1e233d789ef..bbedd968e95 100644 --- a/sys/conf/files.mips +++ b/sys/conf/files.mips @@ -96,3 +96,7 @@ dev/cfe/cfe_api.c optional cfe dev/cfe/cfe_console.c optional cfe_console #dev/cfe/cfe_resource.c optional cfe # not yet needed +dev/siba/siba.c optional siba +dev/siba/siba_pcib.c optional siba pci +dev/siba/siba_cc.c optional siba +#mips/sentry5/siba_mips.c optional siba # not yet diff --git a/sys/conf/ldscript.mips b/sys/conf/ldscript.mips index ca4a70bd32e..3e55dba46d8 100644 --- a/sys/conf/ldscript.mips +++ b/sys/conf/ldscript.mips @@ -43,7 +43,7 @@ PROVIDE (_DYNAMIC = 0); SECTIONS { /* Read-only sections, merged into text segment: */ - . = 0x80100000 + SIZEOF_HEADERS; + . = KERNLOADADDR + SIZEOF_HEADERS; .interp : { *(.interp) } .hash : { *(.hash) } .dynsym : { *(.dynsym) } diff --git a/sys/mips/sentry5/siba_cc.c b/sys/dev/siba/siba_cc.c similarity index 100% rename from sys/mips/sentry5/siba_cc.c rename to sys/dev/siba/siba_cc.c diff --git a/sys/mips/sentry5/siba_mips.c b/sys/dev/siba/siba_mips.c similarity index 100% rename from sys/mips/sentry5/siba_mips.c rename to sys/dev/siba/siba_mips.c diff --git a/sys/mips/sentry5/siba_sdram.c b/sys/dev/siba/siba_sdram.c similarity index 100% rename from sys/mips/sentry5/siba_sdram.c rename to sys/dev/siba/siba_sdram.c diff --git a/sys/mips/alchemy/alchemy_machdep.c b/sys/mips/alchemy/alchemy_machdep.c new file mode 100644 index 00000000000..eca9b18ae0d --- /dev/null +++ b/sys/mips/alchemy/alchemy_machdep.c @@ -0,0 +1,157 @@ +/*- + * Copyright (C) 2007 by Oleksandr Tymoshenko. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "opt_ddb.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern int *edata; +extern int *end; + +static void +mips_init(void) +{ + int i; + + printf("entry: mips_init()\n"); + + bootverbose = 1; + realmem = btoc(16 << 20); + + for (i = 0; i < 10; i++) { + phys_avail[i] = 0; + } + + /* phys_avail regions are in bytes */ + phys_avail[0] = MIPS_KSEG0_TO_PHYS((vm_offset_t)&end); + phys_avail[1] = ctob(realmem); + + physmem = realmem; + + init_param1(); + init_param2(physmem); + mips_cpu_init(); + pmap_bootstrap(); + mips_proc0_init(); + mutex_init(); +#ifdef DDB + kdb_init(); +#endif +} + +void +platform_halt(void) +{ + +} + + +void +platform_identify(void) +{ + +} + +void +platform_reset(void) +{ + + __asm __volatile("li $25, 0xbfc00000"); + __asm __volatile("j $25"); +} + +void +platform_trap_enter(void) +{ + +} + +void +platform_trap_exit(void) +{ + +} + +void +platform_start(__register_t a0 __unused, __register_t a1 __unused, + __register_t a2 __unused, __register_t a3 __unused) +{ + vm_offset_t kernend; + uint64_t platform_counter_freq = 175 * 1000 * 1000; + + /* clear the BSS and SBSS segments */ + kernend = round_page((vm_offset_t)&end); + memset(&edata, 0, kernend - (vm_offset_t)(&edata)); + + cninit(); + mips_init(); + /* Set counter_freq for tick_init_params() */ + platform_counter_freq = 175 * 1000 * 1000; + + mips_timer_init_params(platform_counter_freq, 0); +} diff --git a/sys/mips/alchemy/aureg.h b/sys/mips/alchemy/aureg.h new file mode 100644 index 00000000000..dfa21032763 --- /dev/null +++ b/sys/mips/alchemy/aureg.h @@ -0,0 +1,373 @@ +/* $NetBSD: aureg.h,v 1.18 2006/10/02 06:44:00 gdamore Exp $ */ + +/* + * Copyright 2002 Wasabi Systems, Inc. + * All rights reserved. + * + * Written by Simon Burge for Wasabi Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project by + * Wasabi Systems, Inc. + * 4. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _MIPS_ALCHEMY_AUREG_H +#define _MIPS_ALCHEMY_AUREG_H + +/************************************************************************/ +/******************** AC97 Controller registers *********************/ +/************************************************************************/ +#define AC97_BASE 0x10000000 + +/************************************************************************/ +/*********************** USB Host registers *************************/ +/************************************************************************/ +#define USBH_BASE 0x10100000 +#define AU1550_USBH_BASE 0x14020000 + +#define USBH_ENABLE 0x7fffc +#define USBH_SIZE 0x100000 + +#define AU1550_USBH_ENABLE 0x7ffc +#define AU1550_USBH_SIZE 0x60000 + +/************************************************************************/ +/********************** USB Device registers ************************/ +/************************************************************************/ +#define USBD_BASE 0x10200000 + +/************************************************************************/ +/************************* IRDA registers ***************************/ +/************************************************************************/ +#define IRDA_BASE 0x10300000 + +/************************************************************************/ +/****************** Interrupt Controller registers ******************/ +/************************************************************************/ + +#define IC0_BASE 0x10400000 +#define IC1_BASE 0x11800000 + +/* + * The *_READ registers read the current value of the register + * The *_SET registers set to 1 all bits that are written 1 + * The *_CLEAR registers clear to zero all bits that are written as 1 + */ +#define IC_CONFIG0_READ 0x40 /* See table below */ +#define IC_CONFIG0_SET 0x40 +#define IC_CONFIG0_CLEAR 0x44 + +#define IC_CONFIG1_READ 0x48 /* See table below */ +#define IC_CONFIG1_SET 0x48 +#define IC_CONFIG1_CLEAR 0x4c + +#define IC_CONFIG2_READ 0x50 /* See table below */ +#define IC_CONFIG2_SET 0x50 +#define IC_CONFIG2_CLEAR 0x54 + +#define IC_REQUEST0_INT 0x54 /* Show active interrupts on request 0 */ + +#define IC_SOURCE_READ 0x58 /* Interrupt source */ +#define IC_SOURCE_SET 0x58 /* 0 - test bit used as source */ +#define IC_SOURCE_CLEAR 0x5c /* 1 - peripheral/GPIO used as source */ + +#define IC_REQUEST1_INT 0x5c /* Show active interrupts on request 1 */ + +#define IC_ASSIGN_REQUEST_READ 0x60 /* Assigns the interrupt to one of the */ +#define IC_ASSIGN_REQUEST_SET 0x60 /* CPU requests (0 - assign to request 1, */ +#define IC_ASSIGN_REQUEST_CLEAR 0x64 /* 1 - assign to request 0) */ + +#define IC_WAKEUP_READ 0x68 /* Controls whether the interrupt can */ +#define IC_WAKEUP_SET 0x68 /* cause a wakeup from IDLE */ +#define IC_WAKEUP_CLEAR 0x6c + +#define IC_MASK_READ 0x70 /* Enables/Disables the interrupt */ +#define IC_MASK_SET 0x70 +#define IC_MASK_CLEAR 0x74 + +#define IC_RISING_EDGE 0x78 /* Check/clear rising edge */ + +#define IC_FALLING_EDGE 0x7c /* Check/clear falling edge */ + +#define IC_TEST_BIT 0x80 /* single bit source select */ + +/* + * Interrupt Configuration Register Functions + * + * Cfg2[n] Cfg1[n] Cfg0[n] Function + * 0 0 0 Interrupts Disabled + * 0 0 1 Rising Edge Enabled + * 0 1 0 Falling Edge Enabled + * 0 1 1 Rising and Falling Edge Enabled + * 1 0 0 Interrupts Disabled + * 1 0 1 High Level Enabled + * 1 1 0 Low Level Enabled + * 1 1 1 Both Levels and Both Edges Enabled + */ + +/************************************************************************/ +/************* Programable Serial Controller registers **************/ +/************************************************************************/ + +#define PSC0_BASE 0x11A00000 +#define PSC1_BASE 0x11B00000 +#define PSC2_BASE 0x10A00000 +#define PSC3_BASE 0x10B00000 + + +/************************************************************************/ +/********************** Ethernet MAC registers **********************/ +/************************************************************************/ + +#define MAC0_BASE 0x10500000 +#define MAC1_BASE 0x10510000 +#define MACx_SIZE 0x28 + +#define AU1500_MAC0_BASE 0x11500000 /* Grr, different on Au1500 */ +#define AU1500_MAC1_BASE 0x11510000 /* Grr, different on Au1500 */ + +#define MAC0_ENABLE 0x10520000 +#define MAC1_ENABLE 0x10520004 +#define MACENx_SIZE 0x04 + +#define AU1500_MAC0_ENABLE 0x11520000 /* Grr, different on Au1500 */ +#define AU1500_MAC1_ENABLE 0x11520004 /* Grr, different on Au1500 */ + +#define MAC0_DMA_BASE 0x14004000 +#define MAC1_DMA_BASE 0x14004200 +#define MACx_DMA_SIZE 0x140 + +/************************************************************************/ +/********************** Static Bus registers ************************/ +/************************************************************************/ +#define STATIC_BUS_BASE 0x14001000 + +/************************************************************************/ +/******************** Secure Digital registers **********************/ +/************************************************************************/ +#define SD0_BASE 0x10600000 +#define SD1_BASE 0x10680000 + +/************************************************************************/ +/************************* I^2S registers ***************************/ +/************************************************************************/ +#define I2S_BASE 0x11000000 + +/************************************************************************/ +/************************** UART registers **************************/ +/************************************************************************/ + +#define UART0_BASE 0x11100000 +#define UART1_BASE 0x11200000 +#define UART2_BASE 0x11300000 +#define UART3_BASE 0x11400000 + +/************************************************************************/ +/************************* SSI registers ****************************/ +/************************************************************************/ +#define SSI0_BASE 0x11600000 +#define SSI1_BASE 0x11680000 + +/************************************************************************/ +/************************ GPIO2 registers ***************************/ +/************************************************************************/ +#define GPIO_BASE 0x11900100 + +/************************************************************************/ +/************************ GPIO2 registers ***************************/ +/************************************************************************/ +#define GPIO2_BASE 0x11700000 + +/************************************************************************/ +/************************* PCI registers ****************************/ +/************************************************************************/ +#define PCI_BASE 0x14005000 +#define PCI_HEADER 0x14005100 +#define PCI_MEM_BASE 0x400000000ULL +#define PCI_IO_BASE 0x500000000ULL +#define PCI_CONFIG_BASE 0x600000000ULL + +/************************************************************************/ +/*********************** PCMCIA registers ***************************/ +/************************************************************************/ +#define PCMCIA_BASE 0xF00000000ULL + +/************************************************************************/ +/****************** Programmable Counter registers ******************/ +/************************************************************************/ + +#define SYS_BASE 0x11900000 + +#define PC_BASE SYS_BASE + +#define PC_TRIM0 0x00 /* PC0 Divide (16 bits) */ +#define PC_COUNTER_WRITE0 0x04 /* set PC0 */ +#define PC_MATCH0_0 0x08 /* match counter & interrupt */ +#define PC_MATCH1_0 0x0c /* match counter & interrupt */ +#define PC_MATCH2_0 0x10 /* match counter & interrupt */ +#define PC_COUNTER_CONTROL 0x14 /* Programmable Counter Control */ +#define CC_E1S 0x00800000 /* Enable PC1 write status */ +#define CC_T1S 0x00100000 /* Trim PC1 write status */ +#define CC_M21 0x00080000 /* Match 2 of PC1 write status */ +#define CC_M11 0x00040000 /* Match 1 of PC1 write status */ +#define CC_M01 0x00020000 /* Match 0 of PC1 write status */ +#define CC_C1S 0x00010000 /* PC1 write status */ +#define CC_BP 0x00004000 /* Bypass OSC (use GPIO1) */ +#define CC_EN1 0x00002000 /* Enable PC1 */ +#define CC_BT1 0x00001000 /* Bypass Trim on PC1 */ +#define CC_EN0 0x00000800 /* Enable PC0 */ +#define CC_BT0 0x00000400 /* Bypass Trim on PC0 */ +#define CC_EO 0x00000100 /* Enable Oscillator */ +#define CC_E0S 0x00000080 /* Enable PC0 write status */ +#define CC_32S 0x00000020 /* 32.768kHz OSC status */ +#define CC_T0S 0x00000010 /* Trim PC0 write status */ +#define CC_M20 0x00000008 /* Match 2 of PC0 write status */ +#define CC_M10 0x00000004 /* Match 1 of PC0 write status */ +#define CC_M00 0x00000002 /* Match 0 of PC0 write status */ +#define CC_C0S 0x00000001 /* PC0 write status */ +#define PC_COUNTER_READ_0 0x40 /* get PC0 */ +#define PC_TRIM1 0x44 /* PC1 Divide (16 bits) */ +#define PC_COUNTER_WRITE1 0x48 /* set PC1 */ +#define PC_MATCH0_1 0x4c /* match counter & interrupt */ +#define PC_MATCH1_1 0x50 /* match counter & interrupt */ +#define PC_MATCH2_1 0x54 /* match counter & interrupt */ +#define PC_COUNTER_READ_1 0x58 /* get PC1 */ + +#define PC_SIZE 0x5c /* size of register set */ +#define PC_RATE 32768 /* counter rate is 32.768kHz */ + +/************************************************************************/ +/******************* Frequency Generator Registers ******************/ +/************************************************************************/ + +#define SYS_FREQCTRL0 (SYS_BASE + 0x20) +#define SFC_FRDIV2(f) (f<<22) /* 29:22. Freq Divider 2 */ +#define SFC_FE2 (1<<21) /* Freq generator output enable 2 */ +#define SFC_FS2 (1<<20) /* Freq generator source 2 */ +#define SFC_FRDIV1(f) (f<<12) /* 19:12. Freq Divider 1 */ +#define SFC_FE1 (1<<11) /* Freq generator output enable 1 */ +#define SFC_FS1 (1<<10) /* Freq generator source 1 */ +#define SFC_FRDIV0(f) (f<<2) /* 9:2. Freq Divider 0 */ +#define SFC_FE0 2 /* Freq generator output enable 0 */ +#define SFC_FS0 1 /* Freq generator source 0 */ + +#define SYS_FREQCTRL1 (SYS_BASE + 0x24) +#define SFC_FRDIV5(f) (f<<22) /* 29:22. Freq Divider 5 */ +#define SFC_FE5 (1<<21) /* Freq generator output enable 5 */ +#define SFC_FS5 (1<<20) /* Freq generator source 5 */ +#define SFC_FRDIV4(f) (f<<12) /* 19:12. Freq Divider 4 */ +#define SFC_FE4 (1<<11) /* Freq generator output enable 4 */ +#define SFC_FS4 (1<<10) /* Freq generator source 4 */ +#define SFC_FRDIV3(f) (f<<2) /* 9:2. Freq Divider 3 */ +#define SFC_FE3 2 /* Freq generator output enable 3 */ +#define SFC_FS3 1 /* Freq generator source 3 */ + +/************************************************************************/ +/****************** Clock Source Control Registers ******************/ +/************************************************************************/ + +#define SYS_CLKSRC (SYS_BASE + 0x28) +#define SCS_ME1(n) (n<<27) /* EXTCLK1 Clock Mux input select */ +#define SCS_ME0(n) (n<<22) /* EXTCLK0 Clock Mux input select */ +#define SCS_MPC(n) (n<<17) /* PCI clock mux input select */ +#define SCS_MUH(n) (n<<12) /* USB Host clock mux input select */ +#define SCS_MUD(n) (n<<7) /* USB Device clock mux input select */ +#define SCS_MEx_AUX 0x1 /* Aux clock */ +#define SCS_MEx_FREQ0 0x2 /* FREQ0 */ +#define SCS_MEx_FREQ1 0x3 /* FREQ1 */ +#define SCS_MEx_FREQ2 0x4 /* FREQ2 */ +#define SCS_MEx_FREQ3 0x5 /* FREQ3 */ +#define SCS_MEx_FREQ4 0x6 /* FREQ4 */ +#define SCS_MEx_FREQ5 0x7 /* FREQ5 */ +#define SCS_DE1 (1<<26) /* EXTCLK1 clock divider select */ +#define SCS_CE1 (1<<25) /* EXTCLK1 clock select */ +#define SCS_DE0 (1<<21) /* EXTCLK0 clock divider select */ +#define SCS_CE0 (1<<20) /* EXTCLK0 clock select */ +#define SCS_DPC (1<<16) /* PCI clock divider select */ +#define SCS_CPC (1<<15) /* PCI clock select */ +#define SCS_DUH (1<<11) /* USB Host clock divider select */ +#define SCS_CUH (1<<10) /* USB Host clock select */ +#define SCS_DUD (1<<6) /* USB Device clock divider select */ +#define SCS_CUD (1<<5) /* USB Device clock select */ +/* + * Au1550 bits, needed for PSCs. Note that some bits collide with + * earlier parts. On Au1550, USB clocks (both device and host) are + * shared with PSC2, and must be configured for 48MHz. DBAU1550 YAMON + * does this by default. Also, EXTCLK0 is shared with PSC3. DBAU1550 + * YAMON does not configure any clocks besides PSC2. + */ +#define SCS_MP3(n) (n<<22) /* psc3_intclock mux */ +#define SCS_DP3 (1<<21) /* psc3_intclock divider */ +#define SCS_CP3 (1<<20) /* psc3_intclock select */ +#define SCS_MP1(n) (n<<12) /* psc1_intclock mux */ +#define SCS_DP1 (1<<11) /* psc1_intclock divider */ +#define SCS_CP1 (1<<10) /* psc1_intclock select */ +#define SCS_MP0(n) (n<<7) /* psc0_intclock mux */ +#define SCS_DP0 (1<<6) /* psc0_intclock divider */ +#define SCS_CP0 (1<<5) /* psc0_intclock seelct */ +#define SCS_MP2(n) (n<<2) /* psc2_intclock mux */ +#define SCS_DP2 (1<<1) /* psc2_intclock divider */ +#define SCS_CP2 (1<<0) /* psc2_intclock select */ + +/************************************************************************/ +/*************************** PIN Function *****************************/ +/************************************************************************/ + +#define SYS_PINFUNC (SYS_BASE + 0x2c) +#define SPF_PSC3_MASK (7<<20) +#define SPF_PSC3_AC97 (0<<17) /* select AC97/SPI */ +#define SPF_PSC3_I2S (1<<17) /* select I2S */ +#define SPF_PSC3_SMBUS (3<<17) /* select SMbus */ +#define SPF_PSC3_GPIO (7<<17) /* select gpio215:211 */ +#define SPF_PSC2_MASK (7<<17) +#define SPF_PSC2_AC97 (0<<17) /* select AC97/SPI */ +#define SPF_PSC2_I2S (1<<17) /* select I2S */ +#define SPF_PSC2_SMBUS (3<<17) /* select SMbus */ +#define SPF_PSC2_GPIO (7<<17) /* select gpio210:206*/ +#define SPF_CS (1<<16) /* extclk0 or 32kHz osc */ +#define SPF_USB (1<<15) /* host or device usb otg */ +#define SPF_U3T (1<<14) /* uart3 tx or gpio23 */ +#define SPF_U1R (1<<13) /* uart1 rx or gpio22 */ +#define SPF_U1T (1<<12) /* uart1 tx or gpio21 */ +#define SPF_EX1 (1<<10) /* gpio3 or extclk1 */ +#define SPF_EX0 (1<<9) /* gpio2 or extclk0/32kHz osc*/ +#define SPF_U3 (1<<7) /* gpio14:9 or uart3 */ +#define SPF_MBSa (1<<5) /* must be set */ +#define SPF_NI2 (1<<4) /* enet1 or gpio28:24 */ +#define SPF_U0 (1<<3) /* uart0 or gpio20 */ +#define SPF_MBSb (1<<2) /* must be set */ +#define SPF_S1 (1<<1) /* gpio17 or psc1_sync1 */ +#define SPF_S0 (1<<0) /* gpio16 or psc0_sync1 */ + +/************************************************************************/ +/*************************** PLL Control *****************************/ +/************************************************************************/ + +#define SYS_CPUPLL (SYS_BASE + 0x60) +#define SYS_AUXPLL (SYS_BASE + 0x64) + +#endif /* _MIPS_ALCHEMY_AUREG_H */ diff --git a/sys/mips/alchemy/files.alchemy b/sys/mips/alchemy/files.alchemy new file mode 100644 index 00000000000..8534431d020 --- /dev/null +++ b/sys/mips/alchemy/files.alchemy @@ -0,0 +1,7 @@ +# $FreeBSD$ +# Alchmy on-board devices +# mips/alchemy/console.c standard +mips/alchemy/alchemy_machdep.c standard +mips/alchemy/obio.c standard +mips/alchemy/uart_bus_alchemy.c optional uart +mips/alchemy/uart_cpu_alchemy.c optional uart diff --git a/sys/mips/alchemy/obio.c b/sys/mips/alchemy/obio.c new file mode 100644 index 00000000000..03e098d42ba --- /dev/null +++ b/sys/mips/alchemy/obio.c @@ -0,0 +1,501 @@ +/* $NetBSD: obio.c,v 1.11 2003/07/15 00:25:05 lukem Exp $ */ + +/*- + * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc. + * All rights reserved. + * + * Written by Jason R. Thorpe for Wasabi Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project by + * Wasabi Systems, Inc. + * 4. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +/* MIPS HW interrupts of IRQ/FIQ respectively */ +#define ADM5120_INTR 0 +#define ADM5120_FAST_INTR 1 + +/* Interrupt levels */ +#define INTR_IRQ 0 +#define INTR_FIQ 1 + +int irq_priorities[NIRQS] = { + INTR_IRQ, /* flash */ + INTR_FIQ, /* uart0 */ + INTR_FIQ, /* uart1 */ + INTR_IRQ, /* ahci */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* admsw */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ + INTR_IRQ, /* unknown */ +}; + + +#define REG_READ(o) *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1(ADM5120_BASE_ICU + (o))) +#define REG_WRITE(o,v) (REG_READ(o)) = (v) + +static int obio_activate_resource(device_t, device_t, int, int, + struct resource *); +static device_t obio_add_child(device_t, int, const char *, int); +static struct resource * + obio_alloc_resource(device_t, device_t, int, int *, u_long, + u_long, u_long, u_int); +static int obio_attach(device_t); +static int obio_deactivate_resource(device_t, device_t, int, int, + struct resource *); +static struct resource_list * + obio_get_resource_list(device_t, device_t); +static void obio_hinted_child(device_t, const char *, int); +static int obio_intr(void *); +static int obio_probe(device_t); +static int obio_release_resource(device_t, device_t, int, int, + struct resource *); +static int obio_setup_intr(device_t, device_t, struct resource *, int, + driver_filter_t *, driver_intr_t *, void *, void **); +static int obio_teardown_intr(device_t, device_t, struct resource *, + void *); + +static int +obio_probe(device_t dev) +{ + + return (0); +} + +static int +obio_attach(device_t dev) +{ + struct obio_softc *sc = device_get_softc(dev); + int rid; + + sc->oba_mem_rman.rm_type = RMAN_ARRAY; + sc->oba_mem_rman.rm_descr = "OBIO memeory"; + if (rman_init(&sc->oba_mem_rman) != 0 || + rman_manage_region(&sc->oba_mem_rman, OBIO_MEM_START, + OBIO_MEM_START + OBIO_MEM_SIZE) != 0) + panic("obio_attach: failed to set up I/O rman"); + + sc->oba_irq_rman.rm_type = RMAN_ARRAY; + sc->oba_irq_rman.rm_descr = "OBIO IRQ"; + + if (rman_init(&sc->oba_irq_rman) != 0 || + rman_manage_region(&sc->oba_irq_rman, 0, NIRQS-1) != 0) + panic("obio_attach: failed to set up IRQ rman"); + + /* Hook up our interrupt handler. */ + if ((sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, + ADM5120_INTR, ADM5120_INTR, 1, + RF_SHAREABLE | RF_ACTIVE)) == NULL) { + device_printf(dev, "unable to allocate IRQ resource\n"); + return (ENXIO); + } + + if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC, obio_intr, NULL, + sc, &sc->sc_ih))) { + device_printf(dev, + "WARNING: unable to register interrupt handler\n"); + return (ENXIO); + } + + /* Hook up our FAST interrupt handler. */ + if ((sc->sc_fast_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, + ADM5120_FAST_INTR, ADM5120_FAST_INTR, 1, + RF_SHAREABLE | RF_ACTIVE)) == NULL) { + device_printf(dev, "unable to allocate IRQ resource\n"); + return (ENXIO); + } + + if ((bus_setup_intr(dev, sc->sc_fast_irq, INTR_TYPE_MISC, obio_intr, + NULL, sc, &sc->sc_fast_ih))) { + device_printf(dev, + "WARNING: unable to register interrupt handler\n"); + return (ENXIO); + } + + /* disable all interrupts */ + REG_WRITE(ICU_ENABLE_REG, ICU_INT_MASK); + + bus_generic_probe(dev); + bus_enumerate_hinted_children(dev); + bus_generic_attach(dev); + + return (0); +} + +static struct resource * +obio_alloc_resource(device_t bus, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + struct obio_softc *sc = device_get_softc(bus); + struct obio_ivar *ivar = device_get_ivars(child); + struct resource *rv; + struct resource_list_entry *rle; + struct rman *rm; + int isdefault, needactivate, passthrough; + + isdefault = (start == 0UL && end == ~0UL && count == 1); + needactivate = flags & RF_ACTIVE; + passthrough = (device_get_parent(child) != bus); + rle = NULL; + + if (passthrough) + return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, + rid, start, end, count, flags)); + + /* + * If this is an allocation of the "default" range for a given RID, + * and we know what the resources for this device are (ie. they aren't + * maintained by a child bus), then work out the start/end values. + */ + if (isdefault) { + rle = resource_list_find(&ivar->resources, type, *rid); + if (rle == NULL) + return (NULL); + if (rle->res != NULL) { + panic("%s: resource entry is busy", __func__); + } + start = rle->start; + end = rle->end; + count = rle->count; + } + + switch (type) { + case SYS_RES_IRQ: + rm = &sc->oba_irq_rman; + break; + case SYS_RES_MEMORY: + rm = &sc->oba_mem_rman; + break; + default: + printf("%s: unknown resource type %d\n", __func__, type); + return (0); + } + + rv = rman_reserve_resource(rm, start, end, count, flags, child); + if (rv == 0) { + printf("%s: could not reserve resource\n", __func__); + return (0); + } + + rman_set_rid(rv, *rid); + + if (needactivate) { + if (bus_activate_resource(child, type, *rid, rv)) { + printf("%s: could not activate resource\n", __func__); + rman_release_resource(rv); + return (0); + } + } + + return (rv); +} + +static int +obio_activate_resource(device_t bus, device_t child, int type, int rid, + struct resource *r) +{ + + /* + * If this is a memory resource, track the direct mapping + * in the uncached MIPS KSEG1 segment. + */ + if (type == SYS_RES_MEMORY) { + void *vaddr; + + vaddr = (void *)MIPS_PHYS_TO_KSEG1((intptr_t)rman_get_start(r)); + rman_set_virtual(r, vaddr); + rman_set_bustag(r, MIPS_BUS_SPACE_MEM); + rman_set_bushandle(r, (bus_space_handle_t)vaddr); + } + + return (rman_activate_resource(r)); +} + +static int +obio_deactivate_resource(device_t bus, device_t child, int type, int rid, + struct resource *r) +{ + + return (rman_deactivate_resource(r)); +} + +static int +obio_release_resource(device_t dev, device_t child, int type, + int rid, struct resource *r) +{ + struct resource_list *rl; + struct resource_list_entry *rle; + + rl = obio_get_resource_list(dev, child); + if (rl == NULL) + return (EINVAL); + rle = resource_list_find(rl, type, rid); + if (rle == NULL) + return (EINVAL); + rman_release_resource(r); + rle->res = NULL; + + return (0); +} + +static int +obio_setup_intr(device_t dev, device_t child, struct resource *ires, + int flags, driver_filter_t *filt, driver_intr_t *handler, + void *arg, void **cookiep) +{ + struct obio_softc *sc = device_get_softc(dev); + struct intr_event *event; + int irq, error, priority; + uint32_t irqmask; + + irq = rman_get_start(ires); + + if (irq >= NIRQS) + panic("%s: bad irq %d", __func__, irq); + + event = sc->sc_eventstab[irq]; + if (event == NULL) { + error = intr_event_create(&event, (void *)irq, 0, irq, + (mask_fn)mips_mask_irq, (mask_fn)mips_unmask_irq, + NULL, NULL, "obio intr%d:", irq); + + sc->sc_eventstab[irq] = event; + } + else + panic("obio: Can't share IRQs"); + + intr_event_add_handler(event, device_get_nameunit(child), filt, + handler, arg, intr_priority(flags), flags, cookiep); + + irqmask = 1 << irq; + priority = irq_priorities[irq]; + + if (priority == INTR_FIQ) + REG_WRITE(ICU_MODE_REG, REG_READ(ICU_MODE_REG) | irqmask); + else + REG_WRITE(ICU_MODE_REG, REG_READ(ICU_MODE_REG) & ~irqmask); + + /* enable */ + REG_WRITE(ICU_ENABLE_REG, irqmask); + + return (0); +} + +static int +obio_teardown_intr(device_t dev, device_t child, struct resource *ires, + void *cookie) +{ + struct obio_softc *sc = device_get_softc(dev); + int irq, result; + uint32_t irqmask; + + irq = rman_get_start(ires); + if (irq >= NIRQS) + panic("%s: bad irq %d", __func__, irq); + + if (sc->sc_eventstab[irq] == NULL) + panic("Trying to teardown unoccupied IRQ"); + + irqmask = 1 << irq; /* only used as a mask from here on */ + + /* disable this irq in HW */ + REG_WRITE(ICU_DISABLE_REG, irqmask); + + result = intr_event_remove_handler(cookie); + if (!result) { + sc->sc_eventstab[irq] = NULL; + } + + return (result); +} + +static int +obio_intr(void *arg) +{ + struct obio_softc *sc = arg; + struct intr_event *event; + uint32_t irqstat; + int irq; + + irqstat = REG_READ(ICU_FIQ_STATUS_REG); + irqstat |= REG_READ(ICU_STATUS_REG); + + irq = 0; + while (irqstat != 0) { + if ((irqstat & 1) == 1) { + event = sc->sc_eventstab[irq]; + if (!event || TAILQ_EMPTY(&event->ie_handlers)) + continue; + + /* TODO: pass frame as an argument*/ + /* TODO: log stray interrupt */ + intr_event_handle(event, NULL); + } + + irq++; + irqstat >>= 1; + } + + return (FILTER_HANDLED); +} + +static void +obio_hinted_child(device_t bus, const char *dname, int dunit) +{ + device_t child; + long maddr; + int msize; + int irq; + int result; + + child = BUS_ADD_CHILD(bus, 0, dname, dunit); + + /* + * Set hard-wired resources for hinted child using + * specific RIDs. + */ + resource_long_value(dname, dunit, "maddr", &maddr); + resource_int_value(dname, dunit, "msize", &msize); + + + result = bus_set_resource(child, SYS_RES_MEMORY, 0, + maddr, msize); + if (result != 0) + device_printf(bus, "warning: bus_set_resource() failed\n"); + + if (resource_int_value(dname, dunit, "irq", &irq) == 0) { + result = bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1); + if (result != 0) + device_printf(bus, + "warning: bus_set_resource() failed\n"); + } +} + +static device_t +obio_add_child(device_t bus, int order, const char *name, int unit) +{ + device_t child; + struct obio_ivar *ivar; + + ivar = malloc(sizeof(struct obio_ivar), M_DEVBUF, M_WAITOK | M_ZERO); + if (ivar == NULL) { + printf("Failed to allocate ivar\n"); + return (0); + } + resource_list_init(&ivar->resources); + + child = device_add_child_ordered(bus, order, name, unit); + if (child == NULL) { + printf("Can't add child %s%d ordered\n", name, unit); + return (0); + } + + device_set_ivars(child, ivar); + + return (child); +} + +/* + * Helper routine for bus_generic_rl_get_resource/bus_generic_rl_set_resource + * Provides pointer to resource_list for these routines + */ +static struct resource_list * +obio_get_resource_list(device_t dev, device_t child) +{ + struct obio_ivar *ivar; + + ivar = device_get_ivars(child); + return (&(ivar->resources)); +} + +static device_method_t obio_methods[] = { + DEVMETHOD(bus_activate_resource, obio_activate_resource), + DEVMETHOD(bus_add_child, obio_add_child), + DEVMETHOD(bus_alloc_resource, obio_alloc_resource), + DEVMETHOD(bus_deactivate_resource, obio_deactivate_resource), + DEVMETHOD(bus_get_resource_list, obio_get_resource_list), + DEVMETHOD(bus_hinted_child, obio_hinted_child), + DEVMETHOD(bus_release_resource, obio_release_resource), + DEVMETHOD(bus_setup_intr, obio_setup_intr), + DEVMETHOD(bus_teardown_intr, obio_teardown_intr), + DEVMETHOD(device_attach, obio_attach), + DEVMETHOD(device_probe, obio_probe), + DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), + DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), + + {0, 0}, +}; + +static driver_t obio_driver = { + "obio", + obio_methods, + sizeof(struct obio_softc), +}; +static devclass_t obio_devclass; + +DRIVER_MODULE(obio, nexus, obio_driver, obio_devclass, 0, 0); diff --git a/sys/mips/alchemy/std.alchemy b/sys/mips/alchemy/std.alchemy new file mode 100644 index 00000000000..a955b6765c4 --- /dev/null +++ b/sys/mips/alchemy/std.alchemy @@ -0,0 +1,8 @@ +# $FreeBSD$ +# Standard include file for Alchemy Au1xxx CPUs: +# Au1000, Au1200, Au1250, Au1500 and Au1550 + +files "../alchemy/files.alchemy" + +cpu CPU_MIPS4KC +options ISA_MIPS32 diff --git a/sys/mips/alchemy/uart_bus_alchemy.c b/sys/mips/alchemy/uart_bus_alchemy.c new file mode 100644 index 00000000000..5c2315b8b7c --- /dev/null +++ b/sys/mips/alchemy/uart_bus_alchemy.c @@ -0,0 +1,87 @@ +/*- + * Copyright (c) 2007 Bruce M. Simpson. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * $Id$ + */ +/* + * Skeleton of this file was based on respective code for ARM + * code written by Olivier Houchard. + */ + +#include "opt_uart.h" + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include "uart_if.h" + +static int uart_alchemy_probe(device_t dev); + +static device_method_t uart_alchemy_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, uart_alchemy_probe), + DEVMETHOD(device_attach, uart_bus_attach), + DEVMETHOD(device_detach, uart_bus_detach), + { 0, 0 } +}; + +static driver_t uart_alchemy_driver = { + uart_driver_name, + uart_alchemy_methods, + sizeof(struct uart_softc), +}; + +extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; + +static int +uart_alchemy_probe(device_t dev) +{ + struct uart_softc *sc; + + sc = device_get_softc(dev); + sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); + sc->sc_class = &uart_ns8250_class; + bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); + + return (uart_bus_probe(dev, 0, 0, 0, 0)); +} + +DRIVER_MODULE(uart, obio, uart_alchemy_driver, uart_devclass, 0, 0); diff --git a/sys/mips/alchemy/uart_cpu_alchemy.c b/sys/mips/alchemy/uart_cpu_alchemy.c new file mode 100644 index 00000000000..931aed63126 --- /dev/null +++ b/sys/mips/alchemy/uart_cpu_alchemy.c @@ -0,0 +1,79 @@ +/*- + * Copyright (c) 2006 Wojciech A. Koszek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ +/* + * Skeleton of this file was based on respective code for ARM + * code written by Olivier Houchard. + */ + +#include "opt_uart.h" + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include + +#include +#include + +#include + +bus_space_tag_t uart_bus_space_io; +bus_space_tag_t uart_bus_space_mem; + +int +uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) +{ + + return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0); +} + +int +uart_cpu_getdev(int devtype, struct uart_devinfo *di) +{ + + di->ops = uart_getops(&uart_ns8250_class); + di->bas.chan = 0; + di->bas.bst = 0; + di->bas.regshft = 0; + di->bas.rclk = 0; + di->baudrate = 115200; + di->databits = 8; + di->stopbits = 1; + di->parity = UART_PARITY_NONE; + + uart_bus_space_io = 0; + uart_bus_space_mem = MIPS_PHYS_TO_KSEG1(UART0_BASE); + di->bas.bsh = MIPS_PHYS_TO_KSEG1(UART0_BASE); + + return (0); +} diff --git a/sys/mips/atheros/apb.c b/sys/mips/atheros/apb.c new file mode 100644 index 00000000000..d53408c3b07 --- /dev/null +++ b/sys/mips/atheros/apb.c @@ -0,0 +1,433 @@ +/*- + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#undef APB_DEBUG +#ifdef APB_DEBUG +#define dprintf printf +#else +#define dprintf(x, arg...) +#endif /* APB_DEBUG */ + +static int apb_activate_resource(device_t, device_t, int, int, + struct resource *); +static device_t apb_add_child(device_t, int, const char *, int); +static struct resource * + apb_alloc_resource(device_t, device_t, int, int *, u_long, + u_long, u_long, u_int); +static int apb_attach(device_t); +static int apb_deactivate_resource(device_t, device_t, int, int, + struct resource *); +static struct resource_list * + apb_get_resource_list(device_t, device_t); +static void apb_hinted_child(device_t, const char *, int); +static int apb_intr(void *); +static int apb_probe(device_t); +static int apb_release_resource(device_t, device_t, int, int, + struct resource *); +static int apb_setup_intr(device_t, device_t, struct resource *, int, + driver_filter_t *, driver_intr_t *, void *, void **); +static int apb_teardown_intr(device_t, device_t, struct resource *, + void *); + +static void apb_mask_irq(unsigned int irq) +{ + uint32_t reg; + + reg = ATH_READ_REG(AR71XX_MISC_INTR_MASK); + ATH_WRITE_REG(AR71XX_MISC_INTR_MASK, reg & ~(1 << irq)); + +} + +static void apb_unmask_irq(unsigned int irq) +{ + uint32_t reg; + + reg = ATH_READ_REG(AR71XX_MISC_INTR_MASK); + ATH_WRITE_REG(AR71XX_MISC_INTR_MASK, reg | (1 << irq)); +} + +static int +apb_probe(device_t dev) +{ + + return (0); +} + +static int +apb_attach(device_t dev) +{ + struct apb_softc *sc = device_get_softc(dev); + int rid = 0; + + device_set_desc(dev, "APB Bus bridge"); + sc->apb_irq_rman.rm_type = RMAN_ARRAY; + sc->apb_irq_rman.rm_descr = "APB IRQ"; + + if (rman_init(&sc->apb_irq_rman) != 0 || + rman_manage_region(&sc->apb_irq_rman, + APB_IRQ_BASE, APB_IRQ_END) != 0) + panic("apb_attach: failed to set up IRQ rman"); + + if ((sc->sc_misc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_SHAREABLE | RF_ACTIVE)) == NULL) { + device_printf(dev, "unable to allocate IRQ resource\n"); + return (ENXIO); + } + + if ((bus_setup_intr(dev, sc->sc_misc_irq, INTR_TYPE_MISC, + apb_intr, NULL, sc, &sc->sc_misc_ih))) { + device_printf(dev, + "WARNING: unable to register interrupt handler\n"); + return (ENXIO); + } + + bus_generic_probe(dev); + bus_enumerate_hinted_children(dev); + bus_generic_attach(dev); + + return (0); +} + +static struct resource * +apb_alloc_resource(device_t bus, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + struct apb_softc *sc = device_get_softc(bus); + struct apb_ivar *ivar = device_get_ivars(child); + struct resource *rv; + struct resource_list_entry *rle; + struct rman *rm; + int isdefault, needactivate, passthrough; + + isdefault = (start == 0UL && end == ~0UL); + needactivate = flags & RF_ACTIVE; + /* + * Pass memory requests to nexus device + */ + passthrough = (device_get_parent(child) != bus) || + (type == SYS_RES_MEMORY); + rle = NULL; + + dprintf("%s: entry (%p, %p, %d, %p, %p, %p, %ld, %d)\n", + __func__, bus, child, type, rid, (void *)(intptr_t)start, + (void *)(intptr_t)end, count, flags); + + if (passthrough) + return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, + rid, start, end, count, flags)); + + /* + * If this is an allocation of the "default" range for a given RID, + * and we know what the resources for this device are (ie. they aren't + * maintained by a child bus), then work out the start/end values. + */ + + if (isdefault) { + rle = resource_list_find(&ivar->resources, type, *rid); + if (rle == NULL) { + return (NULL); + } + + if (rle->res != NULL) { + panic("%s: resource entry is busy", __func__); + } + start = rle->start; + end = rle->end; + count = rle->count; + + dprintf("%s: default resource (%p, %p, %ld)\n", + __func__, (void *)(intptr_t)start, + (void *)(intptr_t)end, count); + } + + switch (type) { + case SYS_RES_IRQ: + rm = &sc->apb_irq_rman; + break; + default: + printf("%s: unknown resource type %d\n", __func__, type); + return (0); + } + + rv = rman_reserve_resource(rm, start, end, count, flags, child); + if (rv == 0) { + printf("%s: could not reserve resource\n", __func__); + return (0); + } + + rman_set_rid(rv, *rid); + + if (needactivate) { + if (bus_activate_resource(child, type, *rid, rv)) { + printf("%s: could not activate resource\n", __func__); + rman_release_resource(rv); + return (0); + } + } + + return (rv); +} + +static int +apb_activate_resource(device_t bus, device_t child, int type, int rid, + struct resource *r) +{ + + /* XXX: should we mask/unmask IRQ here? */ + return (BUS_ACTIVATE_RESOURCE(device_get_parent(bus), child, + type, rid, r)); +} + +static int +apb_deactivate_resource(device_t bus, device_t child, int type, int rid, + struct resource *r) +{ + + /* XXX: should we mask/unmask IRQ here? */ + return (BUS_DEACTIVATE_RESOURCE(device_get_parent(bus), child, + type, rid, r)); +} + +static int +apb_release_resource(device_t dev, device_t child, int type, + int rid, struct resource *r) +{ + struct resource_list *rl; + struct resource_list_entry *rle; + + rl = apb_get_resource_list(dev, child); + if (rl == NULL) + return (EINVAL); + rle = resource_list_find(rl, type, rid); + if (rle == NULL) + return (EINVAL); + rman_release_resource(r); + rle->res = NULL; + + return (0); +} + +static int +apb_setup_intr(device_t bus, device_t child, struct resource *ires, + int flags, driver_filter_t *filt, driver_intr_t *handler, + void *arg, void **cookiep) +{ + struct apb_softc *sc = device_get_softc(bus); + struct intr_event *event; + int irq, error; + + irq = rman_get_start(ires); + + if (irq > APB_IRQ_END) + panic("%s: bad irq %d", __func__, irq); + + event = sc->sc_eventstab[irq]; + if (event == NULL) { + error = intr_event_create(&event, (void *)irq, 0, irq, + (mask_fn)apb_mask_irq, (mask_fn)apb_unmask_irq, + NULL, NULL, + "apb intr%d:", irq); + + sc->sc_eventstab[irq] = event; + } + + intr_event_add_handler(event, device_get_nameunit(child), filt, + handler, arg, intr_priority(flags), flags, cookiep); + + return (0); +} + +static int +apb_teardown_intr(device_t dev, device_t child, struct resource *ires, + void *cookie) +{ + struct apb_softc *sc = device_get_softc(dev); + int irq, result; + + irq = rman_get_start(ires); + if (irq > APB_IRQ_END) + panic("%s: bad irq %d", __func__, irq); + + if (sc->sc_eventstab[irq] == NULL) + panic("Trying to teardown unoccupied IRQ"); + + apb_mask_irq(irq); + + result = intr_event_remove_handler(cookie); + if (!result) + sc->sc_eventstab[irq] = NULL; + + return (result); +} + +static int +apb_intr(void *arg) +{ + struct apb_softc *sc = arg; + struct intr_event *event; + uint32_t reg, irq; + + reg = ATH_READ_REG(AR71XX_MISC_INTR_STATUS); + for (irq = 0; irq < APB_NIRQS; irq++) { + if (reg & (1 << irq)) { + event = sc->sc_eventstab[irq]; + if (!event || TAILQ_EMPTY(&event->ie_handlers)) { + printf("Stray IRQ %d\n", irq); + continue; + } + + /* TODO: frame instead of NULL? */ + intr_event_handle(event, NULL); + } + } + + return (FILTER_HANDLED); +} + +static void +apb_hinted_child(device_t bus, const char *dname, int dunit) +{ + device_t child; + long maddr; + int msize; + int irq; + int result; + int mem_hints_count; + + child = BUS_ADD_CHILD(bus, 0, dname, dunit); + + /* + * Set hard-wired resources for hinted child using + * specific RIDs. + */ + mem_hints_count = 0; + if (resource_long_value(dname, dunit, "maddr", &maddr) == 0) + mem_hints_count++; + if (resource_int_value(dname, dunit, "msize", &msize) == 0) + mem_hints_count++; + + /* check if all info for mem resource has been provided */ + if ((mem_hints_count > 0) && (mem_hints_count < 2)) { + printf("Either maddr or msize hint is missing for %s%d\n", + dname, dunit); + } else if (mem_hints_count) { + result = bus_set_resource(child, SYS_RES_MEMORY, 0, + maddr, msize); + if (result != 0) + device_printf(bus, + "warning: bus_set_resource() failed\n"); + } + + if (resource_int_value(dname, dunit, "irq", &irq) == 0) { + result = bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1); + if (result != 0) + device_printf(bus, + "warning: bus_set_resource() failed\n"); + } +} + +static device_t +apb_add_child(device_t bus, int order, const char *name, int unit) +{ + device_t child; + struct apb_ivar *ivar; + + ivar = malloc(sizeof(struct apb_ivar), M_DEVBUF, M_WAITOK | M_ZERO); + if (ivar == NULL) { + printf("Failed to allocate ivar\n"); + return (0); + } + resource_list_init(&ivar->resources); + + child = device_add_child_ordered(bus, order, name, unit); + if (child == NULL) { + printf("Can't add child %s%d ordered\n", name, unit); + return (0); + } + + device_set_ivars(child, ivar); + + return (child); +} + +/* + * Helper routine for bus_generic_rl_get_resource/bus_generic_rl_set_resource + * Provides pointer to resource_list for these routines + */ +static struct resource_list * +apb_get_resource_list(device_t dev, device_t child) +{ + struct apb_ivar *ivar; + + ivar = device_get_ivars(child); + return (&(ivar->resources)); +} + +static device_method_t apb_methods[] = { + DEVMETHOD(bus_activate_resource, apb_activate_resource), + DEVMETHOD(bus_add_child, apb_add_child), + DEVMETHOD(bus_alloc_resource, apb_alloc_resource), + DEVMETHOD(bus_deactivate_resource, apb_deactivate_resource), + DEVMETHOD(bus_get_resource_list, apb_get_resource_list), + DEVMETHOD(bus_hinted_child, apb_hinted_child), + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_release_resource, apb_release_resource), + DEVMETHOD(bus_setup_intr, apb_setup_intr), + DEVMETHOD(bus_teardown_intr, apb_teardown_intr), + DEVMETHOD(device_attach, apb_attach), + DEVMETHOD(device_probe, apb_probe), + DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), + DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), + + {0, 0}, +}; + +static driver_t apb_driver = { + "apb", + apb_methods, + sizeof(struct apb_softc), +}; +static devclass_t apb_devclass; + +DRIVER_MODULE(apb, nexus, apb_driver, apb_devclass, 0, 0); diff --git a/sys/mips/atheros/apbvar.h b/sys/mips/atheros/apbvar.h new file mode 100644 index 00000000000..e1d29f4a662 --- /dev/null +++ b/sys/mips/atheros/apbvar.h @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _APBVAR_H_ +#define _APBVAR_H_ + +#define APB_IRQ_BASE 0 +#define APB_IRQ_END 7 +#define APB_NIRQS 8 + +struct apb_softc { + struct rman apb_irq_rman; + /* IRQ events structs for child devices */ + struct intr_event *sc_eventstab[APB_NIRQS]; + /* Resources and cookies for MIPS CPU INTs */ + struct resource *sc_misc_irq; + void *sc_misc_ih; +}; + +struct apb_ivar { + struct resource_list resources; +}; + +#endif /* _APBVAR_H_ */ diff --git a/sys/mips/atheros/ar71xx_machdep.c b/sys/mips/atheros/ar71xx_machdep.c new file mode 100644 index 00000000000..a5699edb7ee --- /dev/null +++ b/sys/mips/atheros/ar71xx_machdep.c @@ -0,0 +1,161 @@ +/*- + * Copyright (c) 2009 Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include + +#include "opt_ddb.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +extern int *edata; +extern int *end; + +void +platform_halt(void) +{ + +} + +void +platform_identify(void) +{ + +} + +void +platform_reset(void) +{ + uint32_t reg = ATH_READ_REG(AR71XX_RST_RESET); + + ATH_WRITE_REG(AR71XX_RST_RESET, reg | RST_RESET_FULL_CHIP); + /* Wait for reset */ + while(1) + ; +} + +void +platform_trap_enter(void) +{ + +} + +void +platform_trap_exit(void) +{ + +} + +void +platform_start(__register_t a0 __unused, __register_t a1 __unused, + __register_t a2 __unused, __register_t a3 __unused) +{ + vm_offset_t kernend; + uint64_t platform_counter_freq; + uint32_t reg; + + /* clear the BSS and SBSS segments */ + kernend = round_page((vm_offset_t)&end); + memset(&edata, 0, kernend - (vm_offset_t)(&edata)); + + /* TODO: Get available memory from RedBoot. Is it possible? */ + realmem = btoc(64*1024*1024); + /* phys_avail regions are in bytes */ + phys_avail[0] = MIPS_KSEG0_TO_PHYS((vm_offset_t)&end); + phys_avail[1] = ctob(realmem); + + physmem = realmem; + + /* + * ns8250 uart code uses DELAY so ticker should be inititalized + * before cninit. And tick_init_params refers to hz, so * init_param1 + * should be called first. + */ + init_param1(); + /* TODO: Get CPU freq from RedBoot. Is it possible? */ + platform_counter_freq = 680000000UL; + mips_timer_init_params(platform_counter_freq, 0); + cninit(); + + printf("arguments: \n"); + printf(" a0 = %08x\n", a0); + printf(" a1 = %08x\n", a1); + printf(" a2 = %08x\n", a2); + printf(" a3 = %08x\n", a3); + + init_param2(physmem); + mips_cpu_init(); + pmap_bootstrap(); + mips_proc0_init(); + mutex_init(); + + /* + * Reset USB devices + */ + reg = ATH_READ_REG(AR71XX_RST_RESET); + reg |= + RST_RESET_USB_OHCI_DLL | RST_RESET_USB_HOST | RST_RESET_USB_PHY; + ATH_WRITE_REG(AR71XX_RST_RESET, reg); + DELAY(1000); + reg &= + ~(RST_RESET_USB_OHCI_DLL | RST_RESET_USB_HOST | RST_RESET_USB_PHY); + ATH_WRITE_REG(AR71XX_RST_RESET, reg); + + ATH_WRITE_REG(AR71XX_USB_CTRL_CONFIG, + USB_CTRL_CONFIG_OHCI_DES_SWAP | USB_CTRL_CONFIG_OHCI_BUF_SWAP | + USB_CTRL_CONFIG_EHCI_DES_SWAP | USB_CTRL_CONFIG_EHCI_BUF_SWAP); + + ATH_WRITE_REG(AR71XX_USB_CTRL_FLADJ, + (32 << USB_CTRL_FLADJ_HOST_SHIFT) | (3 << USB_CTRL_FLADJ_A5_SHIFT)); + DELAY(1000); + +#ifdef DDB + kdb_init(); +#endif +} diff --git a/sys/mips/atheros/ar71xx_ohci.c b/sys/mips/atheros/ar71xx_ohci.c new file mode 100644 index 00000000000..b7adc617b9c --- /dev/null +++ b/sys/mips/atheros/ar71xx_ohci.c @@ -0,0 +1,205 @@ +/*- + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +static int ar71xx_ohci_attach(device_t dev); +static int ar71xx_ohci_detach(device_t dev); +static int ar71xx_ohci_probe(device_t dev); + +struct ar71xx_ohci_softc +{ + struct ohci_softc sc_ohci; +}; + +static int +ar71xx_ohci_probe(device_t dev) +{ + device_set_desc(dev, "AR71XX integrated OHCI controller"); + return (BUS_PROBE_DEFAULT); +} + +static int +ar71xx_ohci_attach(device_t dev) +{ + struct ar71xx_ohci_softc *sc = device_get_softc(dev); + int err; + int rid; + + rid = 0; + sc->sc_ohci.io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (sc->sc_ohci.io_res == NULL) { + err = ENOMEM; + goto error; + } + sc->sc_ohci.iot = rman_get_bustag(sc->sc_ohci.io_res); + sc->sc_ohci.ioh = rman_get_bushandle(sc->sc_ohci.io_res); + + rid = 0; + sc->sc_ohci.irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_ACTIVE); + if (sc->sc_ohci.irq_res == NULL) { + err = ENOMEM; + goto error; + } + sc->sc_ohci.sc_bus.bdev = device_add_child(dev, "usb", -1); + if (sc->sc_ohci.sc_bus.bdev == NULL) { + err = ENOMEM; + goto error; + } + device_set_ivars(sc->sc_ohci.sc_bus.bdev, &sc->sc_ohci.sc_bus); + + /* Allocate a parent dma tag for DMA maps */ + err = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, + BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0, + NULL, NULL, &sc->sc_ohci.sc_bus.parent_dmatag); + if (err) { + device_printf(dev, "Could not allocate parent DMA tag (%d)\n", + err); + err = ENXIO; + goto error; + } + + /* Allocate a dma tag for transfer buffers */ + err = bus_dma_tag_create(sc->sc_ohci.sc_bus.parent_dmatag, 1, 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, + BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0, + busdma_lock_mutex, &Giant, &sc->sc_ohci.sc_bus.buffer_dmatag); + if (err) { + device_printf(dev, "Could not allocate transfer tag (%d)\n", + err); + err = ENXIO; + goto error; + } + + err = bus_setup_intr(dev, sc->sc_ohci.irq_res, INTR_TYPE_BIO, NULL, + ohci_intr, sc, &sc->sc_ohci.ih); + if (err) { + err = ENXIO; + goto error; + } + strlcpy(sc->sc_ohci.sc_vendor, "Atheros", + sizeof(sc->sc_ohci.sc_vendor)); + + bus_space_write_4(sc->sc_ohci.iot, sc->sc_ohci.ioh, OHCI_CONTROL, 0); + + err = ohci_init(&sc->sc_ohci); + if (!err) { + sc->sc_ohci.sc_flags |= OHCI_SCFLG_DONEINIT; + err = device_probe_and_attach(sc->sc_ohci.sc_bus.bdev); + } + +error: + if (err) { + ar71xx_ohci_detach(dev); + return (err); + } + return (err); +} + +static int +ar71xx_ohci_detach(device_t dev) +{ + struct ar71xx_ohci_softc *sc = device_get_softc(dev); + + if (sc->sc_ohci.sc_flags & OHCI_SCFLG_DONEINIT) { + ohci_detach(&sc->sc_ohci, 0); + sc->sc_ohci.sc_flags &= ~OHCI_SCFLG_DONEINIT; + } + + if (sc->sc_ohci.ih) { + bus_teardown_intr(dev, sc->sc_ohci.irq_res, sc->sc_ohci.ih); + sc->sc_ohci.ih = NULL; + } + + if (sc->sc_ohci.sc_bus.parent_dmatag != NULL) + bus_dma_tag_destroy(sc->sc_ohci.sc_bus.parent_dmatag); + if (sc->sc_ohci.sc_bus.buffer_dmatag != NULL) + bus_dma_tag_destroy(sc->sc_ohci.sc_bus.buffer_dmatag); + + if (sc->sc_ohci.sc_bus.bdev) { + device_delete_child(dev, sc->sc_ohci.sc_bus.bdev); + sc->sc_ohci.sc_bus.bdev = NULL; + } + if (sc->sc_ohci.irq_res) { + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_ohci.irq_res); + sc->sc_ohci.irq_res = NULL; + } + if (sc->sc_ohci.io_res) { + bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_ohci.io_res); + sc->sc_ohci.io_res = NULL; + sc->sc_ohci.iot = 0; + sc->sc_ohci.ioh = 0; + } + return (0); +} + +static device_method_t ohci_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, ar71xx_ohci_probe), + DEVMETHOD(device_attach, ar71xx_ohci_attach), + DEVMETHOD(device_detach, ar71xx_ohci_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + + /* Bus interface */ + DEVMETHOD(bus_print_child, bus_generic_print_child), + + {0, 0} +}; + +static driver_t ohci_driver = { + "ohci", + ohci_methods, + sizeof(struct ar71xx_ohci_softc), +}; + +static devclass_t ohci_devclass; + +DRIVER_MODULE(ohci, apb, ohci_driver, ohci_devclass, 0, 0); diff --git a/sys/mips/atheros/ar71xx_pci.c b/sys/mips/atheros/ar71xx_pci.c new file mode 100644 index 00000000000..d3a9295d7aa --- /dev/null +++ b/sys/mips/atheros/ar71xx_pci.c @@ -0,0 +1,429 @@ +/*- + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include "pcib_if.h" + +#include "mips/atheros/ar71xxreg.h" + +#undef AR71XX_PCI_DEBUG +#ifdef AR71XX_PCI_DEBUG +#define dprintf printf +#else +#define dprintf(x, arg...) +#endif + +struct ar71xx_pci_softc { + device_t sc_dev; + + int sc_busno; + struct rman sc_mem_rman; + struct rman sc_irq_rman; + + struct resource *sc_irq; + void *sc_ih; +}; + +/* + * get bitmask for bytes of interest: + * 0 - we want this byte, 1 - ignore it. e.g: we read 1 byte + * from register 7. Bitmask would be: 0111 + */ +static uint32_t +ar71xx_get_bytes_to_read(int reg, int bytes) +{ + uint32_t bytes_to_read = 0; + if ((bytes % 4) == 0) + bytes_to_read = 0; + else if ((bytes % 4) == 1) + bytes_to_read = (~(1 << (reg % 4))) & 0xf; + else if ((bytes % 4) == 2) + bytes_to_read = (~(3 << (reg % 4))) & 0xf; + else + panic("%s: wrong combination", __func__); + + return (bytes_to_read); +} + +static int +ar71xx_pci_check_bus_error(void) +{ + uint32_t error, addr, has_errors = 0; + error = ATH_READ_REG(AR71XX_PCI_ERROR) & 0x3; + dprintf("%s: PCI error = %02x\n", __func__, error); + if (error) { + addr = ATH_READ_REG(AR71XX_PCI_ERROR_ADDR); + + /* Do not report it yet */ +#if 0 + printf("PCI bus error %d at addr 0x%08x\n", error, addr); +#endif + ATH_WRITE_REG(AR71XX_PCI_ERROR, error); + has_errors = 1; + } + + error = ATH_READ_REG(AR71XX_PCI_AHB_ERROR) & 0x1; + dprintf("%s: AHB error = %02x\n", __func__, error); + if (error) { + addr = ATH_READ_REG(AR71XX_PCI_AHB_ERROR_ADDR); + /* Do not report it yet */ +#if 0 + printf("AHB bus error %d at addr 0x%08x\n", error, addr); +#endif + ATH_WRITE_REG(AR71XX_PCI_AHB_ERROR, error); + has_errors = 1; + } + + return (has_errors); +} + +static uint32_t +ar71xx_pci_make_addr(int bus, int slot, int func, int reg) +{ + if (bus == 0) { + return ((1 << slot) | (func << 8) | (reg & ~3)); + } else { + return ((bus << 16) | (slot << 11) | (func << 8) + | (reg & ~3) | 1); + } +} + +static int +ar71xx_pci_conf_setup(int bus, int slot, int func, int reg, int bytes, + uint32_t cmd) +{ + uint32_t addr = ar71xx_pci_make_addr(bus, slot, func, (reg & ~3)); + cmd |= (ar71xx_get_bytes_to_read(reg, bytes) << 4); + + ATH_WRITE_REG(AR71XX_PCI_CONF_ADDR, addr); + ATH_WRITE_REG(AR71XX_PCI_CONF_CMD, cmd); + + dprintf("%s: tag (%x, %x, %x) %d/%d addr=%08x, cmd=%08x\n", __func__, + bus, slot, func, reg, bytes, addr, cmd); + + return ar71xx_pci_check_bus_error(); +} + +static uint32_t +ar71xx_pci_read_config(device_t dev, int bus, int slot, int func, int reg, + int bytes) +{ + uint32_t data; + uint32_t cmd, shift, mask; + + /* register access is 32-bit aligned */ + shift = (reg & 3) * 8; + if (shift) + mask = (1 << shift) - 1; + else + mask = 0xffffffff; + + dprintf("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, bus, slot, + func, reg, bytes); + + if ((bus == 0) && (slot == 0) && (func == 0)) { + cmd = PCI_LCONF_CMD_READ | (reg & ~3); + ATH_WRITE_REG(AR71XX_PCI_LCONF_CMD, cmd); + data = ATH_READ_REG(AR71XX_PCI_LCONF_READ_DATA); + } else { + if (ar71xx_pci_conf_setup(bus, slot, func, reg, bytes, + PCI_CONF_CMD_READ) == 0) + data = ATH_READ_REG(AR71XX_PCI_CONF_READ_DATA); + else + data = -1; + } + + /* get request bytes from 32-bit word */ + data = (data >> shift) & mask; + + dprintf("%s: read 0x%x\n", __func__, data); + + return (data); +} + +static void +ar71xx_pci_write_config(device_t dev, int bus, int slot, int func, int reg, + uint32_t data, int bytes) +{ + uint32_t cmd; + + dprintf("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, bus, slot, + func, reg, bytes); + + data = data << (8*(reg % 4)); + + if ((bus == 0) && (slot == 0) && (func == 0)) { + cmd = PCI_LCONF_CMD_WRITE | (reg & ~3); + cmd |= ar71xx_get_bytes_to_read(reg, bytes) << 20; + ATH_WRITE_REG(AR71XX_PCI_LCONF_CMD, cmd); + ATH_WRITE_REG(AR71XX_PCI_LCONF_WRITE_DATA, data); + } else { + if (ar71xx_pci_conf_setup(bus, slot, func, reg, bytes, + PCI_CONF_CMD_WRITE) == 0) + ATH_WRITE_REG(AR71XX_PCI_CONF_WRITE_DATA, data); + } +} + +static int +at71xx_pci_intr(void *v) +{ + panic("Implement me: %s\n", __func__); + return FILTER_HANDLED; +} + +static int +ar71xx_pci_probe(device_t dev) +{ + + return (0); +} + +static int +ar71xx_pci_attach(device_t dev) +{ + int busno = 0; + int rid = 0; + uint32_t reset; + struct ar71xx_pci_softc *sc = device_get_softc(dev); + + sc->sc_mem_rman.rm_type = RMAN_ARRAY; + sc->sc_mem_rman.rm_descr = "ar71xx PCI memory window"; + if (rman_init(&sc->sc_mem_rman) != 0 || + rman_manage_region(&sc->sc_mem_rman, AR71XX_PCI_MEM_BASE, + AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1) != 0) { + panic("ar71xx_pci_attach: failed to set up I/O rman"); + } + + sc->sc_irq_rman.rm_type = RMAN_ARRAY; + sc->sc_irq_rman.rm_descr = "ar71xx PCI IRQs"; + if (rman_init(&sc->sc_irq_rman) != 0 || + rman_manage_region(&sc->sc_irq_rman, AR71XX_PCI_IRQ_START, + AR71XX_PCI_IRQ_END) != 0) + panic("ar71xx_pci_attach: failed to set up IRQ rman"); + + + ATH_WRITE_REG(AR71XX_PCI_INTR_STATUS, 0); + ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, 0); + + /* Hook up our interrupt handler. */ + if ((sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_SHAREABLE | RF_ACTIVE)) == NULL) { + device_printf(dev, "unable to allocate IRQ resource\n"); + return ENXIO; + } + + if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC, + at71xx_pci_intr, NULL, sc, &sc->sc_ih))) { + device_printf(dev, + "WARNING: unable to register interrupt handler\n"); + return ENXIO; + } + + /* reset PCI core and PCI bus */ + reset = ATH_READ_REG(AR71XX_RST_RESET); + reset |= (RST_RESET_PCI_CORE | RST_RESET_PCI_BUS); + ATH_WRITE_REG(AR71XX_RST_RESET, reset); + DELAY(1000); + + reset &= ~(RST_RESET_PCI_CORE | RST_RESET_PCI_BUS); + ATH_WRITE_REG(AR71XX_RST_RESET, reset); + DELAY(1000); + + /* Init PCI windows */ + ATH_WRITE_REG(AR71XX_PCI_WINDOW0, PCI_WINDOW0_ADDR); + ATH_WRITE_REG(AR71XX_PCI_WINDOW1, PCI_WINDOW1_ADDR); + ATH_WRITE_REG(AR71XX_PCI_WINDOW2, PCI_WINDOW2_ADDR); + ATH_WRITE_REG(AR71XX_PCI_WINDOW3, PCI_WINDOW3_ADDR); + ATH_WRITE_REG(AR71XX_PCI_WINDOW4, PCI_WINDOW4_ADDR); + ATH_WRITE_REG(AR71XX_PCI_WINDOW5, PCI_WINDOW5_ADDR); + ATH_WRITE_REG(AR71XX_PCI_WINDOW6, PCI_WINDOW6_ADDR); + ATH_WRITE_REG(AR71XX_PCI_WINDOW7, PCI_WINDOW7_CONF_ADDR); + DELAY(1000); + + ar71xx_pci_check_bus_error(); + + /* Fixup internal PCI bridge */ + ar71xx_pci_write_config(dev, 0, 0, 0, PCIR_COMMAND, + PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN + | PCIM_CMD_SERRESPEN | PCIM_CMD_BACKTOBACK + | PCIM_CMD_PERRESPEN | PCIM_CMD_MWRICEN, 2); + + device_add_child(dev, "pci", busno); + return (bus_generic_attach(dev)); +} + +static int +ar71xx_pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) +{ + struct ar71xx_pci_softc *sc = device_get_softc(dev); + + switch (which) { + case PCIB_IVAR_DOMAIN: + *result = 0; + return (0); + case PCIB_IVAR_BUS: + *result = sc->sc_busno; + return (0); + } + + return (ENOENT); +} + +static int +ar71xx_pci_write_ivar(device_t dev, device_t child, int which, uintptr_t result) +{ + struct ar71xx_pci_softc * sc = device_get_softc(dev); + + switch (which) { + case PCIB_IVAR_BUS: + sc->sc_busno = result; + return (0); + } + + return (ENOENT); +} + +static struct resource * +ar71xx_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + + struct ar71xx_pci_softc *sc = device_get_softc(bus); + struct resource *rv = NULL; + struct rman *rm; + + switch (type) { + case SYS_RES_IRQ: + rm = &sc->sc_irq_rman; + break; + case SYS_RES_MEMORY: + rm = &sc->sc_mem_rman; + break; + default: + return (NULL); + } + + rv = rman_reserve_resource(rm, start, end, count, flags, child); + + if (rv == NULL) + return (NULL); + + rman_set_rid(rv, *rid); + + if (flags & RF_ACTIVE) { + if (bus_activate_resource(child, type, *rid, rv)) { + rman_release_resource(rv); + return (NULL); + } + } + + return (rv); +} + +static int +ar71xx_pci_teardown_intr(device_t dev, device_t child, struct resource *res, + void *cookie) +{ + + return (intr_event_remove_handler(cookie)); +} + +static int +ar71xx_pci_maxslots(device_t dev) +{ + + return (PCI_SLOTMAX); +} + +static int +ar71xx_pci_route_interrupt(device_t pcib, device_t device, int pin) +{ + + return (pin); +} + +static device_method_t ar71xx_pci_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, ar71xx_pci_probe), + DEVMETHOD(device_attach, ar71xx_pci_attach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(device_suspend, bus_generic_suspend), + DEVMETHOD(device_resume, bus_generic_resume), + + /* Bus interface */ + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_read_ivar, ar71xx_pci_read_ivar), + DEVMETHOD(bus_write_ivar, ar71xx_pci_write_ivar), + DEVMETHOD(bus_alloc_resource, ar71xx_pci_alloc_resource), + DEVMETHOD(bus_release_resource, bus_generic_release_resource), + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_teardown_intr, ar71xx_pci_teardown_intr), + + /* pcib interface */ + DEVMETHOD(pcib_maxslots, ar71xx_pci_maxslots), + DEVMETHOD(pcib_read_config, ar71xx_pci_read_config), + DEVMETHOD(pcib_write_config, ar71xx_pci_write_config), + DEVMETHOD(pcib_route_interrupt, ar71xx_pci_route_interrupt), + + {0, 0} +}; + +static driver_t ar71xx_pci_driver = { + "pcib", + ar71xx_pci_methods, + sizeof(struct ar71xx_pci_softc), +}; + +static devclass_t ar71xx_pci_devclass; + +DRIVER_MODULE(ar71xx_pci, nexus, ar71xx_pci_driver, ar71xx_pci_devclass, 0, 0); diff --git a/sys/mips/atheros/ar71xxreg.h b/sys/mips/atheros/ar71xxreg.h new file mode 100644 index 00000000000..93677922463 --- /dev/null +++ b/sys/mips/atheros/ar71xxreg.h @@ -0,0 +1,317 @@ +/*- + * Copyright (c) 2009 Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#ifndef _AR71XX_REG_H_ +#define _AR71XX_REG_H_ + +#define ATH_READ_REG(reg) \ + *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((reg))) + +#define ATH_WRITE_REG(reg, val) \ + *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((reg))) = (val) + +/* PCI region */ +#define AR71XX_PCI_MEM_BASE 0x10000000 +/* + * PCI mem windows is 0x08000000 bytes long but we exclude control + * region from the resource manager + */ +#define AR71XX_PCI_MEM_SIZE 0x07000000 +#define AR71XX_PCI_IRQ_START 0 +#define AR71XX_PCI_IRQ_END 2 + +/* PCI config registers */ +#define AR71XX_PCI_LCONF_CMD 0x17010000 +#define PCI_LCONF_CMD_READ 0x00000000 +#define PCI_LCONF_CMD_WRITE 0x00010000 +#define AR71XX_PCI_LCONF_WRITE_DATA 0x17010004 +#define AR71XX_PCI_LCONF_READ_DATA 0x17010008 +#define AR71XX_PCI_CONF_ADDR 0x1701000C +#define AR71XX_PCI_CONF_CMD 0x17010010 +#define PCI_CONF_CMD_READ 0x0000000A +#define PCI_CONF_CMD_WRITE 0x0000000B +#define AR71XX_PCI_CONF_WRITE_DATA 0x17010014 +#define AR71XX_PCI_CONF_READ_DATA 0x17010018 +#define AR71XX_PCI_ERROR 0x1701001C +#define AR71XX_PCI_ERROR_ADDR 0x17010020 +#define AR71XX_PCI_AHB_ERROR 0x17010024 +#define AR71XX_PCI_AHB_ERROR_ADDR 0x17010028 + +/* APB region */ +/* DDR registers */ +#define AR71XX_DDR_CONFIG 0x18000000 +#define AR71XX_DDR_CONFIG2 0x18000004 +#define AR71XX_DDR_MODE_REGISTER 0x18000008 +#define AR71XX_DDR_EXT_MODE_REGISTER 0x1800000C +#define AR71XX_DDR_CONTROL 0x18000010 +#define AR71XX_DDR_REFRESH 0x18000014 +#define AR71XX_DDR_RD_DATA_THIS_CYCLE 0x18000018 +#define AR71XX_TAP_CONTROL0 0x1800001C +#define AR71XX_TAP_CONTROL1 0x18000020 +#define AR71XX_TAP_CONTROL2 0x18000024 +#define AR71XX_TAP_CONTROL3 0x18000028 +#define AR71XX_PCI_WINDOW0 0x1800007C +#define AR71XX_PCI_WINDOW1 0x18000080 +#define AR71XX_PCI_WINDOW2 0x18000084 +#define AR71XX_PCI_WINDOW3 0x18000088 +#define AR71XX_PCI_WINDOW4 0x1800008C +#define AR71XX_PCI_WINDOW5 0x18000090 +#define AR71XX_PCI_WINDOW6 0x18000094 +#define AR71XX_PCI_WINDOW7 0x18000098 +#define AR71XX_WB_FLUSH_GE0 0x1800009C +#define AR71XX_WB_FLUSH_GE1 0x180000A0 +#define AR71XX_WB_FLUSH_USB 0x180000A4 +#define AR71XX_WB_FLUSH_PCI 0x180000A8 + +/* + * Values for PCI_WINDOW_X registers + */ +#define PCI_WINDOW0_ADDR 0x10000000 +#define PCI_WINDOW1_ADDR 0x11000000 +#define PCI_WINDOW2_ADDR 0x12000000 +#define PCI_WINDOW3_ADDR 0x13000000 +#define PCI_WINDOW4_ADDR 0x14000000 +#define PCI_WINDOW5_ADDR 0x15000000 +#define PCI_WINDOW6_ADDR 0x16000000 +#define PCI_WINDOW7_ADDR 0x17000000 +/* This value enables acces to PCI config registers */ +#define PCI_WINDOW7_CONF_ADDR 0x07000000 + +#define AR71XX_UART_ADDR 0x18020000 + +#define AR71XX_USB_CTRL_FLADJ 0x18030000 +#define USB_CTRL_FLADJ_HOST_SHIFT 12 +#define USB_CTRL_FLADJ_A5_SHIFT 10 +#define USB_CTRL_FLADJ_A4_SHIFT 8 +#define USB_CTRL_FLADJ_A3_SHIFT 6 +#define USB_CTRL_FLADJ_A2_SHIFT 4 +#define USB_CTRL_FLADJ_A1_SHIFT 2 +#define USB_CTRL_FLADJ_A0_SHIFT 0 +#define AR71XX_USB_CTRL_CONFIG 0x18030004 +#define USB_CTRL_CONFIG_OHCI_DES_SWAP (1 << 19) +#define USB_CTRL_CONFIG_OHCI_BUF_SWAP (1 << 18) +#define USB_CTRL_CONFIG_EHCI_DES_SWAP (1 << 17) +#define USB_CTRL_CONFIG_EHCI_BUF_SWAP (1 << 16) +#define USB_CTRL_CONFIG_DISABLE_XTL (1 << 13) +#define USB_CTRL_CONFIG_OVERRIDE_XTL (1 << 12) +#define USB_CTRL_CONFIG_CLK_SEL_SHIFT 4 +#define USB_CTRL_CONFIG_CLK_SEL_MASK 3 +#define USB_CTRL_CONFIG_CLK_SEL_12 0 +#define USB_CTRL_CONFIG_CLK_SEL_24 1 +#define USB_CTRL_CONFIG_CLK_SEL_48 2 +#define USB_CTRL_CONFIG_OVER_CURRENT_AS_GPIO (1 << 8) +#define USB_CTRL_CONFIG_SS_SIMULATION_MODE (1 << 2) +#define USB_CTRL_CONFIG_RESUME_UTMI_PLS_DIS (1 << 1) +#define USB_CTRL_CONFIG_UTMI_BACKWARD_ENB (1 << 0) + +#define AR71XX_PLL_CPU_CONFIG 0x18050000 +#define AR71XX_PLL_SEC_CONFIG 0x18050004 +#define AR71XX_PLL_CPU_CLK_CTRL 0x18050008 +#define AR71XX_PLL_ETH_INT0_CLK 0x18050010 +#define AR71XX_PLL_ETH_INT1_CLK 0x18050014 +#define XPLL_ETH_INT_CLK_10 0x00991099 +#define XPLL_ETH_INT_CLK_100 0x00441011 +#define XPLL_ETH_INT_CLK_1000 0x13110000 +#define XPLL_ETH_INT_CLK_1000_GMII 0x14110000 +#define PLL_ETH_INT_CLK_10 0x00991099 +#define PLL_ETH_INT_CLK_100 0x00001099 +#define PLL_ETH_INT_CLK_1000 0x00110000 +#define AR71XX_PLL_ETH_EXT_CLK 0x18050018 +#define AR71XX_PLL_PCI_CLK 0x1805001C + +/* + * APB interrupt status and mask register and interrupt bit numbers for + */ +#define AR71XX_MISC_INTR_STATUS 0x18060010 +#define AR71XX_MISC_INTR_MASK 0x18060014 +#define MISC_INTR_TIMER 0 +#define MISC_INTR_ERROR 1 +#define MISC_INTR_GPIO 2 +#define MISC_INTR_UART 3 +#define MISC_INTR_WATCHDOG 4 +#define MISC_INTR_PERF 5 +#define MISC_INTR_OHCI 6 +#define MISC_INTR_DMA 7 + +#define AR71XX_PCI_INTR_STATUS 0x18060018 +#define AR71XX_PCI_INTR_MASK 0x1806001C +#define PCI_INTR_CORE (1 << 4) + +#define AR71XX_RST_RESET 0x18060024 +#define RST_RESET_FULL_CHIP (1 << 24) /* Same as pulling + the reset pin */ +#define RST_RESET_CPU_COLD (1 << 20) /* Cold reset */ +#define RST_RESET_GE1_MAC (1 << 13) +#define RST_RESET_GE1_PHY (1 << 12) +#define RST_RESET_GE0_MAC (1 << 9) +#define RST_RESET_GE0_PHY (1 << 8) +#define RST_RESET_USB_OHCI_DLL (1 << 6) +#define RST_RESET_USB_HOST (1 << 5) +#define RST_RESET_USB_PHY (1 << 4) +#define RST_RESET_PCI_BUS (1 << 1) +#define RST_RESET_PCI_CORE (1 << 0) + +/* + * GigE adapters region + */ +#define AR71XX_MAC0_BASE 0x19000000 +#define AR71XX_MAC1_BASE 0x1A000000 + +#define AR71XX_MAC_CFG1 0x00 +#define MAC_CFG1_SOFT_RESET (1 << 31) +#define MAC_CFG1_SIMUL_RESET (1 << 30) +#define MAC_CFG1_MAC_RX_BLOCK_RESET (1 << 19) +#define MAC_CFG1_MAC_TX_BLOCK_RESET (1 << 18) +#define MAC_CFG1_RX_FUNC_RESET (1 << 17) +#define MAC_CFG1_TX_FUNC_RESET (1 << 16) +#define MAC_CFG1_LOOPBACK (1 << 8) +#define MAC_CFG1_RXFLOW_CTRL (1 << 5) +#define MAC_CFG1_TXFLOW_CTRL (1 << 4) +#define MAC_CFG1_SYNC_RX (1 << 3) +#define MAC_CFG1_RX_ENABLE (1 << 2) +#define MAC_CFG1_SYNC_TX (1 << 1) +#define MAC_CFG1_TX_ENABLE (1 << 0) +#define AR71XX_MAC_CFG2 0x04 +#define MAC_CFG2_PREAMBLE_LEN_MASK 0xf +#define MAC_CFG2_PREAMBLE_LEN_SHIFT 12 +#define MAC_CFG2_IFACE_MODE_1000 (2 << 8) +#define MAC_CFG2_IFACE_MODE_10_100 (1 << 8) +#define MAC_CFG2_IFACE_MODE_SHIFT 8 +#define MAC_CFG2_IFACE_MODE_MASK 3 +#define MAC_CFG2_HUGE_FRAME (1 << 5) +#define MAC_CFG2_LENGTH_FIELD (1 << 4) +#define MAC_CFG2_ENABLE_PADCRC (1 << 2) +#define MAC_CFG2_ENABLE_CRC (1 << 1) +#define MAC_CFG2_FULL_DUPLEX (1 << 0) +#define AR71XX_MAC_IFG 0x08 +#define AR71XX_MAC_HDUPLEX 0x0C +#define AR71XX_MAC_MAX_FRAME_LEN 0x10 +#define AR71XX_MAC_MII_CFG 0x20 +#define MAC_MII_CFG_RESET (1 << 31) +#define MAC_MII_CFG_SCAN_AUTO_INC (1 << 5) +#define MAC_MII_CFG_PREAMBLE_SUP (1 << 4) +#define MAC_MII_CFG_CLOCK_SELECT_MASK 0x7 +#define MAC_MII_CFG_CLOCK_DIV_4 0 +#define MAC_MII_CFG_CLOCK_DIV_6 2 +#define MAC_MII_CFG_CLOCK_DIV_8 3 +#define MAC_MII_CFG_CLOCK_DIV_10 4 +#define MAC_MII_CFG_CLOCK_DIV_14 5 +#define MAC_MII_CFG_CLOCK_DIV_20 6 +#define MAC_MII_CFG_CLOCK_DIV_28 7 +#define AR71XX_MAC_MII_CMD 0x24 +#define MAC_MII_CMD_SCAN_CYCLE (1 << 1) +#define MAC_MII_CMD_READ 1 +#define MAC_MII_CMD_WRITE 0 +#define AR71XX_MAC_MII_ADDR 0x28 +#define MAC_MII_PHY_ADDR_SHIFT 8 +#define MAC_MII_PHY_ADDR_MASK 0xff +#define MAC_MII_REG_MASK 0x1f +#define AR71XX_MAC_MII_CONTROL 0x2C +#define MAC_MII_CONTROL_MASK 0xffff +#define AR71XX_MAC_MII_STATUS 0x30 +#define MAC_MII_STATUS_MASK 0xffff +#define AR71XX_MAC_MII_INDICATOR 0x34 +#define MAC_MII_INDICATOR_NOT_VALID (1 << 2) +#define MAC_MII_INDICATOR_SCANNING (1 << 1) +#define MAC_MII_INDICATOR_BUSY (1 << 0) +#define AR71XX_MAC_IFCONTROL 0x38 +#define MAC_IFCONTROL_SPEED (1 << 16) +#define AR71XX_MAC_STA_ADDR1 0x40 +#define AR71XX_MAC_STA_ADDR2 0x44 +#define AR71XX_MAC_FIFO_CFG0 0x48 +#define FIFO_CFG0_TX_FABRIC (1 << 4) +#define FIFO_CFG0_TX_SYSTEM (1 << 3) +#define FIFO_CFG0_RX_FABRIC (1 << 2) +#define FIFO_CFG0_RX_SYSTEM (1 << 1) +#define FIFO_CFG0_WATERMARK (1 << 0) +#define FIFO_CFG0_ALL ((1 << 5) - 1) +#define FIFO_CFG0_ENABLE_SHIFT 8 +#define AR71XX_MAC_FIFO_CFG1 0x4C +#define AR71XX_MAC_FIFO_CFG2 0x50 +#define AR71XX_MAC_FIFO_TX_THRESHOLD 0x54 +#define AR71XX_MAC_FIFO_RX_FILTMATCH 0x58 +#define FIFO_RX_FILTMATCH_ALL ((1 << 18) - 1) +#define AR71XX_MAC_FIFO_RX_FILTMASK 0x5C +#define FIFO_RX_FILTMASK_BYTE_MODE (1 << 19) +#define FIFO_RX_FILTMASK_NO_SHORT_FRAME (1 << 18) +#define FIFO_RX_FILTMASK_ALL ((1 << 20) - 1) +/* + * These flags applicable both to AR71XX_MAC_FIFO_RX_FILTMASK and + * to AR71XX_MAC_FIFO_RX_FILTMATCH + */ +#define FIFO_RX_FILT_UNICAST (1 << 17) +#define FIFO_RX_FILT_TRUNC_FRAME (1 << 16) +#define FIFO_RX_FILT_VLAN_TAG (1 << 15) +#define FIFO_RX_FILT_UNSUP_OPCODE (1 << 14) +#define FIFO_RX_FILT_PAUSE_FRAME (1 << 13) +#define FIFO_RX_FILT_CTRL_FRAME (1 << 12) +#define FIFO_RX_FILT_LONG_EVENT (1 << 11) +#define FIFO_RX_FILT_DRIBBLE_NIBBLE (1 << 10) +#define FIFO_RX_FILT_BCAST (1 << 9) +#define FIFO_RX_FILT_MCAST (1 << 8) +#define FIFO_RX_FILT_OK (1 << 7) +#define FIFO_RX_FILT_OORANGE (1 << 6) +#define FIFO_RX_FILT_LEN_MSMTCH (1 << 5) +#define FIFO_RX_FILT_CRC_ERROR (1 << 4) +#define FIFO_RX_FILT_CODE_ERROR (1 << 3) +#define FIFO_RX_FILT_FALSE_CARRIER (1 << 2) +#define FIFO_RX_FILT_RX_DV_EVENT (1 << 1) +#define FIFO_RX_FILT_DROP_EVENT (1 << 0) +#define AR71XX_MAC_FIFO_RAM0 0x60 +#define AR71XX_MAC_FIFO_RAM1 0x64 +#define AR71XX_MAC_FIFO_RAM2 0x68 +#define AR71XX_MAC_FIFO_RAM3 0x6C +#define AR71XX_MAC_FIFO_RAM4 0x70 +#define AR71XX_MAC_FIFO_RAM5 0x74 +#define AR71XX_MAC_FIFO_RAM6 0x78 +#define AR71XX_DMA_TX_CONTROL 0x180 +#define DMA_TX_CONTROL_EN (1 << 0) +#define AR71XX_DMA_TX_DESC 0x184 +#define AR71XX_DMA_TX_STATUS 0x188 +#define DMA_TX_STATUS_PCOUNT_MASK 0xff +#define DMA_TX_STATUS_PCOUNT_SHIFT 16 +#define DMA_TX_STATUS_BUS_ERROR (1 << 3) +#define DMA_TX_STATUS_UNDERRUN (1 << 1) +#define DMA_TX_STATUS_PKT_SENT (1 << 0) +#define AR71XX_DMA_RX_CONTROL 0x18C +#define DMA_RX_CONTROL_EN (1 << 0) +#define AR71XX_DMA_RX_DESC 0x190 +#define AR71XX_DMA_RX_STATUS 0x194 +#define DMA_RX_STATUS_PCOUNT_MASK 0xff +#define DMA_RX_STATUS_PCOUNT_SHIFT 16 +#define DMA_RX_STATUS_BUS_ERROR (1 << 3) +#define DMA_RX_STATUS_OVERFLOW (1 << 1) +#define DMA_RX_STATUS_PKT_RECVD (1 << 0) +#define AR71XX_DMA_INTR 0x198 +#define AR71XX_DMA_INTR_STATUS 0x19C +#define DMA_INTR_ALL ((1 << 8) - 1) +#define DMA_INTR_RX_BUS_ERROR (1 << 7) +#define DMA_INTR_RX_OVERFLOW (1 << 6) +#define DMA_INTR_RX_PKT_RCVD (1 << 4) +#define DMA_INTR_TX_BUS_ERROR (1 << 3) +#define DMA_INTR_TX_UNDERRUN (1 << 1) +#define DMA_INTR_TX_PKT_SENT (1 << 0) + +#endif /* _AR71XX_REG_H_ */ diff --git a/sys/mips/atheros/files.ar71xx b/sys/mips/atheros/files.ar71xx new file mode 100644 index 00000000000..78e1d9ce177 --- /dev/null +++ b/sys/mips/atheros/files.ar71xx @@ -0,0 +1,9 @@ +# $FreeBSD$ + +mips/atheros/apb.c standard +mips/atheros/ar71xx_machdep.c standard +mips/atheros/ar71xx_ohci.c optional ohci +mips/atheros/ar71xx_pci.c optional pci +mips/atheros/if_arge.c optional arge +mips/atheros/uart_bus_ar71xx.c optional uart +mips/atheros/uart_cpu_ar71xx.c optional uart diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c new file mode 100644 index 00000000000..7dbfe70fb29 --- /dev/null +++ b/sys/mips/atheros/if_arge.c @@ -0,0 +1,1657 @@ +/*- + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +/* + * AR71XX gigabit ethernet driver + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +MODULE_DEPEND(arge, ether, 1, 1, 1); +MODULE_DEPEND(arge, miibus, 1, 1, 1); + +#include "miibus_if.h" + +#include +#include + +#undef ARGE_DEBUG +#ifdef ARGE_DEBUG +#define dprintf printf +#else +#define dprintf(x, arg...) +#endif + +static int arge_attach(device_t); +static int arge_detach(device_t); +static int arge_fix_chain(struct mbuf **mp); +static void arge_flush_ddr(struct arge_softc *); +static int arge_ifmedia_upd(struct ifnet *); +static void arge_ifmedia_sts(struct ifnet *, struct ifmediareq *); +static int arge_ioctl(struct ifnet *, u_long, caddr_t); +static void arge_init(void *); +static void arge_init_locked(struct arge_softc *); +static void arge_link_task(void *, int); +static int arge_miibus_readreg(device_t, int, int); +static void arge_miibus_statchg(device_t); +static int arge_miibus_writereg(device_t, int, int, int); +static int arge_probe(device_t); +static void arge_reset_dma(struct arge_softc *); +static int arge_resume(device_t); +static int arge_rx_ring_init(struct arge_softc *); +static int arge_tx_ring_init(struct arge_softc *); +static void arge_shutdown(device_t); +static void arge_start(struct ifnet *); +static void arge_start_locked(struct ifnet *); +static void arge_stop(struct arge_softc *); +static int arge_suspend(device_t); + +static void arge_rx_locked(struct arge_softc *); +static void arge_tx_locked(struct arge_softc *); +static void arge_intr(void *); +static int arge_intr_filter(void *); +static void arge_tx_intr(struct arge_softc *, uint32_t); +static void arge_rx_intr(struct arge_softc *, uint32_t); +static void arge_tick(void *); + +static void arge_dmamap_cb(void *, bus_dma_segment_t *, int, int); +static int arge_dma_alloc(struct arge_softc *); +static void arge_dma_free(struct arge_softc *); +static int arge_newbuf(struct arge_softc *, int); +static __inline void arge_fixup_rx(struct mbuf *); + +static device_method_t arge_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, arge_probe), + DEVMETHOD(device_attach, arge_attach), + DEVMETHOD(device_detach, arge_detach), + DEVMETHOD(device_suspend, arge_suspend), + DEVMETHOD(device_resume, arge_resume), + DEVMETHOD(device_shutdown, arge_shutdown), + + /* bus interface */ + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_driver_added, bus_generic_driver_added), + + /* MII interface */ + DEVMETHOD(miibus_readreg, arge_miibus_readreg), + DEVMETHOD(miibus_writereg, arge_miibus_writereg), + DEVMETHOD(miibus_statchg, arge_miibus_statchg), + + { 0, 0 } +}; + +static driver_t arge_driver = { + "arge", + arge_methods, + sizeof(struct arge_softc) +}; + +static devclass_t arge_devclass; + +DRIVER_MODULE(arge, nexus, arge_driver, arge_devclass, 0, 0); +DRIVER_MODULE(miibus, arge, miibus_driver, miibus_devclass, 0, 0); + +/* + * Flushes all + */ +static void +arge_flush_ddr(struct arge_softc *sc) +{ + + ATH_WRITE_REG(sc->arge_ddr_flush_reg, 1); + while (ATH_READ_REG(sc->arge_ddr_flush_reg) & 1) + ; + + ATH_WRITE_REG(sc->arge_ddr_flush_reg, 1); + while (ATH_READ_REG(sc->arge_ddr_flush_reg) & 1) + ; +} + +static int +arge_probe(device_t dev) +{ + + device_set_desc(dev, "Atheros AR71xx built-in ethernet interface"); + return (0); +} + +static int +arge_attach(device_t dev) +{ + uint8_t eaddr[ETHER_ADDR_LEN]; + struct ifnet *ifp; + struct arge_softc *sc; + int error = 0, rid, phynum; + uint32_t reg; + + sc = device_get_softc(dev); + sc->arge_dev = dev; + sc->arge_mac_unit = device_get_unit(dev); + + KASSERT(((sc->arge_mac_unit == 0) || (sc->arge_mac_unit == 1)), + ("if_arge: Only MAC0 and MAC1 supported")); + if (sc->arge_mac_unit == 0) { + sc->arge_ddr_flush_reg = AR71XX_WB_FLUSH_GE0; + sc->arge_pll_reg = AR71XX_PLL_ETH_INT0_CLK; + } else { + sc->arge_ddr_flush_reg = AR71XX_WB_FLUSH_GE1; + sc->arge_pll_reg = AR71XX_PLL_ETH_INT1_CLK; + } + + /* + * Get which PHY of 5 available we should use for this unit + */ + if (resource_int_value(device_get_name(dev), device_get_unit(dev), + "phy", &phynum) != 0) { + /* + * Use port 4 (WAN) for GE0. For any other port use + * its PHY the same as its unit number + */ + if (sc->arge_mac_unit == 0) + phynum = 4; + else + phynum = sc->arge_mac_unit; + + device_printf(dev, "No PHY specified, using %d\n", phynum); + } + + sc->arge_phy_num = phynum; + + + mtx_init(&sc->arge_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, + MTX_DEF); + callout_init_mtx(&sc->arge_stat_callout, &sc->arge_mtx, 0); + TASK_INIT(&sc->arge_link_task, 0, arge_link_task, sc); + + /* Map control/status registers. */ + sc->arge_rid = 0; + sc->arge_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &sc->arge_rid, RF_ACTIVE); + + if (sc->arge_res == NULL) { + device_printf(dev, "couldn't map memory\n"); + error = ENXIO; + goto fail; + } + + /* Allocate interrupts */ + rid = 0; + sc->arge_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_SHAREABLE | RF_ACTIVE); + + if (sc->arge_irq == NULL) { + device_printf(dev, "couldn't map interrupt\n"); + error = ENXIO; + goto fail; + } + + /* Allocate ifnet structure. */ + ifp = sc->arge_ifp = if_alloc(IFT_ETHER); + + if (ifp == NULL) { + device_printf(dev, "couldn't allocate ifnet structure\n"); + error = ENOSPC; + goto fail; + } + + ifp->if_softc = sc; + if_initname(ifp, device_get_name(dev), device_get_unit(dev)); + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_ioctl = arge_ioctl; + ifp->if_start = arge_start; + ifp->if_init = arge_init; + + /* XXX: add real size */ + IFQ_SET_MAXLEN(&ifp->if_snd, 9); + ifp->if_snd.ifq_maxlen = 9; + IFQ_SET_READY(&ifp->if_snd); + + ifp->if_capenable = ifp->if_capabilities; + + eaddr[0] = 0x00; + eaddr[1] = 0x15; + eaddr[2] = 0x6d; + eaddr[3] = 0xc1; + eaddr[4] = 0x28; + eaddr[5] = 0x2e; + + if (arge_dma_alloc(sc) != 0) { + error = ENXIO; + goto fail; + } + + ARGE_WRITE(sc, AR71XX_MAC_CFG1, + MAC_CFG1_SYNC_RX | MAC_CFG1_RX_ENABLE | + MAC_CFG1_SYNC_TX | MAC_CFG1_TX_ENABLE); + + reg = ARGE_READ(sc, AR71XX_MAC_CFG2); + reg |= MAC_CFG2_ENABLE_PADCRC | MAC_CFG2_LENGTH_FIELD ; + ARGE_WRITE(sc, AR71XX_MAC_CFG2, reg); + + ARGE_WRITE(sc, AR71XX_MAC_MAX_FRAME_LEN, 1536); + + /* Reset MII bus */ + ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_RESET); + DELAY(100); + ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_CLOCK_DIV_28); + DELAY(100); + + /* + * Set all Ethernet address registers to the same initial values + * set all four addresses to 66-88-aa-cc-dd-ee + */ + ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR1, 0x6dc1282e); + ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR2, 0x00000015); + + ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG0, + FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT); + ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG1, 0x0fff0000); + ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG2, 0x00001fff); + + reg = FIFO_RX_FILTMATCH_ALL; + ARGE_WRITE(sc, AR71XX_MAC_FIFO_RX_FILTMATCH, reg); + + reg = FIFO_RX_FILTMASK_ALL; + reg &= ~FIFO_RX_FILTMASK_BYTE_MODE; + ARGE_WRITE(sc, AR71XX_MAC_FIFO_RX_FILTMASK, reg); + + /* Do MII setup. */ + if (mii_phy_probe(dev, &sc->arge_miibus, + arge_ifmedia_upd, arge_ifmedia_sts)) { + device_printf(dev, "MII without any phy!\n"); + error = ENXIO; + goto fail; + } + + /* Call MI attach routine. */ + ether_ifattach(ifp, eaddr); + + /* Hook interrupt last to avoid having to lock softc */ + error = bus_setup_intr(dev, sc->arge_irq, INTR_TYPE_NET | INTR_MPSAFE, + arge_intr_filter, arge_intr, sc, &sc->arge_intrhand); + + if (error) { + device_printf(dev, "couldn't set up irq\n"); + ether_ifdetach(ifp); + goto fail; + } + +fail: + if (error) + arge_detach(dev); + + return (error); +} + +static int +arge_detach(device_t dev) +{ + struct arge_softc *sc = device_get_softc(dev); + struct ifnet *ifp = sc->arge_ifp; + + KASSERT(mtx_initialized(&sc->arge_mtx), ("arge mutex not initialized")); + + /* These should only be active if attach succeeded */ + if (device_is_attached(dev)) { + ARGE_LOCK(sc); + sc->arge_detach = 1; + arge_stop(sc); + ARGE_UNLOCK(sc); + taskqueue_drain(taskqueue_swi, &sc->arge_link_task); + ether_ifdetach(ifp); + } + + if (sc->arge_miibus) + device_delete_child(dev, sc->arge_miibus); + bus_generic_detach(dev); + + if (sc->arge_intrhand) + bus_teardown_intr(dev, sc->arge_irq, sc->arge_intrhand); + + if (sc->arge_res) + bus_release_resource(dev, SYS_RES_MEMORY, sc->arge_rid, + sc->arge_res); + + if (ifp) + if_free(ifp); + + arge_dma_free(sc); + + mtx_destroy(&sc->arge_mtx); + + return (0); + +} + +static int +arge_suspend(device_t dev) +{ + + panic("%s", __func__); + return 0; +} + +static int +arge_resume(device_t dev) +{ + + panic("%s", __func__); + return 0; +} + +static void +arge_shutdown(device_t dev) +{ + struct arge_softc *sc; + + sc = device_get_softc(dev); + + ARGE_LOCK(sc); + arge_stop(sc); + ARGE_UNLOCK(sc); +} + +static int +arge_miibus_readreg(device_t dev, int phy, int reg) +{ + struct arge_softc * sc = device_get_softc(dev); + int i, result; + uint32_t addr = 0x1000 | (phy << MAC_MII_PHY_ADDR_SHIFT) + | (reg & MAC_MII_REG_MASK); + + if (phy != sc->arge_phy_num) + return (0); + + ARGE_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); + ARGE_WRITE(sc, AR71XX_MAC_MII_ADDR, addr); + ARGE_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_READ); + + i = ARGE_MII_TIMEOUT; + while ((ARGE_READ(sc, AR71XX_MAC_MII_INDICATOR) & + MAC_MII_INDICATOR_BUSY) && (i--)) + DELAY(5); + + if (i < 0) { + dprintf("%s timedout\n", __func__); + /* XXX: return ERRNO istead? */ + return (-1); + } + + result = ARGE_READ(sc, AR71XX_MAC_MII_STATUS) & MAC_MII_STATUS_MASK; + ARGE_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); + dprintf("%s: phy=%d, reg=%02x, value[%08x]=%04x\n", __func__, + phy, reg, addr, result); + + return (result); +} + +static int +arge_miibus_writereg(device_t dev, int phy, int reg, int data) +{ + struct arge_softc * sc = device_get_softc(dev); + int i; + uint32_t addr = 0x1000 + | (phy << MAC_MII_PHY_ADDR_SHIFT) | (reg & MAC_MII_REG_MASK); + + dprintf("%s: phy=%d, reg=%02x, value=%04x\n", __func__, + phy, reg, data); + + ARGE_WRITE(sc, AR71XX_MAC_MII_ADDR, addr); + ARGE_WRITE(sc, AR71XX_MAC_MII_CONTROL, data); + + i = ARGE_MII_TIMEOUT; + while ((ARGE_READ(sc, AR71XX_MAC_MII_INDICATOR) & + MAC_MII_INDICATOR_BUSY) && (i--)) + DELAY(5); + + if (i < 0) { + dprintf("%s timedout\n", __func__); + /* XXX: return ERRNO istead? */ + return (-1); + } + + return (0); +} + +static void +arge_miibus_statchg(device_t dev) +{ + struct arge_softc *sc; + + sc = device_get_softc(dev); + taskqueue_enqueue(taskqueue_swi, &sc->arge_link_task); +} + +static void +arge_link_task(void *arg, int pending) +{ + struct arge_softc *sc; + struct mii_data *mii; + struct ifnet *ifp; + uint32_t media; + uint32_t cfg, ifcontrol, rx_filtmask, pll, sec_cfg; + + sc = (struct arge_softc *)arg; + + ARGE_LOCK(sc); + mii = device_get_softc(sc->arge_miibus); + ifp = sc->arge_ifp; + if (mii == NULL || ifp == NULL || + (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + ARGE_UNLOCK(sc); + return; + } + + if (mii->mii_media_status & IFM_ACTIVE) { + + media = IFM_SUBTYPE(mii->mii_media_active); + + if (media != IFM_NONE) { + sc->arge_link_status = 1; + + cfg = ARGE_READ(sc, AR71XX_MAC_CFG2); + ifcontrol = ARGE_READ(sc, AR71XX_MAC_IFCONTROL); + rx_filtmask = + ARGE_READ(sc, AR71XX_MAC_FIFO_RX_FILTMASK); + + cfg &= ~(MAC_CFG2_IFACE_MODE_1000 + | MAC_CFG2_IFACE_MODE_10_100 + | MAC_CFG2_FULL_DUPLEX); + ifcontrol &= ~MAC_IFCONTROL_SPEED; + rx_filtmask &= ~FIFO_RX_FILTMASK_BYTE_MODE; + + switch(media) { + case IFM_10_T: + cfg |= MAC_CFG2_IFACE_MODE_10_100; + pll = PLL_ETH_INT_CLK_10; + break; + case IFM_100_TX: + cfg |= MAC_CFG2_IFACE_MODE_10_100; + ifcontrol |= MAC_IFCONTROL_SPEED; + pll = PLL_ETH_INT_CLK_100; + break; + case IFM_1000_T: + case IFM_1000_SX: + cfg |= MAC_CFG2_IFACE_MODE_1000; + rx_filtmask |= FIFO_RX_FILTMASK_BYTE_MODE; + pll = PLL_ETH_INT_CLK_1000; + break; + default: + pll = PLL_ETH_INT_CLK_100; + device_printf(sc->arge_dev, + "Unknown media %d\n", media); + } + + ARGE_WRITE(sc, AR71XX_MAC_FIFO_TX_THRESHOLD, + 0x008001ff); + + ARGE_WRITE(sc, AR71XX_MAC_CFG2, cfg); + ARGE_WRITE(sc, AR71XX_MAC_IFCONTROL, ifcontrol); + ARGE_WRITE(sc, AR71XX_MAC_FIFO_RX_FILTMASK, + rx_filtmask); + + /* set PLL registers */ + sec_cfg = ATH_READ_REG(AR71XX_PLL_CPU_CONFIG); + sec_cfg &= ~(3 << 17); + sec_cfg |= (2 << 17); + + ATH_WRITE_REG(AR71XX_PLL_CPU_CONFIG, sec_cfg); + DELAY(100); + + ATH_WRITE_REG(sc->arge_pll_reg, pll); + + sec_cfg |= (3 << 17); + ATH_WRITE_REG(AR71XX_PLL_CPU_CONFIG, sec_cfg); + DELAY(100); + + sec_cfg &= ~(3 << 17); + ATH_WRITE_REG(AR71XX_PLL_CPU_CONFIG, sec_cfg); + DELAY(100); + } + } else + sc->arge_link_status = 0; + + ARGE_UNLOCK(sc); +} + +static void +arge_reset_dma(struct arge_softc *sc) +{ + unsigned int i; + + ARGE_WRITE(sc, AR71XX_DMA_RX_CONTROL, 0); + ARGE_WRITE(sc, AR71XX_DMA_TX_CONTROL, 0); + + ARGE_WRITE(sc, AR71XX_DMA_RX_DESC, 0); + ARGE_WRITE(sc, AR71XX_DMA_TX_DESC, 0); + + /* Clear all possible RX interrupts */ + for (i = 0; i < ARGE_RX_RING_COUNT; i++) + ARGE_WRITE(sc, AR71XX_DMA_RX_STATUS, DMA_RX_STATUS_PKT_RECVD); + + /* + * Clear all possible TX interrupts + */ + for (i = 0; i < ARGE_TX_RING_COUNT; i++) + ARGE_WRITE(sc, AR71XX_DMA_TX_STATUS, DMA_TX_STATUS_PKT_SENT); + + /* + * Now Rx/Tx errors + */ + ARGE_WRITE(sc, AR71XX_DMA_RX_STATUS, + DMA_RX_STATUS_BUS_ERROR | DMA_RX_STATUS_OVERFLOW); + ARGE_WRITE(sc, AR71XX_DMA_TX_STATUS, + DMA_TX_STATUS_BUS_ERROR | DMA_TX_STATUS_UNDERRUN); +} + + + +static void +arge_init(void *xsc) +{ + struct arge_softc *sc = xsc; + + ARGE_LOCK(sc); + arge_init_locked(sc); + ARGE_UNLOCK(sc); +} + +static void +arge_init_locked(struct arge_softc *sc) +{ + struct ifnet *ifp = sc->arge_ifp; + struct mii_data *mii; + + ARGE_LOCK_ASSERT(sc); + + mii = device_get_softc(sc->arge_miibus); + + arge_stop(sc); + + /* Init circular RX list. */ + if (arge_rx_ring_init(sc) != 0) { + device_printf(sc->arge_dev, + "initialization failed: no memory for rx buffers\n"); + arge_stop(sc); + return; + } + + /* Init tx descriptors. */ + arge_tx_ring_init(sc); + + arge_reset_dma(sc); + + sc->arge_link_status = 0; + mii_mediachg(mii); + + ifp->if_drv_flags |= IFF_DRV_RUNNING; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + + callout_reset(&sc->arge_stat_callout, hz, arge_tick, sc); + ARGE_WRITE(sc, AR71XX_DMA_TX_DESC, ARGE_TX_RING_ADDR(sc, 0)); + ARGE_WRITE(sc, AR71XX_DMA_RX_DESC, ARGE_RX_RING_ADDR(sc, 0)); + + /* Start listening */ + ARGE_WRITE(sc, AR71XX_DMA_RX_CONTROL, DMA_RX_CONTROL_EN); + + /* Enable interrupts */ + ARGE_WRITE(sc, AR71XX_DMA_INTR, DMA_INTR_ALL); +} + +/* + * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data + * pointers to the fragment pointers. + */ +static int +arge_encap(struct arge_softc *sc, struct mbuf **m_head) +{ + struct arge_txdesc *txd; + struct arge_desc *desc, *prev_desc; + bus_dma_segment_t txsegs[ARGE_MAXFRAGS]; + int error, i, nsegs, prod, si, prev_prod; + + ARGE_LOCK_ASSERT(sc); + + prod = sc->arge_cdata.arge_tx_prod; + txd = &sc->arge_cdata.arge_txdesc[prod]; + error = bus_dmamap_load_mbuf_sg(sc->arge_cdata.arge_tx_tag, + txd->tx_dmamap, *m_head, txsegs, &nsegs, BUS_DMA_NOWAIT); + + if (error == EFBIG) { + panic("EFBIG"); + } else if (error != 0) + return (error); + + if (nsegs == 0) { + m_freem(*m_head); + *m_head = NULL; + return (EIO); + } + + /* Check number of available descriptors. */ + if (sc->arge_cdata.arge_tx_cnt + nsegs >= (ARGE_TX_RING_COUNT - 1)) { + bus_dmamap_unload(sc->arge_cdata.arge_tx_tag, txd->tx_dmamap); + return (ENOBUFS); + } + + txd->tx_m = *m_head; + bus_dmamap_sync(sc->arge_cdata.arge_tx_tag, txd->tx_dmamap, + BUS_DMASYNC_PREWRITE); + + si = prod; + + /* + * Make a list of descriptors for this packet. DMA controller will + * walk through it while arge_link is not zero. + */ + prev_prod = prod; + desc = prev_desc = NULL; + for (i = 0; i < nsegs; i++) { + desc = &sc->arge_rdata.arge_tx_ring[prod]; + desc->packet_ctrl = ARGE_DMASIZE(txsegs[i].ds_len); + + desc->packet_addr = txsegs[i].ds_addr; + /* link with previous descriptor */ + if (prev_desc) + prev_desc->packet_ctrl |= ARGE_DESC_MORE; + + sc->arge_cdata.arge_tx_cnt++; + prev_desc = desc; + ARGE_INC(prod, ARGE_TX_RING_COUNT); + } + + /* Update producer index. */ + sc->arge_cdata.arge_tx_prod = prod; + + /* Sync descriptors. */ + bus_dmamap_sync(sc->arge_cdata.arge_tx_ring_tag, + sc->arge_cdata.arge_tx_ring_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + + /* Start transmitting */ + ARGE_WRITE(sc, AR71XX_DMA_TX_CONTROL, DMA_TX_CONTROL_EN); + return (0); +} + +static void +arge_start(struct ifnet *ifp) +{ + struct arge_softc *sc; + + sc = ifp->if_softc; + + ARGE_LOCK(sc); + arge_start_locked(ifp); + ARGE_UNLOCK(sc); +} + +static void +arge_start_locked(struct ifnet *ifp) +{ + struct arge_softc *sc; + struct mbuf *m_head; + int enq; + + sc = ifp->if_softc; + + ARGE_LOCK_ASSERT(sc); + + if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != + IFF_DRV_RUNNING || sc->arge_link_status == 0 ) + return; + + arge_flush_ddr(sc); + + for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) && + sc->arge_cdata.arge_tx_cnt < ARGE_TX_RING_COUNT - 2; ) { + IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); + if (m_head == NULL) + break; + + /* + * Fix mbuf chain, all fragments should be 4 bytes aligned and + * even 4 bytes + */ + arge_fix_chain(&m_head); + + if (m_head == NULL) { + dprintf("failed to adjust mbuf chain\n"); + } + + /* + * Pack the data into the transmit ring. + */ + if (arge_encap(sc, &m_head)) { + if (m_head == NULL) + break; + IFQ_DRV_PREPEND(&ifp->if_snd, m_head); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } + + enq++; + /* + * If there's a BPF listener, bounce a copy of this frame + * to him. + */ + ETHER_BPF_MTAP(ifp, m_head); + } +} + +static void +arge_stop(struct arge_softc *sc) +{ + struct ifnet *ifp; + + ARGE_LOCK_ASSERT(sc); + + ifp = sc->arge_ifp; + ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + callout_stop(&sc->arge_stat_callout); + + /* mask out interrupts */ + ARGE_WRITE(sc, AR71XX_DMA_INTR, 0); + + arge_reset_dma(sc); +} + + +static int +arge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) +{ + struct arge_softc *sc = ifp->if_softc; + struct ifreq *ifr = (struct ifreq *) data; + struct mii_data *mii; + int error; + + switch (command) { + case SIOCSIFFLAGS: + printf("Implement me: SIOCSIFFLAGS\n"); + error = 0; + break; + case SIOCADDMULTI: + case SIOCDELMULTI: + printf("Implement me: SIOCDELMULTI\n"); + error = 0; + break; + case SIOCGIFMEDIA: + case SIOCSIFMEDIA: + printf("Implement me: SIOCSIFMEDIA\n"); + mii = device_get_softc(sc->arge_miibus); + error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); + break; + case SIOCSIFCAP: + error = 0; + ifp->if_hwassist = 0; + printf("Implement me: SIOCSIFCAP\n"); + break; + default: + error = ether_ioctl(ifp, command, data); + break; + } + + return (error); +} + +/* + * Set media options. + */ +static int +arge_ifmedia_upd(struct ifnet *ifp) +{ + struct arge_softc *sc; + struct mii_data *mii; + struct mii_softc *miisc; + int error; + + sc = ifp->if_softc; + ARGE_LOCK(sc); + mii = device_get_softc(sc->arge_miibus); + if (mii->mii_instance) { + LIST_FOREACH(miisc, &mii->mii_phys, mii_list) + mii_phy_reset(miisc); + } + error = mii_mediachg(mii); + ARGE_UNLOCK(sc); + + return (error); +} + +/* + * Report current media status. + */ +static void +arge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) +{ + struct arge_softc *sc = ifp->if_softc; + struct mii_data *mii; + + mii = device_get_softc(sc->arge_miibus); + ARGE_LOCK(sc); + mii_pollstat(mii); + ARGE_UNLOCK(sc); + ifmr->ifm_active = mii->mii_media_active; + ifmr->ifm_status = mii->mii_media_status; +} + +struct arge_dmamap_arg { + bus_addr_t arge_busaddr; +}; + +static void +arge_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) +{ + struct arge_dmamap_arg *ctx; + + if (error != 0) + return; + ctx = arg; + ctx->arge_busaddr = segs[0].ds_addr; +} + +static int +arge_dma_alloc(struct arge_softc *sc) +{ + struct arge_dmamap_arg ctx; + struct arge_txdesc *txd; + struct arge_rxdesc *rxd; + int error, i; + + /* Create parent DMA tag. */ + error = bus_dma_tag_create( + bus_get_dma_tag(sc->arge_dev), /* parent */ + 1, 0, /* alignment, boundary */ + BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + BUS_SPACE_MAXSIZE_32BIT, /* maxsize */ + 0, /* nsegments */ + BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ + 0, /* flags */ + NULL, NULL, /* lockfunc, lockarg */ + &sc->arge_cdata.arge_parent_tag); + if (error != 0) { + device_printf(sc->arge_dev, "failed to create parent DMA tag\n"); + goto fail; + } + /* Create tag for Tx ring. */ + error = bus_dma_tag_create( + sc->arge_cdata.arge_parent_tag, /* parent */ + ARGE_RING_ALIGN, 0, /* alignment, boundary */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + ARGE_TX_DMA_SIZE, /* maxsize */ + 1, /* nsegments */ + ARGE_TX_DMA_SIZE, /* maxsegsize */ + 0, /* flags */ + NULL, NULL, /* lockfunc, lockarg */ + &sc->arge_cdata.arge_tx_ring_tag); + if (error != 0) { + device_printf(sc->arge_dev, "failed to create Tx ring DMA tag\n"); + goto fail; + } + + /* Create tag for Rx ring. */ + error = bus_dma_tag_create( + sc->arge_cdata.arge_parent_tag, /* parent */ + ARGE_RING_ALIGN, 0, /* alignment, boundary */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + ARGE_RX_DMA_SIZE, /* maxsize */ + 1, /* nsegments */ + ARGE_RX_DMA_SIZE, /* maxsegsize */ + 0, /* flags */ + NULL, NULL, /* lockfunc, lockarg */ + &sc->arge_cdata.arge_rx_ring_tag); + if (error != 0) { + device_printf(sc->arge_dev, "failed to create Rx ring DMA tag\n"); + goto fail; + } + + /* Create tag for Tx buffers. */ + error = bus_dma_tag_create( + sc->arge_cdata.arge_parent_tag, /* parent */ + sizeof(uint32_t), 0, /* alignment, boundary */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + MCLBYTES * ARGE_MAXFRAGS, /* maxsize */ + ARGE_MAXFRAGS, /* nsegments */ + MCLBYTES, /* maxsegsize */ + 0, /* flags */ + NULL, NULL, /* lockfunc, lockarg */ + &sc->arge_cdata.arge_tx_tag); + if (error != 0) { + device_printf(sc->arge_dev, "failed to create Tx DMA tag\n"); + goto fail; + } + + /* Create tag for Rx buffers. */ + error = bus_dma_tag_create( + sc->arge_cdata.arge_parent_tag, /* parent */ + ARGE_RX_ALIGN, 0, /* alignment, boundary */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + MCLBYTES, /* maxsize */ + 1, /* nsegments */ + MCLBYTES, /* maxsegsize */ + 0, /* flags */ + NULL, NULL, /* lockfunc, lockarg */ + &sc->arge_cdata.arge_rx_tag); + if (error != 0) { + device_printf(sc->arge_dev, "failed to create Rx DMA tag\n"); + goto fail; + } + + /* Allocate DMA'able memory and load the DMA map for Tx ring. */ + error = bus_dmamem_alloc(sc->arge_cdata.arge_tx_ring_tag, + (void **)&sc->arge_rdata.arge_tx_ring, BUS_DMA_WAITOK | + BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->arge_cdata.arge_tx_ring_map); + if (error != 0) { + device_printf(sc->arge_dev, + "failed to allocate DMA'able memory for Tx ring\n"); + goto fail; + } + + ctx.arge_busaddr = 0; + error = bus_dmamap_load(sc->arge_cdata.arge_tx_ring_tag, + sc->arge_cdata.arge_tx_ring_map, sc->arge_rdata.arge_tx_ring, + ARGE_TX_DMA_SIZE, arge_dmamap_cb, &ctx, 0); + if (error != 0 || ctx.arge_busaddr == 0) { + device_printf(sc->arge_dev, + "failed to load DMA'able memory for Tx ring\n"); + goto fail; + } + sc->arge_rdata.arge_tx_ring_paddr = ctx.arge_busaddr; + + /* Allocate DMA'able memory and load the DMA map for Rx ring. */ + error = bus_dmamem_alloc(sc->arge_cdata.arge_rx_ring_tag, + (void **)&sc->arge_rdata.arge_rx_ring, BUS_DMA_WAITOK | + BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->arge_cdata.arge_rx_ring_map); + if (error != 0) { + device_printf(sc->arge_dev, + "failed to allocate DMA'able memory for Rx ring\n"); + goto fail; + } + + ctx.arge_busaddr = 0; + error = bus_dmamap_load(sc->arge_cdata.arge_rx_ring_tag, + sc->arge_cdata.arge_rx_ring_map, sc->arge_rdata.arge_rx_ring, + ARGE_RX_DMA_SIZE, arge_dmamap_cb, &ctx, 0); + if (error != 0 || ctx.arge_busaddr == 0) { + device_printf(sc->arge_dev, + "failed to load DMA'able memory for Rx ring\n"); + goto fail; + } + sc->arge_rdata.arge_rx_ring_paddr = ctx.arge_busaddr; + + /* Create DMA maps for Tx buffers. */ + for (i = 0; i < ARGE_TX_RING_COUNT; i++) { + txd = &sc->arge_cdata.arge_txdesc[i]; + txd->tx_m = NULL; + txd->tx_dmamap = NULL; + error = bus_dmamap_create(sc->arge_cdata.arge_tx_tag, 0, + &txd->tx_dmamap); + if (error != 0) { + device_printf(sc->arge_dev, + "failed to create Tx dmamap\n"); + goto fail; + } + } + /* Create DMA maps for Rx buffers. */ + if ((error = bus_dmamap_create(sc->arge_cdata.arge_rx_tag, 0, + &sc->arge_cdata.arge_rx_sparemap)) != 0) { + device_printf(sc->arge_dev, + "failed to create spare Rx dmamap\n"); + goto fail; + } + for (i = 0; i < ARGE_RX_RING_COUNT; i++) { + rxd = &sc->arge_cdata.arge_rxdesc[i]; + rxd->rx_m = NULL; + rxd->rx_dmamap = NULL; + error = bus_dmamap_create(sc->arge_cdata.arge_rx_tag, 0, + &rxd->rx_dmamap); + if (error != 0) { + device_printf(sc->arge_dev, + "failed to create Rx dmamap\n"); + goto fail; + } + } + +fail: + return (error); +} + +static void +arge_dma_free(struct arge_softc *sc) +{ + struct arge_txdesc *txd; + struct arge_rxdesc *rxd; + int i; + + /* Tx ring. */ + if (sc->arge_cdata.arge_tx_ring_tag) { + if (sc->arge_cdata.arge_tx_ring_map) + bus_dmamap_unload(sc->arge_cdata.arge_tx_ring_tag, + sc->arge_cdata.arge_tx_ring_map); + if (sc->arge_cdata.arge_tx_ring_map && + sc->arge_rdata.arge_tx_ring) + bus_dmamem_free(sc->arge_cdata.arge_tx_ring_tag, + sc->arge_rdata.arge_tx_ring, + sc->arge_cdata.arge_tx_ring_map); + sc->arge_rdata.arge_tx_ring = NULL; + sc->arge_cdata.arge_tx_ring_map = NULL; + bus_dma_tag_destroy(sc->arge_cdata.arge_tx_ring_tag); + sc->arge_cdata.arge_tx_ring_tag = NULL; + } + /* Rx ring. */ + if (sc->arge_cdata.arge_rx_ring_tag) { + if (sc->arge_cdata.arge_rx_ring_map) + bus_dmamap_unload(sc->arge_cdata.arge_rx_ring_tag, + sc->arge_cdata.arge_rx_ring_map); + if (sc->arge_cdata.arge_rx_ring_map && + sc->arge_rdata.arge_rx_ring) + bus_dmamem_free(sc->arge_cdata.arge_rx_ring_tag, + sc->arge_rdata.arge_rx_ring, + sc->arge_cdata.arge_rx_ring_map); + sc->arge_rdata.arge_rx_ring = NULL; + sc->arge_cdata.arge_rx_ring_map = NULL; + bus_dma_tag_destroy(sc->arge_cdata.arge_rx_ring_tag); + sc->arge_cdata.arge_rx_ring_tag = NULL; + } + /* Tx buffers. */ + if (sc->arge_cdata.arge_tx_tag) { + for (i = 0; i < ARGE_TX_RING_COUNT; i++) { + txd = &sc->arge_cdata.arge_txdesc[i]; + if (txd->tx_dmamap) { + bus_dmamap_destroy(sc->arge_cdata.arge_tx_tag, + txd->tx_dmamap); + txd->tx_dmamap = NULL; + } + } + bus_dma_tag_destroy(sc->arge_cdata.arge_tx_tag); + sc->arge_cdata.arge_tx_tag = NULL; + } + /* Rx buffers. */ + if (sc->arge_cdata.arge_rx_tag) { + for (i = 0; i < ARGE_RX_RING_COUNT; i++) { + rxd = &sc->arge_cdata.arge_rxdesc[i]; + if (rxd->rx_dmamap) { + bus_dmamap_destroy(sc->arge_cdata.arge_rx_tag, + rxd->rx_dmamap); + rxd->rx_dmamap = NULL; + } + } + if (sc->arge_cdata.arge_rx_sparemap) { + bus_dmamap_destroy(sc->arge_cdata.arge_rx_tag, + sc->arge_cdata.arge_rx_sparemap); + sc->arge_cdata.arge_rx_sparemap = 0; + } + bus_dma_tag_destroy(sc->arge_cdata.arge_rx_tag); + sc->arge_cdata.arge_rx_tag = NULL; + } + + if (sc->arge_cdata.arge_parent_tag) { + bus_dma_tag_destroy(sc->arge_cdata.arge_parent_tag); + sc->arge_cdata.arge_parent_tag = NULL; + } +} + +/* + * Initialize the transmit descriptors. + */ +static int +arge_tx_ring_init(struct arge_softc *sc) +{ + struct arge_ring_data *rd; + struct arge_txdesc *txd; + bus_addr_t addr; + int i; + + sc->arge_cdata.arge_tx_prod = 0; + sc->arge_cdata.arge_tx_cons = 0; + sc->arge_cdata.arge_tx_cnt = 0; + sc->arge_cdata.arge_tx_pkts = 0; + + rd = &sc->arge_rdata; + bzero(rd->arge_tx_ring, sizeof(rd->arge_tx_ring)); + for (i = 0; i < ARGE_TX_RING_COUNT; i++) { + if (i == ARGE_TX_RING_COUNT - 1) + addr = ARGE_TX_RING_ADDR(sc, 0); + else + addr = ARGE_TX_RING_ADDR(sc, i + 1); + rd->arge_tx_ring[i].packet_ctrl = ARGE_DESC_EMPTY; + rd->arge_tx_ring[i].next_desc = addr; + txd = &sc->arge_cdata.arge_txdesc[i]; + txd->tx_m = NULL; + } + + bus_dmamap_sync(sc->arge_cdata.arge_tx_ring_tag, + sc->arge_cdata.arge_tx_ring_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + + return (0); +} + +/* + * Initialize the RX descriptors and allocate mbufs for them. Note that + * we arrange the descriptors in a closed ring, so that the last descriptor + * points back to the first. + */ +static int +arge_rx_ring_init(struct arge_softc *sc) +{ + struct arge_ring_data *rd; + struct arge_rxdesc *rxd; + bus_addr_t addr; + int i; + + sc->arge_cdata.arge_rx_cons = 0; + + rd = &sc->arge_rdata; + bzero(rd->arge_rx_ring, sizeof(rd->arge_rx_ring)); + for (i = 0; i < ARGE_RX_RING_COUNT; i++) { + rxd = &sc->arge_cdata.arge_rxdesc[i]; + rxd->rx_m = NULL; + rxd->desc = &rd->arge_rx_ring[i]; + if (i == ARGE_RX_RING_COUNT - 1) + addr = ARGE_RX_RING_ADDR(sc, 0); + else + addr = ARGE_RX_RING_ADDR(sc, i + 1); + rd->arge_rx_ring[i].packet_ctrl = ARGE_DESC_EMPTY; + rd->arge_rx_ring[i].next_desc = addr; + if (arge_newbuf(sc, i) != 0) + return (ENOBUFS); + } + + bus_dmamap_sync(sc->arge_cdata.arge_rx_ring_tag, + sc->arge_cdata.arge_rx_ring_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + + return (0); +} + +/* + * Initialize an RX descriptor and attach an MBUF cluster. + */ +static int +arge_newbuf(struct arge_softc *sc, int idx) +{ + struct arge_desc *desc; + struct arge_rxdesc *rxd; + struct mbuf *m; + bus_dma_segment_t segs[1]; + bus_dmamap_t map; + int nsegs; + + m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); + if (m == NULL) + return (ENOBUFS); + m->m_len = m->m_pkthdr.len = MCLBYTES; + m_adj(m, sizeof(uint64_t)); + + if (bus_dmamap_load_mbuf_sg(sc->arge_cdata.arge_rx_tag, + sc->arge_cdata.arge_rx_sparemap, m, segs, &nsegs, 0) != 0) { + m_freem(m); + return (ENOBUFS); + } + KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs)); + + rxd = &sc->arge_cdata.arge_rxdesc[idx]; + if (rxd->rx_m != NULL) { + bus_dmamap_sync(sc->arge_cdata.arge_rx_tag, rxd->rx_dmamap, + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->arge_cdata.arge_rx_tag, rxd->rx_dmamap); + } + map = rxd->rx_dmamap; + rxd->rx_dmamap = sc->arge_cdata.arge_rx_sparemap; + sc->arge_cdata.arge_rx_sparemap = map; + bus_dmamap_sync(sc->arge_cdata.arge_rx_tag, rxd->rx_dmamap, + BUS_DMASYNC_PREREAD); + rxd->rx_m = m; + desc = rxd->desc; + desc->packet_addr = segs[0].ds_addr; + desc->packet_ctrl = (desc->packet_ctrl & ~ARGE_DESC_SIZE_MASK) + | ARGE_DMASIZE(segs[0].ds_len); + + return (0); +} + +static __inline void +arge_fixup_rx(struct mbuf *m) +{ + int i; + uint16_t *src, *dst; + + src = mtod(m, uint16_t *); + dst = src - 1; + + for (i = 0; i < (m->m_len / sizeof(uint16_t) + 1); i++) + *dst++ = *src++; + + m->m_data -= ETHER_ALIGN; +} + + +static void +arge_tx_locked(struct arge_softc *sc) +{ + struct arge_txdesc *txd; + struct arge_desc *cur_tx; + struct ifnet *ifp; + uint32_t ctrl; + int cons, prod; + + ARGE_LOCK_ASSERT(sc); + + cons = sc->arge_cdata.arge_tx_cons; + prod = sc->arge_cdata.arge_tx_prod; + if (cons == prod) + return; + + bus_dmamap_sync(sc->arge_cdata.arge_tx_ring_tag, + sc->arge_cdata.arge_tx_ring_map, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + + ifp = sc->arge_ifp; + /* + * Go through our tx list and free mbufs for those + * frames that have been transmitted. + */ + for (; cons != prod; ARGE_INC(cons, ARGE_TX_RING_COUNT)) { + cur_tx = &sc->arge_rdata.arge_tx_ring[cons]; + ctrl = cur_tx->packet_ctrl; + /* Check if descriptor has "finished" flag */ + if ((ctrl & ARGE_DESC_EMPTY) == 0) + break; + + ARGE_WRITE(sc, AR71XX_DMA_TX_STATUS, DMA_TX_STATUS_PKT_SENT); + + sc->arge_cdata.arge_tx_cnt--; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + + txd = &sc->arge_cdata.arge_txdesc[cons]; + + cur_tx->packet_ctrl = ARGE_DESC_EMPTY; + + ifp->if_opackets++; + + bus_dmamap_sync(sc->arge_cdata.arge_tx_tag, txd->tx_dmamap, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->arge_cdata.arge_tx_tag, txd->tx_dmamap); + + /* Free only if it's first descriptor in list */ + if (txd->tx_m) + m_freem(txd->tx_m); + txd->tx_m = NULL; + + /* reset descriptor */ + cur_tx->packet_ctrl = ARGE_DESC_EMPTY; + cur_tx->packet_addr = 0; + } + + sc->arge_cdata.arge_tx_cons = cons; + + bus_dmamap_sync(sc->arge_cdata.arge_tx_ring_tag, + sc->arge_cdata.arge_tx_ring_map, BUS_DMASYNC_PREWRITE); +} + + +static void +arge_rx_locked(struct arge_softc *sc) +{ + struct arge_rxdesc *rxd; + struct ifnet *ifp = sc->arge_ifp; + int cons, prog, packet_len; + struct arge_desc *cur_rx; + struct mbuf *m; + + ARGE_LOCK_ASSERT(sc); + + cons = sc->arge_cdata.arge_rx_cons; + + bus_dmamap_sync(sc->arge_cdata.arge_rx_ring_tag, + sc->arge_cdata.arge_rx_ring_map, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + + for (prog = 0; prog < ARGE_RX_RING_COUNT; + ARGE_INC(cons, ARGE_RX_RING_COUNT)) { + cur_rx = &sc->arge_rdata.arge_rx_ring[cons]; + rxd = &sc->arge_cdata.arge_rxdesc[cons]; + m = rxd->rx_m; + + if ((cur_rx->packet_ctrl & ARGE_DESC_EMPTY) != 0) + break; + + ARGE_WRITE(sc, AR71XX_DMA_RX_STATUS, DMA_RX_STATUS_PKT_RECVD); + + prog++; + + packet_len = ARGE_DMASIZE(cur_rx->packet_ctrl); + bus_dmamap_sync(sc->arge_cdata.arge_rx_tag, rxd->rx_dmamap, + BUS_DMASYNC_PREREAD); + m = rxd->rx_m; + + arge_fixup_rx(m); + m->m_pkthdr.rcvif = ifp; + /* Skip 4 bytes of CRC */ + m->m_pkthdr.len = m->m_len = packet_len - ETHER_CRC_LEN; + ifp->if_ipackets++; + + ARGE_UNLOCK(sc); + (*ifp->if_input)(ifp, m); + ARGE_LOCK(sc); + + /* Reinit descriptor */ + cur_rx->packet_ctrl = ARGE_DESC_EMPTY; + cur_rx->packet_addr = 0; + if (arge_newbuf(sc, cons) != 0) { + device_printf(sc->arge_dev, + "Failed to allocate buffer\n"); + break; + } + + bus_dmamap_sync(sc->arge_cdata.arge_rx_ring_tag, + sc->arge_cdata.arge_rx_ring_map, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + + } + + if (prog > 0) { + sc->arge_cdata.arge_rx_cons = cons; + + bus_dmamap_sync(sc->arge_cdata.arge_rx_ring_tag, + sc->arge_cdata.arge_rx_ring_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + } +} + +static void +arge_rx_intr(struct arge_softc *sc, uint32_t status) +{ + + ARGE_LOCK(sc); + /* interrupts are masked by filter */ + arge_rx_locked(sc); + + /* unmask interrupts */ + ARGE_SET_BITS(sc, + AR71XX_DMA_INTR, DMA_INTR_RX_OVERFLOW | DMA_INTR_RX_PKT_RCVD); + ARGE_UNLOCK(sc); +} + +static int +arge_intr_filter(void *arg) +{ + struct arge_softc *sc = arg; + uint32_t status, ints; + + status = ARGE_READ(sc, AR71XX_DMA_INTR_STATUS); + ints = ARGE_READ(sc, AR71XX_DMA_INTR); + +#if 0 + dprintf("int mask(filter) = %b\n", ints, + "\20\10RX_BUS_ERROR\7RX_OVERFLOW\5RX_PKT_RCVD" + "\4TX_BUS_ERROR\2TX_UNDERRUN\1TX_PKT_SENT"); + dprintf("status(filter) = %b\n", status, + "\20\10RX_BUS_ERROR\7RX_OVERFLOW\5RX_PKT_RCVD" + "\4TX_BUS_ERROR\2TX_UNDERRUN\1TX_PKT_SENT"); +#endif + + if (status & DMA_INTR_ALL) { + if (status & (DMA_INTR_RX_PKT_RCVD | DMA_INTR_RX_OVERFLOW)) + ARGE_CLEAR_BITS(sc, AR71XX_DMA_INTR, + DMA_INTR_RX_OVERFLOW | DMA_INTR_RX_PKT_RCVD); + + if (status & (DMA_INTR_TX_PKT_SENT | DMA_INTR_TX_UNDERRUN)) + ARGE_CLEAR_BITS(sc, AR71XX_DMA_INTR, + DMA_INTR_TX_UNDERRUN | DMA_INTR_TX_PKT_SENT); + + sc->arge_intr_status = status; + return (FILTER_SCHEDULE_THREAD); + } + + sc->arge_intr_status = 0; + return (FILTER_STRAY); +} + +static void +arge_intr(void *arg) +{ + struct arge_softc *sc = arg; + uint32_t status; + + status = sc->arge_intr_status; + +#if 0 + dprintf("int status(intr) = %b\n", status, + "\20\10\7RX_OVERFLOW\5RX_PKT_RCVD" + "\4TX_BUS_ERROR\2TX_UNDERRUN\1TX_PKT_SENT"); +#endif + + /* + * Is it our interrupt at all? + */ + if (status == 0) + return; + + if (status & DMA_INTR_RX_BUS_ERROR) { + ARGE_WRITE(sc, AR71XX_DMA_RX_STATUS, DMA_RX_STATUS_BUS_ERROR); + device_printf(sc->arge_dev, "RX bus error"); + return; + } + + if (status & DMA_INTR_TX_BUS_ERROR) { + ARGE_WRITE(sc, AR71XX_DMA_TX_STATUS, DMA_TX_STATUS_BUS_ERROR); + device_printf(sc->arge_dev, "TX bus error"); + return; + } + + if (status & (DMA_INTR_RX_PKT_RCVD | DMA_INTR_RX_OVERFLOW)) + arge_rx_intr(sc, status); + + if (status & (DMA_INTR_TX_PKT_SENT | DMA_INTR_TX_UNDERRUN)) + arge_tx_intr(sc, status); +} + +static void +arge_tx_intr(struct arge_softc *sc, uint32_t status) +{ + ARGE_LOCK(sc); + + /* Interrupts are masked by filter */ + arge_tx_locked(sc); + + ARGE_UNLOCK(sc); +} + +static void +arge_tick(void *xsc) +{ + struct arge_softc *sc = xsc; + struct mii_data *mii; + + ARGE_LOCK_ASSERT(sc); + + mii = device_get_softc(sc->arge_miibus); + mii_tick(mii); + callout_reset(&sc->arge_stat_callout, hz, arge_tick, sc); +} + +/* + * Create a copy of a single mbuf. It can have either internal or + * external data, it may have a packet header. External data is really + * copied, so the new buffer is writeable. + */ +static struct mbuf * +copy_mbuf(struct mbuf *m) +{ + struct mbuf *new; + + MGET(new, M_DONTWAIT, MT_DATA); + if (new == NULL) + return (NULL); + + if (m->m_flags & M_PKTHDR) { + M_MOVE_PKTHDR(new, m); + if (m->m_len > MHLEN) + MCLGET(new, M_WAIT); + } else { + if (m->m_len > MLEN) + MCLGET(new, M_WAIT); + } + + bcopy(m->m_data, new->m_data, m->m_len); + new->m_len = m->m_len; + new->m_flags &= ~M_RDONLY; + + return (new); +} + + + +static int +arge_fix_chain(struct mbuf **mp) +{ + struct mbuf *m = *mp, *prev = NULL, *next, *new; + u_int mlen = 0, fill = 0; + int first, off; + u_char *d, *cp; + + do { + next = m->m_next; + + if ((uintptr_t)mtod(m, void *) % 4 != 0 || + (m->m_len % 4 != 0 && next)) { + /* + * Needs fixing + */ + first = (m == *mp); + + d = mtod(m, u_char *); + if ((off = (uintptr_t)(void *)d % 4) != 0) { + if (M_WRITABLE(m)) { + bcopy(d, d - off, m->m_len); + m->m_data = (caddr_t)(d - off); + } else { + if ((new = copy_mbuf(m)) == NULL) { + goto fail; + } + if (prev) + prev->m_next = new; + new->m_next = next; + m_free(m); + m = new; + } + } + + if ((off = m->m_len % 4) != 0) { + if (!M_WRITABLE(m)) { + if ((new = copy_mbuf(m)) == NULL) { + goto fail; + } + if (prev) + prev->m_next = new; + new->m_next = next; + m_free(m); + m = new; + } + d = mtod(m, u_char *) + m->m_len; + off = 4 - off; + while (off) { + if (next == NULL) { + *d++ = 0; + fill++; + } else if (next->m_len == 0) { + next = m_free(next); + continue; + } else { + cp = mtod(next, u_char *); + *d++ = *cp++; + next->m_len--; + next->m_data = (caddr_t)cp; + } + off--; + m->m_len++; + } + } + + if (first) + *mp = m; + } + + mlen += m->m_len; + prev = m; + } while ((m = next) != NULL); + + return (mlen - fill); + + fail: + m_freem(*mp); + *mp = NULL; + return (0); +} diff --git a/sys/mips/atheros/if_argevar.h b/sys/mips/atheros/if_argevar.h new file mode 100644 index 00000000000..1966e61aeec --- /dev/null +++ b/sys/mips/atheros/if_argevar.h @@ -0,0 +1,138 @@ +/*- + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __IF_ARGEVAR_H__ +#define __IF_ARGEVAR_H__ + +#define ARGE_TX_RING_COUNT 128 +#define ARGE_RX_RING_COUNT 128 +#define ARGE_RX_DMA_SIZE ARGE_RX_RING_COUNT * sizeof(struct arge_desc) +#define ARGE_TX_DMA_SIZE ARGE_TX_RING_COUNT * sizeof(struct arge_desc) +#define ARGE_MAXFRAGS 8 +#define ARGE_RING_ALIGN sizeof(struct arge_desc) +#define ARGE_RX_ALIGN sizeof(uint32_t) +#define ARGE_MAXFRAGS 8 +#define ARGE_TX_RING_ADDR(sc, i) \ + ((sc)->arge_rdata.arge_tx_ring_paddr + sizeof(struct arge_desc) * (i)) +#define ARGE_RX_RING_ADDR(sc, i) \ + ((sc)->arge_rdata.arge_rx_ring_paddr + sizeof(struct arge_desc) * (i)) +#define ARGE_INC(x,y) (x) = (((x) + 1) % y) + + +#define ARGE_MII_TIMEOUT 1000 + +#define ARGE_LOCK(_sc) mtx_lock(&(_sc)->arge_mtx) +#define ARGE_UNLOCK(_sc) mtx_unlock(&(_sc)->arge_mtx) +#define ARGE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->arge_mtx, MA_OWNED) + +/* + * register space access macros + */ +#define ARGE_WRITE(sc, reg, val) do { \ + bus_write_4(sc->arge_res, (reg), (val)); \ + } while (0) + +#define ARGE_READ(sc, reg) bus_read_4(sc->arge_res, (reg)) + +#define ARGE_SET_BITS(sc, reg, bits) \ + ARGE_WRITE(sc, reg, ARGE_READ(sc, (reg)) | (bits)) + +#define ARGE_CLEAR_BITS(sc, reg, bits) \ + ARGE_WRITE(sc, reg, ARGE_READ(sc, (reg)) & ~(bits)) + +#define ARGE_DESC_EMPTY (1 << 31) +#define ARGE_DESC_MORE (1 << 24) +#define ARGE_DESC_SIZE_MASK ((1 << 12) - 1) +#define ARGE_DMASIZE(len) ((len) & ARGE_DESC_SIZE_MASK) +struct arge_desc { + uint32_t packet_addr; + uint32_t packet_ctrl; + uint32_t next_desc; + uint32_t padding; +}; + +struct arge_txdesc { + struct mbuf *tx_m; + bus_dmamap_t tx_dmamap; +}; + +struct arge_rxdesc { + struct mbuf *rx_m; + bus_dmamap_t rx_dmamap; + struct arge_desc *desc; +}; + +struct arge_chain_data { + bus_dma_tag_t arge_parent_tag; + bus_dma_tag_t arge_tx_tag; + struct arge_txdesc arge_txdesc[ARGE_TX_RING_COUNT]; + bus_dma_tag_t arge_rx_tag; + struct arge_rxdesc arge_rxdesc[ARGE_RX_RING_COUNT]; + bus_dma_tag_t arge_tx_ring_tag; + bus_dma_tag_t arge_rx_ring_tag; + bus_dmamap_t arge_tx_ring_map; + bus_dmamap_t arge_rx_ring_map; + bus_dmamap_t arge_rx_sparemap; + int arge_tx_pkts; + int arge_tx_prod; + int arge_tx_cons; + int arge_tx_cnt; + int arge_rx_cons; +}; + +struct arge_ring_data { + struct arge_desc *arge_rx_ring; + struct arge_desc *arge_tx_ring; + bus_addr_t arge_rx_ring_paddr; + bus_addr_t arge_tx_ring_paddr; +}; + +struct arge_softc { + struct ifnet *arge_ifp; /* interface info */ + device_t arge_dev; + struct resource *arge_res; + int arge_rid; + struct resource *arge_irq; + void *arge_intrhand; + device_t arge_miibus; + bus_dma_tag_t arge_parent_tag; + bus_dma_tag_t arge_tag; + struct mtx arge_mtx; + struct callout arge_stat_callout; + struct task arge_link_task; + struct arge_chain_data arge_cdata; + struct arge_ring_data arge_rdata; + int arge_link_status; + int arge_detach; + uint32_t arge_intr_status; + int arge_mac_unit; + int arge_phy_num; + uint32_t arge_ddr_flush_reg; + uint32_t arge_pll_reg; +}; + +#endif /* __IF_ARGEVAR_H__ */ diff --git a/sys/mips/atheros/uart_bus_ar71xx.c b/sys/mips/atheros/uart_bus_ar71xx.c new file mode 100644 index 00000000000..1cb611ce092 --- /dev/null +++ b/sys/mips/atheros/uart_bus_ar71xx.c @@ -0,0 +1,79 @@ +/*- + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + */ +#include "opt_uart.h" + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include "uart_if.h" + +static int uart_ar71xx_probe(device_t dev); +extern struct uart_class uart_ar71xx_uart_class; + +static device_method_t uart_ar71xx_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, uart_ar71xx_probe), + DEVMETHOD(device_attach, uart_bus_attach), + DEVMETHOD(device_detach, uart_bus_detach), + { 0, 0 } +}; + +static driver_t uart_ar71xx_driver = { + uart_driver_name, + uart_ar71xx_methods, + sizeof(struct uart_softc), +}; + +extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; + +static int +uart_ar71xx_probe(device_t dev) +{ + struct uart_softc *sc; + + sc = device_get_softc(dev); + sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); + sc->sc_class = &uart_ns8250_class; + bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); + + return (uart_bus_probe(dev, 2, 85000000, 0, 0)); +} + +DRIVER_MODULE(uart, apb, uart_ar71xx_driver, uart_devclass, 0, 0); diff --git a/sys/mips/atheros/uart_cpu_ar71xx.c b/sys/mips/atheros/uart_cpu_ar71xx.c new file mode 100644 index 00000000000..4d6b7e79ed1 --- /dev/null +++ b/sys/mips/atheros/uart_cpu_ar71xx.c @@ -0,0 +1,78 @@ +/*- + * Copyright (c) 2009 Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +#include "opt_uart.h" + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include + +#include +#include + +#include + +bus_space_tag_t uart_bus_space_io; +bus_space_tag_t uart_bus_space_mem; + +int +uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) +{ + return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0); +} + +int +uart_cpu_getdev(int devtype, struct uart_devinfo *di) +{ + di->ops = uart_getops(&uart_ns8250_class); + di->bas.chan = 0; + di->bas.bst = MIPS_BUS_SPACE_MEM; + di->bas.regshft = 2; + /* TODO: calculate proper AHB freq using PLL registers */ + di->bas.rclk = 85000000; + di->baudrate = 115200; + di->databits = 8; + di->stopbits = 1; + di->parity = UART_PARITY_NONE; + + /* TODO: check if uart_bus_space_io mandatory to set */ + uart_bus_space_io = MIPS_BUS_SPACE_IO; + uart_bus_space_mem = MIPS_BUS_SPACE_MEM; + /* + * FIXME: + * 3 is to compensate big endian, uart operates + * with bus_space_read_1/bus_space_write_1 and hence gets + * highest byte instead of lowest one. Actual fix will involve + * MIPS bus_space fixing. + */ + di->bas.bsh = MIPS_PHYS_TO_KSEG1(AR71XX_UART_ADDR) + 3; + return (0); +} diff --git a/sys/mips/conf/ADM5120 b/sys/mips/conf/ADM5120 index a03d102251c..7a47abed107 100644 --- a/sys/mips/conf/ADM5120 +++ b/sys/mips/conf/ADM5120 @@ -25,7 +25,6 @@ makeoptions MIPS_LITTLE_ENDIAN=defined # Don't build any modules yet. makeoptions MODULES_OVERRIDE="" -options KERNVIRTADDR=0x80100000 include "../adm5120/std.adm5120" hints "ADM5120.hints" #Default places to look for devices. diff --git a/sys/mips/conf/ALCHEMY b/sys/mips/conf/ALCHEMY new file mode 100644 index 00000000000..c1fb59a11de --- /dev/null +++ b/sys/mips/conf/ALCHEMY @@ -0,0 +1,66 @@ +# ALCHEMY -- Generic kernel for Alchemy Au1xxx CPUs. +# +# For more information on this file, please read the handbook section on +# Kernel Configuration Files: +# +# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# +# The handbook is also available locally in /usr/share/doc/handbook +# if you've installed the doc distribution, otherwise always see the +# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# latest information. +# +# An exhaustive list of options and more detailed explanations of the +# device lines is also present in the ../../conf/NOTES and NOTES files. +# If you are in doubt as to the purpose or necessity of a line, check first +# in NOTES. +# +# $FreeBSD$ + +ident ALCHEMY + +makeoptions ARCH_FLAGS=-march=mips32 +makeoptions MIPS_LITTLE_ENDIAN=defined + +# Don't build any modules yet. +makeoptions MODULES_OVERRIDE="" + +include "../alchemy/std.alchemy" + +hints "ALCHEMY.hints" #Default places to look for devices. + +makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols + +options DDB +options KDB + +options SCHED_4BSD #4BSD scheduler +options INET #InterNETworking +options NFSCLIENT #Network Filesystem Client +options NFS_ROOT #NFS usable as /, requires NFSCLIENT +options PSEUDOFS #Pseudo-filesystem framework +# options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions + +options BOOTP +options BOOTP_NFSROOT +options BOOTP_NFSV3 +options BOOTP_WIRED_TO=admsw0 +options BOOTP_COMPAT + +# options FFS #Berkeley Fast Filesystem +# options SOFTUPDATES #Enable FFS soft updates support +# options UFS_ACL #Support for access control lists +# options UFS_DIRHASH #Improve performance on big directories +options ROOTDEVNAME=\"nfs:10.0.0.1:/mnt/bsd\" + + +# Debugging for use in -current +options INVARIANTS #Enable calls of extra sanity checking +options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS +#options WITNESS #Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed + +device loop +device ether +device uart +# device md diff --git a/sys/mips/conf/AR71XX b/sys/mips/conf/AR71XX new file mode 100644 index 00000000000..936d0f1f88d --- /dev/null +++ b/sys/mips/conf/AR71XX @@ -0,0 +1,37 @@ +# +# $FreeBSD$ +# + +ident AR71XX +cpu CPU_MIPS4KC +options CPU_NOFPU +options ISA_MIPS32 +makeoptions TARGET_BIG_ENDIAN +makeoptions KERNLOADADDR=0x80050000 + +files "../atheros/files.ar71xx" +hints "AR71XX.hints" + +makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols +makeoptions MODULES_OVERRIDE="" + +options DDB +options KDB + +options SCHED_4BSD #4BSD scheduler +options INET #InterNETworking +options NFSCLIENT #Network Filesystem Client +options NFS_ROOT #NFS usable as /, requires NFSCLIENT +options PSEUDOFS #Pseudo-filesystem framework +options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions + +# Debugging for use in -current +options INVARIANTS +options INVARIANT_SUPPORT + +device pci +device uart + +device loop +device ether +device md diff --git a/sys/mips/conf/AR71XX.hints b/sys/mips/conf/AR71XX.hints new file mode 100644 index 00000000000..58fbddec01a --- /dev/null +++ b/sys/mips/conf/AR71XX.hints @@ -0,0 +1,25 @@ +# $FreeBSD$ +hint.apb.0.at="nexus0" +hint.apb.0.maddr=0x18000000 +hint.apb.0.msize=0x01000000 +hint.apb.0.irq=4 + +# uart0 +hint.uart.0.at="apb0" +# see atheros/uart_cpu_ar71xx.c why +3 +hint.uart.0.maddr=0x18020003 +hint.uart.0.msize=0x18 +hint.uart.0.irq=3 + +# pci +hint.pcib.0.at="nexus0" +hint.pcib.0.irq=0 + +hint.arge.0.at="nexus0" +hint.arge.0.maddr=0x19000000 +hint.arge.0.msize=0x1000 +hint.arge.0.irq=2 +# hint.arge.1.at="nexus0" +# hint.arge.1.maddr=0x1A000000 +# hint.arge.1.msize=0x1000 +# hint.arge.1.irq=3 diff --git a/sys/mips/conf/MALTA b/sys/mips/conf/MALTA index 9771c55351e..022cc5245c8 100644 --- a/sys/mips/conf/MALTA +++ b/sys/mips/conf/MALTA @@ -27,7 +27,6 @@ options YAMON # Don't build any modules yet. makeoptions MODULES_OVERRIDE="" -options KERNVIRTADDR=0x80100000 options TICK_USE_YAMON_FREQ=defined #options TICK_USE_MALTA_RTC=defined diff --git a/sys/mips/conf/QEMU b/sys/mips/conf/QEMU index 0a2b122570b..bc7d64951b1 100644 --- a/sys/mips/conf/QEMU +++ b/sys/mips/conf/QEMU @@ -27,7 +27,6 @@ makeoptions ARCH_FLAGS=-march=mips32 # Don't build any modules yet. makeoptions MODULES_OVERRIDE="" -options KERNVIRTADDR=0x80100000 include "../adm5120/std.adm5120" #hints "GENERIC.hints" #Default places to look for devices. diff --git a/sys/mips/conf/SENTRY5 b/sys/mips/conf/SENTRY5 index 7611e44bb7e..c3918e2e35c 100644 --- a/sys/mips/conf/SENTRY5 +++ b/sys/mips/conf/SENTRY5 @@ -41,13 +41,6 @@ options CFE options CFE_CONSOLE options ALT_BREAK_TO_DEBUGGER -# cfe loader expects kernel at 0x80001000 for mips32 w/o backwards -# offsets in the linked elf image (see ldscript hack) -# XXX can we conditionalize the linker stuff on options CFE? -options KERNVIRTADDR=0x80001000 - -makeoptions LDSCRIPT_NAME= ldscript.mips.cfe - #makeoptions ARCH_FLAGS=-march=mips32 makeoptions MIPS_LITTLE_ENDIAN=defined makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols @@ -73,8 +66,8 @@ options INVARIANT_SUPPORT device siba # Sonics SiliconBackplane device pci # siba_pcib -device bfe # XXX will build both pci and siba -device miibus # attachments +# device bfe # XXX will build both pci and siba +# device miibus # attachments # pci devices # notyet: diff --git a/sys/mips/include/bus.h b/sys/mips/include/bus.h index 92557d7cbd3..42ac1df0c2e 100644 --- a/sys/mips/include/bus.h +++ b/sys/mips/include/bus.h @@ -101,9 +101,8 @@ * Map a region of device bus space into CPU virtual address space. */ -static __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr, - bus_size_t size, int flags, - bus_space_handle_t *bshp); +__inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr, + bus_size_t size, int flags, bus_space_handle_t *bshp); static __inline int bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr, diff --git a/sys/mips/mips/elf_machdep.c b/sys/mips/mips/elf_machdep.c index 19cb1a14c93..163d0ee4588 100644 --- a/sys/mips/mips/elf_machdep.c +++ b/sys/mips/mips/elf_machdep.c @@ -86,8 +86,7 @@ static Elf32_Brandinfo freebsd_brand_info = { .interp_path = "/libexec/ld-elf.so.1", .sysvec = &elf32_freebsd_sysvec, .interp_newpath = NULL, - .brand_note = &elf32_freebsd_brandnote, - .flags = BI_BRAND_NOTE + .flags = 0 }; SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY, diff --git a/sys/mips/mips/elf_trampoline.c b/sys/mips/mips/elf_trampoline.c new file mode 100644 index 00000000000..0f2ccc95e31 --- /dev/null +++ b/sys/mips/mips/elf_trampoline.c @@ -0,0 +1,133 @@ +/*- + * Copyright (c) 2005 Olivier Houchard. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); +#include +#include +#include +#include +#include +#include +#include + +/* + * Since we are compiled outside of the normal kernel build process, we + * need to include opt_global.h manually. + */ +#include "opt_global.h" +#include "opt_kernname.h" + +extern char kernel_start[]; +extern char kernel_end[]; + +static __inline void * +memcpy(void *dst, const void *src, int len) +{ + const char *s = src; + char *d = dst; + + while (len) { + if (0 && len >= 4 && !((vm_offset_t)d & 3) && + !((vm_offset_t)s & 3)) { + *(uint32_t *)d = *(uint32_t *)s; + s += 4; + d += 4; + len -= 4; + } else { + *d++ = *s++; + len--; + } + } + return (dst); +} + +static __inline void +bzero(void *addr, int count) +{ + char *tmp = (char *)addr; + + while (count > 0) { + if (count >= 4 && !((vm_offset_t)tmp & 3)) { + *(uint32_t *)tmp = 0; + tmp += 4; + count -= 4; + } else { + *tmp = 0; + tmp++; + count--; + } + } +} + +/* + * Relocate PT_LOAD segements of kernel ELF image to their respective + * virtual addresses and return entry point + */ +void * +load_kernel(void * kstart) +{ + Elf32_Ehdr *eh; + Elf32_Phdr phdr[64] /* XXX */; + int i; + void *entry_point; + + eh = (Elf32_Ehdr *)kstart; + entry_point = (void*)eh->e_entry; + memcpy(phdr, (void *)(kstart + eh->e_phoff ), + eh->e_phnum * sizeof(phdr[0])); + + for (i = 0; i < eh->e_phnum; i++) { + volatile char c; + + if (phdr[i].p_type != PT_LOAD) + continue; + + memcpy((void *)(phdr[i].p_vaddr), + (void*)(kstart + phdr[i].p_offset), phdr[i].p_filesz); + /* Clean space from oversized segments, eg: bss. */ + if (phdr[i].p_filesz < phdr[i].p_memsz) + bzero((void *)(phdr[i].p_vaddr + phdr[i].p_filesz), + phdr[i].p_memsz - phdr[i].p_filesz); + } + + return entry_point; +} + +void +_startC(register_t a0, register_t a1, register_t a2, register_t a3) +{ + unsigned int * code; + int i; + void (*entry_point)(register_t, register_t, register_t, register_t); + + /* + * Relocate segment to the predefined memory location + * Most likely it will be KSEG0/KSEG1 address + */ + entry_point = load_kernel(kernel_start); + + /* Pass saved registers to original _start */ + entry_point(a0, a1, a2, a3); +} diff --git a/sys/mips/mips/inckern.S b/sys/mips/mips/inckern.S new file mode 100644 index 00000000000..8610196d204 --- /dev/null +++ b/sys/mips/mips/inckern.S @@ -0,0 +1,34 @@ +/*- + * Copyright (c) 2005 Olivier Houchard. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "opt_kernname.h" + +#include +__FBSDID("$FreeBSD$") +.section ".real_kernel","aw" +.globl kernel_start; +kernel_start: +.incbin KERNNAME +.globl kernel_end; +kernel_end: diff --git a/sys/mips/mips/nexus.c b/sys/mips/mips/nexus.c index 64cba66d181..e96eeab34ff 100644 --- a/sys/mips/mips/nexus.c +++ b/sys/mips/mips/nexus.c @@ -249,6 +249,8 @@ nexus_hinted_child(device_t bus, const char *dname, int dunit) long maddr; int msize; int result; + int irq; + int mem_hints_count; child = BUS_ADD_CHILD(bus, 0, dname, dunit); @@ -256,17 +258,34 @@ nexus_hinted_child(device_t bus, const char *dname, int dunit) * Set hard-wired resources for hinted child using * specific RIDs. */ - resource_long_value(dname, dunit, "maddr", &maddr); - resource_int_value(dname, dunit, "msize", &msize); + mem_hints_count = 0; + if (resource_long_value(dname, dunit, "maddr", &maddr) == 0) + mem_hints_count++; + if (resource_int_value(dname, dunit, "msize", &msize) == 0) + mem_hints_count++; - dprintf("%s: discovered hinted child %s at maddr %p(%d)\n", - __func__, device_get_nameunit(child), - (void *)(intptr_t)maddr, msize); + /* check if all info for mem resource has been provided */ + if ((mem_hints_count > 0) && (mem_hints_count < 2)) { + printf("Either maddr or msize hint is missing for %s%d\n", + dname, dunit); + } else if (mem_hints_count) { + dprintf("%s: discovered hinted child %s at maddr %p(%d)\n", + __func__, device_get_nameunit(child), + (void *)(intptr_t)maddr, msize); - result = bus_set_resource(child, SYS_RES_MEMORY, MIPS_MEM_RID, - maddr, msize); - if (result != 0) { - device_printf(bus, "warning: bus_set_resource() failed\n"); + result = bus_set_resource(child, SYS_RES_MEMORY, MIPS_MEM_RID, + maddr, msize); + if (result != 0) { + device_printf(bus, + "warning: bus_set_resource() failed\n"); + } + } + + if (resource_int_value(dname, dunit, "irq", &irq) == 0) { + result = bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1); + if (result != 0) + device_printf(bus, + "warning: bus_set_resource() failed\n"); } } diff --git a/sys/mips/sentry5/files.sentry5 b/sys/mips/sentry5/files.sentry5 index 61038e035df..79925094a2d 100644 --- a/sys/mips/sentry5/files.sentry5 +++ b/sys/mips/sentry5/files.sentry5 @@ -4,11 +4,4 @@ # for USB 1.1 OHCI, Ethernet and IPSEC cores # which are believed to be devices we have drivers for # which just need to be tweaked for attachment to an SSB system bus. - mips/sentry5/s5_machdep.c standard -dev/siba/siba.c optional siba -dev/siba/siba_pcib.c optional siba pci -mips/sentry5/siba_cc.c optional siba - -# notyet -#mips/sentry5/siba_mips.c optional siba From 20eb34e255361f6f0e83bf97c6d3a1d53d8d39b0 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 15 Apr 2009 01:47:52 +0000 Subject: [PATCH 033/380] - Cleanout stale #ifdef'ed chunk of code - Fix whitespaces - Explicitly undefine NEXUS_DEBUG flag --- sys/mips/mips/nexus.c | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/sys/mips/mips/nexus.c b/sys/mips/mips/nexus.c index e96eeab34ff..6cd78fd6277 100644 --- a/sys/mips/mips/nexus.c +++ b/sys/mips/mips/nexus.c @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #include #include +#undef NEXUS_DEBUG #ifdef NEXUS_DEBUG #define dprintf printf #else @@ -77,20 +78,6 @@ struct nexus_device { static struct rman irq_rman; static struct rman mem_rman; -#ifdef notyet -/* - * XXX: TODO: Implement bus space barrier functions. - * Currently tag and handle are set when memory resources - * are activated. - */ -struct bus_space_tag nexus_bustag = { - NULL, /* cookie */ - NULL, /* parent bus tag */ - NEXUS_BUS_SPACE, /* type */ - nexus_bus_barrier, /* bus_space_barrier */ -}; -#endif - static struct resource * nexus_alloc_resource(device_t, device_t, int, int *, u_long, u_long, u_long, u_int); @@ -386,22 +373,22 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { #ifdef TARGET_OCTEON - uint64_t temp; + uint64_t temp; #endif /* * If this is a memory resource, track the direct mapping * in the uncached MIPS KSEG1 segment. */ if ((type == SYS_RES_MEMORY) || (type == SYS_RES_IOPORT)) { - caddr_t vaddr = 0; - u_int32_t paddr; - u_int32_t psize; - u_int32_t poffs; - - paddr = rman_get_start(r); - psize = rman_get_size(r); - poffs = paddr - trunc_page(paddr); - vaddr = (caddr_t) pmap_mapdev(paddr-poffs, psize+poffs) + poffs; + caddr_t vaddr = 0; + u_int32_t paddr; + u_int32_t psize; + u_int32_t poffs; + + paddr = rman_get_start(r); + psize = rman_get_size(r); + poffs = paddr - trunc_page(paddr); + vaddr = (caddr_t) pmap_mapdev(paddr-poffs, psize+poffs) + poffs; rman_set_virtual(r, vaddr); rman_set_bustag(r, MIPS_BUS_SPACE_MEM); From 0c6b091e31b113ee1d158157f0965808da0cbe76 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 15 Apr 2009 02:28:26 +0000 Subject: [PATCH 034/380] Use FreeBSD/arm approach for handling bus space access: space tag is a pointer to bus_space structure that defines access methods and hence every bus can define own accessors. Default space is mips_bus_space_generic. It's a simple interface to physical memory, values are read with regard to host system byte order. --- sys/conf/files.mips | 1 + sys/mips/adm5120/obio.c | 2 +- sys/mips/adm5120/uart_cpu_adm5120.c | 4 +- sys/mips/alchemy/obio.c | 2 +- sys/mips/alchemy/uart_cpu_alchemy.c | 4 +- sys/mips/idt/uart_bus_rc32434.c | 4 +- sys/mips/idt/uart_cpu_rc32434.c | 4 +- sys/mips/include/_bus.h | 2 +- sys/mips/include/bus.h | 1442 +++++++++++--------------- sys/mips/malta/gt_pci.c | 67 +- sys/mips/malta/obio.c | 2 +- sys/mips/malta/uart_bus_maltausart.c | 4 +- sys/mips/malta/uart_cpu_maltausart.c | 8 +- sys/mips/mips/bus_space_generic.c | 570 ++++++++++ 14 files changed, 1249 insertions(+), 867 deletions(-) create mode 100644 sys/mips/mips/bus_space_generic.c diff --git a/sys/conf/files.mips b/sys/conf/files.mips index bbedd968e95..3ee1cc69c32 100644 --- a/sys/conf/files.mips +++ b/sys/conf/files.mips @@ -54,6 +54,7 @@ mips/mips/pm_machdep.c standard mips/mips/swtch.S standard mips/mips/tlb.S standard +mips/mips/bus_space_generic.c standard mips/mips/busdma_machdep.c standard mips/mips/cache.c standard mips/mips/cache_mipsNN.c standard diff --git a/sys/mips/adm5120/obio.c b/sys/mips/adm5120/obio.c index 03e098d42ba..7e61ff5de75 100644 --- a/sys/mips/adm5120/obio.c +++ b/sys/mips/adm5120/obio.c @@ -269,7 +269,7 @@ obio_activate_resource(device_t bus, device_t child, int type, int rid, vaddr = (void *)MIPS_PHYS_TO_KSEG1((intptr_t)rman_get_start(r)); rman_set_virtual(r, vaddr); - rman_set_bustag(r, MIPS_BUS_SPACE_MEM); + rman_set_bustag(r, &mips_bus_space_generic); rman_set_bushandle(r, (bus_space_handle_t)vaddr); } diff --git a/sys/mips/adm5120/uart_cpu_adm5120.c b/sys/mips/adm5120/uart_cpu_adm5120.c index 59bed5af266..0828ea56bb2 100644 --- a/sys/mips/adm5120/uart_cpu_adm5120.c +++ b/sys/mips/adm5120/uart_cpu_adm5120.c @@ -67,7 +67,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) di->ops = uart_getops(&uart_adm5120_uart_class); di->bas.chan = 0; - di->bas.bst = 0; + di->bas.bst = &mips_bus_space_generic; di->bas.regshft = 0; di->bas.rclk = 0; di->baudrate = 115200; @@ -76,7 +76,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) di->parity = UART_PARITY_NONE; uart_bus_space_io = 0; - uart_bus_space_mem = MIPS_PHYS_TO_KSEG1(ADM5120_BASE_UART0); + uart_bus_space_mem = &mips_bus_space_generic; di->bas.bsh = MIPS_PHYS_TO_KSEG1(ADM5120_BASE_UART0); return (0); diff --git a/sys/mips/alchemy/obio.c b/sys/mips/alchemy/obio.c index 03e098d42ba..7e61ff5de75 100644 --- a/sys/mips/alchemy/obio.c +++ b/sys/mips/alchemy/obio.c @@ -269,7 +269,7 @@ obio_activate_resource(device_t bus, device_t child, int type, int rid, vaddr = (void *)MIPS_PHYS_TO_KSEG1((intptr_t)rman_get_start(r)); rman_set_virtual(r, vaddr); - rman_set_bustag(r, MIPS_BUS_SPACE_MEM); + rman_set_bustag(r, &mips_bus_space_generic); rman_set_bushandle(r, (bus_space_handle_t)vaddr); } diff --git a/sys/mips/alchemy/uart_cpu_alchemy.c b/sys/mips/alchemy/uart_cpu_alchemy.c index 931aed63126..d38d4cd3ad9 100644 --- a/sys/mips/alchemy/uart_cpu_alchemy.c +++ b/sys/mips/alchemy/uart_cpu_alchemy.c @@ -63,7 +63,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) di->ops = uart_getops(&uart_ns8250_class); di->bas.chan = 0; - di->bas.bst = 0; + di->bas.bst = &mips_bus_space_generic; di->bas.regshft = 0; di->bas.rclk = 0; di->baudrate = 115200; @@ -72,7 +72,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) di->parity = UART_PARITY_NONE; uart_bus_space_io = 0; - uart_bus_space_mem = MIPS_PHYS_TO_KSEG1(UART0_BASE); + uart_bus_space_mem = &mips_bus_space_generic; di->bas.bsh = MIPS_PHYS_TO_KSEG1(UART0_BASE); return (0); diff --git a/sys/mips/idt/uart_bus_rc32434.c b/sys/mips/idt/uart_bus_rc32434.c index 35e937d6ce7..78edf62c052 100644 --- a/sys/mips/idt/uart_bus_rc32434.c +++ b/sys/mips/idt/uart_bus_rc32434.c @@ -88,10 +88,10 @@ uart_rc32434_probe(device_t dev) sc->sc_class = &uart_ns8250_class; bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); sc->sc_sysdev->bas.regshft = 2; - sc->sc_sysdev->bas.bst = 0; + sc->sc_sysdev->bas.bst = &mips_bus_space_generic; sc->sc_sysdev->bas.bsh = MIPS_PHYS_TO_KSEG1(IDT_BASE_UART0); sc->sc_bas.regshft = 2; - sc->sc_bas.bst = 0; + sc->sc_bas.bst = &mips_bus_space_generic; sc->sc_bas.bsh = MIPS_PHYS_TO_KSEG1(IDT_BASE_UART0); return (uart_bus_probe(dev, 2, 330000000UL/2, 0, 0)); diff --git a/sys/mips/idt/uart_cpu_rc32434.c b/sys/mips/idt/uart_cpu_rc32434.c index 6bbc5bd04eb..862c8bcd547 100644 --- a/sys/mips/idt/uart_cpu_rc32434.c +++ b/sys/mips/idt/uart_cpu_rc32434.c @@ -71,7 +71,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) /* Got it. Fill in the instance and return it. */ di->ops = uart_getops(&uart_ns8250_class); di->bas.chan = 0; - di->bas.bst = 0; + di->bas.bst = &mips_bus_space_generic; di->bas.regshft = 2; di->bas.rclk = 330000000UL/2; /* IPbus clock */ di->baudrate = 115200; @@ -79,7 +79,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) di->stopbits = 1; di->parity = UART_PARITY_NONE; uart_bus_space_io = 0; - uart_bus_space_mem = 0; + uart_bus_space_mem = &mips_bus_space_generic; di->bas.bsh = MIPS_PHYS_TO_KSEG1(maddr); return (0); } diff --git a/sys/mips/include/_bus.h b/sys/mips/include/_bus.h index 74865da17db..d29a9dce0d6 100644 --- a/sys/mips/include/_bus.h +++ b/sys/mips/include/_bus.h @@ -43,7 +43,7 @@ typedef uintptr_t bus_size_t; /* * Access methods for bus resources and address space. */ -typedef long bus_space_tag_t; +typedef struct bus_space *bus_space_tag_t; typedef u_long bus_space_handle_t; #endif #endif /* MIPS_INCLUDE__BUS_H */ diff --git a/sys/mips/include/bus.h b/sys/mips/include/bus.h index 42ac1df0c2e..1136bced64a 100644 --- a/sys/mips/include/bus.h +++ b/sys/mips/include/bus.h @@ -1,8 +1,7 @@ -/* $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $ */ +/* $NetBSD: bus.h,v 1.11 2003/07/28 17:35:54 thorpej Exp $ */ + /*- - * $Id: bus.h,v 1.6 2007/08/09 11:23:32 katta Exp $ - * - * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. + * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -38,7 +37,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ -/* +/*- * Copyright (c) 1996 Charles M. Hannum. All rights reserved. * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. * @@ -68,842 +67,657 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * from: src/sys/alpha/include/bus.h,v 1.5 1999/08/28 00:38:40 peter * $FreeBSD$ -*/ + */ #ifndef _MACHINE_BUS_H_ -#define _MACHINE_BUS_H_ +#define _MACHINE_BUS_H_ -#ifdef TARGET_OCTEON -#include -#else #include -#include + +struct bus_space { + /* cookie */ + void *bs_cookie; + + /* mapping/unmapping */ + int (*bs_map) (void *, bus_addr_t, bus_size_t, + int, bus_space_handle_t *); + void (*bs_unmap) (void *, bus_space_handle_t, bus_size_t); + int (*bs_subregion) (void *, bus_space_handle_t, + bus_size_t, bus_size_t, bus_space_handle_t *); + + /* allocation/deallocation */ + int (*bs_alloc) (void *, bus_addr_t, bus_addr_t, + bus_size_t, bus_size_t, bus_size_t, int, + bus_addr_t *, bus_space_handle_t *); + void (*bs_free) (void *, bus_space_handle_t, + bus_size_t); + + /* get kernel virtual address */ + /* barrier */ + void (*bs_barrier) (void *, bus_space_handle_t, + bus_size_t, bus_size_t, int); + + /* read (single) */ + u_int8_t (*bs_r_1) (void *, bus_space_handle_t, bus_size_t); + u_int16_t (*bs_r_2) (void *, bus_space_handle_t, bus_size_t); + u_int32_t (*bs_r_4) (void *, bus_space_handle_t, bus_size_t); + u_int64_t (*bs_r_8) (void *, bus_space_handle_t, bus_size_t); + + /* read multiple */ + void (*bs_rm_1) (void *, bus_space_handle_t, bus_size_t, + u_int8_t *, bus_size_t); + void (*bs_rm_2) (void *, bus_space_handle_t, bus_size_t, + u_int16_t *, bus_size_t); + void (*bs_rm_4) (void *, bus_space_handle_t, + bus_size_t, u_int32_t *, bus_size_t); + void (*bs_rm_8) (void *, bus_space_handle_t, + bus_size_t, u_int64_t *, bus_size_t); + + /* read region */ + void (*bs_rr_1) (void *, bus_space_handle_t, + bus_size_t, u_int8_t *, bus_size_t); + void (*bs_rr_2) (void *, bus_space_handle_t, + bus_size_t, u_int16_t *, bus_size_t); + void (*bs_rr_4) (void *, bus_space_handle_t, + bus_size_t, u_int32_t *, bus_size_t); + void (*bs_rr_8) (void *, bus_space_handle_t, + bus_size_t, u_int64_t *, bus_size_t); + + /* write (single) */ + void (*bs_w_1) (void *, bus_space_handle_t, + bus_size_t, u_int8_t); + void (*bs_w_2) (void *, bus_space_handle_t, + bus_size_t, u_int16_t); + void (*bs_w_4) (void *, bus_space_handle_t, + bus_size_t, u_int32_t); + void (*bs_w_8) (void *, bus_space_handle_t, + bus_size_t, u_int64_t); + + /* write multiple */ + void (*bs_wm_1) (void *, bus_space_handle_t, + bus_size_t, const u_int8_t *, bus_size_t); + void (*bs_wm_2) (void *, bus_space_handle_t, + bus_size_t, const u_int16_t *, bus_size_t); + void (*bs_wm_4) (void *, bus_space_handle_t, + bus_size_t, const u_int32_t *, bus_size_t); + void (*bs_wm_8) (void *, bus_space_handle_t, + bus_size_t, const u_int64_t *, bus_size_t); + + /* write region */ + void (*bs_wr_1) (void *, bus_space_handle_t, + bus_size_t, const u_int8_t *, bus_size_t); + void (*bs_wr_2) (void *, bus_space_handle_t, + bus_size_t, const u_int16_t *, bus_size_t); + void (*bs_wr_4) (void *, bus_space_handle_t, + bus_size_t, const u_int32_t *, bus_size_t); + void (*bs_wr_8) (void *, bus_space_handle_t, + bus_size_t, const u_int64_t *, bus_size_t); + + /* set multiple */ + void (*bs_sm_1) (void *, bus_space_handle_t, + bus_size_t, u_int8_t, bus_size_t); + void (*bs_sm_2) (void *, bus_space_handle_t, + bus_size_t, u_int16_t, bus_size_t); + void (*bs_sm_4) (void *, bus_space_handle_t, + bus_size_t, u_int32_t, bus_size_t); + void (*bs_sm_8) (void *, bus_space_handle_t, + bus_size_t, u_int64_t, bus_size_t); + + /* set region */ + void (*bs_sr_1) (void *, bus_space_handle_t, + bus_size_t, u_int8_t, bus_size_t); + void (*bs_sr_2) (void *, bus_space_handle_t, + bus_size_t, u_int16_t, bus_size_t); + void (*bs_sr_4) (void *, bus_space_handle_t, + bus_size_t, u_int32_t, bus_size_t); + void (*bs_sr_8) (void *, bus_space_handle_t, + bus_size_t, u_int64_t, bus_size_t); + + /* copy */ + void (*bs_c_1) (void *, bus_space_handle_t, bus_size_t, + bus_space_handle_t, bus_size_t, bus_size_t); + void (*bs_c_2) (void *, bus_space_handle_t, bus_size_t, + bus_space_handle_t, bus_size_t, bus_size_t); + void (*bs_c_4) (void *, bus_space_handle_t, bus_size_t, + bus_space_handle_t, bus_size_t, bus_size_t); + void (*bs_c_8) (void *, bus_space_handle_t, bus_size_t, + bus_space_handle_t, bus_size_t, bus_size_t); + + /* read stream (single) */ + u_int8_t (*bs_r_1_s) (void *, bus_space_handle_t, bus_size_t); + u_int16_t (*bs_r_2_s) (void *, bus_space_handle_t, bus_size_t); + u_int32_t (*bs_r_4_s) (void *, bus_space_handle_t, bus_size_t); + u_int64_t (*bs_r_8_s) (void *, bus_space_handle_t, bus_size_t); + + /* read multiple stream */ + void (*bs_rm_1_s) (void *, bus_space_handle_t, bus_size_t, + u_int8_t *, bus_size_t); + void (*bs_rm_2_s) (void *, bus_space_handle_t, bus_size_t, + u_int16_t *, bus_size_t); + void (*bs_rm_4_s) (void *, bus_space_handle_t, + bus_size_t, u_int32_t *, bus_size_t); + void (*bs_rm_8_s) (void *, bus_space_handle_t, + bus_size_t, u_int64_t *, bus_size_t); + + /* read region stream */ + void (*bs_rr_1_s) (void *, bus_space_handle_t, + bus_size_t, u_int8_t *, bus_size_t); + void (*bs_rr_2_s) (void *, bus_space_handle_t, + bus_size_t, u_int16_t *, bus_size_t); + void (*bs_rr_4_s) (void *, bus_space_handle_t, + bus_size_t, u_int32_t *, bus_size_t); + void (*bs_rr_8_s) (void *, bus_space_handle_t, + bus_size_t, u_int64_t *, bus_size_t); + + /* write stream (single) */ + void (*bs_w_1_s) (void *, bus_space_handle_t, + bus_size_t, u_int8_t); + void (*bs_w_2_s) (void *, bus_space_handle_t, + bus_size_t, u_int16_t); + void (*bs_w_4_s) (void *, bus_space_handle_t, + bus_size_t, u_int32_t); + void (*bs_w_8_s) (void *, bus_space_handle_t, + bus_size_t, u_int64_t); + + /* write multiple stream */ + void (*bs_wm_1_s) (void *, bus_space_handle_t, + bus_size_t, const u_int8_t *, bus_size_t); + void (*bs_wm_2_s) (void *, bus_space_handle_t, + bus_size_t, const u_int16_t *, bus_size_t); + void (*bs_wm_4_s) (void *, bus_space_handle_t, + bus_size_t, const u_int32_t *, bus_size_t); + void (*bs_wm_8_s) (void *, bus_space_handle_t, + bus_size_t, const u_int64_t *, bus_size_t); + + /* write region stream */ + void (*bs_wr_1_s) (void *, bus_space_handle_t, + bus_size_t, const u_int8_t *, bus_size_t); + void (*bs_wr_2_s) (void *, bus_space_handle_t, + bus_size_t, const u_int16_t *, bus_size_t); + void (*bs_wr_4_s) (void *, bus_space_handle_t, + bus_size_t, const u_int32_t *, bus_size_t); + void (*bs_wr_8_s) (void *, bus_space_handle_t, + bus_size_t, const u_int64_t *, bus_size_t); +}; + /* - * Values for the mips bus space tag, not to be used directly by MI code. + * Utility macros; INTERNAL USE ONLY. */ -#define MIPS_BUS_SPACE_IO 0 /* space is i/o space */ -#define MIPS_BUS_SPACE_MEM 1 /* space is mem space */ +#define __bs_c(a,b) __CONCAT(a,b) +#define __bs_opname(op,size) __bs_c(__bs_c(__bs_c(bs_,op),_),size) +#define __bs_rs(sz, t, h, o) \ + (*(t)->__bs_opname(r,sz))((t)->bs_cookie, h, o) +#define __bs_ws(sz, t, h, o, v) \ + (*(t)->__bs_opname(w,sz))((t)->bs_cookie, h, o, v) +#define __bs_nonsingle(type, sz, t, h, o, a, c) \ + (*(t)->__bs_opname(type,sz))((t)->bs_cookie, h, o, a, c) +#define __bs_set(type, sz, t, h, o, v, c) \ + (*(t)->__bs_opname(type,sz))((t)->bs_cookie, h, o, v, c) +#define __bs_copy(sz, t, h1, o1, h2, o2, cnt) \ + (*(t)->__bs_opname(c,sz))((t)->bs_cookie, h1, o1, h2, o2, cnt) -#define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF -#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF -#define BUS_SPACE_MAXSIZE 0xFFFFFFFF /* Maximum supported size */ -#define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF -#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF -#define BUS_SPACE_MAXADDR 0xFFFFFFFF +#define __bs_opname_s(op,size) __bs_c(__bs_c(__bs_c(__bs_c(bs_,op),_),size),_s) +#define __bs_rs_s(sz, t, h, o) \ + (*(t)->__bs_opname_s(r,sz))((t)->bs_cookie, h, o) +#define __bs_ws_s(sz, t, h, o, v) \ + (*(t)->__bs_opname_s(w,sz))((t)->bs_cookie, h, o, v) +#define __bs_nonsingle_s(type, sz, t, h, o, a, c) \ + (*(t)->__bs_opname_s(type,sz))((t)->bs_cookie, h, o, a, c) -#define BUS_SPACE_UNRESTRICTED (~0) /* - * Map a region of device bus space into CPU virtual address space. + * Mapping and unmapping operations. */ +#define bus_space_map(t, a, s, c, hp) \ + (*(t)->bs_map)((t)->bs_cookie, (a), (s), (c), (hp)) +#define bus_space_unmap(t, h, s) \ + (*(t)->bs_unmap)((t)->bs_cookie, (h), (s)) +#define bus_space_subregion(t, h, o, s, hp) \ + (*(t)->bs_subregion)((t)->bs_cookie, (h), (o), (s), (hp)) -__inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr, - bus_size_t size, int flags, bus_space_handle_t *bshp); - -static __inline int -bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr, - bus_size_t size __unused, int flags __unused, - bus_space_handle_t *bshp) -{ - - *bshp = addr; - return (0); -} /* - * Unmap a region of device bus space. + * Allocation and deallocation operations. + */ +#define bus_space_alloc(t, rs, re, s, a, b, c, ap, hp) \ + (*(t)->bs_alloc)((t)->bs_cookie, (rs), (re), (s), (a), (b), \ + (c), (ap), (hp)) +#define bus_space_free(t, h, s) \ + (*(t)->bs_free)((t)->bs_cookie, (h), (s)) + +/* + * Bus barrier operations. + */ +#define bus_space_barrier(t, h, o, l, f) \ + (*(t)->bs_barrier)((t)->bs_cookie, (h), (o), (l), (f)) + +#define BUS_SPACE_BARRIER_READ 0x01 +#define BUS_SPACE_BARRIER_WRITE 0x02 + +/* + * Bus read (single) operations. + */ +#define bus_space_read_1(t, h, o) __bs_rs(1,(t),(h),(o)) +#define bus_space_read_2(t, h, o) __bs_rs(2,(t),(h),(o)) +#define bus_space_read_4(t, h, o) __bs_rs(4,(t),(h),(o)) +#define bus_space_read_8(t, h, o) __bs_rs(8,(t),(h),(o)) + +#define bus_space_read_stream_1(t, h, o) __bs_rs_s(1,(t), (h), (o)) +#define bus_space_read_stream_2(t, h, o) __bs_rs_s(2,(t), (h), (o)) +#define bus_space_read_stream_4(t, h, o) __bs_rs_s(4,(t), (h), (o)) +#define bus_space_read_stream_8(t, h, o) __bs_rs_s(8,8,(t),(h),(o)) + +/* + * Bus read multiple operations. + */ +#define bus_space_read_multi_1(t, h, o, a, c) \ + __bs_nonsingle(rm,1,(t),(h),(o),(a),(c)) +#define bus_space_read_multi_2(t, h, o, a, c) \ + __bs_nonsingle(rm,2,(t),(h),(o),(a),(c)) +#define bus_space_read_multi_4(t, h, o, a, c) \ + __bs_nonsingle(rm,4,(t),(h),(o),(a),(c)) +#define bus_space_read_multi_8(t, h, o, a, c) \ + __bs_nonsingle(rm,8,(t),(h),(o),(a),(c)) + +#define bus_space_read_multi_stream_1(t, h, o, a, c) \ + __bs_nonsingle_s(rm,1,(t),(h),(o),(a),(c)) +#define bus_space_read_multi_stream_2(t, h, o, a, c) \ + __bs_nonsingle_s(rm,2,(t),(h),(o),(a),(c)) +#define bus_space_read_multi_stream_4(t, h, o, a, c) \ + __bs_nonsingle_s(rm,4,(t),(h),(o),(a),(c)) +#define bus_space_read_multi_stream_8(t, h, o, a, c) \ + __bs_nonsingle_s(rm,8,(t),(h),(o),(a),(c)) + + +/* + * Bus read region operations. + */ +#define bus_space_read_region_1(t, h, o, a, c) \ + __bs_nonsingle(rr,1,(t),(h),(o),(a),(c)) +#define bus_space_read_region_2(t, h, o, a, c) \ + __bs_nonsingle(rr,2,(t),(h),(o),(a),(c)) +#define bus_space_read_region_4(t, h, o, a, c) \ + __bs_nonsingle(rr,4,(t),(h),(o),(a),(c)) +#define bus_space_read_region_8(t, h, o, a, c) \ + __bs_nonsingle(rr,8,(t),(h),(o),(a),(c)) + +#define bus_space_read_region_stream_1(t, h, o, a, c) \ + __bs_nonsingle_s(rr,1,(t),(h),(o),(a),(c)) +#define bus_space_read_region_stream_2(t, h, o, a, c) \ + __bs_nonsingle_s(rr,2,(t),(h),(o),(a),(c)) +#define bus_space_read_region_stream_4(t, h, o, a, c) \ + __bs_nonsingle_s(rr,4,(t),(h),(o),(a),(c)) +#define bus_space_read_region_stream_8(t, h, o, a, c) \ + __bs_nonsingle_s(rr,8,(t),(h),(o),(a),(c)) + + +/* + * Bus write (single) operations. + */ +#define bus_space_write_1(t, h, o, v) __bs_ws(1,(t),(h),(o),(v)) +#define bus_space_write_2(t, h, o, v) __bs_ws(2,(t),(h),(o),(v)) +#define bus_space_write_4(t, h, o, v) __bs_ws(4,(t),(h),(o),(v)) +#define bus_space_write_8(t, h, o, v) __bs_ws(8,(t),(h),(o),(v)) + +#define bus_space_write_stream_1(t, h, o, v) __bs_ws_s(1,(t),(h),(o),(v)) +#define bus_space_write_stream_2(t, h, o, v) __bs_ws_s(2,(t),(h),(o),(v)) +#define bus_space_write_stream_4(t, h, o, v) __bs_ws_s(4,(t),(h),(o),(v)) +#define bus_space_write_stream_8(t, h, o, v) __bs_ws_s(8,(t),(h),(o),(v)) + + +/* + * Bus write multiple operations. + */ +#define bus_space_write_multi_1(t, h, o, a, c) \ + __bs_nonsingle(wm,1,(t),(h),(o),(a),(c)) +#define bus_space_write_multi_2(t, h, o, a, c) \ + __bs_nonsingle(wm,2,(t),(h),(o),(a),(c)) +#define bus_space_write_multi_4(t, h, o, a, c) \ + __bs_nonsingle(wm,4,(t),(h),(o),(a),(c)) +#define bus_space_write_multi_8(t, h, o, a, c) \ + __bs_nonsingle(wm,8,(t),(h),(o),(a),(c)) + +#define bus_space_write_multi_stream_1(t, h, o, a, c) \ + __bs_nonsingle_s(wm,1,(t),(h),(o),(a),(c)) +#define bus_space_write_multi_stream_2(t, h, o, a, c) \ + __bs_nonsingle_s(wm,2,(t),(h),(o),(a),(c)) +#define bus_space_write_multi_stream_4(t, h, o, a, c) \ + __bs_nonsingle_s(wm,4,(t),(h),(o),(a),(c)) +#define bus_space_write_multi_stream_8(t, h, o, a, c) \ + __bs_nonsingle_s(wm,8,(t),(h),(o),(a),(c)) + + +/* + * Bus write region operations. + */ +#define bus_space_write_region_1(t, h, o, a, c) \ + __bs_nonsingle(wr,1,(t),(h),(o),(a),(c)) +#define bus_space_write_region_2(t, h, o, a, c) \ + __bs_nonsingle(wr,2,(t),(h),(o),(a),(c)) +#define bus_space_write_region_4(t, h, o, a, c) \ + __bs_nonsingle(wr,4,(t),(h),(o),(a),(c)) +#define bus_space_write_region_8(t, h, o, a, c) \ + __bs_nonsingle(wr,8,(t),(h),(o),(a),(c)) + +#define bus_space_write_region_stream_1(t, h, o, a, c) \ + __bs_nonsingle_s(wr,1,(t),(h),(o),(a),(c)) +#define bus_space_write_region_stream_2(t, h, o, a, c) \ + __bs_nonsingle_s(wr,2,(t),(h),(o),(a),(c)) +#define bus_space_write_region_stream_4(t, h, o, a, c) \ + __bs_nonsingle_s(wr,4,(t),(h),(o),(a),(c)) +#define bus_space_write_region_stream_8(t, h, o, a, c) \ + __bs_nonsingle_s(wr,8,(t),(h),(o),(a),(c)) + + +/* + * Set multiple operations. + */ +#define bus_space_set_multi_1(t, h, o, v, c) \ + __bs_set(sm,1,(t),(h),(o),(v),(c)) +#define bus_space_set_multi_2(t, h, o, v, c) \ + __bs_set(sm,2,(t),(h),(o),(v),(c)) +#define bus_space_set_multi_4(t, h, o, v, c) \ + __bs_set(sm,4,(t),(h),(o),(v),(c)) +#define bus_space_set_multi_8(t, h, o, v, c) \ + __bs_set(sm,8,(t),(h),(o),(v),(c)) + + +/* + * Set region operations. + */ +#define bus_space_set_region_1(t, h, o, v, c) \ + __bs_set(sr,1,(t),(h),(o),(v),(c)) +#define bus_space_set_region_2(t, h, o, v, c) \ + __bs_set(sr,2,(t),(h),(o),(v),(c)) +#define bus_space_set_region_4(t, h, o, v, c) \ + __bs_set(sr,4,(t),(h),(o),(v),(c)) +#define bus_space_set_region_8(t, h, o, v, c) \ + __bs_set(sr,8,(t),(h),(o),(v),(c)) + + +/* + * Copy operations. + */ +#define bus_space_copy_region_1(t, h1, o1, h2, o2, c) \ + __bs_copy(1, t, h1, o1, h2, o2, c) +#define bus_space_copy_region_2(t, h1, o1, h2, o2, c) \ + __bs_copy(2, t, h1, o1, h2, o2, c) +#define bus_space_copy_region_4(t, h1, o1, h2, o2, c) \ + __bs_copy(4, t, h1, o1, h2, o2, c) +#define bus_space_copy_region_8(t, h1, o1, h2, o2, c) \ + __bs_copy(8, t, h1, o1, h2, o2, c) + +/* + * Macros to provide prototypes for all the functions used in the + * bus_space structure */ -void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, +#define bs_map_proto(f) \ +int __bs_c(f,_bs_map) (void *t, bus_addr_t addr, \ + bus_size_t size, int cacheable, bus_space_handle_t *bshp); + +#define bs_unmap_proto(f) \ +void __bs_c(f,_bs_unmap) (void *t, bus_space_handle_t bsh, \ bus_size_t size); -/* - * Get a new handle for a subregion of an already-mapped area of bus space. - */ +#define bs_subregion_proto(f) \ +int __bs_c(f,_bs_subregion) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, bus_size_t size, \ + bus_space_handle_t *nbshp); -int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh, - bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp); - -/* - * Allocate a region of memory that is accessible to devices in bus space. - */ - -int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, - bus_addr_t rend, bus_size_t size, bus_size_t align, - bus_size_t boundary, int flags, bus_addr_t *addrp, +#define bs_alloc_proto(f) \ +int __bs_c(f,_bs_alloc) (void *t, bus_addr_t rstart, \ + bus_addr_t rend, bus_size_t size, bus_size_t align, \ + bus_size_t boundary, int cacheable, bus_addr_t *addrp, \ bus_space_handle_t *bshp); -/* - * Free a region of bus space accessible memory. - */ - -void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh, +#define bs_free_proto(f) \ +void __bs_c(f,_bs_free) (void *t, bus_space_handle_t bsh, \ bus_size_t size); +#define bs_barrier_proto(f) \ +void __bs_c(f,_bs_barrier) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, bus_size_t len, int flags); -/* - * Read a 1, 2, 4, or 8 byte quantity from bus space - * described by tag/handle/offset. +#define bs_r_1_proto(f) \ +u_int8_t __bs_c(f,_bs_r_1) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset); + +#define bs_r_2_proto(f) \ +u_int16_t __bs_c(f,_bs_r_2) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset); + +#define bs_r_4_proto(f) \ +u_int32_t __bs_c(f,_bs_r_4) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset); + +#define bs_r_8_proto(f) \ +u_int64_t __bs_c(f,_bs_r_8) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset); + +#define bs_r_1_s_proto(f) \ +u_int8_t __bs_c(f,_bs_r_1_s) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset); + +#define bs_r_2_s_proto(f) \ +u_int16_t __bs_c(f,_bs_r_2_s) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset); + +#define bs_r_4_s_proto(f) \ +u_int32_t __bs_c(f,_bs_r_4_s) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset); + +#define bs_w_1_proto(f) \ +void __bs_c(f,_bs_w_1) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int8_t value); + +#define bs_w_2_proto(f) \ +void __bs_c(f,_bs_w_2) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int16_t value); + +#define bs_w_4_proto(f) \ +void __bs_c(f,_bs_w_4) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int32_t value); + +#define bs_w_8_proto(f) \ +void __bs_c(f,_bs_w_8) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int64_t value); + +#define bs_w_1_s_proto(f) \ +void __bs_c(f,_bs_w_1_s) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int8_t value); + +#define bs_w_2_s_proto(f) \ +void __bs_c(f,_bs_w_2_s) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int16_t value); + +#define bs_w_4_s_proto(f) \ +void __bs_c(f,_bs_w_4_s) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int32_t value); + +#define bs_rm_1_proto(f) \ +void __bs_c(f,_bs_rm_1) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int8_t *addr, bus_size_t count); + +#define bs_rm_2_proto(f) \ +void __bs_c(f,_bs_rm_2) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int16_t *addr, bus_size_t count); + +#define bs_rm_4_proto(f) \ +void __bs_c(f,_bs_rm_4) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int32_t *addr, bus_size_t count); + +#define bs_rm_8_proto(f) \ +void __bs_c(f,_bs_rm_8) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int64_t *addr, bus_size_t count); + +#define bs_wm_1_proto(f) \ +void __bs_c(f,_bs_wm_1) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, const u_int8_t *addr, bus_size_t count); + +#define bs_wm_2_proto(f) \ +void __bs_c(f,_bs_wm_2) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, const u_int16_t *addr, bus_size_t count); + +#define bs_wm_4_proto(f) \ +void __bs_c(f,_bs_wm_4) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, const u_int32_t *addr, bus_size_t count); + +#define bs_wm_8_proto(f) \ +void __bs_c(f,_bs_wm_8) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, const u_int64_t *addr, bus_size_t count); + +#define bs_rr_1_proto(f) \ +void __bs_c(f, _bs_rr_1) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int8_t *addr, bus_size_t count); + +#define bs_rr_2_proto(f) \ +void __bs_c(f, _bs_rr_2) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int16_t *addr, bus_size_t count); + +#define bs_rr_4_proto(f) \ +void __bs_c(f, _bs_rr_4) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int32_t *addr, bus_size_t count); + +#define bs_rr_8_proto(f) \ +void __bs_c(f, _bs_rr_8) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int64_t *addr, bus_size_t count); + +#define bs_wr_1_proto(f) \ +void __bs_c(f, _bs_wr_1) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, const u_int8_t *addr, bus_size_t count); + +#define bs_wr_2_proto(f) \ +void __bs_c(f, _bs_wr_2) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, const u_int16_t *addr, bus_size_t count); + +#define bs_wr_4_proto(f) \ +void __bs_c(f, _bs_wr_4) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, const u_int32_t *addr, bus_size_t count); + +#define bs_wr_8_proto(f) \ +void __bs_c(f, _bs_wr_8) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, const u_int64_t *addr, bus_size_t count); + +#define bs_sm_1_proto(f) \ +void __bs_c(f,_bs_sm_1) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int8_t value, bus_size_t count); + +#define bs_sm_2_proto(f) \ +void __bs_c(f,_bs_sm_2) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int16_t value, bus_size_t count); + +#define bs_sm_4_proto(f) \ +void __bs_c(f,_bs_sm_4) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int32_t value, bus_size_t count); + +#define bs_sm_8_proto(f) \ +void __bs_c(f,_bs_sm_8) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int64_t value, bus_size_t count); + +#define bs_sr_1_proto(f) \ +void __bs_c(f,_bs_sr_1) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int8_t value, bus_size_t count); + +#define bs_sr_2_proto(f) \ +void __bs_c(f,_bs_sr_2) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int16_t value, bus_size_t count); + +#define bs_sr_4_proto(f) \ +void __bs_c(f,_bs_sr_4) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int32_t value, bus_size_t count); + +#define bs_sr_8_proto(f) \ +void __bs_c(f,_bs_sr_8) (void *t, bus_space_handle_t bsh, \ + bus_size_t offset, u_int64_t value, bus_size_t count); + +#define bs_c_1_proto(f) \ +void __bs_c(f,_bs_c_1) (void *t, bus_space_handle_t bsh1, \ + bus_size_t offset1, bus_space_handle_t bsh2, \ + bus_size_t offset2, bus_size_t count); + +#define bs_c_2_proto(f) \ +void __bs_c(f,_bs_c_2) (void *t, bus_space_handle_t bsh1, \ + bus_size_t offset1, bus_space_handle_t bsh2, \ + bus_size_t offset2, bus_size_t count); + +#define bs_c_4_proto(f) \ +void __bs_c(f,_bs_c_4) (void *t, bus_space_handle_t bsh1, \ + bus_size_t offset1, bus_space_handle_t bsh2, \ + bus_size_t offset2, bus_size_t count); + +#define bs_c_8_proto(f) \ +void __bs_c(f,_bs_c_8) (void *t, bus_space_handle_t bsh1, \ + bus_size_t offset1, bus_space_handle_t bsh2, \ + bus_size_t offset2, bus_size_t count); + +#define DECLARE_BUS_SPACE_PROTOTYPES(f) \ + bs_map_proto(f); \ + bs_unmap_proto(f); \ + bs_subregion_proto(f); \ + bs_alloc_proto(f); \ + bs_free_proto(f); \ + bs_barrier_proto(f); \ + bs_r_1_proto(f); \ + bs_r_2_proto(f); \ + bs_r_4_proto(f); \ + bs_r_8_proto(f); \ + bs_r_1_s_proto(f); \ + bs_r_2_s_proto(f); \ + bs_r_4_s_proto(f); \ + bs_w_1_proto(f); \ + bs_w_2_proto(f); \ + bs_w_4_proto(f); \ + bs_w_8_proto(f); \ + bs_w_1_s_proto(f); \ + bs_w_2_s_proto(f); \ + bs_w_4_s_proto(f); \ + bs_rm_1_proto(f); \ + bs_rm_2_proto(f); \ + bs_rm_4_proto(f); \ + bs_rm_8_proto(f); \ + bs_wm_1_proto(f); \ + bs_wm_2_proto(f); \ + bs_wm_4_proto(f); \ + bs_wm_8_proto(f); \ + bs_rr_1_proto(f); \ + bs_rr_2_proto(f); \ + bs_rr_4_proto(f); \ + bs_rr_8_proto(f); \ + bs_wr_1_proto(f); \ + bs_wr_2_proto(f); \ + bs_wr_4_proto(f); \ + bs_wr_8_proto(f); \ + bs_sm_1_proto(f); \ + bs_sm_2_proto(f); \ + bs_sm_4_proto(f); \ + bs_sm_8_proto(f); \ + bs_sr_1_proto(f); \ + bs_sr_2_proto(f); \ + bs_sr_4_proto(f); \ + bs_sr_8_proto(f); \ + bs_c_1_proto(f); \ + bs_c_2_proto(f); \ + bs_c_4_proto(f); \ + bs_c_8_proto(f); + +#define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t) + +#define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF +#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF +#define BUS_SPACE_MAXADDR 0xFFFFFFFF +#define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF +#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF +#define BUS_SPACE_MAXSIZE 0xFFFFFFFF + +/* + * declare generic bus space, it suits all needs in */ -static __inline u_int8_t bus_space_read_1(bus_space_tag_t tag, - bus_space_handle_t handle, - bus_size_t offset); - -static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag, - bus_space_handle_t handle, - bus_size_t offset); - -static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag, - bus_space_handle_t handle, - bus_size_t offset); - -static __inline u_int8_t -bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset) -{ - - if (tag == MIPS_BUS_SPACE_IO) - return (inb(handle + offset)); - return (readb(handle + offset)); -} - -static __inline u_int16_t -bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset) -{ - - if (tag == MIPS_BUS_SPACE_IO) - return (inw(handle + offset)); - return (readw(handle + offset)); -} - -static __inline u_int32_t -bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset) -{ - - if (tag == MIPS_BUS_SPACE_IO) - return (inl(handle + offset)); - return (readl(handle + offset)); -} - -#if 0 /* Cause a link error for bus_space_read_8 */ -#define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!! -#endif - -/* - * Read `count' 1, 2, 4, or 8 byte quantities from bus space - * described by tag/handle/offset and copy into buffer provided. - */ -static __inline void bus_space_read_multi_1(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int8_t *addr, - size_t count); - -static __inline void bus_space_read_multi_2(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int16_t *addr, - size_t count); - -static __inline void bus_space_read_multi_4(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int32_t *addr, - size_t count); - -static __inline void -bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t *addr, size_t count) -{ - - if (tag == MIPS_BUS_SPACE_IO) - while (count--) - *addr++ = inb(bsh + offset); - else - while (count--) - *addr++ = readb(bsh + offset); -} - -static __inline void -bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t *addr, size_t count) -{ - bus_addr_t baddr = bsh + offset; - - if (tag == MIPS_BUS_SPACE_IO) - while (count--) - *addr++ = inw(baddr); - else - while (count--) - *addr++ = readw(baddr); -} - -static __inline void -bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t *addr, size_t count) -{ - bus_addr_t baddr = bsh + offset; - - if (tag == MIPS_BUS_SPACE_IO) - while (count--) - *addr++ = inl(baddr); - else - while (count--) - *addr++ = readl(baddr); -} - -#if 0 /* Cause a link error for bus_space_read_multi_8 */ -#define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!! -#endif - -/* - * Read `count' 1, 2, 4, or 8 byte quantities from bus space - * described by tag/handle and starting at `offset' and copy into - * buffer provided. - */ -static __inline void bus_space_read_region_1(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int8_t *addr, - size_t count); - -static __inline void bus_space_read_region_2(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int16_t *addr, - size_t count); - -static __inline void bus_space_read_region_4(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int32_t *addr, - size_t count); - - -static __inline void -bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t *addr, size_t count) -{ - bus_addr_t baddr = bsh + offset; - - if (tag == MIPS_BUS_SPACE_IO) - while (count--) { - *addr++ = inb(baddr); - baddr += 1; - } - else - while (count--) { - *addr++ = readb(baddr); - baddr += 1; - } -} - -static __inline void -bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t *addr, size_t count) -{ - bus_addr_t baddr = bsh + offset; - - if (tag == MIPS_BUS_SPACE_IO) - while (count--) { - *addr++ = inw(baddr); - baddr += 2; - } - else - while (count--) { - *addr++ = readw(baddr); - baddr += 2; - } -} - -static __inline void -bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t *addr, size_t count) -{ - bus_addr_t baddr = bsh + offset; - - if (tag == MIPS_BUS_SPACE_IO) - while (count--) { - *addr++ = inl(baddr); - baddr += 4; - } - else - while (count--) { - *addr++ = readb(baddr); - baddr += 4; - } -} - -#if 0 /* Cause a link error for bus_space_read_region_8 */ -#define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!! -#endif - -/* - * Write the 1, 2, 4, or 8 byte value `value' to bus space - * described by tag/handle/offset. - */ - -static __inline void bus_space_write_1(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int8_t value); - -static __inline void bus_space_write_2(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int16_t value); - -static __inline void bus_space_write_4(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int32_t value); - -static __inline void -bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t value) -{ - - if (tag == MIPS_BUS_SPACE_IO) - outb(bsh + offset, value); - else - writeb(bsh + offset, value); -} - -static __inline void -bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t value) -{ - - if (tag == MIPS_BUS_SPACE_IO) - outw(bsh + offset, value); - else - writew(bsh + offset, value); -} - -static __inline void -bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t value) -{ - - if (tag == MIPS_BUS_SPACE_IO) - outl(bsh + offset, value); - else - writel(bsh + offset, value); -} - -#if 0 /* Cause a link error for bus_space_write_8 */ -#define bus_space_write_8 !!! bus_space_write_8 not implemented !!! -#endif - -/* - * Write `count' 1, 2, 4, or 8 byte quantities from the buffer - * provided to bus space described by tag/handle/offset. - */ - -static __inline void bus_space_write_multi_1(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - const u_int8_t *addr, - size_t count); -static __inline void bus_space_write_multi_2(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - const u_int16_t *addr, - size_t count); - -static __inline void bus_space_write_multi_4(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - const u_int32_t *addr, - size_t count); - -static __inline void -bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int8_t *addr, size_t count) -{ - bus_addr_t baddr = bsh + offset; - - if (tag == MIPS_BUS_SPACE_IO) - while (count--) - outb(baddr, *addr++); - else - while (count--) - writeb(baddr, *addr++); -} - -static __inline void -bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int16_t *addr, size_t count) -{ - bus_addr_t baddr = bsh + offset; - - if (tag == MIPS_BUS_SPACE_IO) - while (count--) - outw(baddr, *addr++); - else - while (count--) - writew(baddr, *addr++); -} - -static __inline void -bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int32_t *addr, size_t count) -{ - bus_addr_t baddr = bsh + offset; - - if (tag == MIPS_BUS_SPACE_IO) - while (count--) - outl(baddr, *addr++); - else - while (count--) - writel(baddr, *addr++); -} - -#if 0 /* Cause a link error for bus_space_write_multi_8 */ -#define bus_space_write_multi_8(t, h, o, a, c) \ - !!! bus_space_write_multi_8 unimplemented !!! -#endif - -/* - * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided - * to bus space described by tag/handle starting at `offset'. - */ - -static __inline void bus_space_write_region_1(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - const u_int8_t *addr, - size_t count); -static __inline void bus_space_write_region_2(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - const u_int16_t *addr, - size_t count); -static __inline void bus_space_write_region_4(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - const u_int32_t *addr, - size_t count); - -static __inline void -bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int8_t *addr, size_t count) -{ - bus_addr_t baddr = bsh + offset; - - if (tag == MIPS_BUS_SPACE_IO) - while (count--) { - outb(baddr, *addr++); - baddr += 1; - } - else - while (count--) { - writeb(baddr, *addr++); - baddr += 1; - } -} - -static __inline void -bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int16_t *addr, size_t count) -{ - bus_addr_t baddr = bsh + offset; - - if (tag == MIPS_BUS_SPACE_IO) - while (count--) { - outw(baddr, *addr++); - baddr += 2; - } - else - while (count--) { - writew(baddr, *addr++); - baddr += 2; - } -} - -static __inline void -bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int32_t *addr, size_t count) -{ - bus_addr_t baddr = bsh + offset; - - if (tag == MIPS_BUS_SPACE_IO) - while (count--) { - outl(baddr, *addr++); - baddr += 4; - } - else - while (count--) { - writel(baddr, *addr++); - baddr += 4; - } -} - -#if 0 /* Cause a link error for bus_space_write_region_8 */ -#define bus_space_write_region_8 \ - !!! bus_space_write_region_8 unimplemented !!! -#endif - -/* - * Write the 1, 2, 4, or 8 byte value `val' to bus space described - * by tag/handle/offset `count' times. - */ - -static __inline void bus_space_set_multi_1(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - u_int8_t value, size_t count); -static __inline void bus_space_set_multi_2(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - u_int16_t value, size_t count); -static __inline void bus_space_set_multi_4(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - u_int32_t value, size_t count); - -static __inline void -bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t value, size_t count) -{ - bus_addr_t addr = bsh + offset; - - if (tag == MIPS_BUS_SPACE_IO) - while (count--) - outb(addr, value); - else - while (count--) - writeb(addr, value); -} - -static __inline void -bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t value, size_t count) -{ - bus_addr_t addr = bsh + offset; - - if (tag == MIPS_BUS_SPACE_IO) - while (count--) - outw(addr, value); - else - while (count--) - writew(addr, value); -} - -static __inline void -bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t value, size_t count) -{ - bus_addr_t addr = bsh + offset; - - if (tag == MIPS_BUS_SPACE_IO) - while (count--) - outl(addr, value); - else - while (count--) - writel(addr, value); -} - -#if 0 /* Cause a link error for bus_space_set_multi_8 */ -#define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!! -#endif - -/* - * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described - * by tag/handle starting at `offset'. - */ - -static __inline void bus_space_set_region_1(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int8_t value, - size_t count); -static __inline void bus_space_set_region_2(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int16_t value, - size_t count); -static __inline void bus_space_set_region_4(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int32_t value, - size_t count); - -static __inline void -bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t value, size_t count) -{ - bus_addr_t addr = bsh + offset; - - if (tag == MIPS_BUS_SPACE_IO) - for (; count != 0; count--, addr++) - outb(addr, value); - else - for (; count != 0; count--, addr++) - writeb(addr, value); -} - -static __inline void -bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t value, size_t count) -{ - bus_addr_t addr = bsh + offset; - - if (tag == MIPS_BUS_SPACE_IO) - for (; count != 0; count--, addr += 2) - outw(addr, value); - else - for (; count != 0; count--, addr += 2) - writew(addr, value); -} - -static __inline void -bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t value, size_t count) -{ - bus_addr_t addr = bsh + offset; - - if (tag == MIPS_BUS_SPACE_IO) - for (; count != 0; count--, addr += 4) - outl(addr, value); - else - for (; count != 0; count--, addr += 4) - writel(addr, value); -} - -#if 0 /* Cause a link error for bus_space_set_region_8 */ -#define bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!! -#endif - -/* - * Copy `count' 1, 2, 4, or 8 byte values from bus space starting - * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. - */ - -static __inline void bus_space_copy_region_1(bus_space_tag_t tag, - bus_space_handle_t bsh1, - bus_size_t off1, - bus_space_handle_t bsh2, - bus_size_t off2, size_t count); - -static __inline void bus_space_copy_region_2(bus_space_tag_t tag, - bus_space_handle_t bsh1, - bus_size_t off1, - bus_space_handle_t bsh2, - bus_size_t off2, size_t count); - -static __inline void bus_space_copy_region_4(bus_space_tag_t tag, - bus_space_handle_t bsh1, - bus_size_t off1, - bus_space_handle_t bsh2, - bus_size_t off2, size_t count); - -static __inline void -bus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1, - bus_size_t off1, bus_space_handle_t bsh2, - bus_size_t off2, size_t count) -{ - bus_addr_t addr1 = bsh1 + off1; - bus_addr_t addr2 = bsh2 + off2; - - if (tag == MIPS_BUS_SPACE_IO) - { - if (addr1 >= addr2) { - /* src after dest: copy forward */ - for (; count != 0; count--, addr1++, addr2++) - outb(addr2, inb(addr1)); - } else { - /* dest after src: copy backwards */ - for (addr1 += (count - 1), addr2 += (count - 1); - count != 0; count--, addr1--, addr2--) - outb(addr2, inb(addr1)); - } - } else { - if (addr1 >= addr2) { - /* src after dest: copy forward */ - for (; count != 0; count--, addr1++, addr2++) - writeb(addr2, readb(addr1)); - } else { - /* dest after src: copy backwards */ - for (addr1 += (count - 1), addr2 += (count - 1); - count != 0; count--, addr1--, addr2--) - writeb(addr2, readb(addr1)); - } - } -} - -static __inline void -bus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1, - bus_size_t off1, bus_space_handle_t bsh2, - bus_size_t off2, size_t count) -{ - bus_addr_t addr1 = bsh1 + off1; - bus_addr_t addr2 = bsh2 + off2; - - if (tag == MIPS_BUS_SPACE_IO) - { - if (addr1 >= addr2) { - /* src after dest: copy forward */ - for (; count != 0; count--, addr1 += 2, addr2 += 2) - outw(addr2, inw(addr1)); - } else { - /* dest after src: copy backwards */ - for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1); - count != 0; count--, addr1 -= 2, addr2 -= 2) - outw(addr2, inw(addr1)); - } - } else { - if (addr1 >= addr2) { - /* src after dest: copy forward */ - for (; count != 0; count--, addr1 += 2, addr2 += 2) - writew(addr2, readw(addr1)); - } else { - /* dest after src: copy backwards */ - for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1); - count != 0; count--, addr1 -= 2, addr2 -= 2) - writew(addr2, readw(addr1)); - } - } -} - -static __inline void -bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1, - bus_size_t off1, bus_space_handle_t bsh2, - bus_size_t off2, size_t count) -{ - bus_addr_t addr1 = bsh1 + off1; - bus_addr_t addr2 = bsh2 + off2; - - if (tag == MIPS_BUS_SPACE_IO) - { - if (addr1 >= addr2) { - /* src after dest: copy forward */ - for (; count != 0; count--, addr1 += 4, addr2 += 4) - outl(addr2, inl(addr1)); - } else { - /* dest after src: copy backwards */ - for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1); - count != 0; count--, addr1 -= 4, addr2 -= 4) - outl(addr2, inl(addr1)); - } - } else { - if (addr1 >= addr2) { - /* src after dest: copy forward */ - for (; count != 0; count--, addr1 += 4, addr2 += 4) - writel(addr2, readl(addr1)); - } else { - /* dest after src: copy backwards */ - for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1); - count != 0; count--, addr1 -= 4, addr2 -= 4) - writel(addr2, readl(addr1)); - } - } -} - - -#if 0 /* Cause a link error for bus_space_copy_8 */ -#define bus_space_copy_region_8 !!! bus_space_copy_region_8 unimplemented !!! -#endif - - -/* - * Bus read/write barrier methods. - * - * void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh, - * bus_size_t offset, bus_size_t len, int flags); - * - * - * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than - * prevent reordering by the compiler; all Intel x86 processors currently - * retire operations outside the CPU in program order. - */ -#define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ -#define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ - -static __inline void -bus_space_barrier(bus_space_tag_t tag __unused, bus_space_handle_t bsh __unused, - bus_size_t offset __unused, bus_size_t len __unused, int flags) -{ -#if 0 -#ifdef __GNUCLIKE_ASM - if (flags & BUS_SPACE_BARRIER_READ) - __asm __volatile("lock; addl $0,0(%%rsp)" : : : "memory"); - else - __asm __volatile("" : : : "memory"); -#endif -#endif -} - -#ifdef BUS_SPACE_NO_LEGACY -#undef inb -#undef outb -#define inb(a) compiler_error -#define inw(a) compiler_error -#define inl(a) compiler_error -#define outb(a, b) compiler_error -#define outw(a, b) compiler_error -#define outl(a, b) compiler_error -#endif - +DECLARE_BUS_SPACE_PROTOTYPES(generic); +extern struct bus_space mips_bus_space_generic; #include -/* - * Stream accesses are the same as normal accesses on amd64; there are no - * supported bus systems with an endianess different from the host one. - */ -#define bus_space_read_stream_1(t, h, o) bus_space_read_1((t), (h), (o)) -#define bus_space_read_stream_2(t, h, o) bus_space_read_2((t), (h), (o)) -#define bus_space_read_stream_4(t, h, o) bus_space_read_4((t), (h), (o)) - -#define bus_space_read_multi_stream_1(t, h, o, a, c) \ - bus_space_read_multi_1((t), (h), (o), (a), (c)) -#define bus_space_read_multi_stream_2(t, h, o, a, c) \ - bus_space_read_multi_2((t), (h), (o), (a), (c)) -#define bus_space_read_multi_stream_4(t, h, o, a, c) \ - bus_space_read_multi_4((t), (h), (o), (a), (c)) - -#define bus_space_write_stream_1(t, h, o, v) \ - bus_space_write_1((t), (h), (o), (v)) -#define bus_space_write_stream_2(t, h, o, v) \ - bus_space_write_2((t), (h), (o), (v)) -#define bus_space_write_stream_4(t, h, o, v) \ - bus_space_write_4((t), (h), (o), (v)) - -#define bus_space_write_multi_stream_1(t, h, o, a, c) \ - bus_space_write_multi_1((t), (h), (o), (a), (c)) -#define bus_space_write_multi_stream_2(t, h, o, a, c) \ - bus_space_write_multi_2((t), (h), (o), (a), (c)) -#define bus_space_write_multi_stream_4(t, h, o, a, c) \ - bus_space_write_multi_4((t), (h), (o), (a), (c)) - -#define bus_space_set_multi_stream_1(t, h, o, v, c) \ - bus_space_set_multi_1((t), (h), (o), (v), (c)) -#define bus_space_set_multi_stream_2(t, h, o, v, c) \ - bus_space_set_multi_2((t), (h), (o), (v), (c)) -#define bus_space_set_multi_stream_4(t, h, o, v, c) \ - bus_space_set_multi_4((t), (h), (o), (v), (c)) - -#define bus_space_read_region_stream_1(t, h, o, a, c) \ - bus_space_read_region_1((t), (h), (o), (a), (c)) -#define bus_space_read_region_stream_2(t, h, o, a, c) \ - bus_space_read_region_2((t), (h), (o), (a), (c)) -#define bus_space_read_region_stream_4(t, h, o, a, c) \ - bus_space_read_region_4((t), (h), (o), (a), (c)) - -#define bus_space_write_region_stream_1(t, h, o, a, c) \ - bus_space_write_region_1((t), (h), (o), (a), (c)) -#define bus_space_write_region_stream_2(t, h, o, a, c) \ - bus_space_write_region_2((t), (h), (o), (a), (c)) -#define bus_space_write_region_stream_4(t, h, o, a, c) \ - bus_space_write_region_4((t), (h), (o), (a), (c)) - -#define bus_space_set_region_stream_1(t, h, o, v, c) \ - bus_space_set_region_1((t), (h), (o), (v), (c)) -#define bus_space_set_region_stream_2(t, h, o, v, c) \ - bus_space_set_region_2((t), (h), (o), (v), (c)) -#define bus_space_set_region_stream_4(t, h, o, v, c) \ - bus_space_set_region_4((t), (h), (o), (v), (c)) - -#define bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \ - bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c)) -#define bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \ - bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c)) -#define bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \ - bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c)) - -#endif /* !TARGET_OCTEON */ -#endif /* !_MACHINE_BUS_H_ */ +#endif /* _MACHINE_BUS_H_ */ diff --git a/sys/mips/malta/gt_pci.c b/sys/mips/malta/gt_pci.c index e8f7ffd96a9..61e39b847d3 100644 --- a/sys/mips/malta/gt_pci.c +++ b/sys/mips/malta/gt_pci.c @@ -94,8 +94,6 @@ __FBSDID("$FreeBSD$"); struct gt_pci_softc { device_t sc_dev; bus_space_tag_t sc_st; - bus_space_tag_t sc_pciio; - bus_space_tag_t sc_pcimem; bus_space_handle_t sc_ioh_icu1; bus_space_handle_t sc_ioh_icu2; bus_space_handle_t sc_ioh_elcr; @@ -126,14 +124,14 @@ gt_pci_set_icus(struct gt_pci_softc *sc) else sc->sc_imask |= (1U << 2); - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, PIC_OCW1, + bus_space_write_1(sc->sc_st, sc->sc_ioh_icu1, PIC_OCW1, sc->sc_imask & 0xff); - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, PIC_OCW1, + bus_space_write_1(sc->sc_st, sc->sc_ioh_icu2, PIC_OCW1, (sc->sc_imask >> 8) & 0xff); - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_elcr, 0, + bus_space_write_1(sc->sc_st, sc->sc_ioh_elcr, 0, sc->sc_elcr & 0xff); - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_elcr, 1, + bus_space_write_1(sc->sc_st, sc->sc_ioh_elcr, 1, (sc->sc_elcr >> 8) & 0xff); } @@ -145,9 +143,9 @@ gt_pci_intr(void *v) int irq; for (;;) { - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, PIC_OCW3, + bus_space_write_1(sc->sc_st, sc->sc_ioh_icu1, PIC_OCW3, OCW3_SEL | OCW3_P); - irq = bus_space_read_1(sc->sc_pciio, sc->sc_ioh_icu1, PIC_OCW3); + irq = bus_space_read_1(sc->sc_st, sc->sc_ioh_icu1, PIC_OCW3); if ((irq & OCW3_POLL_PENDING) == 0) { return FILTER_HANDLED; @@ -156,9 +154,9 @@ gt_pci_intr(void *v) irq = OCW3_POLL_IRQ(irq); if (irq == 2) { - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, + bus_space_write_1(sc->sc_st, sc->sc_ioh_icu2, PIC_OCW3, OCW3_SEL | OCW3_P); - irq = bus_space_read_1(sc->sc_pciio, sc->sc_ioh_icu2, + irq = bus_space_read_1(sc->sc_st, sc->sc_ioh_icu2, PIC_OCW3); if (irq & OCW3_POLL_PENDING) irq = OCW3_POLL_IRQ(irq) + 8; @@ -177,13 +175,13 @@ gt_pci_intr(void *v) /* Send a specific EOI to the 8259. */ if (irq > 7) { - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, + bus_space_write_1(sc->sc_st, sc->sc_ioh_icu2, PIC_OCW2, OCW2_SELECT | OCW2_EOI | OCW2_SL | OCW2_ILS(irq & 7)); irq = 2; } - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, PIC_OCW2, + bus_space_write_1(sc->sc_st, sc->sc_ioh_icu1, PIC_OCW2, OCW2_SELECT | OCW2_EOI | OCW2_SL | OCW2_ILS(irq)); } @@ -208,8 +206,7 @@ gt_pci_attach(device_t dev) busno = 0; sc->sc_dev = dev; sc->sc_busno = busno; - sc->sc_pciio = MIPS_BUS_SPACE_IO; - sc->sc_pcimem = MIPS_BUS_SPACE_MEM; + sc->sc_st = &mips_bus_space_generic; /* Use KSEG1 to access IO ports for it is uncached */ sc->sc_io = MIPS_PHYS_TO_KSEG1(MALTA_PCI0_IO_BASE); @@ -239,11 +236,11 @@ gt_pci_attach(device_t dev) * Map the PIC/ELCR registers. */ #if 0 - if (bus_space_map(sc->sc_pciio, 0x4d0, 2, 0, &sc->sc_ioh_elcr) != 0) + if (bus_space_map(sc->sc_st, 0x4d0, 2, 0, &sc->sc_ioh_elcr) != 0) device_printf(dev, "unable to map ELCR registers\n"); - if (bus_space_map(sc->sc_pciio, IO_ICU1, 2, 0, &sc->sc_ioh_icu1) != 0) + if (bus_space_map(sc->sc_st, IO_ICU1, 2, 0, &sc->sc_ioh_icu1) != 0) device_printf(dev, "unable to map ICU1 registers\n"); - if (bus_space_map(sc->sc_pciio, IO_ICU2, 2, 0, &sc->sc_ioh_icu2) != 0) + if (bus_space_map(sc->sc_st, IO_ICU2, 2, 0, &sc->sc_ioh_icu2) != 0) device_printf(dev, "unable to map ICU2 registers\n"); #else sc->sc_ioh_elcr = sc->sc_io + 0x4d0; @@ -262,58 +259,58 @@ gt_pci_attach(device_t dev) * Initialize the 8259s. */ /* reset, program device, 4 bytes */ - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 0, + bus_space_write_1(sc->sc_st, sc->sc_ioh_icu1, 0, ICW1_RESET | ICW1_IC4); /* * XXX: values from NetBSD's */ - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 1, + bus_space_write_1(sc->sc_st, sc->sc_ioh_icu1, 1, 0/*XXX*/); - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 1, + bus_space_write_1(sc->sc_st, sc->sc_ioh_icu1, 1, 1 << 2); - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 1, + bus_space_write_1(sc->sc_st, sc->sc_ioh_icu1, 1, ICW4_8086); /* mask all interrupts */ - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 0, + bus_space_write_1(sc->sc_st, sc->sc_ioh_icu1, 0, sc->sc_imask & 0xff); /* enable special mask mode */ - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 1, + bus_space_write_1(sc->sc_st, sc->sc_ioh_icu1, 1, OCW3_SEL | OCW3_ESMM | OCW3_SMM); /* read IRR by default */ - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 1, + bus_space_write_1(sc->sc_st, sc->sc_ioh_icu1, 1, OCW3_SEL | OCW3_RR); /* reset, program device, 4 bytes */ - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, 0, + bus_space_write_1(sc->sc_st, sc->sc_ioh_icu2, 0, ICW1_RESET | ICW1_IC4); - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, 1, + bus_space_write_1(sc->sc_st, sc->sc_ioh_icu2, 1, 0/*XXX*/); - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, 1, + bus_space_write_1(sc->sc_st, sc->sc_ioh_icu2, 1, 1 << 2); - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, 1, + bus_space_write_1(sc->sc_st, sc->sc_ioh_icu2, 1, ICW4_8086); /* mask all interrupts */ - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, 0, + bus_space_write_1(sc->sc_st, sc->sc_ioh_icu2, 0, sc->sc_imask & 0xff); /* enable special mask mode */ - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, 1, + bus_space_write_1(sc->sc_st, sc->sc_ioh_icu2, 1, OCW3_SEL | OCW3_ESMM | OCW3_SMM); /* read IRR by default */ - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, 1, + bus_space_write_1(sc->sc_st, sc->sc_ioh_icu2, 1, OCW3_SEL | OCW3_RR); /* * Default all interrupts to edge-triggered. */ - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_elcr, 0, + bus_space_write_1(sc->sc_st, sc->sc_ioh_elcr, 0, sc->sc_elcr & 0xff); - bus_space_write_1(sc->sc_pciio, sc->sc_ioh_elcr, 1, + bus_space_write_1(sc->sc_st, sc->sc_ioh_elcr, 1, (sc->sc_elcr >> 8) & 0xff); /* @@ -570,12 +567,12 @@ gt_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, break; case SYS_RES_MEMORY: rm = &sc->sc_mem_rman; - bt = sc->sc_pcimem; + bt = sc->sc_st; bh = sc->sc_mem; break; case SYS_RES_IOPORT: rm = &sc->sc_io_rman; - bt = sc->sc_pciio; + bt = sc->sc_st; bh = sc->sc_io; break; default: diff --git a/sys/mips/malta/obio.c b/sys/mips/malta/obio.c index ae486edc97c..1f000809647 100644 --- a/sys/mips/malta/obio.c +++ b/sys/mips/malta/obio.c @@ -84,7 +84,7 @@ obio_attach(device_t dev) { struct obio_softc *sc = device_get_softc(dev); - sc->oba_st = MIPS_BUS_SPACE_IO; + sc->oba_st = &mips_bus_space_generic; sc->oba_addr = MIPS_PHYS_TO_KSEG1(MALTA_UART0ADR); sc->oba_size = MALTA_PCIMEM3_SIZE; sc->oba_rman.rm_type = RMAN_ARRAY; diff --git a/sys/mips/malta/uart_bus_maltausart.c b/sys/mips/malta/uart_bus_maltausart.c index da266a8d54f..57f8ce389c7 100644 --- a/sys/mips/malta/uart_bus_maltausart.c +++ b/sys/mips/malta/uart_bus_maltausart.c @@ -88,9 +88,9 @@ uart_malta_probe(device_t dev) sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); sc->sc_class = &uart_ns8250_class; bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); - sc->sc_sysdev->bas.bst = 0; + sc->sc_sysdev->bas.bst = &mips_bus_space_generic; sc->sc_sysdev->bas.bsh = MIPS_PHYS_TO_KSEG1(MALTA_UART0ADR); - sc->sc_bas.bst = 0; + sc->sc_bas.bst = &mips_bus_space_generic; sc->sc_bas.bsh = MIPS_PHYS_TO_KSEG1(MALTA_UART0ADR); return(uart_bus_probe(dev, 0, 0, 0, 0)); } diff --git a/sys/mips/malta/uart_cpu_maltausart.c b/sys/mips/malta/uart_cpu_maltausart.c index 758d9a7fedb..d25ce5cc954 100644 --- a/sys/mips/malta/uart_cpu_maltausart.c +++ b/sys/mips/malta/uart_cpu_maltausart.c @@ -67,7 +67,8 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) { di->ops = uart_getops(&uart_ns8250_class); di->bas.chan = 0; - di->bas.bst = 0; + di->bas.bst = &mips_bus_space_generic; + di->bas.bsh = MIPS_PHYS_TO_KSEG1(MALTA_UART0ADR); di->bas.regshft = 0; di->bas.rclk = 0; di->baudrate = 115200; @@ -75,8 +76,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) di->stopbits = 1; di->parity = UART_PARITY_NONE; - uart_bus_space_io = MIPS_PHYS_TO_KSEG1(MALTA_UART0ADR); - uart_bus_space_mem = MIPS_PHYS_TO_KSEG1(MALTA_UART0ADR); - di->bas.bsh = MIPS_PHYS_TO_KSEG1(MALTA_UART0ADR); + uart_bus_space_io = NULL; + uart_bus_space_mem = &mips_bus_space_generic; return (0); } diff --git a/sys/mips/mips/bus_space_generic.c b/sys/mips/mips/bus_space_generic.c new file mode 100644 index 00000000000..981cc526963 --- /dev/null +++ b/sys/mips/mips/bus_space_generic.c @@ -0,0 +1,570 @@ +/* $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $ */ +/*- + * $Id: bus.h,v 1.6 2007/08/09 11:23:32 katta Exp $ + * + * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 1996 Charles M. Hannum. All rights reserved. + * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Christopher G. Demetriou + * for the NetBSD Project. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * from: src/sys/alpha/include/bus.h,v 1.5 1999/08/28 00:38:40 peter + * $FreeBSD$ + */ +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +struct bus_space mips_bus_space_generic = { + /* cookie */ + (void *) 0, + + /* mapping/unmapping */ + generic_bs_map, + generic_bs_unmap, + generic_bs_subregion, + + /* allocation/deallocation */ + NULL, + NULL, + + /* barrier */ + generic_bs_barrier, + + /* read (single) */ + generic_bs_r_1, + generic_bs_r_2, + generic_bs_r_4, + NULL, + + /* read multiple */ + generic_bs_rm_1, + generic_bs_rm_2, + generic_bs_rm_4, + NULL, + + /* read region */ + generic_bs_rr_1, + generic_bs_rr_2, + generic_bs_rr_4, + NULL, + + /* write (single) */ + generic_bs_w_1, + generic_bs_w_2, + generic_bs_w_4, + NULL, + + /* write multiple */ + generic_bs_wm_1, + generic_bs_wm_2, + generic_bs_wm_4, + NULL, + + /* write region */ + NULL, + generic_bs_wr_2, + generic_bs_wr_4, + NULL, + + /* set multiple */ + NULL, + NULL, + NULL, + NULL, + + /* set region */ + NULL, + generic_bs_sr_2, + generic_bs_sr_4, + NULL, + + /* copy */ + NULL, + generic_bs_c_2, + NULL, + NULL, + + /* read (single) stream */ + generic_bs_r_1, + generic_bs_r_2, + generic_bs_r_4, + NULL, + + /* read multiple stream */ + generic_bs_rm_1, + generic_bs_rm_2, + generic_bs_rm_4, + NULL, + + /* read region stream */ + generic_bs_rr_1, + generic_bs_rr_2, + generic_bs_rr_4, + NULL, + + /* write (single) stream */ + generic_bs_w_1, + generic_bs_w_2, + generic_bs_w_4, + NULL, + + /* write multiple stream */ + generic_bs_wm_1, + generic_bs_wm_2, + generic_bs_wm_4, + NULL, + + /* write region stream */ + NULL, + generic_bs_wr_2, + generic_bs_wr_4, + NULL, +}; + + + +int +generic_bs_map(void *t __unused, bus_addr_t addr, + bus_size_t size __unused, int flags __unused, + bus_space_handle_t *bshp) +{ + + *bshp = addr; + return (0); +} + +void +generic_bs_unmap(void *t __unused, bus_space_handle_t bh __unused, + bus_size_t size __unused) +{ + + /* Do nothing */ +} + +int +generic_bs_subregion(void *t __unused, bus_space_handle_t handle __unused, + bus_size_t offset __unused, bus_size_t size __unused, + bus_space_handle_t *nhandle __unused) +{ + + printf("SUBREGION?!?!?!\n"); + /* Do nothing */ + return (0); +} + +u_int8_t +generic_bs_r_1(void *t, bus_space_handle_t handle, + bus_size_t offset) +{ + + return (readb(handle + offset)); +} + +u_int16_t +generic_bs_r_2(void *t, bus_space_handle_t handle, + bus_size_t offset) +{ + + return (readw(handle + offset)); +} + +u_int32_t +generic_bs_r_4(void *t, bus_space_handle_t handle, + bus_size_t offset) +{ + + return (readl(handle + offset)); +} + + +void +generic_bs_rm_1(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int8_t *addr, size_t count) +{ + + while (count--) + *addr++ = readb(bsh + offset); +} + +void +generic_bs_rm_2(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int16_t *addr, size_t count) +{ + bus_addr_t baddr = bsh + offset; + + while (count--) + *addr++ = readw(baddr); +} + +void +generic_bs_rm_4(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int32_t *addr, size_t count) +{ + bus_addr_t baddr = bsh + offset; + + while (count--) + *addr++ = readl(baddr); +} + + +/* + * Read `count' 1, 2, 4, or 8 byte quantities from bus space + * described by tag/handle and starting at `offset' and copy into + * buffer provided. + */ +void +generic_bs_rr_1(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int8_t *addr, size_t count) +{ + bus_addr_t baddr = bsh + offset; + + while (count--) { + *addr++ = readb(baddr); + baddr += 1; + } +} + +void +generic_bs_rr_2(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int16_t *addr, size_t count) +{ + bus_addr_t baddr = bsh + offset; + + while (count--) { + *addr++ = readw(baddr); + baddr += 2; + } +} + +void +generic_bs_rr_4(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int32_t *addr, size_t count) +{ + bus_addr_t baddr = bsh + offset; + + while (count--) { + *addr++ = readl(baddr); + baddr += 4; + } +} + +/* + * Write the 1, 2, 4, or 8 byte value `value' to bus space + * described by tag/handle/offset. + */ +void +generic_bs_w_1(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int8_t value) +{ + + writeb(bsh + offset, value); +} + +void +generic_bs_w_2(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int16_t value) +{ + + writew(bsh + offset, value); +} + +void +generic_bs_w_4(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int32_t value) +{ + + writel(bsh + offset, value); +} + +/* + * Write `count' 1, 2, 4, or 8 byte quantities from the buffer + * provided to bus space described by tag/handle/offset. + */ +void +generic_bs_wm_1(void *t, bus_space_handle_t bsh, + bus_size_t offset, const u_int8_t *addr, size_t count) +{ + bus_addr_t baddr = bsh + offset; + + while (count--) + writeb(baddr, *addr++); +} + +void +generic_bs_wm_2(void *t, bus_space_handle_t bsh, + bus_size_t offset, const u_int16_t *addr, size_t count) +{ + bus_addr_t baddr = bsh + offset; + + while (count--) + writew(baddr, *addr++); +} + +void +generic_bs_wm_4(void *t, bus_space_handle_t bsh, + bus_size_t offset, const u_int32_t *addr, size_t count) +{ + bus_addr_t baddr = bsh + offset; + + while (count--) + writel(baddr, *addr++); +} + +/* + * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided + * to bus space described by tag/handle starting at `offset'. + */ +void +generic_bs_wr_1(void *t, bus_space_handle_t bsh, + bus_size_t offset, const u_int8_t *addr, size_t count) +{ + bus_addr_t baddr = bsh + offset; + + while (count--) { + writeb(baddr, *addr++); + baddr += 1; + } +} + +void +generic_bs_wr_2(void *t, bus_space_handle_t bsh, + bus_size_t offset, const u_int16_t *addr, size_t count) +{ + bus_addr_t baddr = bsh + offset; + + while (count--) { + writew(baddr, *addr++); + baddr += 2; + } +} + +void +generic_bs_wr_4(void *t, bus_space_handle_t bsh, + bus_size_t offset, const u_int32_t *addr, size_t count) +{ + bus_addr_t baddr = bsh + offset; + + while (count--) { + writel(baddr, *addr++); + baddr += 4; + } +} + +/* + * Write the 1, 2, 4, or 8 byte value `val' to bus space described + * by tag/handle/offset `count' times. + */ +void +generic_bs_sm_1(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int8_t value, size_t count) +{ + bus_addr_t addr = bsh + offset; + + while (count--) + writeb(addr, value); +} + +void +generic_bs_sm_2(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int16_t value, size_t count) +{ + bus_addr_t addr = bsh + offset; + + while (count--) + writew(addr, value); +} + +void +generic_bs_sm_4(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int32_t value, size_t count) +{ + bus_addr_t addr = bsh + offset; + + while (count--) + writel(addr, value); +} + +/* + * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described + * by tag/handle starting at `offset'. + */ +void +generic_bs_sr_1(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int8_t value, size_t count) +{ + bus_addr_t addr = bsh + offset; + + for (; count != 0; count--, addr++) + writeb(addr, value); +} + +void +generic_bs_sr_2(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int16_t value, size_t count) +{ + bus_addr_t addr = bsh + offset; + + for (; count != 0; count--, addr += 2) + writew(addr, value); +} + +void +generic_bs_sr_4(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int32_t value, size_t count) +{ + bus_addr_t addr = bsh + offset; + + for (; count != 0; count--, addr += 4) + writel(addr, value); +} + +/* + * Copy `count' 1, 2, 4, or 8 byte values from bus space starting + * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. + */ +void +generic_bs_c_1(void *t, bus_space_handle_t bsh1, + bus_size_t off1, bus_space_handle_t bsh2, + bus_size_t off2, size_t count) +{ + bus_addr_t addr1 = bsh1 + off1; + bus_addr_t addr2 = bsh2 + off2; + + if (addr1 >= addr2) { + /* src after dest: copy forward */ + for (; count != 0; count--, addr1++, addr2++) + writeb(addr2, readb(addr1)); + } else { + /* dest after src: copy backwards */ + for (addr1 += (count - 1), addr2 += (count - 1); + count != 0; count--, addr1--, addr2--) + writeb(addr2, readb(addr1)); + } +} + +void +generic_bs_c_2(void *t, bus_space_handle_t bsh1, + bus_size_t off1, bus_space_handle_t bsh2, + bus_size_t off2, size_t count) +{ + bus_addr_t addr1 = bsh1 + off1; + bus_addr_t addr2 = bsh2 + off2; + + if (addr1 >= addr2) { + /* src after dest: copy forward */ + for (; count != 0; count--, addr1 += 2, addr2 += 2) + writew(addr2, readw(addr1)); + } else { + /* dest after src: copy backwards */ + for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1); + count != 0; count--, addr1 -= 2, addr2 -= 2) + writew(addr2, readw(addr1)); + } +} + +void +generic_bs_c_4(void *t, bus_space_handle_t bsh1, + bus_size_t off1, bus_space_handle_t bsh2, + bus_size_t off2, size_t count) +{ + bus_addr_t addr1 = bsh1 + off1; + bus_addr_t addr2 = bsh2 + off2; + + if (addr1 >= addr2) { + /* src after dest: copy forward */ + for (; count != 0; count--, addr1 += 4, addr2 += 4) + writel(addr2, readl(addr1)); + } else { + /* dest after src: copy backwards */ + for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1); + count != 0; count--, addr1 -= 4, addr2 -= 4) + writel(addr2, readl(addr1)); + } +} + +void +generic_bs_barrier(void *t __unused, + bus_space_handle_t bsh __unused, + bus_size_t offset __unused, bus_size_t len __unused, + int flags) +{ +#if 0 + if (flags & BUS_SPACE_BARRIER_WRITE) + mips_dcache_wbinv_all(); +#endif +} From 11683f58dec898d2f09c1126076a43efe308a9e1 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 15 Apr 2009 02:41:35 +0000 Subject: [PATCH 035/380] - mainbus.c seems not to be used, disconnect it from build --- sys/conf/files.mips | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/conf/files.mips b/sys/conf/files.mips index 3ee1cc69c32..aa8fef37d03 100644 --- a/sys/conf/files.mips +++ b/sys/conf/files.mips @@ -38,7 +38,7 @@ mips/mips/cpu.c standard mips/mips/elf_machdep.c standard mips/mips/exception.S standard mips/mips/gdb_machdep.c standard -mips/mips/mainbus.c standard +# mips/mips/mainbus.c standard mips/mips/pmap.c standard mips/mips/trap.c standard mips/mips/vm_machdep.c standard From cbc6cfe0ed34c58c8a13cc18535eeca5a651aeac Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 15 Apr 2009 03:04:33 +0000 Subject: [PATCH 036/380] - Port AR71XX OHCI controller to new USB stack --- sys/mips/atheros/ar71xx_ohci.c | 110 +++++++++++---------------------- 1 file changed, 35 insertions(+), 75 deletions(-) diff --git a/sys/mips/atheros/ar71xx_ohci.c b/sys/mips/atheros/ar71xx_ohci.c index b7adc617b9c..491f13012fe 100644 --- a/sys/mips/atheros/ar71xx_ohci.c +++ b/sys/mips/atheros/ar71xx_ohci.c @@ -28,25 +28,19 @@ #include __FBSDID("$FreeBSD$"); -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - +#include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include + +#include +#include +#include + +#include static int ar71xx_ohci_attach(device_t dev); static int ar71xx_ohci_detach(device_t dev); @@ -72,19 +66,20 @@ ar71xx_ohci_attach(device_t dev) int rid; rid = 0; - sc->sc_ohci.io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + sc->sc_ohci.sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); - if (sc->sc_ohci.io_res == NULL) { + if (sc->sc_ohci.sc_io_res == NULL) { err = ENOMEM; goto error; } - sc->sc_ohci.iot = rman_get_bustag(sc->sc_ohci.io_res); - sc->sc_ohci.ioh = rman_get_bushandle(sc->sc_ohci.io_res); + sc->sc_ohci.sc_io_tag = rman_get_bustag(sc->sc_ohci.sc_io_res); + sc->sc_ohci.sc_io_hdl = rman_get_bushandle(sc->sc_ohci.sc_io_res); + sc->sc_ohci.sc_io_size = rman_get_size(sc->sc_ohci.sc_io_res); rid = 0; - sc->sc_ohci.irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + sc->sc_ohci.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); - if (sc->sc_ohci.irq_res == NULL) { + if (sc->sc_ohci.sc_irq_res == NULL) { err = ENOMEM; goto error; } @@ -95,44 +90,20 @@ ar71xx_ohci_attach(device_t dev) } device_set_ivars(sc->sc_ohci.sc_bus.bdev, &sc->sc_ohci.sc_bus); - /* Allocate a parent dma tag for DMA maps */ - err = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0, - BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, - BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0, - NULL, NULL, &sc->sc_ohci.sc_bus.parent_dmatag); - if (err) { - device_printf(dev, "Could not allocate parent DMA tag (%d)\n", - err); - err = ENXIO; - goto error; - } - - /* Allocate a dma tag for transfer buffers */ - err = bus_dma_tag_create(sc->sc_ohci.sc_bus.parent_dmatag, 1, 0, - BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, - BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0, - busdma_lock_mutex, &Giant, &sc->sc_ohci.sc_bus.buffer_dmatag); - if (err) { - device_printf(dev, "Could not allocate transfer tag (%d)\n", - err); - err = ENXIO; - goto error; - } - - err = bus_setup_intr(dev, sc->sc_ohci.irq_res, INTR_TYPE_BIO, NULL, - ohci_intr, sc, &sc->sc_ohci.ih); + err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res, + INTR_TYPE_BIO | INTR_MPSAFE, NULL, + (driver_intr_t *)ohci_interrupt, sc, &sc->sc_ohci.sc_intr_hdl); if (err) { err = ENXIO; goto error; } - strlcpy(sc->sc_ohci.sc_vendor, "Atheros", - sizeof(sc->sc_ohci.sc_vendor)); - bus_space_write_4(sc->sc_ohci.iot, sc->sc_ohci.ioh, OHCI_CONTROL, 0); + strlcpy(sc->sc_ohci.sc_vendor, "Atheros", sizeof(sc->sc_ohci.sc_vendor)); + + bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl, OHCI_CONTROL, 0); err = ohci_init(&sc->sc_ohci); if (!err) { - sc->sc_ohci.sc_flags |= OHCI_SCFLG_DONEINIT; err = device_probe_and_attach(sc->sc_ohci.sc_bus.bdev); } @@ -149,34 +120,23 @@ ar71xx_ohci_detach(device_t dev) { struct ar71xx_ohci_softc *sc = device_get_softc(dev); - if (sc->sc_ohci.sc_flags & OHCI_SCFLG_DONEINIT) { - ohci_detach(&sc->sc_ohci, 0); - sc->sc_ohci.sc_flags &= ~OHCI_SCFLG_DONEINIT; + if (sc->sc_ohci.sc_intr_hdl) { + bus_teardown_intr(dev, sc->sc_ohci.sc_irq_res, sc->sc_ohci.sc_intr_hdl); + sc->sc_ohci.sc_intr_hdl = NULL; } - - if (sc->sc_ohci.ih) { - bus_teardown_intr(dev, sc->sc_ohci.irq_res, sc->sc_ohci.ih); - sc->sc_ohci.ih = NULL; - } - - if (sc->sc_ohci.sc_bus.parent_dmatag != NULL) - bus_dma_tag_destroy(sc->sc_ohci.sc_bus.parent_dmatag); - if (sc->sc_ohci.sc_bus.buffer_dmatag != NULL) - bus_dma_tag_destroy(sc->sc_ohci.sc_bus.buffer_dmatag); - if (sc->sc_ohci.sc_bus.bdev) { device_delete_child(dev, sc->sc_ohci.sc_bus.bdev); sc->sc_ohci.sc_bus.bdev = NULL; } - if (sc->sc_ohci.irq_res) { - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_ohci.irq_res); - sc->sc_ohci.irq_res = NULL; + if (sc->sc_ohci.sc_irq_res) { + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_ohci.sc_irq_res); + sc->sc_ohci.sc_irq_res = NULL; } - if (sc->sc_ohci.io_res) { - bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_ohci.io_res); - sc->sc_ohci.io_res = NULL; - sc->sc_ohci.iot = 0; - sc->sc_ohci.ioh = 0; + if (sc->sc_ohci.sc_io_res) { + bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_ohci.sc_io_res); + sc->sc_ohci.sc_io_res = NULL; + sc->sc_ohci.sc_io_tag = 0; + sc->sc_ohci.sc_io_hdl = 0; } return (0); } From cf6e3ada3543c40ba0c673ef91fdb4dbecf9d121 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 15 Apr 2009 05:37:17 +0000 Subject: [PATCH 037/380] Fix USB2 quick'n'dirty porting, now system successfully detects OHCI --- sys/mips/atheros/ar71xx_ohci.c | 57 +++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/sys/mips/atheros/ar71xx_ohci.c b/sys/mips/atheros/ar71xx_ohci.c index 491f13012fe..f13279d3ef4 100644 --- a/sys/mips/atheros/ar71xx_ohci.c +++ b/sys/mips/atheros/ar71xx_ohci.c @@ -65,6 +65,19 @@ ar71xx_ohci_attach(device_t dev) int err; int rid; + /* initialise some bus fields */ + sc->sc_ohci.sc_bus.parent = dev; + sc->sc_ohci.sc_bus.devices = sc->sc_ohci.sc_devices; + sc->sc_ohci.sc_bus.devices_max = OHCI_MAX_DEVICES; + + /* get all DMA memory */ + if (usb2_bus_mem_alloc_all(&sc->sc_ohci.sc_bus, + USB_GET_DMA_TAG(dev), &ohci_iterate_hw_softc)) { + return (ENOMEM); + } + + sc->sc_ohci.sc_dev = dev; + rid = 0; sc->sc_ohci.sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); @@ -83,7 +96,7 @@ ar71xx_ohci_attach(device_t dev) err = ENOMEM; goto error; } - sc->sc_ohci.sc_bus.bdev = device_add_child(dev, "usb", -1); + sc->sc_ohci.sc_bus.bdev = device_add_child(dev, "usbus", -1); if (sc->sc_ohci.sc_bus.bdev == NULL) { err = ENOMEM; goto error; @@ -103,9 +116,12 @@ ar71xx_ohci_attach(device_t dev) bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl, OHCI_CONTROL, 0); err = ohci_init(&sc->sc_ohci); - if (!err) { + if (!err) err = device_probe_and_attach(sc->sc_ohci.sc_bus.bdev); - } + + if (err) + goto error; + return (0); error: if (err) { @@ -119,16 +135,39 @@ static int ar71xx_ohci_detach(device_t dev) { struct ar71xx_ohci_softc *sc = device_get_softc(dev); + device_t bdev; + + if (sc->sc_ohci.sc_bus.bdev) { + bdev = sc->sc_ohci.sc_bus.bdev; + device_detach(bdev); + device_delete_child(dev, bdev); + } + /* during module unload there are lots of children leftover */ + device_delete_all_children(dev); + + /* + * Put the controller into reset, then disable clocks and do + * the MI tear down. We have to disable the clocks/hardware + * after we do the rest of the teardown. We also disable the + * clocks in the opposite order we acquire them, but that + * doesn't seem to be absolutely necessary. We free up the + * clocks after we disable them, so the system could, in + * theory, reuse them. + */ + bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl, + OHCI_CONTROL, 0); if (sc->sc_ohci.sc_intr_hdl) { bus_teardown_intr(dev, sc->sc_ohci.sc_irq_res, sc->sc_ohci.sc_intr_hdl); sc->sc_ohci.sc_intr_hdl = NULL; } - if (sc->sc_ohci.sc_bus.bdev) { - device_delete_child(dev, sc->sc_ohci.sc_bus.bdev); - sc->sc_ohci.sc_bus.bdev = NULL; - } - if (sc->sc_ohci.sc_irq_res) { + + if (sc->sc_ohci.sc_irq_res && sc->sc_ohci.sc_intr_hdl) { + /* + * only call ohci_detach() after ohci_init() + */ + ohci_detach(&sc->sc_ohci); + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_ohci.sc_irq_res); sc->sc_ohci.sc_irq_res = NULL; } @@ -138,6 +177,8 @@ ar71xx_ohci_detach(device_t dev) sc->sc_ohci.sc_io_tag = 0; sc->sc_ohci.sc_io_hdl = 0; } + usb2_bus_mem_free_all(&sc->sc_ohci.sc_bus, &ohci_iterate_hw_softc); + return (0); } From 50b3024887105ffacd3bf3b99d78121b9edb314b Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sun, 19 Apr 2009 22:02:14 +0000 Subject: [PATCH 038/380] - Make mips_bus_space_generic be of type bus_space_tag_t instead of struct bus_space and update all relevant places. --- sys/mips/adm5120/obio.c | 2 +- sys/mips/adm5120/uart_cpu_adm5120.c | 4 ++-- sys/mips/alchemy/obio.c | 2 +- sys/mips/alchemy/uart_cpu_alchemy.c | 4 ++-- sys/mips/idt/uart_bus_rc32434.c | 4 ++-- sys/mips/idt/uart_cpu_rc32434.c | 4 ++-- sys/mips/include/bus.h | 2 +- sys/mips/malta/gt_pci.c | 2 +- sys/mips/malta/obio.c | 2 +- sys/mips/malta/uart_bus_maltausart.c | 4 ++-- sys/mips/malta/uart_cpu_maltausart.c | 4 ++-- sys/mips/mips/bus_space_generic.c | 5 +++-- sys/mips/sentry5/obio.c | 4 +--- sys/mips/sentry5/uart_bus_sbusart.c | 4 ++-- sys/mips/sentry5/uart_cpu_sbusart.c | 2 +- 15 files changed, 24 insertions(+), 25 deletions(-) diff --git a/sys/mips/adm5120/obio.c b/sys/mips/adm5120/obio.c index 7e61ff5de75..8d8392834b2 100644 --- a/sys/mips/adm5120/obio.c +++ b/sys/mips/adm5120/obio.c @@ -269,7 +269,7 @@ obio_activate_resource(device_t bus, device_t child, int type, int rid, vaddr = (void *)MIPS_PHYS_TO_KSEG1((intptr_t)rman_get_start(r)); rman_set_virtual(r, vaddr); - rman_set_bustag(r, &mips_bus_space_generic); + rman_set_bustag(r, mips_bus_space_generic); rman_set_bushandle(r, (bus_space_handle_t)vaddr); } diff --git a/sys/mips/adm5120/uart_cpu_adm5120.c b/sys/mips/adm5120/uart_cpu_adm5120.c index 0828ea56bb2..935d109fe16 100644 --- a/sys/mips/adm5120/uart_cpu_adm5120.c +++ b/sys/mips/adm5120/uart_cpu_adm5120.c @@ -67,7 +67,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) di->ops = uart_getops(&uart_adm5120_uart_class); di->bas.chan = 0; - di->bas.bst = &mips_bus_space_generic; + di->bas.bst = mips_bus_space_generic; di->bas.regshft = 0; di->bas.rclk = 0; di->baudrate = 115200; @@ -76,7 +76,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) di->parity = UART_PARITY_NONE; uart_bus_space_io = 0; - uart_bus_space_mem = &mips_bus_space_generic; + uart_bus_space_mem = mips_bus_space_generic; di->bas.bsh = MIPS_PHYS_TO_KSEG1(ADM5120_BASE_UART0); return (0); diff --git a/sys/mips/alchemy/obio.c b/sys/mips/alchemy/obio.c index 7e61ff5de75..8d8392834b2 100644 --- a/sys/mips/alchemy/obio.c +++ b/sys/mips/alchemy/obio.c @@ -269,7 +269,7 @@ obio_activate_resource(device_t bus, device_t child, int type, int rid, vaddr = (void *)MIPS_PHYS_TO_KSEG1((intptr_t)rman_get_start(r)); rman_set_virtual(r, vaddr); - rman_set_bustag(r, &mips_bus_space_generic); + rman_set_bustag(r, mips_bus_space_generic); rman_set_bushandle(r, (bus_space_handle_t)vaddr); } diff --git a/sys/mips/alchemy/uart_cpu_alchemy.c b/sys/mips/alchemy/uart_cpu_alchemy.c index d38d4cd3ad9..c995130ccd2 100644 --- a/sys/mips/alchemy/uart_cpu_alchemy.c +++ b/sys/mips/alchemy/uart_cpu_alchemy.c @@ -63,7 +63,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) di->ops = uart_getops(&uart_ns8250_class); di->bas.chan = 0; - di->bas.bst = &mips_bus_space_generic; + di->bas.bst = mips_bus_space_generic; di->bas.regshft = 0; di->bas.rclk = 0; di->baudrate = 115200; @@ -72,7 +72,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) di->parity = UART_PARITY_NONE; uart_bus_space_io = 0; - uart_bus_space_mem = &mips_bus_space_generic; + uart_bus_space_mem = mips_bus_space_generic; di->bas.bsh = MIPS_PHYS_TO_KSEG1(UART0_BASE); return (0); diff --git a/sys/mips/idt/uart_bus_rc32434.c b/sys/mips/idt/uart_bus_rc32434.c index 78edf62c052..40e47705fc0 100644 --- a/sys/mips/idt/uart_bus_rc32434.c +++ b/sys/mips/idt/uart_bus_rc32434.c @@ -88,10 +88,10 @@ uart_rc32434_probe(device_t dev) sc->sc_class = &uart_ns8250_class; bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); sc->sc_sysdev->bas.regshft = 2; - sc->sc_sysdev->bas.bst = &mips_bus_space_generic; + sc->sc_sysdev->bas.bst = mips_bus_space_generic; sc->sc_sysdev->bas.bsh = MIPS_PHYS_TO_KSEG1(IDT_BASE_UART0); sc->sc_bas.regshft = 2; - sc->sc_bas.bst = &mips_bus_space_generic; + sc->sc_bas.bst = mips_bus_space_generic; sc->sc_bas.bsh = MIPS_PHYS_TO_KSEG1(IDT_BASE_UART0); return (uart_bus_probe(dev, 2, 330000000UL/2, 0, 0)); diff --git a/sys/mips/idt/uart_cpu_rc32434.c b/sys/mips/idt/uart_cpu_rc32434.c index 862c8bcd547..51be944df7e 100644 --- a/sys/mips/idt/uart_cpu_rc32434.c +++ b/sys/mips/idt/uart_cpu_rc32434.c @@ -71,7 +71,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) /* Got it. Fill in the instance and return it. */ di->ops = uart_getops(&uart_ns8250_class); di->bas.chan = 0; - di->bas.bst = &mips_bus_space_generic; + di->bas.bst = mips_bus_space_generic; di->bas.regshft = 2; di->bas.rclk = 330000000UL/2; /* IPbus clock */ di->baudrate = 115200; @@ -79,7 +79,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) di->stopbits = 1; di->parity = UART_PARITY_NONE; uart_bus_space_io = 0; - uart_bus_space_mem = &mips_bus_space_generic; + uart_bus_space_mem = mips_bus_space_generic; di->bas.bsh = MIPS_PHYS_TO_KSEG1(maddr); return (0); } diff --git a/sys/mips/include/bus.h b/sys/mips/include/bus.h index 1136bced64a..ecb50e5f6df 100644 --- a/sys/mips/include/bus.h +++ b/sys/mips/include/bus.h @@ -717,7 +717,7 @@ void __bs_c(f,_bs_c_8) (void *t, bus_space_handle_t bsh1, \ * declare generic bus space, it suits all needs in */ DECLARE_BUS_SPACE_PROTOTYPES(generic); -extern struct bus_space mips_bus_space_generic; +extern bus_space_tag_t mips_bus_space_generic; #include #endif /* _MACHINE_BUS_H_ */ diff --git a/sys/mips/malta/gt_pci.c b/sys/mips/malta/gt_pci.c index 61e39b847d3..b5bb5bd13bb 100644 --- a/sys/mips/malta/gt_pci.c +++ b/sys/mips/malta/gt_pci.c @@ -206,7 +206,7 @@ gt_pci_attach(device_t dev) busno = 0; sc->sc_dev = dev; sc->sc_busno = busno; - sc->sc_st = &mips_bus_space_generic; + sc->sc_st = mips_bus_space_generic; /* Use KSEG1 to access IO ports for it is uncached */ sc->sc_io = MIPS_PHYS_TO_KSEG1(MALTA_PCI0_IO_BASE); diff --git a/sys/mips/malta/obio.c b/sys/mips/malta/obio.c index 1f000809647..39025d5b737 100644 --- a/sys/mips/malta/obio.c +++ b/sys/mips/malta/obio.c @@ -84,7 +84,7 @@ obio_attach(device_t dev) { struct obio_softc *sc = device_get_softc(dev); - sc->oba_st = &mips_bus_space_generic; + sc->oba_st = mips_bus_space_generic; sc->oba_addr = MIPS_PHYS_TO_KSEG1(MALTA_UART0ADR); sc->oba_size = MALTA_PCIMEM3_SIZE; sc->oba_rman.rm_type = RMAN_ARRAY; diff --git a/sys/mips/malta/uart_bus_maltausart.c b/sys/mips/malta/uart_bus_maltausart.c index 57f8ce389c7..e82384f0558 100644 --- a/sys/mips/malta/uart_bus_maltausart.c +++ b/sys/mips/malta/uart_bus_maltausart.c @@ -88,9 +88,9 @@ uart_malta_probe(device_t dev) sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); sc->sc_class = &uart_ns8250_class; bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); - sc->sc_sysdev->bas.bst = &mips_bus_space_generic; + sc->sc_sysdev->bas.bst = mips_bus_space_generic; sc->sc_sysdev->bas.bsh = MIPS_PHYS_TO_KSEG1(MALTA_UART0ADR); - sc->sc_bas.bst = &mips_bus_space_generic; + sc->sc_bas.bst = mips_bus_space_generic; sc->sc_bas.bsh = MIPS_PHYS_TO_KSEG1(MALTA_UART0ADR); return(uart_bus_probe(dev, 0, 0, 0, 0)); } diff --git a/sys/mips/malta/uart_cpu_maltausart.c b/sys/mips/malta/uart_cpu_maltausart.c index d25ce5cc954..01ef8db332d 100644 --- a/sys/mips/malta/uart_cpu_maltausart.c +++ b/sys/mips/malta/uart_cpu_maltausart.c @@ -67,7 +67,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) { di->ops = uart_getops(&uart_ns8250_class); di->bas.chan = 0; - di->bas.bst = &mips_bus_space_generic; + di->bas.bst = mips_bus_space_generic; di->bas.bsh = MIPS_PHYS_TO_KSEG1(MALTA_UART0ADR); di->bas.regshft = 0; di->bas.rclk = 0; @@ -77,6 +77,6 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) di->parity = UART_PARITY_NONE; uart_bus_space_io = NULL; - uart_bus_space_mem = &mips_bus_space_generic; + uart_bus_space_mem = mips_bus_space_generic; return (0); } diff --git a/sys/mips/mips/bus_space_generic.c b/sys/mips/mips/bus_space_generic.c index 981cc526963..8f8ec6283e2 100644 --- a/sys/mips/mips/bus_space_generic.c +++ b/sys/mips/mips/bus_space_generic.c @@ -89,7 +89,7 @@ __FBSDID("$FreeBSD$"); #include #include -struct bus_space mips_bus_space_generic = { +static struct bus_space generic_space = { /* cookie */ (void *) 0, @@ -196,7 +196,8 @@ struct bus_space mips_bus_space_generic = { NULL, }; - +/* generic bus_space tag */ +bus_space_tag_t mips_bus_space_generic = &generic_space; int generic_bs_map(void *t __unused, bus_addr_t addr, diff --git a/sys/mips/sentry5/obio.c b/sys/mips/sentry5/obio.c index 073035800ff..65c76aba382 100644 --- a/sys/mips/sentry5/obio.c +++ b/sys/mips/sentry5/obio.c @@ -119,7 +119,6 @@ obio_alloc_resource(device_t bus, device_t child, int type, int *rid, { struct resource *rv; struct rman *rm; - bus_space_tag_t bt = 0; bus_space_handle_t bh = 0; struct obio_softc *sc = device_get_softc(bus); @@ -131,7 +130,6 @@ obio_alloc_resource(device_t bus, device_t child, int type, int *rid, return (NULL); case SYS_RES_IOPORT: rm = &sc->oba_rman; - bt = sc->oba_st; bh = sc->oba_addr; start = bh; break; @@ -146,7 +144,7 @@ obio_alloc_resource(device_t bus, device_t child, int type, int *rid, if (type == SYS_RES_IRQ) return (rv); rman_set_rid(rv, *rid); - rman_set_bustag(rv, bt); + rman_set_bustag(rv, mips_bus_space_generic); rman_set_bushandle(rv, bh); if (0) { diff --git a/sys/mips/sentry5/uart_bus_sbusart.c b/sys/mips/sentry5/uart_bus_sbusart.c index 21a6f58c019..c6c4c8d13a9 100644 --- a/sys/mips/sentry5/uart_bus_sbusart.c +++ b/sys/mips/sentry5/uart_bus_sbusart.c @@ -85,9 +85,9 @@ uart_malta_probe(device_t dev) sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); sc->sc_class = &uart_ns8250_class; bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); - sc->sc_sysdev->bas.bst = 0; + sc->sc_sysdev->bas.bst = mips_bus_space_generic; sc->sc_sysdev->bas.bsh = MIPS_PHYS_TO_KSEG1(SENTRY5_UART1ADR); - sc->sc_bas.bst = 0; + sc->sc_bas.bst = mips_bus_space_generic; sc->sc_bas.bsh = MIPS_PHYS_TO_KSEG1(SENTRY5_UART1ADR); return(uart_bus_probe(dev, 0, 0, 0, 0)); } diff --git a/sys/mips/sentry5/uart_cpu_sbusart.c b/sys/mips/sentry5/uart_cpu_sbusart.c index 10ee7be9446..68b761d9d74 100644 --- a/sys/mips/sentry5/uart_cpu_sbusart.c +++ b/sys/mips/sentry5/uart_cpu_sbusart.c @@ -76,7 +76,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) di->parity = UART_PARITY_NONE; uart_bus_space_io = MIPS_PHYS_TO_KSEG1(SENTRY5_UART1ADR); - uart_bus_space_mem = MIPS_PHYS_TO_KSEG1(SENTRY5_UART1ADR); + uart_bus_space_mem = mips_bus_space_generic; di->bas.bsh = MIPS_PHYS_TO_KSEG1(SENTRY5_UART1ADR); return (0); } From 06dfe1506543c9cee43dc2aa7773723e146ad959 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sun, 19 Apr 2009 22:56:35 +0000 Subject: [PATCH 039/380] - Handle byte-order issue for non-word accesses to memory mapped registers with ar71xx_bus_space_reversed. Note, that byte order of values is handled by drivers. bus_spaces fixes only position of register in word. - Replace .hints hack for AR71XX UART with ar71xx_bus_space_reversed. --- sys/mips/atheros/ar71xx_bus_space_reversed.c | 181 +++++++++++++++++++ sys/mips/atheros/ar71xx_bus_space_reversed.h | 33 ++++ sys/mips/atheros/files.ar71xx | 1 + sys/mips/atheros/uart_cpu_ar71xx.c | 9 +- sys/mips/conf/AR71XX.hints | 2 +- 5 files changed, 221 insertions(+), 5 deletions(-) create mode 100644 sys/mips/atheros/ar71xx_bus_space_reversed.c create mode 100644 sys/mips/atheros/ar71xx_bus_space_reversed.h diff --git a/sys/mips/atheros/ar71xx_bus_space_reversed.c b/sys/mips/atheros/ar71xx_bus_space_reversed.c new file mode 100644 index 00000000000..e03ade628f5 --- /dev/null +++ b/sys/mips/atheros/ar71xx_bus_space_reversed.c @@ -0,0 +1,181 @@ +/*- + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include +#include + +static bs_r_1_proto(reversed); +static bs_r_2_proto(reversed); +static bs_w_1_proto(reversed); +static bs_w_2_proto(reversed); + +/* + * Bus space that handles offsets in word for 1/2 bytes read/write access. + * Byte order of values is handled by device drivers itself. + */ +static struct bus_space bus_space_reversed = { + /* cookie */ + (void *) 0, + + /* mapping/unmapping */ + generic_bs_map, + generic_bs_unmap, + generic_bs_subregion, + + /* allocation/deallocation */ + NULL, + NULL, + + /* barrier */ + generic_bs_barrier, + + /* read (single) */ + reversed_bs_r_1, + reversed_bs_r_2, + generic_bs_r_4, + NULL, + + /* read multiple */ + generic_bs_rm_1, + generic_bs_rm_2, + generic_bs_rm_4, + NULL, + + /* read region */ + generic_bs_rr_1, + generic_bs_rr_2, + generic_bs_rr_4, + NULL, + + /* write (single) */ + reversed_bs_w_1, + reversed_bs_w_2, + generic_bs_w_4, + NULL, + + /* write multiple */ + generic_bs_wm_1, + generic_bs_wm_2, + generic_bs_wm_4, + NULL, + + /* write region */ + NULL, + generic_bs_wr_2, + generic_bs_wr_4, + NULL, + + /* set multiple */ + NULL, + NULL, + NULL, + NULL, + + /* set region */ + NULL, + generic_bs_sr_2, + generic_bs_sr_4, + NULL, + + /* copy */ + NULL, + generic_bs_c_2, + NULL, + NULL, + + /* read (single) stream */ + generic_bs_r_1, + generic_bs_r_2, + generic_bs_r_4, + NULL, + + /* read multiple stream */ + generic_bs_rm_1, + generic_bs_rm_2, + generic_bs_rm_4, + NULL, + + /* read region stream */ + generic_bs_rr_1, + generic_bs_rr_2, + generic_bs_rr_4, + NULL, + + /* write (single) stream */ + generic_bs_w_1, + generic_bs_w_2, + generic_bs_w_4, + NULL, + + /* write multiple stream */ + generic_bs_wm_1, + generic_bs_wm_2, + generic_bs_wm_4, + NULL, + + /* write region stream */ + NULL, + generic_bs_wr_2, + generic_bs_wr_4, + NULL, +}; + +bus_space_tag_t ar71xx_bus_space_reversed = &bus_space_reversed; + +static uint8_t +reversed_bs_r_1(void *t, bus_space_handle_t h, bus_size_t o) +{ + + return readb(h + (o &~ 3) + (3 - (o & 3))); +} + +static void +reversed_bs_w_1(void *t, bus_space_handle_t h, bus_size_t o, u_int8_t v) +{ + + writeb(h + (o &~ 3) + (3 - (o & 3)), v); +} + +static uint16_t +reversed_bs_r_2(void *t, bus_space_handle_t h, bus_size_t o) +{ + + return readw(h + (o &~ 3) + (2 - (o & 3))); +} + +static void +reversed_bs_w_2(void *t, bus_space_handle_t h, bus_size_t o, uint16_t v) +{ + + writew(h + (o &~ 3) + (2 - (o & 3)), v); +} diff --git a/sys/mips/atheros/ar71xx_bus_space_reversed.h b/sys/mips/atheros/ar71xx_bus_space_reversed.h new file mode 100644 index 00000000000..c8d28dc7035 --- /dev/null +++ b/sys/mips/atheros/ar71xx_bus_space_reversed.h @@ -0,0 +1,33 @@ +/*- + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __AR71XX_BUS_SPACE_REVERSEDH__ +#define __AR71XX_BUS_SPACE_REVERSEDH__ + +extern bus_space_tag_t ar71xx_bus_space_reversed; + +#endif /* __AR71XX_BUS_SPACE_REVERSEDH__ */ diff --git a/sys/mips/atheros/files.ar71xx b/sys/mips/atheros/files.ar71xx index 78e1d9ce177..47440b124e1 100644 --- a/sys/mips/atheros/files.ar71xx +++ b/sys/mips/atheros/files.ar71xx @@ -7,3 +7,4 @@ mips/atheros/ar71xx_pci.c optional pci mips/atheros/if_arge.c optional arge mips/atheros/uart_bus_ar71xx.c optional uart mips/atheros/uart_cpu_ar71xx.c optional uart +mips/atheros/ar71xx_bus_space_reversed.c standard diff --git a/sys/mips/atheros/uart_cpu_ar71xx.c b/sys/mips/atheros/uart_cpu_ar71xx.c index 4d6b7e79ed1..81a490ebbb1 100644 --- a/sys/mips/atheros/uart_cpu_ar71xx.c +++ b/sys/mips/atheros/uart_cpu_ar71xx.c @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include bus_space_tag_t uart_bus_space_io; bus_space_tag_t uart_bus_space_mem; @@ -54,7 +55,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) { di->ops = uart_getops(&uart_ns8250_class); di->bas.chan = 0; - di->bas.bst = MIPS_BUS_SPACE_MEM; + di->bas.bst = &ar71xx_bus_space_reversed; di->bas.regshft = 2; /* TODO: calculate proper AHB freq using PLL registers */ di->bas.rclk = 85000000; @@ -64,8 +65,8 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) di->parity = UART_PARITY_NONE; /* TODO: check if uart_bus_space_io mandatory to set */ - uart_bus_space_io = MIPS_BUS_SPACE_IO; - uart_bus_space_mem = MIPS_BUS_SPACE_MEM; + uart_bus_space_io = NULL; + uart_bus_space_mem = &ar71xx_bus_space_reversed; /* * FIXME: * 3 is to compensate big endian, uart operates @@ -73,6 +74,6 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) * highest byte instead of lowest one. Actual fix will involve * MIPS bus_space fixing. */ - di->bas.bsh = MIPS_PHYS_TO_KSEG1(AR71XX_UART_ADDR) + 3; + di->bas.bsh = MIPS_PHYS_TO_KSEG1(AR71XX_UART_ADDR); return (0); } diff --git a/sys/mips/conf/AR71XX.hints b/sys/mips/conf/AR71XX.hints index 58fbddec01a..d091805369a 100644 --- a/sys/mips/conf/AR71XX.hints +++ b/sys/mips/conf/AR71XX.hints @@ -7,7 +7,7 @@ hint.apb.0.irq=4 # uart0 hint.uart.0.at="apb0" # see atheros/uart_cpu_ar71xx.c why +3 -hint.uart.0.maddr=0x18020003 +hint.uart.0.maddr=0x18020000 hint.uart.0.msize=0x18 hint.uart.0.irq=3 From e6a88aa8ade03257c78f9b22479130be16f0ae95 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sun, 19 Apr 2009 22:58:36 +0000 Subject: [PATCH 040/380] - Add EHCI controller driver for AR71XX-based boards. --- sys/mips/atheros/ar71xx_ehci.c | 291 +++++++++++++++++++++++++++++++++ sys/mips/atheros/files.ar71xx | 1 + 2 files changed, 292 insertions(+) create mode 100644 sys/mips/atheros/ar71xx_ehci.c diff --git a/sys/mips/atheros/ar71xx_ehci.c b/sys/mips/atheros/ar71xx_ehci.c new file mode 100644 index 00000000000..272a52f609f --- /dev/null +++ b/sys/mips/atheros/ar71xx_ehci.c @@ -0,0 +1,291 @@ +/*- + * Copyright (c) 2008 Sam Leffler. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * AR71XX attachment driver for the USB Enhanced Host Controller. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "opt_bus.h" + +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#define EHCI_HC_DEVSTR "AR71XX Integrated USB 2.0 controller" + +struct ar71xx_ehci_softc { + ehci_softc_t base; /* storage for EHCI code */ +}; + +static device_attach_t ar71xx_ehci_attach; +static device_detach_t ar71xx_ehci_detach; +static device_shutdown_t ar71xx_ehci_shutdown; +static device_suspend_t ar71xx_ehci_suspend; +static device_resume_t ar71xx_ehci_resume; + +bs_r_1_proto(reversed); +bs_w_1_proto(reversed); + +static int +ar71xx_ehci_suspend(device_t self) +{ + ehci_softc_t *sc = device_get_softc(self); + int err; + + err = bus_generic_suspend(self); + if (err) + return (err); + ehci_suspend(sc); + return (0); +} + +static int +ar71xx_ehci_resume(device_t self) +{ + ehci_softc_t *sc = device_get_softc(self); + + ehci_resume(sc); + + bus_generic_resume(self); + + return (0); +} + +static int +ar71xx_ehci_shutdown(device_t self) +{ + ehci_softc_t *sc = device_get_softc(self); + int err; + + err = bus_generic_shutdown(self); + if (err) + return (err); + ehci_shutdown(sc); + + return (0); +} + +static int +ar71xx_ehci_probe(device_t self) +{ + + device_set_desc(self, EHCI_HC_DEVSTR); + printf("EHCI probed\n"); + + return (BUS_PROBE_DEFAULT); +} + +static int +ar71xx_ehci_attach(device_t self) +{ + struct ar71xx_ehci_softc *isc = device_get_softc(self); + ehci_softc_t *sc = &isc->base; + int err; + int rid; + + printf("EHCI attach\n"); + /* initialise some bus fields */ + sc->sc_bus.parent = self; + sc->sc_bus.devices = sc->sc_devices; + sc->sc_bus.devices_max = EHCI_MAX_DEVICES; + + /* get all DMA memory */ + if (usb2_bus_mem_alloc_all(&sc->sc_bus, + USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc)) { + return (ENOMEM); + } + + sc->sc_bus.usbrev = USB_REV_2_0; + + /* NB: hints fix the memory location and irq */ + + rid = 0; + sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE); + if (!sc->sc_io_res) { + device_printf(self, "Could not map memory\n"); + goto error; + } + + /* + * Craft special resource for bus space ops that handle + * byte-alignment of non-word addresses. + */ + sc->sc_io_tag = &ar71xx_bus_space_reversed; + sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res); + sc->sc_io_size = rman_get_size(sc->sc_io_res); + + rid = 0; + sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid, + RF_ACTIVE); + if (sc->sc_irq_res == NULL) { + device_printf(self, "Could not allocate irq\n"); + goto error; + } + sc->sc_bus.bdev = device_add_child(self, "usbus", -1); + if (!sc->sc_bus.bdev) { + device_printf(self, "Could not add USB device\n"); + goto error; + } + device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus); + device_set_desc(sc->sc_bus.bdev, EHCI_HC_DEVSTR); + + sprintf(sc->sc_vendor, "Atheros"); + + + err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, + NULL, (driver_intr_t *)ehci_interrupt, sc, &sc->sc_intr_hdl); + if (err) { + device_printf(self, "Could not setup irq, %d\n", err); + sc->sc_intr_hdl = NULL; + goto error; + } + + /* + * Arrange to force Host mode, select big-endian byte alignment, + * and arrange to not terminate reset operations (the adapter + * will ignore it if we do but might as well save a reg write). + * Also, the controller has an embedded Transaction Translator + * which means port speed must be read from the Port Status + * register following a port enable. + */ + sc->sc_flags |= EHCI_SCFLG_TT + | EHCI_SCFLG_SETMODE + | EHCI_SCFLG_BIGEDESC + | EHCI_SCFLG_BIGEMMIO + | EHCI_SCFLG_NORESTERM + ; + (void) ehci_reset(sc); + + err = ehci_init(sc); + if (!err) { + err = device_probe_and_attach(sc->sc_bus.bdev); + } + if (err) { + device_printf(self, "USB init failed err=%d\n", err); + goto error; + } + return (0); + +error: + ar71xx_ehci_detach(self); + return (ENXIO); +} + +static int +ar71xx_ehci_detach(device_t self) +{ + struct ar71xx_ehci_softc *isc = device_get_softc(self); + ehci_softc_t *sc = &isc->base; + device_t bdev; + int err; + + if (sc->sc_bus.bdev) { + bdev = sc->sc_bus.bdev; + device_detach(bdev); + device_delete_child(self, bdev); + } + /* during module unload there are lots of children leftover */ + device_delete_all_children(self); + + /* + * disable interrupts that might have been switched on in ehci_init + */ + if (sc->sc_io_res) { + EWRITE4(sc, EHCI_USBINTR, 0); + } + + if (sc->sc_irq_res && sc->sc_intr_hdl) { + /* + * only call ehci_detach() after ehci_init() + */ + ehci_detach(sc); + + err = bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl); + + if (err) + /* XXX or should we panic? */ + device_printf(self, "Could not tear down irq, %d\n", + err); + sc->sc_intr_hdl = NULL; + } + + if (sc->sc_irq_res) { + bus_release_resource(self, SYS_RES_IRQ, 0, sc->sc_irq_res); + sc->sc_irq_res = NULL; + } + if (sc->sc_io_res) { + bus_release_resource(self, SYS_RES_MEMORY, 0, + sc->sc_io_res); + sc->sc_io_res = NULL; + } + usb2_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc); + + return (0); +} + +static device_method_t ehci_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, ar71xx_ehci_probe), + DEVMETHOD(device_attach, ar71xx_ehci_attach), + DEVMETHOD(device_detach, ar71xx_ehci_detach), + DEVMETHOD(device_suspend, ar71xx_ehci_suspend), + DEVMETHOD(device_resume, ar71xx_ehci_resume), + DEVMETHOD(device_shutdown, ar71xx_ehci_shutdown), + + /* Bus interface */ + DEVMETHOD(bus_print_child, bus_generic_print_child), + + {0, 0} +}; + +static driver_t ehci_driver = { + "ehci", + ehci_methods, + sizeof(struct ar71xx_ehci_softc), +}; + +static devclass_t ehci_devclass; + +DRIVER_MODULE(ehci, nexus, ehci_driver, ehci_devclass, 0, 0); +MODULE_DEPEND(ehci, usb, 1, 1, 1); diff --git a/sys/mips/atheros/files.ar71xx b/sys/mips/atheros/files.ar71xx index 47440b124e1..0f1e8f16bf8 100644 --- a/sys/mips/atheros/files.ar71xx +++ b/sys/mips/atheros/files.ar71xx @@ -2,6 +2,7 @@ mips/atheros/apb.c standard mips/atheros/ar71xx_machdep.c standard +mips/atheros/ar71xx_ehci.c optional ehci mips/atheros/ar71xx_ohci.c optional ohci mips/atheros/ar71xx_pci.c optional pci mips/atheros/if_arge.c optional arge From c058a01081e40601d8e07956aecff448404172ae Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sun, 19 Apr 2009 23:06:15 +0000 Subject: [PATCH 041/380] - Remove garbage debug output - ar71xx_bus_space_reversed is bus_space_tag_t, use it this way --- sys/mips/atheros/ar71xx_ehci.c | 4 +--- sys/mips/atheros/uart_cpu_ar71xx.c | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/sys/mips/atheros/ar71xx_ehci.c b/sys/mips/atheros/ar71xx_ehci.c index 272a52f609f..cb716678758 100644 --- a/sys/mips/atheros/ar71xx_ehci.c +++ b/sys/mips/atheros/ar71xx_ehci.c @@ -111,7 +111,6 @@ ar71xx_ehci_probe(device_t self) { device_set_desc(self, EHCI_HC_DEVSTR); - printf("EHCI probed\n"); return (BUS_PROBE_DEFAULT); } @@ -124,7 +123,6 @@ ar71xx_ehci_attach(device_t self) int err; int rid; - printf("EHCI attach\n"); /* initialise some bus fields */ sc->sc_bus.parent = self; sc->sc_bus.devices = sc->sc_devices; @@ -151,7 +149,7 @@ ar71xx_ehci_attach(device_t self) * Craft special resource for bus space ops that handle * byte-alignment of non-word addresses. */ - sc->sc_io_tag = &ar71xx_bus_space_reversed; + sc->sc_io_tag = ar71xx_bus_space_reversed; sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res); sc->sc_io_size = rman_get_size(sc->sc_io_res); diff --git a/sys/mips/atheros/uart_cpu_ar71xx.c b/sys/mips/atheros/uart_cpu_ar71xx.c index 81a490ebbb1..c18bc7141b5 100644 --- a/sys/mips/atheros/uart_cpu_ar71xx.c +++ b/sys/mips/atheros/uart_cpu_ar71xx.c @@ -55,7 +55,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) { di->ops = uart_getops(&uart_ns8250_class); di->bas.chan = 0; - di->bas.bst = &ar71xx_bus_space_reversed; + di->bas.bst = ar71xx_bus_space_reversed; di->bas.regshft = 2; /* TODO: calculate proper AHB freq using PLL registers */ di->bas.rclk = 85000000; @@ -66,7 +66,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) /* TODO: check if uart_bus_space_io mandatory to set */ uart_bus_space_io = NULL; - uart_bus_space_mem = &ar71xx_bus_space_reversed; + uart_bus_space_mem = ar71xx_bus_space_reversed; /* * FIXME: * 3 is to compensate big endian, uart operates From 0b67040463384601b3c4abe822d3f5f191ce204c Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sun, 19 Apr 2009 23:08:23 +0000 Subject: [PATCH 042/380] - Expand memory window for apb to include OHCI memory region - Add hints for EHCI and OHCI controllers --- sys/mips/conf/AR71XX.hints | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/sys/mips/conf/AR71XX.hints b/sys/mips/conf/AR71XX.hints index d091805369a..091650a36c2 100644 --- a/sys/mips/conf/AR71XX.hints +++ b/sys/mips/conf/AR71XX.hints @@ -1,7 +1,7 @@ # $FreeBSD$ hint.apb.0.at="nexus0" hint.apb.0.maddr=0x18000000 -hint.apb.0.msize=0x01000000 +hint.apb.0.msize=0x06000000 hint.apb.0.irq=4 # uart0 @@ -11,6 +11,18 @@ hint.uart.0.maddr=0x18020000 hint.uart.0.msize=0x18 hint.uart.0.irq=3 +#ohci +hint.ohci.0.at="apb0" +hint.ohci.0.maddr=0x1c000000 +hint.ohci.0.msize=0x01000000 +hint.ohci.0.irq=6 + +#ehci +hint.ehci.0.at="nexus0" +hint.ehci.0.maddr=0x1b000000 +hint.ehci.0.msize=0x01000000 +hint.ehci.0.irq=1 + # pci hint.pcib.0.at="nexus0" hint.pcib.0.irq=0 From c124ae524dfa40c90b7778ca697a8741301e5a85 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sun, 19 Apr 2009 23:15:04 +0000 Subject: [PATCH 043/380] - Enable USB and EHCI - Include if_arge to build - Add NFS root options - Disable pci ATM and add stubs for wifi adapter config --- sys/mips/conf/AR71XX | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/sys/mips/conf/AR71XX b/sys/mips/conf/AR71XX index 936d0f1f88d..b8dfc1997f8 100644 --- a/sys/mips/conf/AR71XX +++ b/sys/mips/conf/AR71XX @@ -29,9 +29,36 @@ options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions options INVARIANTS options INVARIANT_SUPPORT -device pci +options BOOTP +options BOOTP_NFSROOT +options BOOTP_NFSV3 +options BOOTP_WIRED_TO=arge0 +options BOOTP_COMPAT +options ROOTDEVNAME=\"nfs:192.168.10.1:/mnt/bsd\" + +# device pci +# Wireless NIC cards +# device wlan # 802.11 support +# device wlan_wep # 802.11 WEP support +# device wlan_ccmp # 802.11 CCMP support +# device wlan_tkip # 802.11 TKIP support + +# device ath # Atheros pci/cardbus NIC's +# option AH_SUPPORT_AR5416 +# device ath_hal +# device ath_ar5212 # Atheros HAL (Hardware Access Layer) +# device ath_rate_sample + +device mii +device arge + device uart +device usb +options USB_EHCI_BIG_ENDIAN_DESC # handle big-endian byte order +options USB_DEBUG +device ehci + device loop device ether device md From e19cc06695539ed5e1a78fa3c2d4668262e89d6f Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 24 Apr 2009 03:38:51 +0000 Subject: [PATCH 044/380] - Fix whitespace to conform style(9) --- sys/mips/mips/cpu.c | 226 +++++++++++++++++++++++--------------------- 1 file changed, 117 insertions(+), 109 deletions(-) diff --git a/sys/mips/mips/cpu.c b/sys/mips/mips/cpu.c index f9596e2ba8b..b2f9bed8a87 100644 --- a/sys/mips/mips/cpu.c +++ b/sys/mips/mips/cpu.c @@ -64,61 +64,66 @@ union cpuprid fpu_id; static void mips_get_identity(struct mips_cpuinfo *cpuinfo) { - u_int32_t prid; - u_int32_t cfg0; - u_int32_t cfg1; - u_int32_t tmp; + u_int32_t prid; + u_int32_t cfg0; + u_int32_t cfg1; + u_int32_t tmp; - memset(cpuinfo, 0, sizeof(struct mips_cpuinfo)); + memset(cpuinfo, 0, sizeof(struct mips_cpuinfo)); - /* Read and store the PrID ID for CPU identification. */ - prid = mips_rd_prid(); - cpuinfo->cpu_vendor = MIPS_PRID_CID(prid); - cpuinfo->cpu_rev = MIPS_PRID_REV(prid); - cpuinfo->cpu_impl = MIPS_PRID_IMPL(prid); + /* Read and store the PrID ID for CPU identification. */ + prid = mips_rd_prid(); + cpuinfo->cpu_vendor = MIPS_PRID_CID(prid); + cpuinfo->cpu_rev = MIPS_PRID_REV(prid); + cpuinfo->cpu_impl = MIPS_PRID_IMPL(prid); - /* Read config register selection 0 to learn TLB type. */ - cfg0 = mips_rd_config(); + /* Read config register selection 0 to learn TLB type. */ + cfg0 = mips_rd_config(); - cpuinfo->tlb_type = ((cfg0 & MIPS_CONFIG0_MT_MASK) >> MIPS_CONFIG0_MT_SHIFT); - cpuinfo->icache_virtual = cfg0 & MIPS_CONFIG0_VI; + cpuinfo->tlb_type = + ((cfg0 & MIPS_CONFIG0_MT_MASK) >> MIPS_CONFIG0_MT_SHIFT); + cpuinfo->icache_virtual = cfg0 & MIPS_CONFIG0_VI; - /* If config register selection 1 does not exist, exit. */ - if (!(cfg0 & MIPS3_CONFIG_CM)) - return; + /* If config register selection 1 does not exist, exit. */ + if (!(cfg0 & MIPS3_CONFIG_CM)) + return; - /* Learn TLB size and L1 cache geometry. */ - cfg1 = mips_rd_config_sel1(); - cpuinfo->tlb_nentries = ((cfg1 & MIPS_CONFIG1_TLBSZ_MASK) >> MIPS_CONFIG1_TLBSZ_SHIFT) + 1; + /* Learn TLB size and L1 cache geometry. */ + cfg1 = mips_rd_config_sel1(); + cpuinfo->tlb_nentries = + ((cfg1 & MIPS_CONFIG1_TLBSZ_MASK) >> MIPS_CONFIG1_TLBSZ_SHIFT) + 1; - /* L1 instruction cache. */ - tmp = 1 << (((cfg1 & MIPS_CONFIG1_IL_MASK) >> MIPS_CONFIG1_IL_SHIFT) + 1); - if (tmp != 0) { - cpuinfo->l1.ic_linesize = tmp; - cpuinfo->l1.ic_nways = (((cfg1 & MIPS_CONFIG1_IA_MASK) >> MIPS_CONFIG1_IA_SHIFT)) + 1; - cpuinfo->l1.ic_nsets = 1 << (((cfg1 & MIPS_CONFIG1_IS_MASK) >> MIPS_CONFIG1_IS_SHIFT) + 6); - cpuinfo->l1.ic_size = cpuinfo->l1.ic_linesize * cpuinfo->l1.ic_nsets - * cpuinfo->l1.ic_nways; - } + /* L1 instruction cache. */ + tmp = 1 << (((cfg1 & MIPS_CONFIG1_IL_MASK) >> MIPS_CONFIG1_IL_SHIFT) + 1); + if (tmp != 0) { + cpuinfo->l1.ic_linesize = tmp; + cpuinfo->l1.ic_nways = (((cfg1 & MIPS_CONFIG1_IA_MASK) >> MIPS_CONFIG1_IA_SHIFT)) + 1; + cpuinfo->l1.ic_nsets = + 1 << (((cfg1 & MIPS_CONFIG1_IS_MASK) >> MIPS_CONFIG1_IS_SHIFT) + 6); + cpuinfo->l1.ic_size = + cpuinfo->l1.ic_linesize * cpuinfo->l1.ic_nsets * cpuinfo->l1.ic_nways; + } - /* L1 data cache. */ - tmp = 1 << (((cfg1 & MIPS_CONFIG1_DL_MASK) >> MIPS_CONFIG1_DL_SHIFT) + 1); - if (tmp != 0) { - cpuinfo->l1.dc_linesize = tmp; - cpuinfo->l1.dc_nways = (((cfg1 & MIPS_CONFIG1_DA_MASK) >> MIPS_CONFIG1_DA_SHIFT)) + 1; - cpuinfo->l1.dc_nsets = 1 << (((cfg1 & MIPS_CONFIG1_DS_MASK) >> MIPS_CONFIG1_DS_SHIFT) + 6); + /* L1 data cache. */ + tmp = 1 << (((cfg1 & MIPS_CONFIG1_DL_MASK) >> MIPS_CONFIG1_DL_SHIFT) + 1); + if (tmp != 0) { + cpuinfo->l1.dc_linesize = tmp; + cpuinfo->l1.dc_nways = + (((cfg1 & MIPS_CONFIG1_DA_MASK) >> MIPS_CONFIG1_DA_SHIFT)) + 1; + cpuinfo->l1.dc_nsets = + 1 << (((cfg1 & MIPS_CONFIG1_DS_MASK) >> MIPS_CONFIG1_DS_SHIFT) + 6); #ifdef TARGET_OCTEON - /* - * Octeon does 128 byte line-size. But Config-Sel1 doesn't show - * 128 line-size, 1 Set, 64 ways. - */ - cpuinfo->l1.dc_linesize = 128; - cpuinfo->l1.dc_nsets = 1; - cpuinfo->l1.dc_nways = 64; + /* + * Octeon does 128 byte line-size. But Config-Sel1 doesn't show + * 128 line-size, 1 Set, 64 ways. + */ + cpuinfo->l1.dc_linesize = 128; + cpuinfo->l1.dc_nsets = 1; + cpuinfo->l1.dc_nways = 64; #endif - cpuinfo->l1.dc_size = cpuinfo->l1.dc_linesize * cpuinfo->l1.dc_nsets - * cpuinfo->l1.dc_nways; - } + cpuinfo->l1.dc_size = cpuinfo->l1.dc_linesize + * cpuinfo->l1.dc_nsets * cpuinfo->l1.dc_nways; + } } void @@ -141,77 +146,80 @@ mips_cpu_init(void) void cpu_identify(void) { - printf("cpu%d: ", 0); /* XXX per-cpu */ - switch (cpuinfo.cpu_vendor) { - case MIPS_PRID_CID_MTI: - printf("MIPS Technologies"); - break; - case MIPS_PRID_CID_BROADCOM: - case MIPS_PRID_CID_SIBYTE: - printf("Broadcom"); - break; - case MIPS_PRID_CID_ALCHEMY: - printf("AMD"); - break; - case MIPS_PRID_CID_SANDCRAFT: - printf("Sandcraft"); - break; - case MIPS_PRID_CID_PHILIPS: - printf("Philips"); - break; - case MIPS_PRID_CID_TOSHIBA: - printf("Toshiba"); - break; - case MIPS_PRID_CID_LSI: - printf("LSI"); - break; - case MIPS_PRID_CID_LEXRA: - printf("Lexra"); - break; - case MIPS_PRID_CID_PREHISTORIC: - default: - printf("Unknown"); - break; - } - printf(" processor v%d.%d\n", cpuinfo.cpu_rev, cpuinfo.cpu_impl); - - printf(" MMU: "); - if (cpuinfo.tlb_type == MIPS_MMU_NONE) { - printf("none present\n"); - } else { - if (cpuinfo.tlb_type == MIPS_MMU_TLB) { - printf("Standard TLB"); - } else if (cpuinfo.tlb_type == MIPS_MMU_BAT) { - printf("Standard BAT"); - } else if (cpuinfo.tlb_type == MIPS_MMU_FIXED) { - printf("Fixed mapping"); + printf("cpu%d: ", 0); /* XXX per-cpu */ + switch (cpuinfo.cpu_vendor) { + case MIPS_PRID_CID_MTI: + printf("MIPS Technologies"); + break; + case MIPS_PRID_CID_BROADCOM: + case MIPS_PRID_CID_SIBYTE: + printf("Broadcom"); + break; + case MIPS_PRID_CID_ALCHEMY: + printf("AMD"); + break; + case MIPS_PRID_CID_SANDCRAFT: + printf("Sandcraft"); + break; + case MIPS_PRID_CID_PHILIPS: + printf("Philips"); + break; + case MIPS_PRID_CID_TOSHIBA: + printf("Toshiba"); + break; + case MIPS_PRID_CID_LSI: + printf("LSI"); + break; + case MIPS_PRID_CID_LEXRA: + printf("Lexra"); + break; + case MIPS_PRID_CID_PREHISTORIC: + default: + printf("Unknown"); + break; } - printf(", %d entries\n", cpuinfo.tlb_nentries); - } + printf(" processor v%d.%d\n", cpuinfo.cpu_rev, cpuinfo.cpu_impl); - printf(" L1 i-cache: "); - if (cpuinfo.l1.ic_linesize == 0) { - printf("disabled"); - } else { - if (cpuinfo.l1.ic_nways == 1) { - printf("direct-mapped with"); + printf(" MMU: "); + if (cpuinfo.tlb_type == MIPS_MMU_NONE) { + printf("none present\n"); } else { - printf ("%d ways of", cpuinfo.l1.ic_nways); + if (cpuinfo.tlb_type == MIPS_MMU_TLB) { + printf("Standard TLB"); + } else if (cpuinfo.tlb_type == MIPS_MMU_BAT) { + printf("Standard BAT"); + } else if (cpuinfo.tlb_type == MIPS_MMU_FIXED) { + printf("Fixed mapping"); + } + printf(", %d entries\n", cpuinfo.tlb_nentries); } - printf(" %d sets, %d bytes per line\n", cpuinfo.l1.ic_nsets, cpuinfo.l1.ic_linesize); - } - printf(" L1 d-cache: "); - if (cpuinfo.l1.dc_linesize == 0) { - printf("disabled"); - } else { - if (cpuinfo.l1.dc_nways == 1) { - printf("direct-mapped with"); + printf(" L1 i-cache: "); + if (cpuinfo.l1.ic_linesize == 0) { + printf("disabled"); } else { - printf ("%d ways of", cpuinfo.l1.dc_nways); + if (cpuinfo.l1.ic_nways == 1) { + printf("direct-mapped with"); + } else { + printf ("%d ways of", cpuinfo.l1.ic_nways); + } + printf(" %d sets, %d bytes per line\n", + cpuinfo.l1.ic_nsets, cpuinfo.l1.ic_linesize); } - printf(" %d sets, %d bytes per line\n", cpuinfo.l1.dc_nsets, cpuinfo.l1.dc_linesize); - } + + printf(" L1 d-cache: "); + if (cpuinfo.l1.dc_linesize == 0) { + printf("disabled"); + } else { + if (cpuinfo.l1.dc_nways == 1) { + printf("direct-mapped with"); + } else { + printf ("%d ways of", cpuinfo.l1.dc_nways); + } + printf(" %d sets, %d bytes per line\n", + cpuinfo.l1.dc_nsets, cpuinfo.l1.dc_linesize); + } + } static struct rman cpu_hardirq_rman; From 7323fa4005143a3066f05522cdd3558515fdca84 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 24 Apr 2009 04:17:21 +0000 Subject: [PATCH 045/380] - Define accessor functions for CP0 Config(16) register selects 1, 2, 3. Content of these registers is defined in MIPS spec and can be used for obtaining info about CPU capabilities. --- sys/mips/include/cpufunc.h | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/sys/mips/include/cpufunc.h b/sys/mips/include/cpufunc.h index f3aa5a4c120..1cddc4fb230 100644 --- a/sys/mips/include/cpufunc.h +++ b/sys/mips/include/cpufunc.h @@ -212,18 +212,24 @@ MIPS_RDRW32_COP0(pagemask, MIPS_COP_0_TLB_PG_MASK); MIPS_RDRW32_COP0(prid, MIPS_COP_0_PRID); MIPS_RDRW32_COP0(watchlo, MIPS_COP_0_WATCH_LO); MIPS_RDRW32_COP0(watchhi, MIPS_COP_0_WATCH_HI); +#undef MIPS_RDRW32_COP0 -static __inline uint32_t -mips_rd_config_sel1(void) -{ - int v0; - __asm __volatile("mfc0 %[v0], $16, 1 ;" - : [v0] "=&r" (v0)); - mips_barrier(); - return (v0); +#define MIPS_RD_CONFIG_SEL(sel) \ +static __inline uint32_t \ +mips_rd_config_sel##sel(void) \ +{ \ + int v0; \ + __asm __volatile("mfc0 %[v0], $16, " #sel " ;" \ + : [v0] "=&r" (v0)); \ + mips_barrier(); \ + return (v0); \ } -#undef MIPS_RDRW32_COP0 + +MIPS_RD_CONFIG_SEL(1); +MIPS_RD_CONFIG_SEL(2); +MIPS_RD_CONFIG_SEL(3); +#undef MIPS_RD_CONFIG_SEL static __inline register_t intr_disable(void) From 709410480c4053b093af0e1f3791db648094d15a Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 24 Apr 2009 04:18:16 +0000 Subject: [PATCH 046/380] - Print supported CPU capabilities during stratup --- sys/mips/mips/cpu.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/sys/mips/mips/cpu.c b/sys/mips/mips/cpu.c index b2f9bed8a87..a51b5911172 100644 --- a/sys/mips/mips/cpu.c +++ b/sys/mips/mips/cpu.c @@ -146,6 +146,7 @@ mips_cpu_init(void) void cpu_identify(void) { + uint32_t cfg0, cfg1, cfg2, cfg3; printf("cpu%d: ", 0); /* XXX per-cpu */ switch (cpuinfo.cpu_vendor) { case MIPS_PRID_CID_MTI: @@ -220,6 +221,32 @@ cpu_identify(void) cpuinfo.l1.dc_nsets, cpuinfo.l1.dc_linesize); } + cfg0 = mips_rd_config(); + /* If config register selection 1 does not exist, exit. */ + if (!(cfg0 & MIPS3_CONFIG_CM)) + return; + + cfg1 = mips_rd_config_sel1(); + printf(" Config1=0x%b\n", cfg1, + "\20\7COP2\6MDMX\5PerfCount\4WatchRegs\3MIPS16\2EJTAG\1FPU"); + + /* If config register selection 2 does not exist, exit. */ + if (!(cfg1 & MIPS3_CONFIG_CM)) + return; + cfg2 = mips_rd_config_sel2(); + /* + * Config2 contains no useful information other then Config3 + * existence flag + */ + + /* If config register selection 3 does not exist, exit. */ + if (!(cfg2 & MIPS3_CONFIG_CM)) + return; + cfg3 = mips_rd_config_sel2(); + + /* Print Config3 if it contains any useful info */ + if (cfg3 & ~(0x80000000)) + printf(" Config3=0x%b\n", cfg3, "\20\2SmartMIPS\1TraceLogic"); } static struct rman cpu_hardirq_rman; From ffb90c259ee9dada6faf88b43ed1c8d3cc0da94c Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 24 Apr 2009 05:28:44 +0000 Subject: [PATCH 047/380] Fix cut'n'paste code. cfg3 should get the value of selector 3 Spotted by: thompa@ --- sys/mips/mips/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/mips/cpu.c b/sys/mips/mips/cpu.c index a51b5911172..cb70f9e5103 100644 --- a/sys/mips/mips/cpu.c +++ b/sys/mips/mips/cpu.c @@ -242,7 +242,7 @@ cpu_identify(void) /* If config register selection 3 does not exist, exit. */ if (!(cfg2 & MIPS3_CONFIG_CM)) return; - cfg3 = mips_rd_config_sel2(); + cfg3 = mips_rd_config_sel3(); /* Print Config3 if it contains any useful info */ if (cfg3 & ~(0x80000000)) From 00c35cc20bc622ad20855d30db0571bdcf0db667 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 27 Apr 2009 18:29:59 +0000 Subject: [PATCH 048/380] - Use naming convention the same as MIPS spec does: eliminate _sel1 sufix and just use selector number. e.g. mips_rd_config_sel1 -> mips_rd_config1 - Add WatchHi/WatchLo accessors for selctors 1..3 (for debug purposes) --- sys/mips/include/cpufunc.h | 48 ++++++++++++++++++++++++-------------- sys/mips/mips/cpu.c | 8 +++---- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/sys/mips/include/cpufunc.h b/sys/mips/include/cpufunc.h index 1cddc4fb230..28d47332c10 100644 --- a/sys/mips/include/cpufunc.h +++ b/sys/mips/include/cpufunc.h @@ -183,6 +183,28 @@ mips_wr_ ## n (uint32_t a0) \ mips_barrier(); \ } struct __hack +#define MIPS_RDRW32_COP0_SEL(n,r,s) \ +static __inline uint32_t \ +mips_rd_ ## n ## s(void) \ +{ \ + int v0; \ + __asm __volatile ("mfc0 %[v0], $"__XSTRING(r)", "__XSTRING(s)";" \ + : [v0] "=&r"(v0)); \ + mips_barrier(); \ + return (v0); \ +} \ +static __inline void \ +mips_wr_ ## n ## s(uint32_t a0) \ +{ \ + __asm __volatile ("mtc0 %[a0], $"__XSTRING(r)", "__XSTRING(s)";" \ + __XSTRING(COP0_SYNC)";" \ + "nop;" \ + "nop;" \ + : \ + : [a0] "r"(a0)); \ + mips_barrier(); \ +} struct __hack + #ifdef TARGET_OCTEON static __inline void mips_sync_icache (void) { @@ -197,6 +219,9 @@ static __inline void mips_sync_icache (void) MIPS_RDRW32_COP0(compare, MIPS_COP_0_COMPARE); MIPS_RDRW32_COP0(config, MIPS_COP_0_CONFIG); +MIPS_RDRW32_COP0_SEL(config, MIPS_COP_0_CONFIG, 1); +MIPS_RDRW32_COP0_SEL(config, MIPS_COP_0_CONFIG, 2); +MIPS_RDRW32_COP0_SEL(config, MIPS_COP_0_CONFIG, 3); MIPS_RDRW32_COP0(count, MIPS_COP_0_COUNT); MIPS_RDRW32_COP0(index, MIPS_COP_0_TLB_INDEX); MIPS_RDRW32_COP0(wired, MIPS_COP_0_TLB_WIRED); @@ -211,26 +236,15 @@ MIPS_RDRW32_COP0(entryhi, MIPS_COP_0_TLB_HI); MIPS_RDRW32_COP0(pagemask, MIPS_COP_0_TLB_PG_MASK); MIPS_RDRW32_COP0(prid, MIPS_COP_0_PRID); MIPS_RDRW32_COP0(watchlo, MIPS_COP_0_WATCH_LO); +MIPS_RDRW32_COP0_SEL(watchlo, MIPS_COP_0_WATCH_LO, 1); +MIPS_RDRW32_COP0_SEL(watchlo, MIPS_COP_0_WATCH_LO, 2); +MIPS_RDRW32_COP0_SEL(watchlo, MIPS_COP_0_WATCH_LO, 3); MIPS_RDRW32_COP0(watchhi, MIPS_COP_0_WATCH_HI); +MIPS_RDRW32_COP0_SEL(watchhi, MIPS_COP_0_WATCH_HI, 1); +MIPS_RDRW32_COP0_SEL(watchhi, MIPS_COP_0_WATCH_HI, 2); +MIPS_RDRW32_COP0_SEL(watchhi, MIPS_COP_0_WATCH_HI, 3); #undef MIPS_RDRW32_COP0 -#define MIPS_RD_CONFIG_SEL(sel) \ -static __inline uint32_t \ -mips_rd_config_sel##sel(void) \ -{ \ - int v0; \ - __asm __volatile("mfc0 %[v0], $16, " #sel " ;" \ - : [v0] "=&r" (v0)); \ - mips_barrier(); \ - return (v0); \ -} - - -MIPS_RD_CONFIG_SEL(1); -MIPS_RD_CONFIG_SEL(2); -MIPS_RD_CONFIG_SEL(3); -#undef MIPS_RD_CONFIG_SEL - static __inline register_t intr_disable(void) { diff --git a/sys/mips/mips/cpu.c b/sys/mips/mips/cpu.c index cb70f9e5103..7bd27184d6c 100644 --- a/sys/mips/mips/cpu.c +++ b/sys/mips/mips/cpu.c @@ -89,7 +89,7 @@ mips_get_identity(struct mips_cpuinfo *cpuinfo) return; /* Learn TLB size and L1 cache geometry. */ - cfg1 = mips_rd_config_sel1(); + cfg1 = mips_rd_config1(); cpuinfo->tlb_nentries = ((cfg1 & MIPS_CONFIG1_TLBSZ_MASK) >> MIPS_CONFIG1_TLBSZ_SHIFT) + 1; @@ -226,14 +226,14 @@ cpu_identify(void) if (!(cfg0 & MIPS3_CONFIG_CM)) return; - cfg1 = mips_rd_config_sel1(); + cfg1 = mips_rd_config1(); printf(" Config1=0x%b\n", cfg1, "\20\7COP2\6MDMX\5PerfCount\4WatchRegs\3MIPS16\2EJTAG\1FPU"); /* If config register selection 2 does not exist, exit. */ if (!(cfg1 & MIPS3_CONFIG_CM)) return; - cfg2 = mips_rd_config_sel2(); + cfg2 = mips_rd_config2(); /* * Config2 contains no useful information other then Config3 * existence flag @@ -242,7 +242,7 @@ cpu_identify(void) /* If config register selection 3 does not exist, exit. */ if (!(cfg2 & MIPS3_CONFIG_CM)) return; - cfg3 = mips_rd_config_sel3(); + cfg3 = mips_rd_config3(); /* Print Config3 if it contains any useful info */ if (cfg3 & ~(0x80000000)) From 3a8b0ab3f31f193fd6bf67882b9465a960312438 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 27 Apr 2009 18:46:57 +0000 Subject: [PATCH 049/380] - Use new spacebus - Be a bit more verbose on failures - style(9) fixes - Use default rid value of 0 instead of MIPS_MEM_RID (0x20) --- sys/mips/mips/nexus.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sys/mips/mips/nexus.c b/sys/mips/mips/nexus.c index 6cd78fd6277..2578d2f12f4 100644 --- a/sys/mips/mips/nexus.c +++ b/sys/mips/mips/nexus.c @@ -255,13 +255,14 @@ nexus_hinted_child(device_t bus, const char *dname, int dunit) if ((mem_hints_count > 0) && (mem_hints_count < 2)) { printf("Either maddr or msize hint is missing for %s%d\n", dname, dunit); - } else if (mem_hints_count) { + } + else if (mem_hints_count) { dprintf("%s: discovered hinted child %s at maddr %p(%d)\n", __func__, device_get_nameunit(child), (void *)(intptr_t)maddr, msize); - result = bus_set_resource(child, SYS_RES_MEMORY, MIPS_MEM_RID, - maddr, msize); + result = bus_set_resource(child, SYS_RES_MEMORY, 0, maddr, + msize); if (result != 0) { device_printf(bus, "warning: bus_set_resource() failed\n"); @@ -351,7 +352,8 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, rv = rman_reserve_resource(rm, start, end, count, flags, child); if (rv == 0) { - printf("%s: could not reserve resource\n", __func__); + printf("%s: could not reserve resource for %s\n", __func__, + device_get_nameunit(child)); return (0); } @@ -391,7 +393,7 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid, vaddr = (caddr_t) pmap_mapdev(paddr-poffs, psize+poffs) + poffs; rman_set_virtual(r, vaddr); - rman_set_bustag(r, MIPS_BUS_SPACE_MEM); + rman_set_bustag(r, mips_bus_space_generic); #ifdef TARGET_OCTEON temp = 0x0000000000000000; temp |= (uint32_t)vaddr; From c2312937452c88ae46e91f6141ebf476726e7bd8 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 27 Apr 2009 19:18:55 +0000 Subject: [PATCH 050/380] - Cast argument to proper type in order to avoid warnings like "shift value is too large for given type" --- sys/mips/include/endian.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/mips/include/endian.h b/sys/mips/include/endian.h index 1d2b4fe024f..b43b1e9bf6d 100644 --- a/sys/mips/include/endian.h +++ b/sys/mips/include/endian.h @@ -108,12 +108,12 @@ __bswap64_var(__uint64_t _x) ((_x << 40) & ((__uint64_t)0xff << 48)) | ((_x << 56))); } -#define __bswap16(x) (__uint16_t)(__is_constant(x) ? __bswap16_const(x) : \ - __bswap16_var(x)) -#define __bswap32(x) (__uint32_t)(__is_constant(x) ? __bswap32_const(x) : \ - __bswap32_var(x)) -#define __bswap64(x) (__uint64_t)(__is_constant(x) ? __bswap64_const(x) : \ - __bswap64_var(x)) +#define __bswap16(x) (__uint16_t)(__is_constant(x) ? \ + __bswap16_const((__uint16_t)x) : __bswap16_var((__uint16_t)x)) +#define __bswap32(x) (__uint32_t)(__is_constant(x) ? \ + __bswap32_const((__uint32_t)x) : __bswap32_var((__uint32_t)x)) +#define __bswap64(x) (__uint64_t)(__is_constant(x) ? \ + __bswap64_const((__uint64_t)x) : __bswap64_var((__uint64_t)x)) #ifdef __MIPSEB__ #define __htonl(x) ((__uint32_t)(x)) From 4f3aceef8897db45335f60a5f1339b43d4db3bb0 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 28 Apr 2009 02:59:18 +0000 Subject: [PATCH 051/380] - When destroying va -> pa mapping writeback all caches or we may endup with partial page content in SDRAM - style(9) fix --- sys/mips/mips/pmap.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index de18279ed39..cc0daa25418 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -699,6 +699,11 @@ pmap_kremove(vm_offset_t va) { register pt_entry_t *pte; + /* + * Write back all caches from the page being destroyed + */ + mips_dcache_wbinv_range(va, NBPG); + pte = pmap_pte(kernel_pmap, va); *pte = PTE_G; pmap_invalidate_page(kernel_pmap, va); @@ -1523,6 +1528,12 @@ pmap_remove_page(struct pmap *pmap, vm_offset_t va) if (!ptq || !pmap_pte_v(ptq)) { return; } + + /* + * Write back all caches from the page being destroyed + */ + mips_dcache_wbinv_range(va, NBPG); + /* * get a local va for mappings for this pmap. */ @@ -1608,6 +1619,14 @@ pmap_remove_all(vm_page_t m) while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) { PMAP_LOCK(pv->pv_pmap); + + /* + * If it's last mapping writeback all caches from + * the page being destroyed + */ + if (m->md.pv_list_count == 1) + mips_dcache_wbinv_range(pv->pv_va, NBPG); + pv->pv_pmap->pm_stats.resident_count--; pte = pmap_pte(pv->pv_pmap, pv->pv_va); @@ -2501,9 +2520,7 @@ pmap_remove_pages(pmap_t pmap) PMAP_LOCK(pmap); sched_pin(); //XXX need to be TAILQ_FOREACH_SAFE ? - for (pv = TAILQ_FIRST(&pmap->pm_pvlist); - pv; - pv = npv) { + for (pv = TAILQ_FIRST(&pmap->pm_pvlist); pv; pv = npv) { pte = pmap_pte(pv->pv_pmap, pv->pv_va); if (!pmap_pte_v(pte)) From 26a323c653be7da45299196c0bc8abfc2a7d3a28 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 29 Apr 2009 03:21:53 +0000 Subject: [PATCH 052/380] - accummulate interrupt causes in filter instead of rewriting old. The only place where status should be overrided - interrupt handler --- sys/mips/atheros/if_arge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index 7dbfe70fb29..a3f38e09ccc 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -1471,7 +1471,7 @@ arge_intr_filter(void *arg) ARGE_CLEAR_BITS(sc, AR71XX_DMA_INTR, DMA_INTR_TX_UNDERRUN | DMA_INTR_TX_PKT_SENT); - sc->arge_intr_status = status; + sc->arge_intr_status |= status; return (FILTER_SCHEDULE_THREAD); } From ccf8f87398a8fcd1c81a9b424109d22df467a798 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 6 May 2009 02:31:07 +0000 Subject: [PATCH 053/380] - Handle memory requests on apb level, do not pass them up to nexus - Unmask IRQ in bus_intr_setup - Do not count timer IRQ (IRQ0) as stray --- sys/mips/atheros/apb.c | 28 +++++++++++++++++++++++----- sys/mips/atheros/apbvar.h | 1 + 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/sys/mips/atheros/apb.c b/sys/mips/atheros/apb.c index d53408c3b07..f6e20a7d200 100644 --- a/sys/mips/atheros/apb.c +++ b/sys/mips/atheros/apb.c @@ -101,6 +101,16 @@ apb_attach(device_t dev) int rid = 0; device_set_desc(dev, "APB Bus bridge"); + + sc->apb_mem_rman.rm_type = RMAN_ARRAY; + sc->apb_mem_rman.rm_descr = "APB memory window"; + + if (rman_init(&sc->apb_mem_rman) != 0 || + rman_manage_region(&sc->apb_mem_rman, + AR71XX_APB_BASE, + AR71XX_APB_BASE + AR71XX_APB_SIZE - 1) != 0) + panic("apb_attach: failed to set up memory rman"); + sc->apb_irq_rman.rm_type = RMAN_ARRAY; sc->apb_irq_rman.rm_descr = "APB IRQ"; @@ -145,18 +155,19 @@ apb_alloc_resource(device_t bus, device_t child, int type, int *rid, /* * Pass memory requests to nexus device */ - passthrough = (device_get_parent(child) != bus) || - (type == SYS_RES_MEMORY); + passthrough = (device_get_parent(child) != bus); rle = NULL; - dprintf("%s: entry (%p, %p, %d, %p, %p, %p, %ld, %d)\n", - __func__, bus, child, type, rid, (void *)(intptr_t)start, + dprintf("%s: entry (%p, %p, %d, %d, %p, %p, %ld, %d)\n", + __func__, bus, child, type, *rid, (void *)(intptr_t)start, (void *)(intptr_t)end, count, flags); if (passthrough) return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, rid, start, end, count, flags)); + printf("not pass through\n"); + /* * If this is an allocation of the "default" range for a given RID, * and we know what the resources for this device are (ie. they aren't @@ -185,6 +196,9 @@ apb_alloc_resource(device_t bus, device_t child, int type, int *rid, case SYS_RES_IRQ: rm = &sc->apb_irq_rman; break; + case SYS_RES_MEMORY: + rm = &sc->apb_mem_rman; + break; default: printf("%s: unknown resource type %d\n", __func__, type); return (0); @@ -275,6 +289,8 @@ apb_setup_intr(device_t bus, device_t child, struct resource *ires, intr_event_add_handler(event, device_get_nameunit(child), filt, handler, arg, intr_priority(flags), flags, cookiep); + apb_unmask_irq(irq); + return (0); } @@ -313,7 +329,9 @@ apb_intr(void *arg) if (reg & (1 << irq)) { event = sc->sc_eventstab[irq]; if (!event || TAILQ_EMPTY(&event->ie_handlers)) { - printf("Stray IRQ %d\n", irq); + /* Ignore timer interrupts */ + if (irq != 0) + printf("Stray IRQ %d\n", irq); continue; } diff --git a/sys/mips/atheros/apbvar.h b/sys/mips/atheros/apbvar.h index e1d29f4a662..9afd690d2a8 100644 --- a/sys/mips/atheros/apbvar.h +++ b/sys/mips/atheros/apbvar.h @@ -34,6 +34,7 @@ struct apb_softc { struct rman apb_irq_rman; + struct rman apb_mem_rman; /* IRQ events structs for child devices */ struct intr_event *sc_eventstab[APB_NIRQS]; /* Resources and cookies for MIPS CPU INTs */ From 07e615d62583adec3c6bf08efb0cfb075ef4d601 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 6 May 2009 02:31:46 +0000 Subject: [PATCH 054/380] - Add APB base and size for memory rman in apb --- sys/mips/atheros/ar71xxreg.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sys/mips/atheros/ar71xxreg.h b/sys/mips/atheros/ar71xxreg.h index 93677922463..189a84e6225 100644 --- a/sys/mips/atheros/ar71xxreg.h +++ b/sys/mips/atheros/ar71xxreg.h @@ -60,6 +60,15 @@ #define AR71XX_PCI_AHB_ERROR_ADDR 0x17010028 /* APB region */ +/* + * Size is not really true actual APB window size is + * 0x01000000 but it should handle OHCI memory as well + * because this controller's interrupt is routed through + * APB. + */ +#define AR71XX_APB_BASE 0x18000000 +#define AR71XX_APB_SIZE 0x06000000 + /* DDR registers */ #define AR71XX_DDR_CONFIG 0x18000000 #define AR71XX_DDR_CONFIG2 0x18000004 From 1540246aab613064282a56dc19167d01a647031c Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 6 May 2009 02:34:35 +0000 Subject: [PATCH 055/380] - Rollback to legacy NFS RPC implementation. New one has unaligned memory access after nfsm_dissect --- sys/mips/conf/AR71XX | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/mips/conf/AR71XX b/sys/mips/conf/AR71XX index b8dfc1997f8..d8add88b7c2 100644 --- a/sys/mips/conf/AR71XX +++ b/sys/mips/conf/AR71XX @@ -25,6 +25,7 @@ options NFS_ROOT #NFS usable as /, requires NFSCLIENT options PSEUDOFS #Pseudo-filesystem framework options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions +options NFS_LEGACYRPC # Debugging for use in -current options INVARIANTS options INVARIANT_SUPPORT From ccf532a44b2ecfbab475de3a4b296609b64b12aa Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 6 May 2009 02:46:04 +0000 Subject: [PATCH 056/380] - Rollback to the hack with 3-bytes offset in base address. uart_bus_XXXXX resources are handled in uart(4) code and we need more sophysticated way to define which space should be used for device based on hints --- sys/mips/atheros/uart_bus_ar71xx.c | 6 ++++++ sys/mips/conf/AR71XX.hints | 4 +--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/sys/mips/atheros/uart_bus_ar71xx.c b/sys/mips/atheros/uart_bus_ar71xx.c index 1cb611ce092..a1abf4c5e98 100644 --- a/sys/mips/atheros/uart_bus_ar71xx.c +++ b/sys/mips/atheros/uart_bus_ar71xx.c @@ -72,6 +72,12 @@ uart_ar71xx_probe(device_t dev) sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); sc->sc_class = &uart_ns8250_class; bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); + sc->sc_sysdev->bas.regshft = 2; + sc->sc_sysdev->bas.bst = mips_bus_space_generic; + sc->sc_sysdev->bas.bsh = MIPS_PHYS_TO_KSEG1(AR71XX_UART_ADDR) + 3; + sc->sc_bas.regshft = 2; + sc->sc_bas.bst = mips_bus_space_generic; + sc->sc_bas.bsh = MIPS_PHYS_TO_KSEG1(AR71XX_UART_ADDR) + 3; return (uart_bus_probe(dev, 2, 85000000, 0, 0)); } diff --git a/sys/mips/conf/AR71XX.hints b/sys/mips/conf/AR71XX.hints index 091650a36c2..35635064e60 100644 --- a/sys/mips/conf/AR71XX.hints +++ b/sys/mips/conf/AR71XX.hints @@ -1,13 +1,11 @@ # $FreeBSD$ hint.apb.0.at="nexus0" -hint.apb.0.maddr=0x18000000 -hint.apb.0.msize=0x06000000 hint.apb.0.irq=4 # uart0 hint.uart.0.at="apb0" # see atheros/uart_cpu_ar71xx.c why +3 -hint.uart.0.maddr=0x18020000 +hint.uart.0.maddr=0x18020003 hint.uart.0.msize=0x18 hint.uart.0.irq=3 From aa5b8134138490860b526387c5b1c1dfdeb4d56d Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 6 May 2009 02:55:43 +0000 Subject: [PATCH 057/380] - Use index ops in order to avoid TLBMiss exceptions when flushing caches on mapping removal - Writeback all VA for page that is being copied in pmap_copy_page to guaranty up-to-date data in SDRAM --- sys/mips/mips/pmap.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index cc0daa25418..7b6164979f3 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -187,6 +187,7 @@ static int init_pte_prot(vm_offset_t va, vm_page_t m, vm_prot_t prot); static void pmap_TLB_invalidate_kernel(vm_offset_t); static void pmap_TLB_update_kernel(vm_offset_t, pt_entry_t); static void pmap_init_fpage(void); +static void pmap_flush_pvcache(vm_page_t m); #ifdef SMP static void pmap_invalidate_page_action(void *arg); @@ -702,7 +703,7 @@ pmap_kremove(vm_offset_t va) /* * Write back all caches from the page being destroyed */ - mips_dcache_wbinv_range(va, NBPG); + mips_dcache_wbinv_range_index(va, NBPG); pte = pmap_pte(kernel_pmap, va); *pte = PTE_G; @@ -1532,7 +1533,7 @@ pmap_remove_page(struct pmap *pmap, vm_offset_t va) /* * Write back all caches from the page being destroyed */ - mips_dcache_wbinv_range(va, NBPG); + mips_dcache_wbinv_range_index(va, NBPG); /* * get a local va for mappings for this pmap. @@ -1625,7 +1626,7 @@ pmap_remove_all(vm_page_t m) * the page being destroyed */ if (m->md.pv_list_count == 1) - mips_dcache_wbinv_range(pv->pv_va, NBPG); + mips_dcache_wbinv_range_index(pv->pv_va, NBPG); pv->pv_pmap->pm_stats.resident_count--; @@ -2373,7 +2374,6 @@ pmap_copy_page(vm_page_t src, vm_page_t dst) vm_paddr_t phy_src = VM_PAGE_TO_PHYS(src); vm_paddr_t phy_dst = VM_PAGE_TO_PHYS(dst); - #ifdef VM_ALLOC_WIRED_TLB_PG_POOL if (need_wired_tlb_page_pool) { struct fpage *fp1, *fp2; @@ -2403,9 +2403,14 @@ pmap_copy_page(vm_page_t src, vm_page_t dst) #endif { if ((phy_src < MIPS_KSEG0_LARGEST_PHYS) && (phy_dst < MIPS_KSEG0_LARGEST_PHYS)) { - /* easy case, all can be accessed via KSEG0 */ - va_src = MIPS_PHYS_TO_CACHED(phy_src); - va_dst = MIPS_PHYS_TO_CACHED(phy_dst); + /* easy case, all can be accessed via KSEG1 */ + /* + * Flush all caches for VA that are mapped to this page + * to make sure that data in SDRAM is up to date + */ + pmap_flush_pvcache(src); + va_src = MIPS_PHYS_TO_UNCACHED(phy_src); + va_dst = MIPS_PHYS_TO_UNCACHED(phy_dst); bcopy((caddr_t)va_src, (caddr_t)va_dst, PAGE_SIZE); } else { int cpu; @@ -3291,3 +3296,16 @@ pmap_kextract(vm_offset_t va) } return pa; } + +static void +pmap_flush_pvcache(vm_page_t m) +{ + pv_entry_t pv; + + if (m != NULL) { + for (pv = TAILQ_FIRST(&m->md.pv_list); pv; + pv = TAILQ_NEXT(pv, pv_list)) { + mips_dcache_wbinv_range_index(pv->pv_va, NBPG); + } + } +} From 5db10e923def8c040335b4a3c346bc83efbfc6ed Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 7 May 2009 03:39:23 +0000 Subject: [PATCH 058/380] - Add interrupt handling for AR71XX PCI bridge --- sys/mips/atheros/ar71xx_pci.c | 113 ++++++++++++++++++++++++++++++---- sys/mips/atheros/ar71xxreg.h | 1 + 2 files changed, 103 insertions(+), 11 deletions(-) diff --git a/sys/mips/atheros/ar71xx_pci.c b/sys/mips/atheros/ar71xx_pci.c index d3a9295d7aa..8aaf60d248f 100644 --- a/sys/mips/atheros/ar71xx_pci.c +++ b/sys/mips/atheros/ar71xx_pci.c @@ -68,10 +68,34 @@ struct ar71xx_pci_softc { struct rman sc_mem_rman; struct rman sc_irq_rman; + struct intr_event *sc_eventstab[AR71XX_PCI_NIRQS]; struct resource *sc_irq; void *sc_ih; }; +static int ar71xx_pci_setup_intr(device_t, device_t, struct resource *, int, + driver_filter_t *, driver_intr_t *, void *, void **); +static int ar71xx_pci_teardown_intr(device_t, device_t, struct resource *, + void *); +static int ar71xx_pci_intr(void *); + +static void ar71xx_pci_mask_irq(unsigned int irq) +{ + uint32_t reg; + + reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK); + ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, reg & ~(1 << irq)); + +} + +static void ar71xx_pci_unmask_irq(unsigned int irq) +{ + uint32_t reg; + + reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK); + ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, reg | (1 << irq)); +} + /* * get bitmask for bytes of interest: * 0 - we want this byte, 1 - ignore it. e.g: we read 1 byte @@ -212,13 +236,6 @@ ar71xx_pci_write_config(device_t dev, int bus, int slot, int func, int reg, } } -static int -at71xx_pci_intr(void *v) -{ - panic("Implement me: %s\n", __func__); - return FILTER_HANDLED; -} - static int ar71xx_pci_probe(device_t dev) { @@ -261,7 +278,7 @@ ar71xx_pci_attach(device_t dev) } if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC, - at71xx_pci_intr, NULL, sc, &sc->sc_ih))) { + ar71xx_pci_intr, NULL, sc, &sc->sc_ih))) { device_printf(dev, "WARNING: unable to register interrupt handler\n"); return ENXIO; @@ -369,11 +386,85 @@ ar71xx_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, } static int -ar71xx_pci_teardown_intr(device_t dev, device_t child, struct resource *res, +ar71xx_pci_setup_intr(device_t bus, device_t child, struct resource *ires, + int flags, driver_filter_t *filt, driver_intr_t *handler, + void *arg, void **cookiep) +{ + struct ar71xx_pci_softc *sc = device_get_softc(bus); + struct intr_event *event; + int irq, error; + + irq = rman_get_start(ires); + + if (irq > AR71XX_PCI_IRQ_END) + panic("%s: bad irq %d", __func__, irq); + + event = sc->sc_eventstab[irq]; + if (event == NULL) { + error = intr_event_create(&event, (void *)irq, 0, irq, + (mask_fn)ar71xx_pci_mask_irq, + (mask_fn)ar71xx_pci_unmask_irq, + NULL, NULL, + "ar71xx_pci intr%d:", irq); + + sc->sc_eventstab[irq] = event; + } + + intr_event_add_handler(event, device_get_nameunit(child), filt, + handler, arg, intr_priority(flags), flags, cookiep); + + ar71xx_pci_unmask_irq(irq); + + return (0); +} + +static int +ar71xx_pci_teardown_intr(device_t dev, device_t child, struct resource *ires, void *cookie) { + struct ar71xx_pci_softc *sc = device_get_softc(dev); + int irq, result; - return (intr_event_remove_handler(cookie)); + irq = rman_get_start(ires); + if (irq > AR71XX_PCI_IRQ_END) + panic("%s: bad irq %d", __func__, irq); + + if (sc->sc_eventstab[irq] == NULL) + panic("Trying to teardown unoccupied IRQ"); + + ar71xx_pci_mask_irq(irq); + + result = intr_event_remove_handler(cookie); + if (!result) + sc->sc_eventstab[irq] = NULL; + + return (result); +} + +static int +ar71xx_pci_intr(void *arg) +{ + struct ar71xx_pci_softc *sc = arg; + struct intr_event *event; + uint32_t reg, irq; + + reg = ATH_READ_REG(AR71XX_PCI_INTR_STATUS); + for (irq = AR71XX_PCI_IRQ_START; irq <= AR71XX_PCI_IRQ_END; irq++) { + if (reg & (1 << irq)) { + event = sc->sc_eventstab[irq]; + if (!event || TAILQ_EMPTY(&event->ie_handlers)) { + /* Ignore timer interrupts */ + if (irq != 0) + printf("Stray IRQ %d\n", irq); + continue; + } + + /* TODO: frame instead of NULL? */ + intr_event_handle(event, NULL); + } + } + + return (FILTER_HANDLED); } static int @@ -406,7 +497,7 @@ static device_method_t ar71xx_pci_methods[] = { DEVMETHOD(bus_release_resource, bus_generic_release_resource), DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_setup_intr, ar71xx_pci_setup_intr), DEVMETHOD(bus_teardown_intr, ar71xx_pci_teardown_intr), /* pcib interface */ diff --git a/sys/mips/atheros/ar71xxreg.h b/sys/mips/atheros/ar71xxreg.h index 189a84e6225..ba2fb8aa471 100644 --- a/sys/mips/atheros/ar71xxreg.h +++ b/sys/mips/atheros/ar71xxreg.h @@ -41,6 +41,7 @@ #define AR71XX_PCI_MEM_SIZE 0x07000000 #define AR71XX_PCI_IRQ_START 0 #define AR71XX_PCI_IRQ_END 2 +#define AR71XX_PCI_NIRQS 3 /* PCI config registers */ #define AR71XX_PCI_LCONF_CMD 0x17010000 From a88b9b52e335bde14898c46e56cc8df2d5ecf238 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 14 May 2009 21:15:27 +0000 Subject: [PATCH 059/380] - Remove garbage debug output --- sys/mips/atheros/apb.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/mips/atheros/apb.c b/sys/mips/atheros/apb.c index f6e20a7d200..fad29ecab52 100644 --- a/sys/mips/atheros/apb.c +++ b/sys/mips/atheros/apb.c @@ -166,8 +166,6 @@ apb_alloc_resource(device_t bus, device_t child, int type, int *rid, return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, rid, start, end, count, flags)); - printf("not pass through\n"); - /* * If this is an allocation of the "default" range for a given RID, * and we know what the resources for this device are (ie. they aren't From c5d30a225484e0cc3108eb729679e3305370b7e6 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 14 May 2009 21:26:07 +0000 Subject: [PATCH 060/380] - Off by one check fix. Check for last address in region to fit in KSEG1 --- sys/mips/mips/pmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index c8dabf4aa56..0842ea3e460 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -2819,7 +2819,7 @@ pmap_mapdev(vm_offset_t pa, vm_size_t size) * KSEG1 maps only first 512M of phys address space. For * pa > 0x20000000 we should make proper mapping * using pmap_kenter. */ - if (pa + size < MIPS_KSEG0_LARGEST_PHYS) + if ((pa + size - 1) < MIPS_KSEG0_LARGEST_PHYS) return (void *)MIPS_PHYS_TO_KSEG1(pa); else { offset = pa & PAGE_MASK; From ce205fb47f118dd0afd01d7c65dcfb16cf880723 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 14 May 2009 21:27:03 +0000 Subject: [PATCH 061/380] - Add SPI-related registers --- sys/mips/atheros/ar71xxreg.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sys/mips/atheros/ar71xxreg.h b/sys/mips/atheros/ar71xxreg.h index ba2fb8aa471..8f595cf3c32 100644 --- a/sys/mips/atheros/ar71xxreg.h +++ b/sys/mips/atheros/ar71xxreg.h @@ -324,4 +324,17 @@ #define DMA_INTR_TX_UNDERRUN (1 << 1) #define DMA_INTR_TX_PKT_SENT (1 << 0) +#define AR71XX_SPI_BASE 0x1f000000 +#define AR71XX_SPI_FS 0x00 +#define AR71XX_SPI_CTRL 0x04 +#define SPI_CTRL_REMAP_DISABLE (1 << 6) +#define SPI_CTRL_CLOCK_DIVIDER_MASK ((1 << 6) - 1) +#define AR71XX_SPI_IO_CTRL 0x08 +#define SPI_IO_CTRL_CS2 (1 << 18) +#define SPI_IO_CTRL_CS1 (1 << 17) +#define SPI_IO_CTRL_CS0 (1 << 16) +#define SPI_IO_CTRL_CLK (1 << 8) +#define SPI_IO_CTRL_DO 1 +#define AR71XX_SPI_RDS 0x0C + #endif /* _AR71XX_REG_H_ */ From 9b54fef7f52ac09d70d3648dfb6ff7727db5e4f8 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 15 May 2009 01:51:47 +0000 Subject: [PATCH 062/380] - Add definitions for PLL CPU Config register fields --- sys/mips/atheros/ar71xxreg.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/sys/mips/atheros/ar71xxreg.h b/sys/mips/atheros/ar71xxreg.h index 8f595cf3c32..b519df2e08a 100644 --- a/sys/mips/atheros/ar71xxreg.h +++ b/sys/mips/atheros/ar71xxreg.h @@ -136,7 +136,26 @@ #define USB_CTRL_CONFIG_RESUME_UTMI_PLS_DIS (1 << 1) #define USB_CTRL_CONFIG_UTMI_BACKWARD_ENB (1 << 0) +#define AR71XX_BASE_FREQ 40000000 #define AR71XX_PLL_CPU_CONFIG 0x18050000 +#define PLL_SW_UPDATE (1 << 31) +#define PLL_LOCKED (1 << 30) +#define PLL_AHB_DIV_SHIFT 20 +#define PLL_AHB_DIV_MASK 7 +#define PLL_DDR_DIV_SEL_SHIFT 18 +#define PLL_DDR_DIV_SEL_MASK 3 +#define PLL_CPU_DIV_SEL_SHIFT 16 +#define PLL_CPU_DIV_SEL_MASK 2 +#define PLL_LOOP_BW_SHIFT 12 +#define PLL_LOOP_BW_MASK 0xf +#define PLL_DIV_IN_SHIFT 10 +#define PLL_DIV_IN_MASK 3 +#define PLL_DIV_OUT_SHIFT 8 +#define PLL_DIV_OUT_MASK 3 +#define PLL_FB_SHIFT 3 +#define PLL_FB_MASK 0x1f +#define PLL_BYPASS (1 << 1) +#define PLL_POWER_DOWN (1 << 0) #define AR71XX_PLL_SEC_CONFIG 0x18050004 #define AR71XX_PLL_CPU_CLK_CTRL 0x18050008 #define AR71XX_PLL_ETH_INT0_CLK 0x18050010 From b31707c84937b5d535396a0c0d731d91952dbb2f Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 15 May 2009 01:53:09 +0000 Subject: [PATCH 063/380] - Calculate CPU frequency using dividers from PLL registers --- sys/mips/atheros/ar71xx_machdep.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/sys/mips/atheros/ar71xx_machdep.c b/sys/mips/atheros/ar71xx_machdep.c index a5699edb7ee..98576ef6332 100644 --- a/sys/mips/atheros/ar71xx_machdep.c +++ b/sys/mips/atheros/ar71xx_machdep.c @@ -97,8 +97,8 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, __register_t a2 __unused, __register_t a3 __unused) { vm_offset_t kernend; - uint64_t platform_counter_freq; - uint32_t reg; + uint64_t platform_counter_freq, freq; + uint32_t reg, div, pll_config; /* clear the BSS and SBSS segments */ kernend = round_page((vm_offset_t)&end); @@ -118,11 +118,16 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, * should be called first. */ init_param1(); - /* TODO: Get CPU freq from RedBoot. Is it possible? */ - platform_counter_freq = 680000000UL; + pll_config = ATH_READ_REG(AR71XX_PLL_CPU_CONFIG); + div = ((pll_config >> PLL_FB_SHIFT) & PLL_FB_MASK) + 1; + freq = div * AR71XX_BASE_FREQ; + div = ((pll_config >> PLL_CPU_DIV_SEL_SHIFT) & PLL_CPU_DIV_SEL_MASK) + + 1; + platform_counter_freq = freq / div; mips_timer_init_params(platform_counter_freq, 0); cninit(); + printf("platform frequency: %lld\n", platform_counter_freq); printf("arguments: \n"); printf(" a0 = %08x\n", a0); printf(" a1 = %08x\n", a1); From b75cca0708c49d336a8ca585321fb000c9c61ad3 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 15 May 2009 01:54:32 +0000 Subject: [PATCH 064/380] - Calculate clock frequency using PLL registers - Remove stale comments --- sys/mips/atheros/uart_cpu_ar71xx.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/sys/mips/atheros/uart_cpu_ar71xx.c b/sys/mips/atheros/uart_cpu_ar71xx.c index c18bc7141b5..67b5d98c1d2 100644 --- a/sys/mips/atheros/uart_cpu_ar71xx.c +++ b/sys/mips/atheros/uart_cpu_ar71xx.c @@ -53,27 +53,34 @@ uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) int uart_cpu_getdev(int devtype, struct uart_devinfo *di) { + uint32_t pll_config, div; + uint64_t freq; + + /* PLL freq */ + pll_config = ATH_READ_REG(AR71XX_PLL_CPU_CONFIG); + div = ((pll_config >> PLL_FB_SHIFT) & PLL_FB_MASK) + 1; + freq = div * AR71XX_BASE_FREQ; + /* CPU freq */ + div = ((pll_config >> PLL_CPU_DIV_SEL_SHIFT) & PLL_CPU_DIV_SEL_MASK) + + 1; + freq = freq / div; + /* AHB freq */ + div = (((pll_config >> PLL_AHB_DIV_SHIFT) & PLL_AHB_DIV_MASK) + 1) * 2; + freq = freq / div; + di->ops = uart_getops(&uart_ns8250_class); di->bas.chan = 0; di->bas.bst = ar71xx_bus_space_reversed; di->bas.regshft = 2; - /* TODO: calculate proper AHB freq using PLL registers */ - di->bas.rclk = 85000000; + di->bas.rclk = freq; di->baudrate = 115200; di->databits = 8; di->stopbits = 1; + di->parity = UART_PARITY_NONE; - /* TODO: check if uart_bus_space_io mandatory to set */ uart_bus_space_io = NULL; uart_bus_space_mem = ar71xx_bus_space_reversed; - /* - * FIXME: - * 3 is to compensate big endian, uart operates - * with bus_space_read_1/bus_space_write_1 and hence gets - * highest byte instead of lowest one. Actual fix will involve - * MIPS bus_space fixing. - */ di->bas.bsh = MIPS_PHYS_TO_KSEG1(AR71XX_UART_ADDR); return (0); } From bcc90b6ff59e8d139ecf0a3ee3696aa230e982a8 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 15 May 2009 21:36:50 +0000 Subject: [PATCH 065/380] - Add pci bus space that translates byte order to little endian, may be it will be merged with bus_space_reversed later - Handle memory resources close to bus in order to control bus_space_tag --- sys/mips/atheros/ar71xx_pci.c | 30 +++- sys/mips/atheros/ar71xx_pci_bus_space.c | 198 ++++++++++++++++++++++++ sys/mips/atheros/ar71xx_pci_bus_space.h | 33 ++++ sys/mips/atheros/files.ar71xx | 1 + 4 files changed, 259 insertions(+), 3 deletions(-) create mode 100644 sys/mips/atheros/ar71xx_pci_bus_space.c create mode 100644 sys/mips/atheros/ar71xx_pci_bus_space.h diff --git a/sys/mips/atheros/ar71xx_pci.c b/sys/mips/atheros/ar71xx_pci.c index 8aaf60d248f..ee186b7aa61 100644 --- a/sys/mips/atheros/ar71xx_pci.c +++ b/sys/mips/atheros/ar71xx_pci.c @@ -52,7 +52,8 @@ __FBSDID("$FreeBSD$"); #include #include "pcib_if.h" -#include "mips/atheros/ar71xxreg.h" +#include +#include #undef AR71XX_PCI_DEBUG #ifdef AR71XX_PCI_DEBUG @@ -354,7 +355,7 @@ ar71xx_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, { struct ar71xx_pci_softc *sc = device_get_softc(bus); - struct resource *rv = NULL; + struct resource *rv; struct rman *rm; switch (type) { @@ -382,9 +383,32 @@ ar71xx_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, } } + return (rv); } + +static int +ar71xx_pci_activate_resource(device_t bus, device_t child, int type, int rid, + struct resource *r) +{ + int res = (BUS_ACTIVATE_RESOURCE(device_get_parent(bus), + child, type, rid, r)); + + if (!res) { + switch(type) { + case SYS_RES_MEMORY: + case SYS_RES_IOPORT: + rman_set_bustag(r, ar71xx_bus_space_pcimem); + break; + } + } + + return (res); +} + + + static int ar71xx_pci_setup_intr(device_t bus, device_t child, struct resource *ires, int flags, driver_filter_t *filt, driver_intr_t *handler, @@ -495,7 +519,7 @@ static device_method_t ar71xx_pci_methods[] = { DEVMETHOD(bus_write_ivar, ar71xx_pci_write_ivar), DEVMETHOD(bus_alloc_resource, ar71xx_pci_alloc_resource), DEVMETHOD(bus_release_resource, bus_generic_release_resource), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_activate_resource, ar71xx_pci_activate_resource), DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), DEVMETHOD(bus_setup_intr, ar71xx_pci_setup_intr), DEVMETHOD(bus_teardown_intr, ar71xx_pci_teardown_intr), diff --git a/sys/mips/atheros/ar71xx_pci_bus_space.c b/sys/mips/atheros/ar71xx_pci_bus_space.c new file mode 100644 index 00000000000..55401819673 --- /dev/null +++ b/sys/mips/atheros/ar71xx_pci_bus_space.c @@ -0,0 +1,198 @@ +/*- + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include + +static bs_r_1_s_proto(pcimem); +static bs_r_2_s_proto(pcimem); +static bs_r_4_s_proto(pcimem); +static bs_w_1_s_proto(pcimem); +static bs_w_2_s_proto(pcimem); +static bs_w_4_s_proto(pcimem); + +/* + * Bus space that handles offsets in word for 1/2 bytes read/write access. + * Byte order of values is handled by device drivers itself. + */ +static struct bus_space bus_space_pcimem = { + /* cookie */ + (void *) 0, + + /* mapping/unmapping */ + generic_bs_map, + generic_bs_unmap, + generic_bs_subregion, + + /* allocation/deallocation */ + NULL, + NULL, + + /* barrier */ + generic_bs_barrier, + + /* read (single) */ + generic_bs_r_1, + generic_bs_r_2, + generic_bs_r_4, + NULL, + + /* read multiple */ + generic_bs_rm_1, + generic_bs_rm_2, + generic_bs_rm_4, + NULL, + + /* read region */ + generic_bs_rr_1, + generic_bs_rr_2, + generic_bs_rr_4, + NULL, + + /* write (single) */ + generic_bs_w_1, + generic_bs_w_2, + generic_bs_w_4, + NULL, + + /* write multiple */ + generic_bs_wm_1, + generic_bs_wm_2, + generic_bs_wm_4, + NULL, + + /* write region */ + NULL, + generic_bs_wr_2, + generic_bs_wr_4, + NULL, + + /* set multiple */ + NULL, + NULL, + NULL, + NULL, + + /* set region */ + NULL, + generic_bs_sr_2, + generic_bs_sr_4, + NULL, + + /* copy */ + NULL, + generic_bs_c_2, + NULL, + NULL, + + /* read (single) stream */ + pcimem_bs_r_1_s, + pcimem_bs_r_2_s, + pcimem_bs_r_4_s, + NULL, + + /* read multiple stream */ + generic_bs_rm_1, + generic_bs_rm_2, + generic_bs_rm_4, + NULL, + + /* read region stream */ + generic_bs_rr_1, + generic_bs_rr_2, + generic_bs_rr_4, + NULL, + + /* write (single) stream */ + pcimem_bs_w_1_s, + pcimem_bs_w_2_s, + pcimem_bs_w_4_s, + NULL, + + /* write multiple stream */ + generic_bs_wm_1, + generic_bs_wm_2, + generic_bs_wm_4, + NULL, + + /* write region stream */ + NULL, + generic_bs_wr_2, + generic_bs_wr_4, + NULL, +}; + +bus_space_tag_t ar71xx_bus_space_pcimem = &bus_space_pcimem; + +static uint8_t +pcimem_bs_r_1_s(void *t, bus_space_handle_t h, bus_size_t o) +{ + + return readb(h + (o &~ 3) + (3 - (o & 3))); +} + +static void +pcimem_bs_w_1_s(void *t, bus_space_handle_t h, bus_size_t o, u_int8_t v) +{ + + writeb(h + (o &~ 3) + (3 - (o & 3)), v); +} + +static uint16_t +pcimem_bs_r_2_s(void *t, bus_space_handle_t h, bus_size_t o) +{ + + return readw(h + (o &~ 3) + (2 - (o & 3))); +} + +static void +pcimem_bs_w_2_s(void *t, bus_space_handle_t h, bus_size_t o, uint16_t v) +{ + + writew(h + (o &~ 3) + (2 - (o & 3)), v); +} + +static uint32_t +pcimem_bs_r_4_s(void *t, bus_space_handle_t h, bus_size_t o) +{ + + return le32toh(readl(h + o)); +} + +static void +pcimem_bs_w_4_s(void *t, bus_space_handle_t h, bus_size_t o, uint32_t v) +{ + + writel(h + o, htole32(v)); +} diff --git a/sys/mips/atheros/ar71xx_pci_bus_space.h b/sys/mips/atheros/ar71xx_pci_bus_space.h new file mode 100644 index 00000000000..5dead02a1ec --- /dev/null +++ b/sys/mips/atheros/ar71xx_pci_bus_space.h @@ -0,0 +1,33 @@ +/*- + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __AR71XX_PCI_BUS_SPACEH__ +#define __AR71XX_PCI_BUS_SPACEH__ + +extern bus_space_tag_t ar71xx_bus_space_pcimem; + +#endif /* __AR71XX_PCI_BUS_SPACEH__ */ diff --git a/sys/mips/atheros/files.ar71xx b/sys/mips/atheros/files.ar71xx index 0f1e8f16bf8..047fad85fc9 100644 --- a/sys/mips/atheros/files.ar71xx +++ b/sys/mips/atheros/files.ar71xx @@ -5,6 +5,7 @@ mips/atheros/ar71xx_machdep.c standard mips/atheros/ar71xx_ehci.c optional ehci mips/atheros/ar71xx_ohci.c optional ohci mips/atheros/ar71xx_pci.c optional pci +mips/atheros/ar71xx_pci_bus_space.c optional pci mips/atheros/if_arge.c optional arge mips/atheros/uart_bus_ar71xx.c optional uart mips/atheros/uart_cpu_ar71xx.c optional uart From a2f4a6ee3cf4e7280317a9eb09e17ba6d3567e02 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sat, 16 May 2009 02:34:03 +0000 Subject: [PATCH 066/380] - Add informational title for cache info lines to separate them from environment variables dump --- sys/mips/mips/cache_mipsNN.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/mips/mips/cache_mipsNN.c b/sys/mips/mips/cache_mipsNN.c index 4037885b73e..1b27776a0dc 100644 --- a/sys/mips/mips/cache_mipsNN.c +++ b/sys/mips/mips/cache_mipsNN.c @@ -115,6 +115,7 @@ mipsNN_cache_init(struct mips_cpuinfo * cpuinfo) pdcache_way_mask = cpuinfo->l1.dc_nways - 1; #define CACHE_DEBUG #ifdef CACHE_DEBUG + printf("Cache info:\n"); if (cpuinfo->icache_virtual) printf(" icache is virtual\n"); printf(" picache_stride = %d\n", picache_stride); From 9270c7be8b9d5d266a9e89090cf1e809e27e0268 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sat, 16 May 2009 02:39:13 +0000 Subject: [PATCH 067/380] - Add MIPS_IS_KSEG0_ADDR, MIPS_IS_KSEG1_ADDR and MIPS_IS_VALID_PTR macroses thet check if address belongs to KSEG0, KSEG1 or both of them respectively. --- sys/mips/include/cpu.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sys/mips/include/cpu.h b/sys/mips/include/cpu.h index 20b41e2a027..11b81df381b 100644 --- a/sys/mips/include/cpu.h +++ b/sys/mips/include/cpu.h @@ -72,6 +72,15 @@ #define MIPS_KSEG0_TO_PHYS(x) ((unsigned)(x) & MIPS_PHYS_MASK) #define MIPS_KSEG1_TO_PHYS(x) ((unsigned)(x) & MIPS_PHYS_MASK) +#define MIPS_IS_KSEG0_ADDR(x) \ + (((vm_offset_t)(x) >= MIPS_KSEG0_START) && \ + ((vm_offset_t)(x) <= MIPS_KSEG0_END)) +#define MIPS_IS_KSEG1_ADDR(x) \ + (((vm_offset_t)(x) >= MIPS_KSEG1_START) && \ + ((vm_offset_t)(x) <= MIPS_KSEG1_END)) +#define MIPS_IS_VALID_PTR(x) (MIPS_IS_KSEG0_ADDR(x) || \ + MIPS_IS_KSEG1_ADDR(x)) + /* * Status register. */ From 89616da3f5c98abe29e75562ce2550216c9c5946 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sat, 16 May 2009 02:43:24 +0000 Subject: [PATCH 068/380] - Get memory size and base MAC address from RedBoot (if available) --- sys/mips/atheros/ar71xx_machdep.c | 54 +++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/sys/mips/atheros/ar71xx_machdep.c b/sys/mips/atheros/ar71xx_machdep.c index 98576ef6332..5abe75bccca 100644 --- a/sys/mips/atheros/ar71xx_machdep.c +++ b/sys/mips/atheros/ar71xx_machdep.c @@ -45,6 +45,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include #include #include @@ -56,6 +58,7 @@ __FBSDID("$FreeBSD$"); extern int *edata; extern int *end; +uint32_t ar711_base_mac[ETHER_ADDR_LEN]; void platform_halt(void) @@ -99,13 +102,43 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, vm_offset_t kernend; uint64_t platform_counter_freq, freq; uint32_t reg, div, pll_config; + int argc, i, count = 0; + char **argv, **envp; /* clear the BSS and SBSS segments */ kernend = round_page((vm_offset_t)&end); memset(&edata, 0, kernend - (vm_offset_t)(&edata)); - /* TODO: Get available memory from RedBoot. Is it possible? */ - realmem = btoc(64*1024*1024); + argc = a0; + argv = (char**)a1; + envp = (char**)a2; + /* + * Protect ourselves from garbage in registers + */ + if (MIPS_IS_VALID_PTR(envp)) { + for (i = 0; envp[i]; i += 2) + { + if (strcmp(envp[i], "memsize") == 0) + realmem = btoc(strtoul(envp[i+1], NULL, 16)); + else if (strcmp(envp[i], "ethaddr") == 0) { + count = sscanf(envp[i+1], "%x.%x.%x.%x.%x.%x", + &ar711_base_mac[0], &ar711_base_mac[1], + &ar711_base_mac[2], &ar711_base_mac[3], + &ar711_base_mac[4], &ar711_base_mac[5]); + if (count < 6) + memset(ar711_base_mac, 0, + sizeof(ar711_base_mac)); + } + } + } + + /* + * Just wild guess. RedBoot let us down and didn't reported + * memory size + */ + if (realmem == 0) + realmem = btoc(32*1024*1024); + /* phys_avail regions are in bytes */ phys_avail[0] = MIPS_KSEG0_TO_PHYS((vm_offset_t)&end); phys_avail[1] = ctob(realmem); @@ -134,6 +167,23 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, printf(" a2 = %08x\n", a2); printf(" a3 = %08x\n", a3); + printf("Cmd line:"); + if (MIPS_IS_VALID_PTR(argv)) { + for (i = 0; i < argc; i++) + printf(" %s", argv[i]); + } + else + printf ("argv is invalid"); + printf("\n"); + + printf("Environment:\n"); + if (MIPS_IS_VALID_PTR(envp)) { + for (i = 0; envp[i]; i+=2) + printf(" %s = %s\n", envp[i], envp[i+1]); + } + else + printf ("envp is invalid\n"); + init_param2(physmem); mips_cpu_init(); pmap_bootstrap(); From b665f0d4b7a699d01af0d54ae233c48cf2d845cb Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sat, 16 May 2009 02:45:38 +0000 Subject: [PATCH 069/380] - Set MAC Address obtained from RedBoot or generate random one --- sys/mips/atheros/if_arge.c | 39 +++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index a3f38e09ccc..b3237c2c385 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -152,6 +152,13 @@ static devclass_t arge_devclass; DRIVER_MODULE(arge, nexus, arge_driver, arge_devclass, 0, 0); DRIVER_MODULE(miibus, arge, miibus_driver, miibus_devclass, 0, 0); +/* + * RedBoot passes MAC address to entry point as environment + * variable. platfrom_start parses it and stores in this variable + */ +extern uint32_t ar711_base_mac[ETHER_ADDR_LEN]; + + /* * Flushes all */ @@ -183,7 +190,8 @@ arge_attach(device_t dev) struct ifnet *ifp; struct arge_softc *sc; int error = 0, rid, phynum; - uint32_t reg; + uint32_t reg, rnd; + int is_base_mac_empty, i; sc = device_get_softc(dev); sc->arge_dev = dev; @@ -269,12 +277,29 @@ arge_attach(device_t dev) ifp->if_capenable = ifp->if_capabilities; - eaddr[0] = 0x00; - eaddr[1] = 0x15; - eaddr[2] = 0x6d; - eaddr[3] = 0xc1; - eaddr[4] = 0x28; - eaddr[5] = 0x2e; + is_base_mac_empty = 1; + for (i = 0; i < ETHER_ADDR_LEN; i++) { + eaddr[i] = ar711_base_mac[i] & 0xff; + if (eaddr[i] != 0) + is_base_mac_empty = 0; + } + + if (is_base_mac_empty) { + /* + * No MAC address configured. Generate the random one. + */ + if (bootverbose) + device_printf(dev, + "Generating random ethernet address.\n"); + + rnd = arc4random(); + eaddr[0] = 'b'; + eaddr[1] = 's'; + eaddr[2] = 'd'; + eaddr[3] = (rnd >> 24) & 0xff; + eaddr[4] = (rnd >> 16) & 0xff; + eaddr[5] = (rnd >> 8) & 0xff; + } if (arge_dma_alloc(sc) != 0) { error = ENXIO; From cd5bdf0367b619cb1ab1e859923c629950c93aa1 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 18 May 2009 23:20:56 +0000 Subject: [PATCH 070/380] - Add support for MX25Lxxx SPI flash (readonly atm) --- sys/conf/files | 1 + sys/dev/flash/mx25l.c | 313 +++++++++++++++++++++++++++++++++++++++ sys/dev/flash/mx25lreg.h | 56 +++++++ 3 files changed, 370 insertions(+) create mode 100644 sys/dev/flash/mx25l.c create mode 100644 sys/dev/flash/mx25lreg.h diff --git a/sys/conf/files b/sys/conf/files index 567f32cf40f..52667727330 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -903,6 +903,7 @@ dev/firewire/if_fwip.c optional fwip dev/firewire/sbp.c optional sbp dev/firewire/sbp_targ.c optional sbp_targ dev/flash/at45d.c optional at45d +dev/flash/mx25l.c optional mx25l dev/fxp/if_fxp.c optional fxp dev/gem/if_gem.c optional gem dev/gem/if_gem_pci.c optional gem pci diff --git a/sys/dev/flash/mx25l.c b/sys/dev/flash/mx25l.c new file mode 100644 index 00000000000..cdbf4e519bd --- /dev/null +++ b/sys/dev/flash/mx25l.c @@ -0,0 +1,313 @@ +/*- + * Copyright (c) 2006 M. Warner Losh. All rights reserved. + * Copyright (c) 2009 Oleksandr Tymoshenko. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "spibus_if.h" + +#include + +struct mx25l_flash_ident +{ + const char *name; + uint8_t manufacturer_id; + uint16_t device_id; + unsigned int sectorsize; + unsigned int sectorcount; +}; + +struct mx25l_softc +{ + device_t sc_dev; + uint8_t sc_manufacturer_id; + uint16_t sc_device_id; + struct mtx sc_mtx; + struct disk *sc_disk; + struct proc *sc_p; + struct bio_queue_head sc_bio_queue; +}; + +#define M25PXX_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) +#define M25PXX_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) +#define M25PXX_LOCK_INIT(_sc) \ + mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_dev), \ + "mx25l", MTX_DEF) +#define M25PXX_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); +#define M25PXX_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); +#define M25PXX_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); + +/* disk routines */ +static int mx25l_open(struct disk *dp); +static int mx25l_close(struct disk *dp); +static int mx25l_ioctl(struct disk *, u_long, void *, int, struct thread *); +static void mx25l_strategy(struct bio *bp); +static void mx25l_task(void *arg); + +struct mx25l_flash_ident flash_devices[] = { + { "mx25ll32", 0xc2, 0x2016, 64 * 1024, 64 }, + { "mx25ll64", 0xc2, 0x2017, 64 * 1024, 128 }, + { "mx25ll128", 0xc2, 0x2018, 64 * 1024, 256 }, +}; + +static uint8_t +mx25l_get_status(device_t dev) +{ + uint8_t txBuf[2], rxBuf[2]; + struct spi_command cmd; + int err; + + memset(&cmd, 0, sizeof(cmd)); + memset(txBuf, 0, sizeof(txBuf)); + memset(rxBuf, 0, sizeof(rxBuf)); + + txBuf[0] = CMD_READ_STATUS; + cmd.tx_cmd = txBuf; + cmd.rx_cmd = rxBuf; + cmd.rx_cmd_sz = 2; + cmd.tx_cmd_sz = 2; + err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd); + return (rxBuf[1]); +} + +static void +mx25l_wait_for_device_ready(device_t dev) +{ + while ((mx25l_get_status(dev) & STATUS_WIP)) + continue; +} + +static struct mx25l_flash_ident* +mx25l_get_device_ident(struct mx25l_softc *sc) +{ + device_t dev = sc->sc_dev; + uint8_t txBuf[8], rxBuf[8]; + struct spi_command cmd; + uint8_t manufacturer_id; + uint16_t dev_id; + int err, i; + + memset(&cmd, 0, sizeof(cmd)); + memset(txBuf, 0, sizeof(txBuf)); + memset(rxBuf, 0, sizeof(rxBuf)); + + txBuf[0] = CMD_READ_IDENT; + cmd.tx_cmd = &txBuf; + cmd.rx_cmd = &rxBuf; + /* + * Some compatible devices has extended two-bytes ID + * We'll use only manufacturer/deviceid atm + */ + cmd.tx_cmd_sz = 4; + cmd.rx_cmd_sz = 4; + err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd); + if (err) + return (NULL); + + manufacturer_id = rxBuf[1]; + dev_id = (rxBuf[2] << 8) | (rxBuf[3]); + + for (i = 0; + i < sizeof(flash_devices)/sizeof(struct mx25l_flash_ident); i++) { + if ((flash_devices[i].manufacturer_id == manufacturer_id) && + (flash_devices[i].device_id == dev_id)) + return &flash_devices[i]; + } + + printf("Unknown SPI flash device. Vendor: %02x, device id: %04x\n", + manufacturer_id, dev_id); + return (NULL); +} + +static int +mx25l_probe(device_t dev) +{ + device_set_desc(dev, "M25Pxx Flash Family"); + return (0); +} + +static int +mx25l_attach(device_t dev) +{ + struct mx25l_softc *sc; + struct mx25l_flash_ident *ident; + + sc = device_get_softc(dev); + sc->sc_dev = dev; + M25PXX_LOCK_INIT(sc); + + ident = mx25l_get_device_ident(sc); + if (ident == NULL) + return (ENXIO); + + mx25l_wait_for_device_ready(sc->sc_dev); + + sc->sc_disk = disk_alloc(); + sc->sc_disk->d_open = mx25l_open; + sc->sc_disk->d_close = mx25l_close; + sc->sc_disk->d_strategy = mx25l_strategy; + sc->sc_disk->d_ioctl = mx25l_ioctl; + sc->sc_disk->d_name = "flash/spi"; + sc->sc_disk->d_drv1 = sc; + sc->sc_disk->d_maxsize = DFLTPHYS; + sc->sc_disk->d_sectorsize = ident->sectorsize; + sc->sc_disk->d_mediasize = ident->sectorsize * ident->sectorcount; + sc->sc_disk->d_unit = device_get_unit(sc->sc_dev); + sc->sc_disk->d_dump = NULL; /* NB: no dumps */ + + /* NB: use stripesize to hold the erase/region size for RedBoot */ + sc->sc_disk->d_stripesize = ident->sectorsize; + + disk_create(sc->sc_disk, DISK_VERSION); + bioq_init(&sc->sc_bio_queue); + + kproc_create(&mx25l_task, sc, &sc->sc_p, 0, 0, "task: mx25l flash"); + device_printf(sc->sc_dev, "%s, sector %d bytes, %d sectors\n", + ident->name, ident->sectorsize, ident->sectorcount); + + return (0); +} + +static int +mx25l_detach(device_t dev) +{ + + return (EIO); +} + +static int +mx25l_open(struct disk *dp) +{ + return (0); +} + +static int +mx25l_close(struct disk *dp) +{ + + return (0); +} + +static int +mx25l_ioctl(struct disk *dp, u_long cmd, void *data, int fflag, + struct thread *td) +{ + + return (EINVAL); +} + + +static void +mx25l_strategy(struct bio *bp) +{ + struct mx25l_softc *sc; + + sc = (struct mx25l_softc *)bp->bio_disk->d_drv1; + M25PXX_LOCK(sc); + bioq_disksort(&sc->sc_bio_queue, bp); + wakeup(sc); + M25PXX_UNLOCK(sc); +} + +static void +mx25l_task(void *arg) +{ + struct mx25l_softc *sc = (struct mx25l_softc*)arg; + struct bio *bp; + uint8_t txBuf[8], rxBuf[8]; + struct spi_command cmd; + device_t dev, pdev; + + for (;;) { + dev = sc->sc_dev; + pdev = device_get_parent(dev); + M25PXX_LOCK(sc); + do { + bp = bioq_first(&sc->sc_bio_queue); + if (bp == NULL) + msleep(sc, &sc->sc_mtx, PRIBIO, "jobqueue", 0); + } while (bp == NULL); + bioq_remove(&sc->sc_bio_queue, bp); + M25PXX_UNLOCK(sc); + + if (bp->bio_cmd == BIO_READ) { + txBuf[0] = CMD_FAST_READ; + cmd.tx_cmd_sz = 5; + cmd.rx_cmd_sz = 5; + + txBuf[1] = (((bp->bio_offset) >> 16) & 0xff); + txBuf[2] = (((bp->bio_offset) >> 8) & 0xff); + txBuf[3] = ((bp->bio_offset) & 0xff); + /* Dummy byte */ + txBuf[4] = 0; + + cmd.tx_cmd = txBuf; + cmd.rx_cmd = rxBuf; + cmd.tx_data = bp->bio_data; + cmd.tx_data_sz = bp->bio_bcount; + cmd.rx_data = bp->bio_data; + cmd.rx_data_sz = bp->bio_bcount; + bp->bio_error = SPIBUS_TRANSFER(pdev, dev, &cmd); + } + else + bp->bio_error = EINVAL; + + biodone(bp); + } +} + +static devclass_t mx25l_devclass; + +static device_method_t mx25l_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, mx25l_probe), + DEVMETHOD(device_attach, mx25l_attach), + DEVMETHOD(device_detach, mx25l_detach), + + { 0, 0 } +}; + +static driver_t mx25l_driver = { + "mx25l", + mx25l_methods, + sizeof(struct mx25l_softc), +}; + +DRIVER_MODULE(mx25l, spibus, mx25l_driver, mx25l_devclass, 0, 0); diff --git a/sys/dev/flash/mx25lreg.h b/sys/dev/flash/mx25lreg.h new file mode 100644 index 00000000000..7575b5be076 --- /dev/null +++ b/sys/dev/flash/mx25lreg.h @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __MX25LREG_H__ +#define __MX25LREG_H__ + +/* + * Commands + */ +#define CMD_WRITE_ENABLE 0x06 +#define CMD_WRITE_DISABLE 0x04 +#define CMD_READ_IDENT 0x9F +#define CMD_READ_STATUS 0x05 +#define CMD_WRITE_STATUS 0x01 +#define CMD_READ 0x03 +#define CMD_FAST_READ 0x0B +#define CMD_PAGE_PROGRAM 0x02 +#define CMD_SECTOR_ERASE 0xD8 +#define CMD_BULK_ERASE 0xC7 + +/* + * Status register flags + */ +#define STATUS_SRWD (1 << 7) +#define STATUS_BP2 (1 << 4) +#define STATUS_BP1 (1 << 3) +#define STATUS_BP0 (1 << 2) +#define STATUS_WEL (1 << 1) +#define STATUS_WIP (1 << 0) + +#endif /* __MX25LREG_H__ */ + From 28bdd4f5c35e1098355768b04b8369d006e5d3ad Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 18 May 2009 23:30:15 +0000 Subject: [PATCH 071/380] - Unwire spibus from at91_spi in projects/mips as well --- sys/arm/at91/at91.c | 2 +- sys/arm/at91/at91_spi.c | 2 +- sys/dev/spibus/spibus.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/arm/at91/at91.c b/sys/arm/at91/at91.c index 17e466e216b..222fce062d0 100644 --- a/sys/arm/at91/at91.c +++ b/sys/arm/at91/at91.c @@ -409,7 +409,7 @@ struct cpu_devs at91rm9200_devs[] = AT91RM92_IRQ_SSC2 }, { - "at91_spi", 0, + "spi", 0, AT91RM92_BASE + AT91RM92_SPI_BASE, AT91RM92_SPI_SIZE, AT91RM92_IRQ_SPI }, diff --git a/sys/arm/at91/at91_spi.c b/sys/arm/at91/at91_spi.c index 53c33807ee5..2252f00c8d2 100644 --- a/sys/arm/at91/at91_spi.c +++ b/sys/arm/at91/at91_spi.c @@ -297,7 +297,7 @@ static device_method_t at91_spi_methods[] = { }; static driver_t at91_spi_driver = { - "at91_spi", + "spi", at91_spi_methods, sizeof(struct at91_spi_softc), }; diff --git a/sys/dev/spibus/spibus.c b/sys/dev/spibus/spibus.c index 76b4a8cc3c7..33205ea64f1 100644 --- a/sys/dev/spibus/spibus.c +++ b/sys/dev/spibus/spibus.c @@ -194,5 +194,5 @@ static driver_t spibus_driver = { devclass_t spibus_devclass; -DRIVER_MODULE(spibus, at91_spi, spibus_driver, spibus_devclass, 0, 0); +DRIVER_MODULE(spibus, spi, spibus_driver, spibus_devclass, 0, 0); MODULE_VERSION(spibus, 1); From 495d422f4931cdb466d459f67f77d8355540f14f Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 18 May 2009 23:32:04 +0000 Subject: [PATCH 072/380] - Add SPI bus driver for ar71xx SoC --- sys/mips/atheros/ar71xx_spi.c | 228 ++++++++++++++++++++++++++++++++++ sys/mips/atheros/files.ar71xx | 1 + 2 files changed, 229 insertions(+) create mode 100644 sys/mips/atheros/ar71xx_spi.c diff --git a/sys/mips/atheros/ar71xx_spi.c b/sys/mips/atheros/ar71xx_spi.c new file mode 100644 index 00000000000..9f7eb1acd87 --- /dev/null +++ b/sys/mips/atheros/ar71xx_spi.c @@ -0,0 +1,228 @@ +/*- + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include "spibus_if.h" + +#include + +#undef AR71XX_SPI_DEBUG +#ifdef AR71XX_SPI_DEBUG +#define dprintf printf +#else +#define dprintf(x, arg...) +#endif + +/* + * register space access macros + */ +#define SPI_WRITE(sc, reg, val) do { \ + bus_write_4(sc->sc_mem_res, (reg), (val)); \ + } while (0) + +#define SPI_READ(sc, reg) bus_read_4(sc->sc_mem_res, (reg)) + +#define SPI_SET_BITS(sc, reg, bits) \ + SPI_WRITE(sc, reg, SPI_READ(sc, (reg)) | (bits)) + +#define SPI_CLEAR_BITS(sc, reg, bits) \ + SPI_WRITE(sc, reg, SPI_READ(sc, (reg)) & ~(bits)) + +struct ar71xx_spi_softc { + device_t sc_dev; + struct resource *sc_mem_res; + uint32_t sc_reg_ioctrl; +}; + +static int +ar71xx_spi_probe(device_t dev) +{ + device_set_desc(dev, "AR71XX SPI"); + return (0); +} + +static int +ar71xx_spi_attach(device_t dev) +{ + struct ar71xx_spi_softc *sc = device_get_softc(dev); + int rid; + + sc->sc_dev = dev; + rid = 0; + sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (!sc->sc_mem_res) { + device_printf(dev, "Could not map memory\n"); + return (ENXIO); + } + + sc->sc_reg_ioctrl = SPI_READ(sc, AR71XX_SPI_IO_CTRL); + + SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, SPI_IO_CTRL_CS0 | SPI_IO_CTRL_CS1 | + SPI_IO_CTRL_CS2); + SPI_WRITE(sc, AR71XX_SPI_CTRL, sc->sc_reg_ioctrl); + SPI_WRITE(sc, AR71XX_SPI_FS, 0); + + device_add_child(dev, "spibus", 0); + return (bus_generic_attach(dev)); +} + +static void +ar71xx_spi_chip_activate(struct ar71xx_spi_softc *sc, int cs) +{ + uint32_t ioctrl = SPI_IO_CTRL_CS0 |SPI_IO_CTRL_CS1 | SPI_IO_CTRL_CS2; + /* + * Put respective CSx to low + */ + ioctrl &= ~(SPI_IO_CTRL_CS0 << cs); + + SPI_WRITE(sc, AR71XX_SPI_FS, 1); + SPI_WRITE(sc, AR71XX_SPI_CTRL, 0x43); + SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, ioctrl); +} + +static void +ar71xx_spi_chip_deactivate(struct ar71xx_spi_softc *sc, int cs) +{ + /* + * Put all CSx to high + */ + SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, SPI_IO_CTRL_CS0 | SPI_IO_CTRL_CS1 | + SPI_IO_CTRL_CS2); + SPI_WRITE(sc, AR71XX_SPI_CTRL, sc->sc_reg_ioctrl); + SPI_WRITE(sc, AR71XX_SPI_FS, 0); +} + +static uint8_t +ar71xx_spi_txrx(struct ar71xx_spi_softc *sc, uint8_t data) +{ + int bit; + /* CS0 */ + uint32_t ioctrl = SPI_IO_CTRL_CS1 | SPI_IO_CTRL_CS2; + + uint32_t iod, rds; + for (bit = 7; bit >=0; bit--) { + if (data & (1 << bit)) + iod = ioctrl | SPI_IO_CTRL_DO; + else + iod = ioctrl & ~SPI_IO_CTRL_DO; + SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, iod); + SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, iod | SPI_IO_CTRL_CLK); + } + + rds = SPI_READ(sc, AR71XX_SPI_RDS); + + return (rds & 0xff); +} + +static int +ar71xx_spi_transfer(device_t dev, device_t child, struct spi_command *cmd) +{ + struct ar71xx_spi_softc *sc; + uint8_t *buf_in, *buf_out; + struct spibus_ivar *devi = SPIBUS_IVAR(child); + int i; + + sc = device_get_softc(dev); + + ar71xx_spi_chip_activate(sc, devi->cs); + + KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz, + ("TX/RX command sizes should be equal")); + KASSERT(cmd->tx_data_sz == cmd->rx_data_sz, + ("TX/RX data sizes should be equal")); + + /* + * Transfer command + */ + buf_out = (uint8_t *)cmd->tx_cmd; + buf_in = (uint8_t *)cmd->rx_cmd; + for (i = 0; i < cmd->tx_cmd_sz; i++) + buf_in[i] = ar71xx_spi_txrx(sc, buf_out[i]); + + /* + * Receive/transmit data (depends on command) + */ + buf_out = (uint8_t *)cmd->tx_data; + buf_in = (uint8_t *)cmd->rx_data; + for (i = 0; i < cmd->tx_data_sz; i++) + buf_in[i] = ar71xx_spi_txrx(sc, buf_out[i]); + + ar71xx_spi_chip_deactivate(sc, devi->cs); + + return (0); +} + +static int +ar71xx_spi_detach(device_t dev) +{ + + return (EBUSY); /* XXX */ +} + +static device_method_t ar71xx_spi_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, ar71xx_spi_probe), + DEVMETHOD(device_attach, ar71xx_spi_attach), + DEVMETHOD(device_detach, ar71xx_spi_detach), + + DEVMETHOD(spibus_transfer, ar71xx_spi_transfer), + + {0, 0} +}; + +static driver_t ar71xx_spi_driver = { + "spi", + ar71xx_spi_methods, + sizeof(struct ar71xx_spi_softc), +}; + +static devclass_t ar71xx_spi_devclass; + +DRIVER_MODULE(ar71xx_spi, nexus, ar71xx_spi_driver, ar71xx_spi_devclass, 0, 0); diff --git a/sys/mips/atheros/files.ar71xx b/sys/mips/atheros/files.ar71xx index 047fad85fc9..cb2e00bc05a 100644 --- a/sys/mips/atheros/files.ar71xx +++ b/sys/mips/atheros/files.ar71xx @@ -6,6 +6,7 @@ mips/atheros/ar71xx_ehci.c optional ehci mips/atheros/ar71xx_ohci.c optional ohci mips/atheros/ar71xx_pci.c optional pci mips/atheros/ar71xx_pci_bus_space.c optional pci +mips/atheros/ar71xx_spi.c optional ar71xx_spi mips/atheros/if_arge.c optional arge mips/atheros/uart_bus_ar71xx.c optional uart mips/atheros/uart_cpu_ar71xx.c optional uart From e0e8ed6ab1b3924e0cfe6cfbf8b03db831d17b6d Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 18 May 2009 23:36:11 +0000 Subject: [PATCH 073/380] - Add spibus and mx25l device --- sys/mips/conf/AR71XX.hints | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sys/mips/conf/AR71XX.hints b/sys/mips/conf/AR71XX.hints index 35635064e60..17026c10a80 100644 --- a/sys/mips/conf/AR71XX.hints +++ b/sys/mips/conf/AR71XX.hints @@ -33,3 +33,11 @@ hint.arge.0.irq=2 # hint.arge.1.maddr=0x1A000000 # hint.arge.1.msize=0x1000 # hint.arge.1.irq=3 + +# SPI flash +hint.spi.0.at="nexus0" +hint.spi.0.maddr=0x1f000000 +hint.spi.0.msize=0x10 + +hint.mx25l.0.at="spibus0" +hint.mx25l.0.cs=0 From dea84102351c802be61f7efb18770a82fea0d427 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 19 May 2009 02:43:21 +0000 Subject: [PATCH 074/380] - Cleanup ticker initialization code. For some MIPS cpu Counter register increments only every second cycle. The only timing references for us is Count value. Therefore it's better to convert frequencies related to it and use them. Besides cleanup this commit fixes twice more then requested sleep interval problem. --- sys/mips/mips/tick.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/sys/mips/mips/tick.c b/sys/mips/mips/tick.c index faae90ed57b..d767950c24e 100644 --- a/sys/mips/mips/tick.c +++ b/sys/mips/mips/tick.c @@ -138,25 +138,19 @@ mips_timer_init_params(uint64_t platform_counter_freq, int double_count) * function should be called before cninit. */ counter_freq = platform_counter_freq; + /* + * XXX: Some MIPS32 cores update the Count register only every two + * pipeline cycles. + */ + if (double_count != 0) + counter_freq /= 2; + cycles_per_tick = counter_freq / 1000; - if (double_count) - cycles_per_tick *= 2; cycles_per_hz = counter_freq / hz; cycles_per_usec = counter_freq / (1 * 1000 * 1000); cycles_per_sec = counter_freq ; counter_timecounter.tc_frequency = counter_freq; - /* - * XXX: Some MIPS32 cores update the Count register only every two - * pipeline cycles. - * XXX2: We can read this from the hardware register on some - * systems. Need to investigate. - */ - if (double_count != 0) { - cycles_per_hz /= 2; - cycles_per_usec /= 2; - cycles_per_sec /= 2; - } printf("hz=%d cyl_per_hz:%jd cyl_per_usec:%jd freq:%jd cyl_per_hz:%jd cyl_per_sec:%jd\n", hz, cycles_per_tick, @@ -346,6 +340,7 @@ clock_attach(device_t dev) device_printf(dev, "bus_setup_intr returned %d\n", error); return (error); } + mips_wr_compare(mips_rd_count() + counter_freq / hz); return (0); } From f92ba068308dfc6eb101e309be5563be0bcf17a7 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 19 May 2009 02:51:30 +0000 Subject: [PATCH 075/380] - ar71xx increases Count value every two cycles --- sys/mips/atheros/ar71xx_machdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/atheros/ar71xx_machdep.c b/sys/mips/atheros/ar71xx_machdep.c index 5abe75bccca..a12095980a6 100644 --- a/sys/mips/atheros/ar71xx_machdep.c +++ b/sys/mips/atheros/ar71xx_machdep.c @@ -157,7 +157,7 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, div = ((pll_config >> PLL_CPU_DIV_SEL_SHIFT) & PLL_CPU_DIV_SEL_MASK) + 1; platform_counter_freq = freq / div; - mips_timer_init_params(platform_counter_freq, 0); + mips_timer_init_params(platform_counter_freq, 1); cninit(); printf("platform frequency: %lld\n", platform_counter_freq); From 52e6bd28014e242d2aa6cc3e6bf8f917c166f510 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 20 May 2009 23:07:10 +0000 Subject: [PATCH 076/380] - Invalidate caches for respective areain KSEG0 in order to prevent further overwriting of KSEG1 data with writeback. --- sys/mips/mips/pmap.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index 0842ea3e460..19e141dc5d6 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -2411,6 +2411,8 @@ pmap_copy_page(vm_page_t src, vm_page_t dst) * to make sure that data in SDRAM is up to date */ pmap_flush_pvcache(src); + mips_dcache_wbinv_range_index( + MIPS_PHYS_TO_CACHED(phy_dst), NBPG); va_src = MIPS_PHYS_TO_UNCACHED(phy_src); va_dst = MIPS_PHYS_TO_UNCACHED(phy_dst); bcopy((caddr_t)va_src, (caddr_t)va_dst, PAGE_SIZE); @@ -2916,6 +2918,7 @@ pmap_activate(struct thread *td) PCPU_SET(segbase, pmap->pm_segtab); MachSetPID(pmap->pm_asid[PCPU_GET(cpuid)].asid); } + PCPU_SET(curpmap, pmap); critical_exit(); } From 58a5af46ef3a4cfcb1d0751c87f17369d53ec12b Mon Sep 17 00:00:00 2001 From: Doug White Date: Thu, 21 May 2009 22:12:42 +0000 Subject: [PATCH 077/380] Add some missing bits to arge: * In arge_attach(), hard reset the MAC blocks before configuring the MAC. * In arge_reset_dma(), clear pending packet interrupts based off the hardware counter instead of acking every packet in the ring, as the hardware counter can exceed the ring size. If the reset was successful the counters will be zero anyway. * In arge_encap(), remove an unused variable. * In arge_tx_locked(), remove redundant setting of the EMPTY flag as the TX DMA engine sets it for us. * In arge_intr(), remember to clear the interrupt status bits relayed from arge_intr_filter(). * Handle RX overflow and TX underflow. * In arge_tx_intr(), remember to unmask the TX interrupt bits after processing them. --- sys/mips/atheros/if_arge.c | 54 ++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index b3237c2c385..15357920a5c 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -306,6 +306,28 @@ arge_attach(device_t dev) goto fail; } + /* Initialize the MAC block */ + + /* Step 1. Soft-reset MAC */ + ARGE_SET_BITS(sc, AR71XX_MAC_CFG1, MAC_CFG1_SOFT_RESET); + DELAY(20); + + /* Step 2. Punt the MAC core from the central reset register */ + reg = ATH_READ_REG(AR71XX_RST_RESET); + if (sc->arge_mac_unit == 0) + reg |= RST_RESET_GE0_MAC; + else if (sc->arge_mac_unit == 1) + reg |= RST_RESET_GE1_MAC; + ATH_WRITE_REG(AR71XX_RST_RESET, reg); + DELAY(100); + reg = ATH_READ_REG(AR71XX_RST_RESET); + if (sc->arge_mac_unit == 0) + reg &= ~RST_RESET_GE0_MAC; + else if (sc->arge_mac_unit == 1) + reg &= ~RST_RESET_GE1_MAC; + ATH_WRITE_REG(AR71XX_RST_RESET, reg); + + /* Step 3. Reconfigure MAC block */ ARGE_WRITE(sc, AR71XX_MAC_CFG1, MAC_CFG1_SYNC_RX | MAC_CFG1_RX_ENABLE | MAC_CFG1_SYNC_TX | MAC_CFG1_TX_ENABLE); @@ -612,13 +634,13 @@ arge_reset_dma(struct arge_softc *sc) ARGE_WRITE(sc, AR71XX_DMA_TX_DESC, 0); /* Clear all possible RX interrupts */ - for (i = 0; i < ARGE_RX_RING_COUNT; i++) + while(ARGE_READ(sc, AR71XX_DMA_RX_STATUS) & DMA_RX_STATUS_PKT_RECVD) ARGE_WRITE(sc, AR71XX_DMA_RX_STATUS, DMA_RX_STATUS_PKT_RECVD); /* * Clear all possible TX interrupts */ - for (i = 0; i < ARGE_TX_RING_COUNT; i++) + while(ARGE_READ(sc, AR71XX_DMA_TX_STATUS) & DMA_TX_STATUS_PKT_SENT) ARGE_WRITE(sc, AR71XX_DMA_TX_STATUS, DMA_TX_STATUS_PKT_SENT); /* @@ -694,7 +716,7 @@ arge_encap(struct arge_softc *sc, struct mbuf **m_head) struct arge_txdesc *txd; struct arge_desc *desc, *prev_desc; bus_dma_segment_t txsegs[ARGE_MAXFRAGS]; - int error, i, nsegs, prod, si, prev_prod; + int error, i, nsegs, prod, prev_prod; ARGE_LOCK_ASSERT(sc); @@ -724,8 +746,6 @@ arge_encap(struct arge_softc *sc, struct mbuf **m_head) bus_dmamap_sync(sc->arge_cdata.arge_tx_tag, txd->tx_dmamap, BUS_DMASYNC_PREWRITE); - si = prod; - /* * Make a list of descriptors for this packet. DMA controller will * walk through it while arge_link is not zero. @@ -1361,8 +1381,6 @@ arge_tx_locked(struct arge_softc *sc) txd = &sc->arge_cdata.arge_txdesc[cons]; - cur_tx->packet_ctrl = ARGE_DESC_EMPTY; - ifp->if_opackets++; bus_dmamap_sync(sc->arge_cdata.arge_tx_tag, txd->tx_dmamap, @@ -1375,7 +1393,6 @@ arge_tx_locked(struct arge_softc *sc) txd->tx_m = NULL; /* reset descriptor */ - cur_tx->packet_ctrl = ARGE_DESC_EMPTY; cur_tx->packet_addr = 0; } @@ -1463,6 +1480,13 @@ arge_rx_intr(struct arge_softc *sc, uint32_t status) /* interrupts are masked by filter */ arge_rx_locked(sc); + /* RX overrun disables the receiver. Clear indication and + re-enable rx. */ + if ( status | DMA_INTR_RX_OVERFLOW) { + ARGE_WRITE(sc, AR71XX_DMA_RX_STATUS, DMA_RX_STATUS_OVERFLOW); + ARGE_WRITE(sc, AR71XX_DMA_RX_CONTROL, DMA_RX_CONTROL_EN); + } + /* unmask interrupts */ ARGE_SET_BITS(sc, AR71XX_DMA_INTR, DMA_INTR_RX_OVERFLOW | DMA_INTR_RX_PKT_RCVD); @@ -1511,6 +1535,7 @@ arge_intr(void *arg) uint32_t status; status = sc->arge_intr_status; + sc->arge_intr_status = 0; #if 0 dprintf("int status(intr) = %b\n", status, @@ -1551,6 +1576,19 @@ arge_tx_intr(struct arge_softc *sc, uint32_t status) /* Interrupts are masked by filter */ arge_tx_locked(sc); + /* Underrun turns off TX. Clear underrun indication. + If there's anything left in the ring, reactivate the tx. */ + if (status & DMA_INTR_TX_UNDERRUN) { + ARGE_WRITE(sc, AR71XX_DMA_TX_STATUS, DMA_TX_STATUS_UNDERRUN); + if (sc->arge_cdata.arge_tx_pkts > 0 ) { + ARGE_WRITE(sc, AR71XX_DMA_TX_CONTROL, DMA_TX_CONTROL_EN); + } + } + + /* unmask interrupts */ + ARGE_SET_BITS(sc, + AR71XX_DMA_INTR, DMA_INTR_TX_UNDERRUN | DMA_INTR_TX_PKT_SENT); + ARGE_UNLOCK(sc); } From 58f0ea3143b6be257875e5e26aa37e806e363a49 Mon Sep 17 00:00:00 2001 From: Doug White Date: Fri, 22 May 2009 20:08:13 +0000 Subject: [PATCH 078/380] Remove unused variable. --- sys/mips/atheros/if_arge.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index 15357920a5c..a487b6418f3 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -625,8 +625,6 @@ arge_link_task(void *arg, int pending) static void arge_reset_dma(struct arge_softc *sc) { - unsigned int i; - ARGE_WRITE(sc, AR71XX_DMA_RX_CONTROL, 0); ARGE_WRITE(sc, AR71XX_DMA_TX_CONTROL, 0); From 41917f9933059edde0d29cb7b7b4b74dd77cbbc4 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sat, 23 May 2009 06:30:03 +0000 Subject: [PATCH 079/380] - Wrong logical operator was used for flag check --- sys/mips/atheros/if_arge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index a487b6418f3..3fd08222923 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -1480,7 +1480,7 @@ arge_rx_intr(struct arge_softc *sc, uint32_t status) /* RX overrun disables the receiver. Clear indication and re-enable rx. */ - if ( status | DMA_INTR_RX_OVERFLOW) { + if ( status & DMA_INTR_RX_OVERFLOW) { ARGE_WRITE(sc, AR71XX_DMA_RX_STATUS, DMA_RX_STATUS_OVERFLOW); ARGE_WRITE(sc, AR71XX_DMA_RX_CONTROL, DMA_RX_CONTROL_EN); } From 070f07e3dee2cd6d69f945c86a39a7fbe9664379 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sat, 23 May 2009 18:00:20 +0000 Subject: [PATCH 080/380] - Remove stale comments - Replace a1 with k1 to while restoring context. a1 was there by mistake, interrupts are disabled at this point and it's safe to use k0, k1. This code never was reached beacasue current Status register handling prevented interrupta from user mode. --- sys/mips/mips/exception.S | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/sys/mips/mips/exception.S b/sys/mips/mips/exception.S index fb7614df970..31327fc8591 100644 --- a/sys/mips/mips/exception.S +++ b/sys/mips/mips/exception.S @@ -689,36 +689,27 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra) /* * Call the interrupt handler. */ + break la k0, _C_LABEL(cpu_intr) jalr k0 sw a3, STAND_RA_OFFSET(sp) # for debugging + /* - * Since interrupts are enabled at this point, we use a1 instead of - * k0 or k1 to store the PCB pointer. This is because k0 and k1 - * are not preserved across interrupts. ** RRS - And how did the - * get enabled? cpu_intr clears the cause register but it does - * not touch the sr as far as I can see thus intr are still - * disabled. + * DO_AST enabled interrupts */ DO_AST /* - * Restore user registers and return. NOTE: interrupts are enabled. + * Restore user registers and return. */ - -/* - * Since interrupts are enabled at this point, we use a1 instead of - * k0 or k1 to store the PCB pointer. This is because k0 and k1 - * are not preserved across interrupts. - */ - mtc0 zero, COP_0_STATUS_REG + mtc0 zero, COP_0_STATUS_REG # re-disable interrupts ITLBNOPFIX li v0, SR_EXL mtc0 v0, COP_0_STATUS_REG # set exeption level bit. ITLBNOPFIX GET_CPU_PCPU(k1) - lw a1, PC_CURPCB(k1) + lw k1, PC_CURPCB(k1) RESTORE_U_PCB_REG(s0, S0, k1) RESTORE_U_PCB_REG(s1, S1, k1) RESTORE_U_PCB_REG(s2, S2, k1) From 5dc8f9e2ee08af5b421cbc8a82f73a25518d9d48 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sat, 23 May 2009 18:18:06 +0000 Subject: [PATCH 081/380] - Calculate clock frequency using PLL registers --- sys/mips/atheros/uart_bus_ar71xx.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/sys/mips/atheros/uart_bus_ar71xx.c b/sys/mips/atheros/uart_bus_ar71xx.c index a1abf4c5e98..380c3daba6b 100644 --- a/sys/mips/atheros/uart_bus_ar71xx.c +++ b/sys/mips/atheros/uart_bus_ar71xx.c @@ -67,6 +67,20 @@ static int uart_ar71xx_probe(device_t dev) { struct uart_softc *sc; + uint32_t pll_config, div; + uint64_t freq; + + /* PLL freq */ + pll_config = ATH_READ_REG(AR71XX_PLL_CPU_CONFIG); + div = ((pll_config >> PLL_FB_SHIFT) & PLL_FB_MASK) + 1; + freq = div * AR71XX_BASE_FREQ; + /* CPU freq */ + div = ((pll_config >> PLL_CPU_DIV_SEL_SHIFT) & PLL_CPU_DIV_SEL_MASK) + + 1; + freq = freq / div; + /* AHB freq */ + div = (((pll_config >> PLL_AHB_DIV_SHIFT) & PLL_AHB_DIV_MASK) + 1) * 2; + freq = freq / div; sc = device_get_softc(dev); sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); @@ -79,7 +93,7 @@ uart_ar71xx_probe(device_t dev) sc->sc_bas.bst = mips_bus_space_generic; sc->sc_bas.bsh = MIPS_PHYS_TO_KSEG1(AR71XX_UART_ADDR) + 3; - return (uart_bus_probe(dev, 2, 85000000, 0, 0)); + return (uart_bus_probe(dev, 2, freq, 0, 0)); } DRIVER_MODULE(uart, apb, uart_ar71xx_driver, uart_devclass, 0, 0); From 687fba47a728d63ead839d0fee87bde65662ee98 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sat, 23 May 2009 19:42:23 +0000 Subject: [PATCH 082/380] - cpu_establish_hardintr modifies INT_MASK of Status register, so we should use disableintr/restoreintr that modifies only IE bit. --- sys/mips/mips/nexus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/mips/mips/nexus.c b/sys/mips/mips/nexus.c index 2578d2f12f4..b2d2b481e69 100644 --- a/sys/mips/mips/nexus.c +++ b/sys/mips/mips/nexus.c @@ -169,14 +169,14 @@ nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags, { int irq; - register_t sr = intr_disable(); + intrmask_t s = disableintr(); irq = rman_get_start(res); if (irq >= NUM_MIPS_IRQS) return (0); cpu_establish_hardintr(device_get_nameunit(child), filt, intr, arg, irq, flags, cookiep); - intr_restore(sr); + restoreintr(s); return (0); } From ccbbcd481f7e3e5d78f3a1e981b1a97fb184f37a Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 26 May 2009 03:45:58 +0000 Subject: [PATCH 083/380] - Add polling support - Get rid of arge_fix_chain, use m_defrag like if_vr - Rework interrupt handling routine to avoid race that lead to disabling RX interrupts - Enable full duplex if requested - Properly set station MAC address - Slightly optimize RX loop - Initialize FILTERMATCH and FILTERMASK registers as linux driver does --- sys/mips/atheros/ar71xxreg.h | 105 +++++++--- sys/mips/atheros/if_arge.c | 360 ++++++++++++++--------------------- 2 files changed, 225 insertions(+), 240 deletions(-) diff --git a/sys/mips/atheros/ar71xxreg.h b/sys/mips/atheros/ar71xxreg.h index b519df2e08a..c5765320749 100644 --- a/sys/mips/atheros/ar71xxreg.h +++ b/sys/mips/atheros/ar71xxreg.h @@ -281,33 +281,92 @@ #define AR71XX_MAC_FIFO_CFG2 0x50 #define AR71XX_MAC_FIFO_TX_THRESHOLD 0x54 #define AR71XX_MAC_FIFO_RX_FILTMATCH 0x58 -#define FIFO_RX_FILTMATCH_ALL ((1 << 18) - 1) -#define AR71XX_MAC_FIFO_RX_FILTMASK 0x5C -#define FIFO_RX_FILTMASK_BYTE_MODE (1 << 19) -#define FIFO_RX_FILTMASK_NO_SHORT_FRAME (1 << 18) -#define FIFO_RX_FILTMASK_ALL ((1 << 20) - 1) /* * These flags applicable both to AR71XX_MAC_FIFO_RX_FILTMASK and * to AR71XX_MAC_FIFO_RX_FILTMATCH */ -#define FIFO_RX_FILT_UNICAST (1 << 17) -#define FIFO_RX_FILT_TRUNC_FRAME (1 << 16) -#define FIFO_RX_FILT_VLAN_TAG (1 << 15) -#define FIFO_RX_FILT_UNSUP_OPCODE (1 << 14) -#define FIFO_RX_FILT_PAUSE_FRAME (1 << 13) -#define FIFO_RX_FILT_CTRL_FRAME (1 << 12) -#define FIFO_RX_FILT_LONG_EVENT (1 << 11) -#define FIFO_RX_FILT_DRIBBLE_NIBBLE (1 << 10) -#define FIFO_RX_FILT_BCAST (1 << 9) -#define FIFO_RX_FILT_MCAST (1 << 8) -#define FIFO_RX_FILT_OK (1 << 7) -#define FIFO_RX_FILT_OORANGE (1 << 6) -#define FIFO_RX_FILT_LEN_MSMTCH (1 << 5) -#define FIFO_RX_FILT_CRC_ERROR (1 << 4) -#define FIFO_RX_FILT_CODE_ERROR (1 << 3) -#define FIFO_RX_FILT_FALSE_CARRIER (1 << 2) -#define FIFO_RX_FILT_RX_DV_EVENT (1 << 1) -#define FIFO_RX_FILT_DROP_EVENT (1 << 0) +#define FIFO_RX_MATCH_UNICAST (1 << 17) +#define FIFO_RX_MATCH_TRUNC_FRAME (1 << 16) +#define FIFO_RX_MATCH_VLAN_TAG (1 << 15) +#define FIFO_RX_MATCH_UNSUP_OPCODE (1 << 14) +#define FIFO_RX_MATCH_PAUSE_FRAME (1 << 13) +#define FIFO_RX_MATCH_CTRL_FRAME (1 << 12) +#define FIFO_RX_MATCH_LONG_EVENT (1 << 11) +#define FIFO_RX_MATCH_DRIBBLE_NIBBLE (1 << 10) +#define FIFO_RX_MATCH_BCAST (1 << 9) +#define FIFO_RX_MATCH_MCAST (1 << 8) +#define FIFO_RX_MATCH_OK (1 << 7) +#define FIFO_RX_MATCH_OORANGE (1 << 6) +#define FIFO_RX_MATCH_LEN_MSMTCH (1 << 5) +#define FIFO_RX_MATCH_CRC_ERROR (1 << 4) +#define FIFO_RX_MATCH_CODE_ERROR (1 << 3) +#define FIFO_RX_MATCH_FALSE_CARRIER (1 << 2) +#define FIFO_RX_MATCH_RX_DV_EVENT (1 << 1) +#define FIFO_RX_MATCH_DROP_EVENT (1 << 0) +/* + * Exclude unicast and truncated frames from matching + */ +#define FIFO_RX_FILTMATCH_DEFAULT \ + (FIFO_RX_MATCH_VLAN_TAG | \ + FIFO_RX_MATCH_UNSUP_OPCODE | \ + FIFO_RX_MATCH_PAUSE_FRAME | \ + FIFO_RX_MATCH_CTRL_FRAME | \ + FIFO_RX_MATCH_LONG_EVENT | \ + FIFO_RX_MATCH_DRIBBLE_NIBBLE | \ + FIFO_RX_MATCH_BCAST | \ + FIFO_RX_MATCH_MCAST | \ + FIFO_RX_MATCH_OK | \ + FIFO_RX_MATCH_OORANGE | \ + FIFO_RX_MATCH_LEN_MSMTCH | \ + FIFO_RX_MATCH_CRC_ERROR | \ + FIFO_RX_MATCH_CODE_ERROR | \ + FIFO_RX_MATCH_FALSE_CARRIER | \ + FIFO_RX_MATCH_RX_DV_EVENT | \ + FIFO_RX_MATCH_DROP_EVENT) +#define AR71XX_MAC_FIFO_RX_FILTMASK 0x5C +#define FIFO_RX_MASK_BYTE_MODE (1 << 19) +#define FIFO_RX_MASK_NO_SHORT_FRAME (1 << 18) +#define FIFO_RX_MASK_BIT17 (1 << 17) +#define FIFO_RX_MASK_BIT16 (1 << 16) +#define FIFO_RX_MASK_TRUNC_FRAME (1 << 15) +#define FIFO_RX_MASK_LONG_EVENT (1 << 14) +#define FIFO_RX_MASK_VLAN_TAG (1 << 13) +#define FIFO_RX_MASK_UNSUP_OPCODE (1 << 12) +#define FIFO_RX_MASK_PAUSE_FRAME (1 << 11) +#define FIFO_RX_MASK_CTRL_FRAME (1 << 10) +#define FIFO_RX_MASK_DRIBBLE_NIBBLE (1 << 9) +#define FIFO_RX_MASK_BCAST (1 << 8) +#define FIFO_RX_MASK_MCAST (1 << 7) +#define FIFO_RX_MASK_OK (1 << 6) +#define FIFO_RX_MASK_OORANGE (1 << 5) +#define FIFO_RX_MASK_LEN_MSMTCH (1 << 4) +#define FIFO_RX_MASK_CODE_ERROR (1 << 3) +#define FIFO_RX_MASK_FALSE_CARRIER (1 << 2) +#define FIFO_RX_MASK_RX_DV_EVENT (1 << 1) +#define FIFO_RX_MASK_DROP_EVENT (1 << 0) + +/* + * Len. mismatch, unsup. opcode and short frmae bits excluded + */ +#define FIFO_RX_FILTMASK_DEFAULT \ + (FIFO_RX_MASK_NO_SHORT_FRAME | \ + FIFO_RX_MASK_BIT17 | \ + FIFO_RX_MASK_BIT16 | \ + FIFO_RX_MASK_TRUNC_FRAME | \ + FIFO_RX_MASK_LONG_EVENT | \ + FIFO_RX_MASK_VLAN_TAG | \ + FIFO_RX_MASK_PAUSE_FRAME | \ + FIFO_RX_MASK_CTRL_FRAME | \ + FIFO_RX_MASK_DRIBBLE_NIBBLE | \ + FIFO_RX_MASK_BCAST | \ + FIFO_RX_MASK_MCAST | \ + FIFO_RX_MASK_OK | \ + FIFO_RX_MASK_OORANGE | \ + FIFO_RX_MASK_CODE_ERROR | \ + FIFO_RX_MASK_FALSE_CARRIER | \ + FIFO_RX_MASK_RX_DV_EVENT | \ + FIFO_RX_MASK_DROP_EVENT) + #define AR71XX_MAC_FIFO_RAM0 0x60 #define AR71XX_MAC_FIFO_RAM1 0x64 #define AR71XX_MAC_FIFO_RAM2 0x68 diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index 3fd08222923..5c863a7366e 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -31,6 +31,10 @@ __FBSDID("$FreeBSD$"); /* * AR71XX gigabit ethernet driver */ +#ifdef HAVE_KERNEL_OPTION_HEADERS +#include "opt_device_polling.h" +#endif + #include #include #include @@ -84,7 +88,6 @@ MODULE_DEPEND(arge, miibus, 1, 1, 1); static int arge_attach(device_t); static int arge_detach(device_t); -static int arge_fix_chain(struct mbuf **mp); static void arge_flush_ddr(struct arge_softc *); static int arge_ifmedia_upd(struct ifnet *); static void arge_ifmedia_sts(struct ifnet *, struct ifmediareq *); @@ -100,6 +103,7 @@ static void arge_reset_dma(struct arge_softc *); static int arge_resume(device_t); static int arge_rx_ring_init(struct arge_softc *); static int arge_tx_ring_init(struct arge_softc *); +static void arge_poll(struct ifnet *, enum poll_cmd, int); static void arge_shutdown(device_t); static void arge_start(struct ifnet *); static void arge_start_locked(struct ifnet *); @@ -110,8 +114,6 @@ static void arge_rx_locked(struct arge_softc *); static void arge_tx_locked(struct arge_softc *); static void arge_intr(void *); static int arge_intr_filter(void *); -static void arge_tx_intr(struct arge_softc *, uint32_t); -static void arge_rx_intr(struct arge_softc *, uint32_t); static void arge_tick(void *); static void arge_dmamap_cb(void *, bus_dma_segment_t *, int, int); @@ -271,11 +273,14 @@ arge_attach(device_t dev) ifp->if_init = arge_init; /* XXX: add real size */ - IFQ_SET_MAXLEN(&ifp->if_snd, 9); - ifp->if_snd.ifq_maxlen = 9; + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); + ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; IFQ_SET_READY(&ifp->if_snd); ifp->if_capenable = ifp->if_capabilities; +#ifdef DEVICE_POLLING + ifp->if_capabilities |= IFCAP_POLLING; +#endif is_base_mac_empty = 1; for (i = 0; i < ETHER_ADDR_LEN; i++) { @@ -348,20 +353,20 @@ arge_attach(device_t dev) * Set all Ethernet address registers to the same initial values * set all four addresses to 66-88-aa-cc-dd-ee */ - ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR1, 0x6dc1282e); - ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR2, 0x00000015); + ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR1, + (eaddr[2] << 24) | (eaddr[3] << 16) | (eaddr[4] << 8) | eaddr[5]); + ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR2, (eaddr[0] << 8) | eaddr[1]); ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG0, FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT); ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG1, 0x0fff0000); ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG2, 0x00001fff); - reg = FIFO_RX_FILTMATCH_ALL; - ARGE_WRITE(sc, AR71XX_MAC_FIFO_RX_FILTMATCH, reg); + ARGE_WRITE(sc, AR71XX_MAC_FIFO_RX_FILTMATCH, + FIFO_RX_FILTMATCH_DEFAULT); - reg = FIFO_RX_FILTMASK_ALL; - reg &= ~FIFO_RX_FILTMASK_BYTE_MODE; - ARGE_WRITE(sc, AR71XX_MAC_FIFO_RX_FILTMASK, reg); + ARGE_WRITE(sc, AR71XX_MAC_FIFO_RX_FILTMASK, + FIFO_RX_FILTMASK_DEFAULT); /* Do MII setup. */ if (mii_phy_probe(dev, &sc->arge_miibus, @@ -394,7 +399,7 @@ fail: static int arge_detach(device_t dev) { - struct arge_softc *sc = device_get_softc(dev); + struct arge_softc *sc = device_get_softc(dev); struct ifnet *ifp = sc->arge_ifp; KASSERT(mtx_initialized(&sc->arge_mtx), ("arge mutex not initialized")); @@ -403,6 +408,11 @@ arge_detach(device_t dev) if (device_is_attached(dev)) { ARGE_LOCK(sc); sc->arge_detach = 1; +#ifdef DEVICE_POLLING + if (ifp->if_capenable & IFCAP_POLLING) + ether_poll_deregister(ifp); +#endif + arge_stop(sc); ARGE_UNLOCK(sc); taskqueue_drain(taskqueue_swi, &sc->arge_link_task); @@ -558,15 +568,18 @@ arge_link_task(void *arg, int pending) sc->arge_link_status = 1; cfg = ARGE_READ(sc, AR71XX_MAC_CFG2); - ifcontrol = ARGE_READ(sc, AR71XX_MAC_IFCONTROL); - rx_filtmask = - ARGE_READ(sc, AR71XX_MAC_FIFO_RX_FILTMASK); - cfg &= ~(MAC_CFG2_IFACE_MODE_1000 | MAC_CFG2_IFACE_MODE_10_100 | MAC_CFG2_FULL_DUPLEX); + + if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) + cfg |= MAC_CFG2_FULL_DUPLEX; + + ifcontrol = ARGE_READ(sc, AR71XX_MAC_IFCONTROL); ifcontrol &= ~MAC_IFCONTROL_SPEED; - rx_filtmask &= ~FIFO_RX_FILTMASK_BYTE_MODE; + rx_filtmask = + ARGE_READ(sc, AR71XX_MAC_FIFO_RX_FILTMASK); + rx_filtmask &= ~FIFO_RX_MASK_BYTE_MODE; switch(media) { case IFM_10_T: @@ -581,7 +594,7 @@ arge_link_task(void *arg, int pending) case IFM_1000_T: case IFM_1000_SX: cfg |= MAC_CFG2_IFACE_MODE_1000; - rx_filtmask |= FIFO_RX_FILTMASK_BYTE_MODE; + rx_filtmask |= FIFO_RX_MASK_BYTE_MODE; pll = PLL_ETH_INT_CLK_1000; break; default: @@ -694,6 +707,7 @@ arge_init_locked(struct arge_softc *sc) ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; callout_reset(&sc->arge_stat_callout, hz, arge_tick, sc); + ARGE_WRITE(sc, AR71XX_DMA_TX_DESC, ARGE_TX_RING_ADDR(sc, 0)); ARGE_WRITE(sc, AR71XX_DMA_RX_DESC, ARGE_RX_RING_ADDR(sc, 0)); @@ -715,9 +729,24 @@ arge_encap(struct arge_softc *sc, struct mbuf **m_head) struct arge_desc *desc, *prev_desc; bus_dma_segment_t txsegs[ARGE_MAXFRAGS]; int error, i, nsegs, prod, prev_prod; + struct mbuf *m; ARGE_LOCK_ASSERT(sc); + /* + * Fix mbuf chain, all fragments should be 4 bytes aligned and + * even 4 bytes + */ + m = *m_head; + if((mtod(m, intptr_t) & 3) != 0) { + m = m_defrag(*m_head, M_DONTWAIT); + if (m == NULL) { + *m_head = NULL; + return (ENOBUFS); + } + *m_head = m; + } + prod = sc->arge_cdata.arge_tx_prod; txd = &sc->arge_cdata.arge_txdesc[prod]; error = bus_dmamap_load_mbuf_sg(sc->arge_cdata.arge_tx_tag, @@ -754,7 +783,11 @@ arge_encap(struct arge_softc *sc, struct mbuf **m_head) desc = &sc->arge_rdata.arge_tx_ring[prod]; desc->packet_ctrl = ARGE_DMASIZE(txsegs[i].ds_len); + if (txsegs[i].ds_addr & 3) + panic("TX packet address unaligned\n"); + desc->packet_addr = txsegs[i].ds_addr; + /* link with previous descriptor */ if (prev_desc) prev_desc->packet_ctrl |= ARGE_DESC_MORE; @@ -812,15 +845,6 @@ arge_start_locked(struct ifnet *ifp) if (m_head == NULL) break; - /* - * Fix mbuf chain, all fragments should be 4 bytes aligned and - * even 4 bytes - */ - arge_fix_chain(&m_head); - - if (m_head == NULL) { - dprintf("failed to adjust mbuf chain\n"); - } /* * Pack the data into the transmit ring. @@ -867,6 +891,9 @@ arge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) struct ifreq *ifr = (struct ifreq *) data; struct mii_data *mii; int error; +#ifdef DEVICE_POLLING + int mask; +#endif switch (command) { case SIOCSIFFLAGS: @@ -884,11 +911,30 @@ arge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) mii = device_get_softc(sc->arge_miibus); error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); break; - case SIOCSIFCAP: - error = 0; - ifp->if_hwassist = 0; + case SIOCSIFCAP: printf("Implement me: SIOCSIFCAP\n"); - break; +#ifdef DEVICE_POLLING + mask = ifp->if_capenable ^ ifr->ifr_reqcap; + error = 0; + if (mask & IFCAP_POLLING) { + if (ifr->ifr_reqcap & IFCAP_POLLING) { + ARGE_WRITE(sc, AR71XX_DMA_INTR, 0); + error = ether_poll_register(arge_poll, ifp); + if (error) + return error; + ARGE_LOCK(sc); + ifp->if_capenable |= IFCAP_POLLING; + ARGE_UNLOCK(sc); + } else { + ARGE_WRITE(sc, AR71XX_DMA_INTR, DMA_INTR_ALL); + error = ether_poll_deregister(ifp); + ARGE_LOCK(sc); + ifp->if_capenable &= ~IFCAP_POLLING; + ARGE_UNLOCK(sc); + } + } + break; +#endif default: error = ether_ioctl(ifp, command, data); break; @@ -1040,7 +1086,7 @@ arge_dma_alloc(struct arge_softc *sc) BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ MCLBYTES, /* maxsize */ - 1, /* nsegments */ + BUS_SPACE_UNRESTRICTED, /* nsegments */ MCLBYTES, /* maxsegsize */ 0, /* flags */ NULL, NULL, /* lockfunc, lockarg */ @@ -1265,10 +1311,10 @@ arge_rx_ring_init(struct arge_softc *sc) addr = ARGE_RX_RING_ADDR(sc, 0); else addr = ARGE_RX_RING_ADDR(sc, i + 1); - rd->arge_rx_ring[i].packet_ctrl = ARGE_DESC_EMPTY; rd->arge_rx_ring[i].next_desc = addr; - if (arge_newbuf(sc, i) != 0) + if (arge_newbuf(sc, i) != 0) { return (ENOBUFS); + } } bus_dmamap_sync(sc->arge_cdata.arge_rx_ring_tag, @@ -1313,13 +1359,12 @@ arge_newbuf(struct arge_softc *sc, int idx) map = rxd->rx_dmamap; rxd->rx_dmamap = sc->arge_cdata.arge_rx_sparemap; sc->arge_cdata.arge_rx_sparemap = map; - bus_dmamap_sync(sc->arge_cdata.arge_rx_tag, rxd->rx_dmamap, - BUS_DMASYNC_PREREAD); rxd->rx_m = m; desc = rxd->desc; + if (segs[0].ds_addr & 3) + panic("RX packet address unaligned"); desc->packet_addr = segs[0].ds_addr; - desc->packet_ctrl = (desc->packet_ctrl & ~ARGE_DESC_SIZE_MASK) - | ARGE_DMASIZE(segs[0].ds_len); + desc->packet_ctrl = ARGE_DESC_EMPTY | ARGE_DMASIZE(segs[0].ds_len); return (0); } @@ -1339,6 +1384,21 @@ arge_fixup_rx(struct mbuf *m) m->m_data -= ETHER_ALIGN; } +#ifdef DEVICE_POLLING +static void +arge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) +{ + struct arge_softc *sc = ifp->if_softc; + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + ARGE_LOCK(sc); + arge_tx_locked(sc); + arge_rx_locked(sc); + ARGE_UNLOCK(sc); + } +} +#endif /* DEVICE_POLLING */ + static void arge_tx_locked(struct arge_softc *sc) @@ -1406,7 +1466,7 @@ arge_rx_locked(struct arge_softc *sc) { struct arge_rxdesc *rxd; struct ifnet *ifp = sc->arge_ifp; - int cons, prog, packet_len; + int cons, prog, packet_len, i; struct arge_desc *cur_rx; struct mbuf *m; @@ -1445,23 +1505,26 @@ arge_rx_locked(struct arge_softc *sc) ARGE_UNLOCK(sc); (*ifp->if_input)(ifp, m); ARGE_LOCK(sc); - - /* Reinit descriptor */ - cur_rx->packet_ctrl = ARGE_DESC_EMPTY; cur_rx->packet_addr = 0; - if (arge_newbuf(sc, cons) != 0) { - device_printf(sc->arge_dev, - "Failed to allocate buffer\n"); - break; + } + + if (prog > 0) { + + i = sc->arge_cdata.arge_rx_cons; + for (; prog > 0 ; prog--) { + if (arge_newbuf(sc, i) != 0) { + device_printf(sc->arge_dev, + "Failed to allocate buffer\n"); + break; + } + ARGE_INC(i, ARGE_RX_RING_COUNT); } bus_dmamap_sync(sc->arge_cdata.arge_rx_ring_tag, sc->arge_cdata.arge_rx_ring_map, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - } - if (prog > 0) { sc->arge_cdata.arge_rx_cons = cons; bus_dmamap_sync(sc->arge_cdata.arge_rx_ring_tag, @@ -1470,27 +1533,6 @@ arge_rx_locked(struct arge_softc *sc) } } -static void -arge_rx_intr(struct arge_softc *sc, uint32_t status) -{ - - ARGE_LOCK(sc); - /* interrupts are masked by filter */ - arge_rx_locked(sc); - - /* RX overrun disables the receiver. Clear indication and - re-enable rx. */ - if ( status & DMA_INTR_RX_OVERFLOW) { - ARGE_WRITE(sc, AR71XX_DMA_RX_STATUS, DMA_RX_STATUS_OVERFLOW); - ARGE_WRITE(sc, AR71XX_DMA_RX_CONTROL, DMA_RX_CONTROL_EN); - } - - /* unmask interrupts */ - ARGE_SET_BITS(sc, - AR71XX_DMA_INTR, DMA_INTR_RX_OVERFLOW | DMA_INTR_RX_PKT_RCVD); - ARGE_UNLOCK(sc); -} - static int arge_intr_filter(void *arg) { @@ -1510,17 +1552,10 @@ arge_intr_filter(void *arg) #endif if (status & DMA_INTR_ALL) { - if (status & (DMA_INTR_RX_PKT_RCVD | DMA_INTR_RX_OVERFLOW)) - ARGE_CLEAR_BITS(sc, AR71XX_DMA_INTR, - DMA_INTR_RX_OVERFLOW | DMA_INTR_RX_PKT_RCVD); - - if (status & (DMA_INTR_TX_PKT_SENT | DMA_INTR_TX_UNDERRUN)) - ARGE_CLEAR_BITS(sc, AR71XX_DMA_INTR, - DMA_INTR_TX_UNDERRUN | DMA_INTR_TX_PKT_SENT); - sc->arge_intr_status |= status; + ARGE_WRITE(sc, AR71XX_DMA_INTR, 0); return (FILTER_SCHEDULE_THREAD); - } + } sc->arge_intr_status = 0; return (FILTER_STRAY); @@ -1532,8 +1567,8 @@ arge_intr(void *arg) struct arge_softc *sc = arg; uint32_t status; - status = sc->arge_intr_status; - sc->arge_intr_status = 0; + status = ARGE_READ(sc, AR71XX_DMA_INTR_STATUS); + status |= sc->arge_intr_status; #if 0 dprintf("int status(intr) = %b\n", status, @@ -1559,37 +1594,42 @@ arge_intr(void *arg) return; } - if (status & (DMA_INTR_RX_PKT_RCVD | DMA_INTR_RX_OVERFLOW)) - arge_rx_intr(sc, status); - - if (status & (DMA_INTR_TX_PKT_SENT | DMA_INTR_TX_UNDERRUN)) - arge_tx_intr(sc, status); -} - -static void -arge_tx_intr(struct arge_softc *sc, uint32_t status) -{ ARGE_LOCK(sc); - /* Interrupts are masked by filter */ - arge_tx_locked(sc); + if (status & DMA_INTR_RX_PKT_RCVD) + arge_rx_locked(sc); - /* Underrun turns off TX. Clear underrun indication. - If there's anything left in the ring, reactivate the tx. */ - if (status & DMA_INTR_TX_UNDERRUN) { - ARGE_WRITE(sc, AR71XX_DMA_TX_STATUS, DMA_TX_STATUS_UNDERRUN); - if (sc->arge_cdata.arge_tx_pkts > 0 ) { - ARGE_WRITE(sc, AR71XX_DMA_TX_CONTROL, DMA_TX_CONTROL_EN); - } + /* + * RX overrun disables the receiver. + * Clear indication and re-enable rx. + */ + if ( status & DMA_INTR_RX_OVERFLOW) { + ARGE_WRITE(sc, AR71XX_DMA_RX_STATUS, DMA_RX_STATUS_OVERFLOW); + ARGE_WRITE(sc, AR71XX_DMA_RX_CONTROL, DMA_RX_CONTROL_EN); } - /* unmask interrupts */ - ARGE_SET_BITS(sc, - AR71XX_DMA_INTR, DMA_INTR_TX_UNDERRUN | DMA_INTR_TX_PKT_SENT); + if (status & DMA_INTR_TX_PKT_SENT) + arge_tx_locked(sc); + /* + * Underrun turns off TX. Clear underrun indication. + * If there's anything left in the ring, reactivate the tx. + */ + if (status & DMA_INTR_TX_UNDERRUN) { + ARGE_WRITE(sc, AR71XX_DMA_TX_STATUS, DMA_TX_STATUS_UNDERRUN); + if (sc->arge_cdata.arge_tx_pkts > 0 ) { + ARGE_WRITE(sc, AR71XX_DMA_TX_CONTROL, + DMA_TX_CONTROL_EN); + } + } ARGE_UNLOCK(sc); + /* + * re-enable all interrupts + */ + ARGE_WRITE(sc, AR71XX_DMA_INTR, DMA_INTR_ALL); } + static void arge_tick(void *xsc) { @@ -1602,117 +1642,3 @@ arge_tick(void *xsc) mii_tick(mii); callout_reset(&sc->arge_stat_callout, hz, arge_tick, sc); } - -/* - * Create a copy of a single mbuf. It can have either internal or - * external data, it may have a packet header. External data is really - * copied, so the new buffer is writeable. - */ -static struct mbuf * -copy_mbuf(struct mbuf *m) -{ - struct mbuf *new; - - MGET(new, M_DONTWAIT, MT_DATA); - if (new == NULL) - return (NULL); - - if (m->m_flags & M_PKTHDR) { - M_MOVE_PKTHDR(new, m); - if (m->m_len > MHLEN) - MCLGET(new, M_WAIT); - } else { - if (m->m_len > MLEN) - MCLGET(new, M_WAIT); - } - - bcopy(m->m_data, new->m_data, m->m_len); - new->m_len = m->m_len; - new->m_flags &= ~M_RDONLY; - - return (new); -} - - - -static int -arge_fix_chain(struct mbuf **mp) -{ - struct mbuf *m = *mp, *prev = NULL, *next, *new; - u_int mlen = 0, fill = 0; - int first, off; - u_char *d, *cp; - - do { - next = m->m_next; - - if ((uintptr_t)mtod(m, void *) % 4 != 0 || - (m->m_len % 4 != 0 && next)) { - /* - * Needs fixing - */ - first = (m == *mp); - - d = mtod(m, u_char *); - if ((off = (uintptr_t)(void *)d % 4) != 0) { - if (M_WRITABLE(m)) { - bcopy(d, d - off, m->m_len); - m->m_data = (caddr_t)(d - off); - } else { - if ((new = copy_mbuf(m)) == NULL) { - goto fail; - } - if (prev) - prev->m_next = new; - new->m_next = next; - m_free(m); - m = new; - } - } - - if ((off = m->m_len % 4) != 0) { - if (!M_WRITABLE(m)) { - if ((new = copy_mbuf(m)) == NULL) { - goto fail; - } - if (prev) - prev->m_next = new; - new->m_next = next; - m_free(m); - m = new; - } - d = mtod(m, u_char *) + m->m_len; - off = 4 - off; - while (off) { - if (next == NULL) { - *d++ = 0; - fill++; - } else if (next->m_len == 0) { - next = m_free(next); - continue; - } else { - cp = mtod(next, u_char *); - *d++ = *cp++; - next->m_len--; - next->m_data = (caddr_t)cp; - } - off--; - m->m_len++; - } - } - - if (first) - *mp = m; - } - - mlen += m->m_len; - prev = m; - } while ((m = next) != NULL); - - return (mlen - fill); - - fail: - m_freem(*mp); - *mp = NULL; - return (0); -} From b6713e96f9dc97d173c6cd3ac87e41a421d644b8 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 26 May 2009 04:51:56 +0000 Subject: [PATCH 084/380] - Provide proper pre_thread/post_ithread functions for GT PCI controller. --- sys/mips/malta/gt_pci.c | 75 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 66 insertions(+), 9 deletions(-) diff --git a/sys/mips/malta/gt_pci.c b/sys/mips/malta/gt_pci.c index b5bb5bd13bb..152730370cf 100644 --- a/sys/mips/malta/gt_pci.c +++ b/sys/mips/malta/gt_pci.c @@ -91,6 +91,13 @@ __FBSDID("$FreeBSD$"); #define OCW3_POLL_IRQ(x) ((x) & 0x7f) #define OCW3_POLL_PENDING (1U << 7) +struct gt_pci_softc; + +struct gt_pci_intr_cookie { + int irq; + struct gt_pci_softc *sc; +}; + struct gt_pci_softc { device_t sc_dev; bus_space_tag_t sc_st; @@ -107,6 +114,7 @@ struct gt_pci_softc { struct resource *sc_irq; struct intr_event *sc_eventstab[ICU_LEN]; + struct gt_pci_intr_cookie sc_intr_cookies[ICU_LEN]; uint16_t sc_imask; uint16_t sc_elcr; @@ -115,6 +123,51 @@ struct gt_pci_softc { void *sc_ih; }; +static void gt_pci_set_icus(struct gt_pci_softc *); +static int gt_pci_intr(void *v); +static int gt_pci_probe(device_t); +static int gt_pci_attach(device_t); +static int gt_pci_activate_resource(device_t, device_t, int, int, + struct resource *); +static int gt_pci_setup_intr(device_t, device_t, struct resource *, + int, driver_filter_t *, driver_intr_t *, void *, void **); +static int gt_pci_teardown_intr(device_t, device_t, struct resource *, void*); +static int gt_pci_maxslots(device_t ); +static int gt_pci_conf_setup(struct gt_pci_softc *, int, int, int, int, + uint32_t *); +static uint32_t gt_pci_read_config(device_t, int, int, int, int, int); +static void gt_pci_write_config(device_t, int, int, int, int, uint32_t, int); +static int gt_pci_route_interrupt(device_t pcib, device_t dev, int pin); +static struct resource * gt_pci_alloc_resource(device_t, device_t, int, + int *, u_long, u_long, u_long, u_int); + +static void +gt_pci_mask_irq(void *source) +{ + struct gt_pci_intr_cookie *cookie = source; + struct gt_pci_softc *sc = cookie->sc; + int irq = cookie->irq; + + sc->sc_imask |= (1 << irq); + sc->sc_elcr |= (1 << irq); + + gt_pci_set_icus(sc); +} + +static void +gt_pci_unmask_irq(void *source) +{ + struct gt_pci_intr_cookie *cookie = source; + struct gt_pci_softc *sc = cookie->sc; + int irq = cookie->irq; + + /* Enable it, set trigger mode. */ + sc->sc_imask &= ~(1 << irq); + sc->sc_elcr &= ~(1 << irq); + + gt_pci_set_icus(sc); +} + static void gt_pci_set_icus(struct gt_pci_softc *sc) { @@ -629,10 +682,13 @@ gt_pci_setup_intr(device_t dev, device_t child, struct resource *ires, panic("%s: bad irq or type", __func__); event = sc->sc_eventstab[irq]; + sc->sc_intr_cookies[irq].irq = irq; + sc->sc_intr_cookies[irq].sc = sc; if (event == NULL) { - error = intr_event_create(&event, (void *)irq, 0, irq, - (mask_fn)mips_mask_irq, (mask_fn)mips_unmask_irq, - (mask_fn)mips_unmask_irq, NULL, "gt_pci intr%d:", irq); + error = intr_event_create(&event, + (void *)&sc->sc_intr_cookies[irq], 0, irq, + gt_pci_mask_irq, gt_pci_unmask_irq, + NULL, NULL, "gt_pci intr%d:", irq); if (error) return 0; sc->sc_eventstab[irq] = event; @@ -641,12 +697,7 @@ gt_pci_setup_intr(device_t dev, device_t child, struct resource *ires, intr_event_add_handler(event, device_get_nameunit(child), filt, handler, arg, intr_priority(flags), flags, cookiep); - /* Enable it, set trigger mode. */ - sc->sc_imask &= ~(1 << irq); - sc->sc_elcr &= ~(1 << irq); - - gt_pci_set_icus(sc); - + gt_pci_unmask_irq((void *)&sc->sc_intr_cookies[irq]); return 0; } @@ -654,6 +705,12 @@ static int gt_pci_teardown_intr(device_t dev, device_t child, struct resource *res, void *cookie) { + struct gt_pci_softc *sc = device_get_softc(dev); + int irq; + + irq = rman_get_start(res); + gt_pci_mask_irq((void *)&sc->sc_intr_cookies[irq]); + return (intr_event_remove_handler(cookie)); } From c3ab9e8c95af128ca9319494f5e43c1f443e9668 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 26 May 2009 05:52:24 +0000 Subject: [PATCH 085/380] - Provide proper pre_ithread/post_ithread functions --- sys/mips/adm5120/obio.c | 53 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/sys/mips/adm5120/obio.c b/sys/mips/adm5120/obio.c index 8d8392834b2..ad6cb6e2ea7 100644 --- a/sys/mips/adm5120/obio.c +++ b/sys/mips/adm5120/obio.c @@ -120,6 +120,39 @@ static int obio_setup_intr(device_t, device_t, struct resource *, int, static int obio_teardown_intr(device_t, device_t, struct resource *, void *); + +static void +obio_mask_irq(void *source) +{ + int irq; + uint32_t irqmask; + uint32_t reg; + + irq = (int)source; + irqmask = 1 << irq; + + /* disable IRQ */ + reg = REG_READ(ICU_DISABLE_REG); + REG_WRITE(ICU_DISABLE_REG, (reg | irqmask)); +} + +static void +obio_unmask_irq(void *source) +{ + int irq; + uint32_t irqmask; + uint32_t reg; + + irq = (int)source; + irqmask = 1 << irq; + + /* disable IRQ */ + reg = REG_READ(ICU_DISABLE_REG); + REG_WRITE(ICU_DISABLE_REG, (reg & ~irqmask)); + +} + + static int obio_probe(device_t dev) { @@ -321,7 +354,7 @@ obio_setup_intr(device_t dev, device_t child, struct resource *ires, event = sc->sc_eventstab[irq]; if (event == NULL) { error = intr_event_create(&event, (void *)irq, 0, irq, - (mask_fn)mips_mask_irq, (mask_fn)mips_unmask_irq, + obio_mask_irq, obio_unmask_irq, NULL, NULL, "obio intr%d:", irq); sc->sc_eventstab[irq] = event; @@ -343,6 +376,8 @@ obio_setup_intr(device_t dev, device_t child, struct resource *ires, /* enable */ REG_WRITE(ICU_ENABLE_REG, irqmask); + obio_unmask_irq((void*)irq); + return (0); } @@ -351,7 +386,7 @@ obio_teardown_intr(device_t dev, device_t child, struct resource *ires, void *cookie) { struct obio_softc *sc = device_get_softc(dev); - int irq, result; + int irq, result, priority; uint32_t irqmask; irq = rman_get_start(ires); @@ -361,10 +396,18 @@ obio_teardown_intr(device_t dev, device_t child, struct resource *ires, if (sc->sc_eventstab[irq] == NULL) panic("Trying to teardown unoccupied IRQ"); - irqmask = 1 << irq; /* only used as a mask from here on */ + irqmask = (1 << irq); + priority = irq_priorities[irq]; - /* disable this irq in HW */ - REG_WRITE(ICU_DISABLE_REG, irqmask); + if (priority == INTR_FIQ) + REG_WRITE(ICU_MODE_REG, REG_READ(ICU_MODE_REG) & ~irqmask); + else + REG_WRITE(ICU_MODE_REG, REG_READ(ICU_MODE_REG) | irqmask); + + /* disable */ + irqmask = REG_READ(ICU_ENABLE_REG); + irqmask &= ~(1 << irq); + REG_WRITE(ICU_ENABLE_REG, irqmask); result = intr_event_remove_handler(cookie); if (!result) { From c7657b54ac9e2dbd3b71cf3906d847dfaf649f00 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 26 May 2009 05:59:05 +0000 Subject: [PATCH 086/380] - Provide proper pre_ithread/post_ithread functions for both hard and soft interrupts - Do not handle masked interrupts - Do not write Cause register because most bytes are read-only and writing the same byte to RW fields are pointless. And in case of software interrupt utterly wrong --- sys/mips/mips/intr_machdep.c | 52 ++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/sys/mips/mips/intr_machdep.c b/sys/mips/mips/intr_machdep.c index 67259750386..0d7b95014a7 100644 --- a/sys/mips/mips/intr_machdep.c +++ b/sys/mips/mips/intr_machdep.c @@ -53,18 +53,39 @@ static int intrcnt_index = 0; static int last_printed = 0; #endif -void -mips_mask_irq(void) +static void +mips_mask_hard_irq(void *source) { + int irq = (int)source; + mips_wr_status(mips_rd_status() & ~(((1 << irq) << 8) << 2)); } -void -mips_unmask_irq(void) +static void +mips_unmask_hard_irq(void *source) { + int irq = (int)source; + mips_wr_status(mips_rd_status() | (((1 << irq) << 8) << 2)); } +static void +mips_mask_soft_irq(void *source) +{ + int irq = (int)source; + + mips_wr_status(mips_rd_status() & ~((1 << irq) << 8)); +} + +static void +mips_unmask_soft_irq(void *source) +{ + int irq = (int)source; + + mips_wr_status(mips_rd_status() | ((1 << irq) << 8)); +} + + void cpu_establish_hardintr(const char *name, driver_filter_t *filt, void (*handler)(void*), void *arg, int irq, int flags, void **cookiep) @@ -72,8 +93,10 @@ cpu_establish_hardintr(const char *name, driver_filter_t *filt, struct intr_event *event; int error; +#if 0 printf("Establish HARD IRQ %d: filt %p handler %p arg %p\n", irq, filt, handler, arg); +#endif /* * We have 6 levels, but thats 0 - 5 (not including 6) */ @@ -83,7 +106,7 @@ cpu_establish_hardintr(const char *name, driver_filter_t *filt, event = hardintr_events[irq]; if (event == NULL) { error = intr_event_create(&event, (void *)irq, 0, irq, - (mask_fn)mips_mask_irq, (mask_fn)mips_unmask_irq, + mips_mask_hard_irq, mips_unmask_hard_irq, NULL, NULL, "hard intr%d:", irq); if (error) return; @@ -101,7 +124,7 @@ cpu_establish_hardintr(const char *name, driver_filter_t *filt, intr_event_add_handler(event, name, filt, handler, arg, intr_priority(flags), flags, cookiep); - mips_wr_status(mips_rd_status() | (((1 << irq) << 8) << 2)); + mips_unmask_hard_irq((void*)irq); } void @@ -112,15 +135,17 @@ cpu_establish_softintr(const char *name, driver_filter_t *filt, struct intr_event *event; int error; +#if 0 printf("Establish SOFT IRQ %d: filt %p handler %p arg %p\n", irq, filt, handler, arg); +#endif if (irq < 0 || irq > NSOFT_IRQS) panic("%s called for unknown hard intr %d", __func__, irq); event = softintr_events[irq]; if (event == NULL) { error = intr_event_create(&event, (void *)irq, 0, irq, - (mask_fn)mips_mask_irq, (mask_fn)mips_unmask_irq, + mips_mask_soft_irq, mips_unmask_soft_irq, NULL, NULL, "intr%d:", irq); if (error) return; @@ -130,22 +155,27 @@ cpu_establish_softintr(const char *name, driver_filter_t *filt, intr_event_add_handler(event, name, filt, handler, arg, intr_priority(flags), flags, cookiep); - mips_wr_status(mips_rd_status() | (((1<< irq) << 8))); + mips_unmask_soft_irq((void*)irq); } void cpu_intr(struct trapframe *tf) { struct intr_event *event; - register_t cause; + register_t cause, status; int hard, i, intr; critical_enter(); cause = mips_rd_cause(); + status = mips_rd_status(); intr = (cause & MIPS_INT_MASK) >> 8; - cause &= ~MIPS_INT_MASK; - mips_wr_cause(cause); + /* + * Do not handle masked interrupts. They were masked by + * pre_ithread function (mips_mask_XXX_intr) and will be + * unmasked once ithread is through with handler + */ + intr &= (status & MIPS_INT_MASK) >> 8; while ((i = fls(intr)) != 0) { intr &= ~(1 << (i - 1)); switch (i) { From be6bd37babfca8d39f19363826dc6a905bcecabd Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 26 May 2009 06:01:17 +0000 Subject: [PATCH 087/380] - Remove now unused NetBSDism intr.h --- sys/mips/include/intr.h | 94 ----------------------------------------- sys/mips/include/psl.h | 4 -- sys/mips/mips/trap.c | 1 - 3 files changed, 99 deletions(-) delete mode 100644 sys/mips/include/intr.h diff --git a/sys/mips/include/intr.h b/sys/mips/include/intr.h deleted file mode 100644 index c406379f012..00000000000 --- a/sys/mips/include/intr.h +++ /dev/null @@ -1,94 +0,0 @@ -/* $NetBSD: intr.h,v 1.5 1996/05/13 06:11:28 mycroft Exp $ */ - -/*- - * Copyright (c) 1996 Charles M. Hannum. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Charles M. Hannum. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * JNPR: intr.h,v 1.4 2007/08/09 11:23:32 katta - * $FreeBSD$ - */ - -#ifndef _MACHINE_INTR_H_ -#define _MACHINE_INTR_H_ - -/* Interrupt sharing types. */ -#define IST_NONE 0 /* none */ -#define IST_PULSE 1 /* pulsed */ -#define IST_EDGE 2 /* edge-triggered */ -#define IST_LEVEL 3 /* level-triggered */ - -#ifndef _LOCORE - -/* - * Index into intrcnt[], which is defined in exceptions.S - * Index # = irq # - 1 - */ -#define INTRCNT_HARDCLOCK 0 -#define INTRCNT_RTC 1 -#define INTRCNT_SIO 2 /* irq 3 */ -#define INTRCNT_PE 3 /* irq 4 */ -#define INTRCNT_PICNIC 4 /* irq 5 */ - -extern uint32_t idle_mask; -extern void (*mips_ack_interrupt)(int, uint32_t); - -typedef int ih_func_t(void *); - -struct intr_event; - -struct mips_intr_handler { - int (*ih_func) (void *); - void *ih_arg; - struct intr_event *ih_event; - u_int ih_flags; - volatile long *ih_count; - int ih_level; - int ih_irq; - void *frame; -}; - -extern struct mips_intr_handler intr_handlers[]; - -typedef void (*mask_fn)(void *); - -void mips_mask_irq(void); -void mips_unmask_irq(void); - -struct trapframe; -void mips_set_intr(int pri, uint32_t mask, - uint32_t (*int_hand)(uint32_t, struct trapframe *)); -uint32_t mips_handle_interrupts(uint32_t pending, struct trapframe *cf); -void intr_enable_source(uintptr_t irq); -struct trapframe * mips_get_trapframe(void *ih_arg); -int inthand_add(const char *name, u_int irq, void (*handler)(void *), - void *arg, int flags, void **cookiep); -int inthand_remove(u_int irq, void *cookie); -void bvif_attach(void); - -#endif /* _LOCORE */ - -#endif /* !_MACHINE_INTR_H_ */ diff --git a/sys/mips/include/psl.h b/sys/mips/include/psl.h index 9d05d133ee2..f02a1a95fa9 100644 --- a/sys/mips/include/psl.h +++ b/sys/mips/include/psl.h @@ -47,8 +47,4 @@ #define USERMODE(ps) (((ps) & SR_KSU_MASK) == SR_KSU_USER) #define BASEPRI(ps) (((ps) & (INT_MASK | SR_INT_ENA_PREV)) \ == (INT_MASK | SR_INT_ENA_PREV)) - -#ifdef _KERNEL -#include -#endif #endif /* _MACHINE_PSL_H_ */ diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c index 6d047ccdda2..89d1671ef36 100644 --- a/sys/mips/mips/trap.c +++ b/sys/mips/mips/trap.c @@ -76,7 +76,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include From aac33d70330bffe276c4853347bbf78df5587d45 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 26 May 2009 06:02:38 +0000 Subject: [PATCH 088/380] - Remove erroneus "break" instruction, it was meant for debug --- sys/mips/mips/exception.S | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/mips/mips/exception.S b/sys/mips/mips/exception.S index 31327fc8591..c44c87f2273 100644 --- a/sys/mips/mips/exception.S +++ b/sys/mips/mips/exception.S @@ -689,7 +689,6 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra) /* * Call the interrupt handler. */ - break la k0, _C_LABEL(cpu_intr) jalr k0 sw a3, STAND_RA_OFFSET(sp) # for debugging From 0e59084d6868e39ef60d2bc93edc85651e079404 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 26 May 2009 06:20:50 +0000 Subject: [PATCH 089/380] - Preserve INT_MASK fields in Status register across context switches. They should be modified only by interrupt setup/teardown and pre_ithread/post_ithread functions --- sys/mips/mips/exception.S | 13 +++++++++++++ sys/mips/mips/pm_machdep.c | 3 ++- sys/mips/mips/swtch.S | 9 +++++++++ sys/mips/mips/vm_machdep.c | 8 +++----- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/sys/mips/mips/exception.S b/sys/mips/mips/exception.S index c44c87f2273..e53849072bb 100644 --- a/sys/mips/mips/exception.S +++ b/sys/mips/mips/exception.S @@ -593,6 +593,19 @@ NNON_LEAF(MipsKernIntr, KERN_EXC_FRAME_SIZE, ra) jalr k0 sw a3, STAND_RA_OFFSET + KERN_REG_SIZE(sp) /* Why no AST processing here? */ + + /* + * Update interrupt mask in saved status register + * Some of interrupts could be disabled by + * intr filters + */ + mfc0 a0, COP_0_STATUS_REG + and a0, a0, SR_INT_MASK + RESTORE_REG(a1, SR, sp) + and a1, a1, ~SR_INT_MASK + or a1, a1, a0 + SAVE_REG(a1, SR, sp) + /* * Restore registers and return from the interrupt. */ diff --git a/sys/mips/mips/pm_machdep.c b/sys/mips/mips/pm_machdep.c index e9e6ea294a7..f877f65c80f 100644 --- a/sys/mips/mips/pm_machdep.c +++ b/sys/mips/mips/pm_machdep.c @@ -482,7 +482,8 @@ exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings) // td->td_frame->sr = SR_KSU_USER | SR_EXL | SR_INT_ENAB; //? td->td_frame->sr |= idle_mask & ALL_INT_MASK; #else - td->td_frame->sr = SR_KSU_USER | SR_EXL;// mips2 also did COP_0_BIT + td->td_frame->sr = SR_KSU_USER | SR_EXL | SR_INT_ENAB | + (mips_rd_status() & ALL_INT_MASK); #endif #ifdef TARGET_OCTEON td->td_frame->sr |= MIPS_SR_COP_2_BIT | MIPS32_SR_PX | MIPS_SR_UX | diff --git a/sys/mips/mips/swtch.S b/sys/mips/mips/swtch.S index 84585cb36c5..7a016fa4e99 100644 --- a/sys/mips/mips/swtch.S +++ b/sys/mips/mips/swtch.S @@ -224,6 +224,11 @@ LEAF(fork_trampoline) RESTORE_U_PCB_REG(s8, S8, k1) RESTORE_U_PCB_REG(ra, RA, k1) RESTORE_U_PCB_REG(sp, SP, k1) + li k1, ~SR_INT_MASK + and k0, k0, k1 + mfc0 k1, COP_0_STATUS_REG + and k1, k1, SR_INT_MASK + or k0, k0, k1 mtc0 k0, COP_0_STATUS_REG # switch to user mode (when eret...) HAZARD_DELAY sync @@ -410,6 +415,10 @@ sw2: * In case there are CPU-specific registers that need * to be restored with the other registers do so here. */ + mfc0 t0, COP_0_STATUS_REG + and t0, t0, SR_INT_MASK + and v0, v0, ~SR_INT_MASK + or v0, v0, t0 mtc0 v0, COP_0_STATUS_REG ITLBNOPFIX diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c index 26b64778b8c..143d6ddb927 100644 --- a/sys/mips/mips/vm_machdep.c +++ b/sys/mips/mips/vm_machdep.c @@ -148,7 +148,7 @@ cpu_fork(register struct thread *td1,register struct proc *p2, pcb2->pcb_context.val[PCB_REG_S0] = (register_t)fork_return; pcb2->pcb_context.val[PCB_REG_S1] = (register_t)td2; pcb2->pcb_context.val[PCB_REG_S2] = (register_t)td2->td_frame; - pcb2->pcb_context.val[PCB_REG_SR] = SR_INT_MASK; + pcb2->pcb_context.val[PCB_REG_SR] = SR_INT_MASK & mips_rd_status(); /* * FREEBSD_DEVELOPERS_FIXME: * Setup any other CPU-Specific registers (Not MIPS Standard) @@ -298,11 +298,9 @@ cpu_set_upcall(struct thread *td, struct thread *td0) pcb2->pcb_context.val[PCB_REG_S0] = (register_t)fork_return; pcb2->pcb_context.val[PCB_REG_S1] = (register_t)td; pcb2->pcb_context.val[PCB_REG_S2] = (register_t)td->td_frame; - - /* Dont set IE bit in SR. sched lock release will take care of it */ -/* idle_mask is jmips pcb2->pcb_context.val[11] = (ALL_INT_MASK & idle_mask); */ - pcb2->pcb_context.val[PCB_REG_SR] = SR_INT_MASK; + pcb2->pcb_context.val[PCB_REG_SR] = SR_INT_MASK & mips_rd_status(); + #ifdef TARGET_OCTEON pcb2->pcb_context.val[PCB_REG_SR] |= MIPS_SR_COP_2_BIT | MIPS_SR_COP_0_BIT | MIPS32_SR_PX | MIPS_SR_UX | MIPS_SR_KX | MIPS_SR_SX; From 5d54a91aa4d9644bf58af507a374f53cea968267 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 26 May 2009 16:29:35 +0000 Subject: [PATCH 090/380] - Add UFS support - Enable PCI - Add bpf and random devices for wpa_supplicant - Disable USB - Add SPI bus and MX25L support --- sys/mips/conf/AR71XX | 55 +++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/sys/mips/conf/AR71XX b/sys/mips/conf/AR71XX index d8add88b7c2..0ceb1b65eaa 100644 --- a/sys/mips/conf/AR71XX +++ b/sys/mips/conf/AR71XX @@ -8,6 +8,7 @@ options CPU_NOFPU options ISA_MIPS32 makeoptions TARGET_BIG_ENDIAN makeoptions KERNLOADADDR=0x80050000 +options HZ=1000 files "../atheros/files.ar71xx" hints "AR71XX.hints" @@ -27,8 +28,15 @@ options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions options NFS_LEGACYRPC # Debugging for use in -current -options INVARIANTS -options INVARIANT_SUPPORT +# options INVARIANTS +# options INVARIANT_SUPPORT +# options WITNESS +# options WITNESS_SKIPSPIN +options FFS #Berkeley Fast Filesystem +options SOFTUPDATES #Enable FFS soft updates support +options UFS_ACL #Support for access control lists +options UFS_DIRHASH #Improve performance on big directories + options BOOTP options BOOTP_NFSROOT @@ -37,29 +45,40 @@ options BOOTP_WIRED_TO=arge0 options BOOTP_COMPAT options ROOTDEVNAME=\"nfs:192.168.10.1:/mnt/bsd\" -# device pci -# Wireless NIC cards -# device wlan # 802.11 support -# device wlan_wep # 802.11 WEP support -# device wlan_ccmp # 802.11 CCMP support -# device wlan_tkip # 802.11 TKIP support +device pci -# device ath # Atheros pci/cardbus NIC's -# option AH_SUPPORT_AR5416 -# device ath_hal -# device ath_ar5212 # Atheros HAL (Hardware Access Layer) -# device ath_rate_sample +# Wireless NIC cards +options IEEE80211_DEBUG +options IEEE80211_SUPPORT_TDMA +device wlan # 802.11 support +device wlan_wep # 802.11 WEP support +device wlan_ccmp # 802.11 CCMP support +device wlan_tkip # 802.11 TKIP support + +device ath # Atheros pci/cardbus NIC's +options ATH_DEBUG +option AH_SUPPORT_AR5416 +device ath_hal +device ath_ar5212 # Atheros HAL (Hardware Access Layer) +device ath_rate_sample device mii device arge -device uart +# device usb +# options USB_EHCI_BIG_ENDIAN_DESC # handle big-endian byte order +# options USB_DEBUG +# device ehci -device usb -options USB_EHCI_BIG_ENDIAN_DESC # handle big-endian byte order -options USB_DEBUG -device ehci +device spibus +device ar71xx_spi +device mx25l +# device geom_redboot + +device uart device loop device ether device md +device bpf +device random From 7dafc31d3eb896dc84173413feb7cf7fe13b970b Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 26 May 2009 16:35:05 +0000 Subject: [PATCH 091/380] - Add type cast for atomic_cmpset_acq_ptr arguments --- sys/mips/include/atomic.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/mips/include/atomic.h b/sys/mips/include/atomic.h index 9f800cd1d21..9b2d18a698e 100644 --- a/sys/mips/include/atomic.h +++ b/sys/mips/include/atomic.h @@ -435,7 +435,9 @@ atomic_fetchadd_32(__volatile uint32_t *p, uint32_t v) #define atomic_subtract_acq_ptr atomic_subtract_acq_32 #define atomic_subtract_rel_ptr atomic_subtract_rel_32 #define atomic_cmpset_ptr atomic_cmpset_32 -#define atomic_cmpset_acq_ptr atomic_cmpset_acq_32 +#define atomic_cmpset_acq_ptr(dst, old, new) \ + atomic_cmpset_acq_32((volatile u_int *)(dst), \ + (u_int)(old), (u_int)(new)) #define atomic_cmpset_rel_ptr atomic_cmpset_rel_32 #define atomic_load_acq_ptr atomic_load_acq_32 #define atomic_store_rel_ptr atomic_store_rel_32 From 571ef3dd823e3e3834ff5616f921322206a67981 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 26 May 2009 17:43:32 +0000 Subject: [PATCH 092/380] - arge_poll should be decalred only if DEVICE_POLLING is enabled - Revert Rx buffer nsegments from BUS_SPACE_UNRESTRICTED to ARGE_MAXFRAGS --- sys/mips/atheros/if_arge.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index 5c863a7366e..c4f48f3c3fb 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -103,7 +103,9 @@ static void arge_reset_dma(struct arge_softc *); static int arge_resume(device_t); static int arge_rx_ring_init(struct arge_softc *); static int arge_tx_ring_init(struct arge_softc *); +#ifdef DEVICE_POLLING static void arge_poll(struct ifnet *, enum poll_cmd, int); +#endif static void arge_shutdown(device_t); static void arge_start(struct ifnet *); static void arge_start_locked(struct ifnet *); @@ -1086,7 +1088,7 @@ arge_dma_alloc(struct arge_softc *sc) BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ MCLBYTES, /* maxsize */ - BUS_SPACE_UNRESTRICTED, /* nsegments */ + ARGE_MAXFRAGS, /* nsegments */ MCLBYTES, /* maxsegsize */ 0, /* flags */ NULL, NULL, /* lockfunc, lockarg */ From 66ecdee881ef333a89abf13be787f9d5fb01bb03 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 26 May 2009 17:50:50 +0000 Subject: [PATCH 093/380] - style(9) fixes - Get rid of obsolete mask_fn --- sys/mips/atheros/apb.c | 14 +++++++++----- sys/mips/atheros/ar71xx_pci.c | 16 +++++++++------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/sys/mips/atheros/apb.c b/sys/mips/atheros/apb.c index fad29ecab52..ee8a167c76c 100644 --- a/sys/mips/atheros/apb.c +++ b/sys/mips/atheros/apb.c @@ -70,8 +70,10 @@ static int apb_setup_intr(device_t, device_t, struct resource *, int, static int apb_teardown_intr(device_t, device_t, struct resource *, void *); -static void apb_mask_irq(unsigned int irq) +static void +apb_mask_irq(void *source) { + unsigned int irq = (unsigned int)source; uint32_t reg; reg = ATH_READ_REG(AR71XX_MISC_INTR_MASK); @@ -79,9 +81,11 @@ static void apb_mask_irq(unsigned int irq) } -static void apb_unmask_irq(unsigned int irq) +static void +apb_unmask_irq(void *source) { uint32_t reg; + unsigned int irq = (unsigned int)source; reg = ATH_READ_REG(AR71XX_MISC_INTR_MASK); ATH_WRITE_REG(AR71XX_MISC_INTR_MASK, reg | (1 << irq)); @@ -277,7 +281,7 @@ apb_setup_intr(device_t bus, device_t child, struct resource *ires, event = sc->sc_eventstab[irq]; if (event == NULL) { error = intr_event_create(&event, (void *)irq, 0, irq, - (mask_fn)apb_mask_irq, (mask_fn)apb_unmask_irq, + apb_mask_irq, apb_unmask_irq, NULL, NULL, "apb intr%d:", irq); @@ -287,7 +291,7 @@ apb_setup_intr(device_t bus, device_t child, struct resource *ires, intr_event_add_handler(event, device_get_nameunit(child), filt, handler, arg, intr_priority(flags), flags, cookiep); - apb_unmask_irq(irq); + apb_unmask_irq((void*)irq); return (0); } @@ -306,7 +310,7 @@ apb_teardown_intr(device_t dev, device_t child, struct resource *ires, if (sc->sc_eventstab[irq] == NULL) panic("Trying to teardown unoccupied IRQ"); - apb_mask_irq(irq); + apb_mask_irq((void*)irq); result = intr_event_remove_handler(cookie); if (!result) diff --git a/sys/mips/atheros/ar71xx_pci.c b/sys/mips/atheros/ar71xx_pci.c index ee186b7aa61..5a3697d80c4 100644 --- a/sys/mips/atheros/ar71xx_pci.c +++ b/sys/mips/atheros/ar71xx_pci.c @@ -80,18 +80,22 @@ static int ar71xx_pci_teardown_intr(device_t, device_t, struct resource *, void *); static int ar71xx_pci_intr(void *); -static void ar71xx_pci_mask_irq(unsigned int irq) +static void +ar71xx_pci_mask_irq(void *source) { uint32_t reg; + unsigned int irq = (unsigned int)source; reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK); ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, reg & ~(1 << irq)); } -static void ar71xx_pci_unmask_irq(unsigned int irq) +static void +ar71xx_pci_unmask_irq(void *source) { uint32_t reg; + unsigned int irq = (unsigned int)source; reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK); ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, reg | (1 << irq)); @@ -426,9 +430,7 @@ ar71xx_pci_setup_intr(device_t bus, device_t child, struct resource *ires, event = sc->sc_eventstab[irq]; if (event == NULL) { error = intr_event_create(&event, (void *)irq, 0, irq, - (mask_fn)ar71xx_pci_mask_irq, - (mask_fn)ar71xx_pci_unmask_irq, - NULL, NULL, + ar71xx_pci_mask_irq, ar71xx_pci_unmask_irq, NULL, NULL, "ar71xx_pci intr%d:", irq); sc->sc_eventstab[irq] = event; @@ -437,7 +439,7 @@ ar71xx_pci_setup_intr(device_t bus, device_t child, struct resource *ires, intr_event_add_handler(event, device_get_nameunit(child), filt, handler, arg, intr_priority(flags), flags, cookiep); - ar71xx_pci_unmask_irq(irq); + ar71xx_pci_unmask_irq((void*)irq); return (0); } @@ -456,7 +458,7 @@ ar71xx_pci_teardown_intr(device_t dev, device_t child, struct resource *ires, if (sc->sc_eventstab[irq] == NULL) panic("Trying to teardown unoccupied IRQ"); - ar71xx_pci_mask_irq(irq); + ar71xx_pci_mask_irq((void*)irq); result = intr_event_remove_handler(cookie); if (!result) From 16a7c7be6d66bd3d8d5b2f413ed008bde61f5ff3 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 26 May 2009 22:40:12 +0000 Subject: [PATCH 094/380] - Replace CPU_NOFPU and SOFTFLOAT options with CPU_FPU. By default we assume that there is no FPU, because majority of SoC does not have it. --- sys/conf/options.mips | 3 +-- sys/mips/conf/AR71XX | 1 - sys/mips/conf/SENTRY5 | 1 - sys/mips/include/float.h | 6 +++--- sys/mips/malta/std.malta | 1 - sys/mips/mips/locore.S | 2 +- sys/mips/mips/trap.c | 2 +- 7 files changed, 6 insertions(+), 10 deletions(-) diff --git a/sys/conf/options.mips b/sys/conf/options.mips index 42e02639b9a..1b218a466cf 100644 --- a/sys/conf/options.mips +++ b/sys/conf/options.mips @@ -31,8 +31,8 @@ CPU_MIPS4KC opt_global.h CPU_MIPS32 opt_global.h CPU_MIPS64 opt_global.h -CPU_NOFPU opt_global.h CPU_SENTRY5 opt_global.h +CPU_HAVEFPU opt_global.h ISA_MIPS1 opt_cputype.h ISA_MIPS3 opt_cputype.h @@ -48,7 +48,6 @@ CFE_CONSOLE opt_global.h KERNPHYSADDR opt_global.h KERNVIRTADDR opt_global.h PHYSADDR opt_global.h -SOFTFLOAT opt_global.h TARGET_OCTEON opt_global.h TARGET_EMULATOR opt_ddb.h diff --git a/sys/mips/conf/AR71XX b/sys/mips/conf/AR71XX index 0ceb1b65eaa..a66d305e698 100644 --- a/sys/mips/conf/AR71XX +++ b/sys/mips/conf/AR71XX @@ -4,7 +4,6 @@ ident AR71XX cpu CPU_MIPS4KC -options CPU_NOFPU options ISA_MIPS32 makeoptions TARGET_BIG_ENDIAN makeoptions KERNLOADADDR=0x80050000 diff --git a/sys/mips/conf/SENTRY5 b/sys/mips/conf/SENTRY5 index c3918e2e35c..c035350cb15 100644 --- a/sys/mips/conf/SENTRY5 +++ b/sys/mips/conf/SENTRY5 @@ -26,7 +26,6 @@ ident SENTRY5 cpu CPU_MIPS4KC -options CPU_NOFPU options ISA_MIPS32 options CPU_SENTRY5 # XXX should this be a # sub-cpu option? diff --git a/sys/mips/include/float.h b/sys/mips/include/float.h index 750feb0886f..ff7e65cf1db 100644 --- a/sys/mips/include/float.h +++ b/sys/mips/include/float.h @@ -42,10 +42,10 @@ extern int __flt_rounds(void); __END_DECLS #define FLT_RADIX 2 /* b */ -#ifdef SOFTFLOAT -#define FLT_ROUNDS -1 -#else +#ifdef CPU_HAVEFPU #define FLT_ROUNDS __flt_rounds() /* FP addition rounds to nearest */ +#else +#define FLT_ROUNDS -1 #endif /* * XXXMIPS: MIPS32 has both float and double type, so set FLT_EVAL_METHOD diff --git a/sys/mips/malta/std.malta b/sys/mips/malta/std.malta index ca67e562826..8a796fea6bd 100644 --- a/sys/mips/malta/std.malta +++ b/sys/mips/malta/std.malta @@ -3,7 +3,6 @@ files "../malta/files.malta" cpu CPU_MIPS4KC options ISA_MIPS32 -options SOFTFLOAT device pci device ata device atadisk diff --git a/sys/mips/mips/locore.S b/sys/mips/mips/locore.S index afcabd41db7..6655eb6cb2f 100644 --- a/sys/mips/mips/locore.S +++ b/sys/mips/mips/locore.S @@ -145,7 +145,7 @@ VECTOR(_locore, unknown) /* Read and store the PrID FPU ID for CPU identification, if any. */ mfc0 t2, COP_0_STATUS_REG mfc0 t0, MIPS_COP_0_PRID -#ifndef CPU_NOFPU +#ifdef CPU_HAVEFPU and t2, MIPS_SR_COP_1_BIT beqz t2, 1f move t1, zero diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c index 89d1671ef36..0e0fa35a336 100644 --- a/sys/mips/mips/trap.c +++ b/sys/mips/mips/trap.c @@ -928,7 +928,7 @@ dofault: goto err; break; case T_COP_UNUSABLE + T_USER: -#if defined(SOFTFLOAT) +#if !defined(CPU_HAVEFPU) /* FP (COP1) instruction */ if ((trapframe->cause & CR_COP_ERR) == 0x10000000) { i = SIGILL; From 40570d7175abf398018a379a70d55248e57ca071 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 28 May 2009 00:47:50 +0000 Subject: [PATCH 095/380] - Revert fix by dwhite that has been accidentally lost in r192783 commit. --- sys/mips/atheros/if_arge.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index c4f48f3c3fb..08cd443b62f 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -1624,6 +1624,10 @@ arge_intr(void *arg) } } + /* + * We handled all bits, clear status + */ + sc->arge_intr_status = 0; ARGE_UNLOCK(sc); /* * re-enable all interrupts From 5948288d9766cc6057fc5301326bcd594325300b Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 5 Jun 2009 08:37:11 +0000 Subject: [PATCH 096/380] - Use restoreintr instead of enableint while accessing pcpu in DO_AST --- sys/mips/include/asm.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/mips/include/asm.h b/sys/mips/include/asm.h index 0df221e26d5..56ea37b0ec8 100644 --- a/sys/mips/include/asm.h +++ b/sys/mips/include/asm.h @@ -311,13 +311,14 @@ _C_LABEL(x): la s0, _C_LABEL(disableintr) ;\ jalr s0 ;\ nop ;\ + move a0, v0 ;\ GET_CPU_PCPU(s1) ;\ lw s3, PC_CURPCB(s1) ;\ lw s1, PC_CURTHREAD(s1) ;\ lw s2, TD_FLAGS(s1) ;\ li s0, TDF_ASTPENDING | TDF_NEEDRESCHED;\ and s2, s0 ;\ - la s0, _C_LABEL(enableintr) ;\ + la s0, _C_LABEL(restoreintr) ;\ jalr s0 ;\ nop ;\ beq s2, zero, 4f ;\ From 02f00631b614dcce84e242cc50afe40db404ad55 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 5 Jun 2009 09:21:03 +0000 Subject: [PATCH 097/380] - Status register should be set last in RESTORE_CPU in order to prevent race over k0, k1 registers. - Update interrupts mask in saved status register for MipsUserIntr and MipsUserGenException. It might be modified by intr filter or ithread. --- sys/mips/mips/exception.S | 48 +++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/sys/mips/mips/exception.S b/sys/mips/mips/exception.S index e53849072bb..b14c1479e9c 100644 --- a/sys/mips/mips/exception.S +++ b/sys/mips/mips/exception.S @@ -326,10 +326,9 @@ SlowFault: #define RESTORE_CPU \ mtc0 zero,COP_0_STATUS_REG ;\ - RESTORE_REG(a0, SR, sp) ;\ + RESTORE_REG(k0, SR, sp) ;\ RESTORE_REG(t0, MULLO, sp) ;\ RESTORE_REG(t1, MULHI, sp) ;\ - mtc0 a0, COP_0_STATUS_REG ;\ mtlo t0 ;\ mthi t1 ;\ _MTC0 v0, COP_0_EXC_PC ;\ @@ -362,7 +361,8 @@ SlowFault: RESTORE_REG(s8, S8, sp) ;\ RESTORE_REG(gp, GP, sp) ;\ RESTORE_REG(ra, RA, sp) ;\ - addu sp, sp, KERN_EXC_FRAME_SIZE + addu sp, sp, KERN_EXC_FRAME_SIZE;\ + mtc0 k0, COP_0_STATUS_REG /* @@ -484,16 +484,19 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra) la k0, _C_LABEL(trap) jalr k0 nop + /* * Restore user registers and return. * First disable interrupts and set exeption level. */ DO_AST - mtc0 zero, COP_0_STATUS_REG # disable int + mfc0 t0, COP_0_STATUS_REG # disable int + and t0, t0, ~(MIPS_SR_INT_IE) + mtc0 t0, COP_0_STATUS_REG ITLBNOPFIX - li v0, SR_EXL - mtc0 v0, COP_0_STATUS_REG # set exeption level + or t0, t0, SR_EXL + mtc0 t0, COP_0_STATUS_REG # set exeption level ITLBNOPFIX /* @@ -504,6 +507,18 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra) GET_CPU_PCPU(k1) lw k1, PC_CURPCB(k1) + /* + * Update interrupt mask in saved status register + * Some of interrupts could be enabled by ithread + * scheduled by ast() + */ + mfc0 a0, COP_0_STATUS_REG + and a0, a0, SR_INT_MASK + RESTORE_U_PCB_REG(a1, SR, k1) + and a1, a1, ~SR_INT_MASK + or a1, a1, a0 + SAVE_U_PCB_REG(a1, SR, k1) + RESTORE_U_PCB_REG(t0, MULLO, k1) RESTORE_U_PCB_REG(t1, MULHI, k1) mtlo t0 @@ -714,14 +729,29 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra) /* * Restore user registers and return. */ - mtc0 zero, COP_0_STATUS_REG # re-disable interrupts + mfc0 t0, COP_0_STATUS_REG # disable int + and t0, t0, ~(MIPS_SR_INT_IE) + mtc0 t0, COP_0_STATUS_REG ITLBNOPFIX - li v0, SR_EXL - mtc0 v0, COP_0_STATUS_REG # set exeption level bit. + or t0, t0, SR_EXL + mtc0 t0, COP_0_STATUS_REG # set exeption level ITLBNOPFIX GET_CPU_PCPU(k1) lw k1, PC_CURPCB(k1) + + /* + * Update interrupt mask in saved status register + * Some of interrupts could be disabled by + * intr filters + */ + mfc0 a0, COP_0_STATUS_REG + and a0, a0, SR_INT_MASK + RESTORE_U_PCB_REG(a1, SR, k1) + and a1, a1, ~SR_INT_MASK + or a1, a1, a0 + SAVE_U_PCB_REG(a1, SR, k1) + RESTORE_U_PCB_REG(s0, S0, k1) RESTORE_U_PCB_REG(s1, S1, k1) RESTORE_U_PCB_REG(s2, S2, k1) From b64bb4d93e63730cd6b66ff306d19133a867564d Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 12 Jun 2009 12:10:10 +0000 Subject: [PATCH 098/380] - Switch no normal RPC oimplementation. Unaligned access bug has been fixed --- sys/mips/conf/AR71XX | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/conf/AR71XX b/sys/mips/conf/AR71XX index a66d305e698..e06ea43dd02 100644 --- a/sys/mips/conf/AR71XX +++ b/sys/mips/conf/AR71XX @@ -25,7 +25,7 @@ options NFS_ROOT #NFS usable as /, requires NFSCLIENT options PSEUDOFS #Pseudo-filesystem framework options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions -options NFS_LEGACYRPC +# options NFS_LEGACYRPC # Debugging for use in -current # options INVARIANTS # options INVARIANT_SUPPORT From fdf715588619e5ec000aaa9084afe8140ff2f3e2 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 12 Jun 2009 12:17:32 +0000 Subject: [PATCH 099/380] - Fix functions prototypes to make compiler happy --- sys/mips/atheros/ar71xx_pci.c | 8 ++++---- sys/mips/atheros/if_arge.c | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/sys/mips/atheros/ar71xx_pci.c b/sys/mips/atheros/ar71xx_pci.c index 5a3697d80c4..6d3430b1821 100644 --- a/sys/mips/atheros/ar71xx_pci.c +++ b/sys/mips/atheros/ar71xx_pci.c @@ -182,8 +182,8 @@ ar71xx_pci_conf_setup(int bus, int slot, int func, int reg, int bytes, } static uint32_t -ar71xx_pci_read_config(device_t dev, int bus, int slot, int func, int reg, - int bytes) +ar71xx_pci_read_config(device_t dev, u_int bus, u_int slot, u_int func, + u_int reg, int bytes) { uint32_t data; uint32_t cmd, shift, mask; @@ -219,8 +219,8 @@ ar71xx_pci_read_config(device_t dev, int bus, int slot, int func, int reg, } static void -ar71xx_pci_write_config(device_t dev, int bus, int slot, int func, int reg, - uint32_t data, int bytes) +ar71xx_pci_write_config(device_t dev, u_int bus, u_int slot, u_int func, + u_int reg, uint32_t data, int bytes) { uint32_t cmd; diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index 08cd443b62f..5a6244efe83 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -106,7 +106,7 @@ static int arge_tx_ring_init(struct arge_softc *); #ifdef DEVICE_POLLING static void arge_poll(struct ifnet *, enum poll_cmd, int); #endif -static void arge_shutdown(device_t); +static int arge_shutdown(device_t); static void arge_start(struct ifnet *); static void arge_start_locked(struct ifnet *); static void arge_stop(struct arge_softc *); @@ -459,7 +459,7 @@ arge_resume(device_t dev) return 0; } -static void +static int arge_shutdown(device_t dev) { struct arge_softc *sc; @@ -469,6 +469,8 @@ arge_shutdown(device_t dev) ARGE_LOCK(sc); arge_stop(sc); ARGE_UNLOCK(sc); + + return (0); } static int From 75c19420472db4e701b32c24d728669be1a18990 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 02:46:07 +0000 Subject: [PATCH 100/380] Import Cavium's FreeBSD port, or the Octeon specific pieces, verbatim. Yes, this puts things in the wrong place, doesn't compile and is woefully incomplete. However, it will allow us to more easily track against the upstream sources without needing to import the entire Cavium tree under vendor. This port is based on FreeBSD 7.0 as of April 2007 and the pre-import MIPS tree (aka mips2), so much work is necessary here. --- sys/mips/conf/OCTEON.hints | 13 + sys/mips/conf/OCTEON32 | 83 ++ sys/mips/mips4k/octeon32/asm_octeon.S | 143 +++ sys/mips/mips4k/octeon32/files.octeon32 | 21 + sys/mips/mips4k/octeon32/obio.c | 185 ++++ sys/mips/mips4k/octeon32/obiovar.h | 58 ++ sys/mips/mips4k/octeon32/octeon_machdep.c | 914 ++++++++++++++++++ sys/mips/mips4k/octeon32/octeonreg.h | 246 +++++ sys/mips/mips4k/octeon32/std.octeon32 | 21 + .../mips4k/octeon32/uart_bus_octeonusart.c | 119 +++ .../mips4k/octeon32/uart_cpu_octeonusart.c | 83 ++ sys/mips/mips4k/std.mips4k | 5 + 12 files changed, 1891 insertions(+) create mode 100644 sys/mips/conf/OCTEON.hints create mode 100644 sys/mips/conf/OCTEON32 create mode 100644 sys/mips/mips4k/octeon32/asm_octeon.S create mode 100644 sys/mips/mips4k/octeon32/files.octeon32 create mode 100644 sys/mips/mips4k/octeon32/obio.c create mode 100644 sys/mips/mips4k/octeon32/obiovar.h create mode 100644 sys/mips/mips4k/octeon32/octeon_machdep.c create mode 100644 sys/mips/mips4k/octeon32/octeonreg.h create mode 100644 sys/mips/mips4k/octeon32/std.octeon32 create mode 100644 sys/mips/mips4k/octeon32/uart_bus_octeonusart.c create mode 100644 sys/mips/mips4k/octeon32/uart_cpu_octeonusart.c create mode 100644 sys/mips/mips4k/std.mips4k diff --git a/sys/mips/conf/OCTEON.hints b/sys/mips/conf/OCTEON.hints new file mode 100644 index 00000000000..d8bc18c250d --- /dev/null +++ b/sys/mips/conf/OCTEON.hints @@ -0,0 +1,13 @@ +# /* +# * This product includes software developed by the University of + +# * California, Berkeley and its contributors." +# */ +# device.hints +hw.uart.console="io:0x1" +hint.obio.0.at="nexus" +hint.obio.0.maddr="0x1" +hint.obio.0.flags="0x1" +hint.uart.0.at="obio" +hint.uart.0.maddr="0x1" +hint.uart.0.flags="0x1" diff --git a/sys/mips/conf/OCTEON32 b/sys/mips/conf/OCTEON32 new file mode 100644 index 00000000000..65145353098 --- /dev/null +++ b/sys/mips/conf/OCTEON32 @@ -0,0 +1,83 @@ +# QEMU -- Generic kernel configuration file for FreeBSD/mips +# +# For more information on this file, please read the handbook section on +# Kernel Configuration Files: +# +# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# +# The handbook is also available locally in /usr/share/doc/handbook +# if you've installed the doc distribution, otherwise always see the +# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# latest information. +# +# An exhaustive list of options and more detailed explanations of the +# device lines is also present in the ../../conf/NOTES and NOTES files. +# If you are in doubt as to the purpose or necessity of a line, check first +# in NOTES. +# +# $FreeBSD$ + +machine mips +cpu CPU_MIPS4KC +ident CAVIUM + +#makeoptions ARCH_FLAGS=-march=mips32 + +# Don't build any modules yet. +makeoptions MODULES_OVERRIDE="" + +options KERNVIRTADDR=0x80100000 +include "../mips4k/octeon32/std.octeon32" + +hints "OCTEON.hints" #Default places to look for devices. + +makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols + +options DDB +options KDB + +options SCHED_4BSD #4BSD scheduler +options INET #InterNETworking +options NFSCLIENT #Network Filesystem Client +#options NFS_ROOT #NFS usable as /, requires NFSCLIENT +options PSEUDOFS #Pseudo-filesystem framework +options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions +#options ROOTDEVNAME=\"ufs:ad0s1a\" # Original +options NO_SWAPPING + + +options FFS #Berkeley Fast Filesystem +options SOFTUPDATES #Enable FFS soft updates support +options UFS_ACL #Support for access control lists +options UFS_DIRHASH #Improve performance on big directories + + +# Debugging for use in -current +options INVARIANTS #Enable calls of extra sanity checking +options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS +#options WITNESS #Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed + +device genclock +device loop +device ether +device md +device mem +device uart +device uart_oct16550 +device rgmii +#options VERBOSE_SYSINIT + + +# +# Use the following for Compact Flash file-system +device cf +options ROOTDEVNAME = \"ufs:cf0s2\" # Unmask if compact flash is needed as RFS + +# +# Use the following for RFS in mem-device +#options MD_ROOT +#options ROOTDEVNAME = \"ufs:md0\" + +#options MD_ROOT_SIZE = 21264 +options SMP diff --git a/sys/mips/mips4k/octeon32/asm_octeon.S b/sys/mips/mips4k/octeon32/asm_octeon.S new file mode 100644 index 00000000000..e4df30e6cb2 --- /dev/null +++ b/sys/mips/mips4k/octeon32/asm_octeon.S @@ -0,0 +1,143 @@ + +#include +#include +#include +#include +#include + +#include "assym.s" + + + +#define CPU_DISABLE_INTERRUPTS(reg, reg2, reg3) \ + mfc0 reg, MIPS_COP_0_STATUS; \ + nop; \ + move reg3, reg; \ + li reg2, ~MIPS_SR_INT_IE; \ + and reg, reg2, reg; \ + mtc0 reg, MIPS_COP_0_STATUS; \ + COP0_SYNC + + + +#define CPU_ENABLE_INTERRUPTS(reg, reg3) \ + mfc0 reg, MIPS_COP_0_STATUS; \ + nop; \ + or reg, reg, reg3; \ + mtc0 reg, MIPS_COP_0_STATUS; \ + COP0_SYNC + + +#define PUSHR(reg) \ + addiu sp,sp,-16 ; \ + sd reg, 8(sp) ; \ + nop ; + +#define POPR(reg) \ + ld reg, 8(sp) ; \ + addiu sp,sp,16 ; \ + nop ; + + + + +/* + * octeon_ciu_get_interrupt_reg_addr + * + * Given Int-X, En-X combination, return the CIU Interrupt Enable Register addr + * a0 = ciu Int-X: 0/1 + * a1 = ciu EN-0: 0/1 + */ +LEAF(octeon_ciu_get_interrupt_reg_addr) + .set noreorder + .set mips3 + + beqz a0, ciu_get_interrupt_reg_addr_Int_0 + nop + +ciu_get_interrupt_reg_addr_Int_1: + beqz a1, ciu_get_interrupt_reg_addr_Int_1_En_0 + nop + +ciu_get_interrupt_reg_addr_Int_1_En1: + li a0, OCTEON_CIU_ADDR_HI + dsll32 a0, a0, 0 + nop + ori a0, OCTEON_CIU_EN1_INT1_LO + j ciu_get_interrupt_reg_addr_ret + nop + +ciu_get_interrupt_reg_addr_Int_1_En_0: + li a0, OCTEON_CIU_ADDR_HI + dsll32 a0, a0, 0 + nop + ori a0, OCTEON_CIU_EN0_INT1_LO + j ciu_get_interrupt_reg_addr_ret + nop + +ciu_get_interrupt_reg_addr_Int_0: + beqz a1, ciu_get_interrupt_reg_addr_Int_0_En_0 + nop + +ciu_get_interrupt_reg_addr_Int_0_En_1: + li a0, OCTEON_CIU_ADDR_HI + dsll32 a0, a0, 0 + nop + ori a0, OCTEON_CIU_EN1_INT0_LO + j ciu_get_interrupt_reg_addr_ret + nop + +ciu_get_interrupt_reg_addr_Int_0_En_0: + li a0, OCTEON_CIU_ADDR_HI + dsll32 a0, a0, 0 + nop + ori a0, OCTEON_CIU_EN0_INT0_LO + + +ciu_get_interrupt_reg_addr_ret: + j ra + nop + + .set mips0 + .set reorder +END(octeon_ciu_get_interrupt_reg_addr) + + + +/* + * octeon_ciu_mask_all_interrupts + * + * a0 = ciu Interrupt-X: 0/1 + * a1 = ciu Enable-X: 0/1 + */ +LEAF(octeon_ciu_mask_all_interrupts) + .set noreorder + .set mips3 + + PUSHR(ra) + PUSHR(s0) + + move t0, a0 + move t1, a1 + li a0, MIPS_SR_INT_IE + CPU_DISABLE_INTERRUPTS(a2, a1, s0) + move a0, t0 + move t1, a1 + jal octeon_ciu_get_interrupt_reg_addr + nop + ld a2, 0(a0) # Dummy read + nop + move a2, zero # Clear all + sd a2, 0(a0) # Write new Enable bits + nop + CPU_ENABLE_INTERRUPTS(a2, s0) + + POPR(s0) + POPR(ra) + j ra # Return + nop # (bd slot) + + .set mips0 + .set reorder +END(octeon_ciu_mask_all_interrupts) + diff --git a/sys/mips/mips4k/octeon32/files.octeon32 b/sys/mips/mips4k/octeon32/files.octeon32 new file mode 100644 index 00000000000..7785a4ddbc1 --- /dev/null +++ b/sys/mips/mips4k/octeon32/files.octeon32 @@ -0,0 +1,21 @@ +# /* +# * This product includes software developed by the University of +# * California, Berkeley and its contributors." +# */ +# $FreeBSD$ +# Octeon Support Files +# +mips/mips4k/octeon32/obio.c optional uart +mips/mips4k/octeon32/uart_cpu_octeonusart.c optional uart +mips/mips4k/octeon32/uart_bus_octeonusart.c optional uart +dev/uart/uart_dev_oct16550.c optional uart +mips/mips/mp_machdep.c optional smp +mips/mips4k/octeon32/octeon_machdep.c standard + +dev/flash/octeon_ebt3000_cf.c optional cf + +dev/le/octeon_fau.c optional rgmii +dev/le/octeon_fpa.c optional rgmii +dev/le/octeon_ipd.c optional rgmii +dev/le/octeon_pko.c optional rgmii +dev/le/octeon_rgmx.c optional rgmii diff --git a/sys/mips/mips4k/octeon32/obio.c b/sys/mips/mips4k/octeon32/obio.c new file mode 100644 index 00000000000..3fa125012a4 --- /dev/null +++ b/sys/mips/mips4k/octeon32/obio.c @@ -0,0 +1,185 @@ +/* $NetBSD: obio.c,v 1.11 2003/07/15 00:25:05 lukem Exp $ */ + +/*- + * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc. + * All rights reserved. + * + * Written by Jason R. Thorpe for Wasabi Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project by + * Wasabi Systems, Inc. + * 4. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * On-board device autoconfiguration support for Intel IQ80321 + * evaluation boards. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +int obio_probe(device_t); +int obio_attach(device_t); + +/* + * We need only one obio. + * Any other device hanging off of it, shouldn't cause multiple of + * these to be found. + */ +static int have_one = 0; + +int +obio_probe(device_t dev) +{ + if(!have_one) + { + have_one = 1; + return 0; + } + else + return (ENXIO); +} + +int +obio_attach(device_t dev) +{ + struct obio_softc *sc = device_get_softc(dev); + + sc->oba_st = MIPS_BUS_SPACE_IO; + sc->oba_addr = OCTEON_UART0ADR; + sc->oba_size = 0x10000; + sc->oba_rman.rm_type = RMAN_ARRAY; + sc->oba_rman.rm_descr = "OBIO I/O"; + if (rman_init(&sc->oba_rman) != 0 || + rman_manage_region(&sc->oba_rman, + sc->oba_addr, sc->oba_addr + sc->oba_size) != 0) + panic("obio_attach: failed to set up I/O rman"); + sc->oba_irq_rman.rm_type = RMAN_ARRAY; + sc->oba_irq_rman.rm_descr = "OBIO IRQ"; + + /* + * This module is intended for UART purposes only and + * it's IRQ is 0 corresponding to IP2. + */ + if (rman_init(&sc->oba_irq_rman) != 0 || + rman_manage_region(&sc->oba_irq_rman, 0, 0) != 0) + panic("obio_attach: failed to set up IRQ rman"); + + device_add_child(dev, "uart", 1); /* Setup Uart-1 first. */ + device_add_child(dev, "uart", 0); /* Uart-0 next. So it is first in console list */ + bus_generic_probe(dev); + bus_generic_attach(dev); + return (0); +} + +static struct resource * +obio_alloc_resource(device_t bus, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + struct resource *rv; + struct rman *rm; + bus_space_tag_t bt = 0; + bus_space_handle_t bh = 0; + struct obio_softc *sc = device_get_softc(bus); + + switch (type) { + case SYS_RES_IRQ: + rm = &sc->oba_irq_rman; + break; + case SYS_RES_MEMORY: + return (NULL); + case SYS_RES_IOPORT: + rm = &sc->oba_rman; + bt = sc->oba_st; + bh = device_get_unit(child) ? OCTEON_UART1ADR : OCTEON_UART0ADR; + start = bh; + break; + default: + return (NULL); + } + + rv = rman_reserve_resource(rm, start, end, count, flags, child); + if (rv == NULL) { + return (NULL); + } + if (type == SYS_RES_IRQ) { + return (rv); + } + rman_set_rid(rv, *rid); + rman_set_bustag(rv, bt); + rman_set_bushandle(rv, bh); + + if (0) { + if (bus_activate_resource(child, type, *rid, rv)) { + rman_release_resource(rv); + return (NULL); + } + } + return (rv); + +} + +static int +obio_activate_resource(device_t bus, device_t child, int type, int rid, + struct resource *r) +{ + return (0); +} +static device_method_t obio_methods[] = { + DEVMETHOD(device_probe, obio_probe), + DEVMETHOD(device_attach, obio_attach), + + DEVMETHOD(bus_alloc_resource, obio_alloc_resource), + DEVMETHOD(bus_activate_resource, obio_activate_resource), + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + + {0, 0}, +}; + +static driver_t obio_driver = { + "obio", + obio_methods, + sizeof(struct obio_softc), +}; +static devclass_t obio_devclass; + +DRIVER_MODULE(obio, nexus, obio_driver, obio_devclass, 0, 0); diff --git a/sys/mips/mips4k/octeon32/obiovar.h b/sys/mips/mips4k/octeon32/obiovar.h new file mode 100644 index 00000000000..ab8b6b225b4 --- /dev/null +++ b/sys/mips/mips4k/octeon32/obiovar.h @@ -0,0 +1,58 @@ +/* $NetBSD: obiovar.h,v 1.4 2003/06/16 17:40:53 thorpej Exp $ */ + +/*- + * Copyright (c) 2002, 2003 Wasabi Systems, Inc. + * All rights reserved. + * + * Written by Jason R. Thorpe for Wasabi Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project by + * Wasabi Systems, Inc. + * 4. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + * + */ + +#ifndef _OCTEON_OBIOVAR_H_ +#define _OCTEON_OBIOVAR_H_ + +#include + +struct obio_softc { + bus_space_tag_t oba_st; /* bus space tag */ + bus_addr_t oba_addr; /* address of device */ + bus_size_t oba_size; /* size of device */ + int oba_width; /* bus width */ + int oba_irq; /* XINT interrupt bit # */ + struct rman oba_rman; + struct rman oba_irq_rman; + +}; +extern struct bus_space obio_bs_tag; + +#endif /* _OCTEON_OBIOVAR_H_ */ diff --git a/sys/mips/mips4k/octeon32/octeon_machdep.c b/sys/mips/mips4k/octeon32/octeon_machdep.c new file mode 100644 index 00000000000..10f80b835a9 --- /dev/null +++ b/sys/mips/mips4k/octeon32/octeon_machdep.c @@ -0,0 +1,914 @@ +/*- + * Copyright (c) 2006 Wojciech A. Koszek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#if defined(__mips_n64) + #define MAX_APP_DESC_ADDR 0xffffffffafffffff +#else + #define MAX_APP_DESC_ADDR 0xafffffff +#endif + + +/* + * Perform a board-level soft-reset. + * Note that this is not emulated by gxemul. + */ +void octeon_reset (void) +{ + void (*reset_func)(void) = (void (*)(void) )0x1fc00000; + reset_func(); +} + + +static inline uint32_t octeon_disable_interrupts (void) +{ + uint32_t status_bits; + + status_bits = mips_rd_status(); + mips_wr_status(status_bits & ~MIPS_SR_INT_IE); + return (status_bits); +} + + +static inline void octeon_set_interrupts (uint32_t status_bits) +{ + mips_wr_status(status_bits); +} + + +void octeon_led_write_char (int char_position, char val) +{ + uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8); + + if (!octeon_board_real()) return; + + char_position &= 0x7; /* only 8 chars */ + ptr += char_position; + oct_write8_x8(ptr, val); +} + +void octeon_led_write_char0 (char val) +{ + uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8); + + if (!octeon_board_real()) return; + + oct_write8_x8(ptr, val); +} + +void octeon_led_write_hexchar (int char_position, char hexval) +{ + uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8); + char char1, char2; + + if (!octeon_board_real()) return; + + char1 = (hexval >> 4) & 0x0f; char1 = (char1 < 10)?char1+'0':char1+'7'; + char2 = (hexval & 0x0f); char2 = (char2 < 10)?char2+'0':char2+'7'; + char_position &= 0x7; /* only 8 chars */ + if (char_position > 6) char_position = 6; + ptr += char_position; + oct_write8_x8(ptr, char1); + ptr++; + oct_write8_x8(ptr, char2); +} + +void octeon_led_write_string (const char *str) +{ + uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8); + int i; + + if (!octeon_board_real()) return; + + for (i=0; i<8; i++, ptr++) { + if (str && *str) { + oct_write8_x8(ptr, *str++); + } else { + oct_write8_x8(ptr, ' '); + } + oct_read64(OCTEON_MIO_BOOT_BIST_STAT); + } +} + +static char progress[8] = { '-', '/', '|', '\\', '-', '/', '|', '\\'}; + +void octeon_led_run_wheel (/*int count, */int *prog_count, int led_position) +{ + if (!octeon_board_real()) return; + + octeon_led_write_char(led_position, progress[*prog_count]); + *prog_count += 1; + *prog_count &= 0x7; +} + +#define LSR_DATAREADY 0x01 /* Data ready */ +#define LSR_THRE 0x20 /* Transmit holding register empty */ +#define LSR_TEMT 0x40 /* Transmitter Empty. THR, TSR & FIFO */ +#define USR_TXFIFO_NOTFULL 0x02 /* Uart TX FIFO Not full */ + +/* + * octeon_uart_write_byte + * + * Put out a single byte off of uart port. + */ + +void octeon_uart_write_byte (int uart_index, uint8_t ch) +{ + uint64_t val, val2; + if ((uart_index < 0) || (uart_index > 1)) { + return; + } + + while (1) { + val = oct_read64(OCTEON_MIO_UART0_LSR + (uart_index * 0x400)); + val2 = oct_read64(OCTEON_MIO_UART0_USR + (uart_index * 0x400)); + if ((((uint8_t) val) & LSR_THRE) || + (((uint8_t) val2) & USR_TXFIFO_NOTFULL)) { + break; + } + } + + /* Write the byte */ + oct_write8(OCTEON_MIO_UART0_THR + (uart_index * 0x400), (uint64_t) ch); + + /* Force Flush the IOBus */ + oct_read64(OCTEON_MIO_BOOT_BIST_STAT); +} + + +void octeon_uart_write_byte0 (uint8_t ch) +{ + uint64_t val, val2; + + while (1) { + val = oct_read64(OCTEON_MIO_UART0_LSR); + val2 = oct_read64(OCTEON_MIO_UART0_USR); + if ((((uint8_t) val) & LSR_THRE) || + (((uint8_t) val2) & USR_TXFIFO_NOTFULL)) { + break; + } + } + + /* Write the byte */ + oct_write8(OCTEON_MIO_UART0_THR, (uint64_t) ch); + + /* Force Flush the IOBus */ + oct_read64(OCTEON_MIO_BOOT_BIST_STAT); +} + +/* + * octeon_uart_write_string + * + */ +void octeon_uart_write_string (int uart_index, const char *str) +{ + /* Just loop writing one byte at a time */ + + while (*str) + { + octeon_uart_write_byte(uart_index, *str); + if (*str == '\n') { + octeon_uart_write_byte(uart_index, '\r'); + } + str++; + } + } + +static char wstr[30]; + +void octeon_led_write_hex (uint32_t wl) +{ + char nbuf[80]; + + sprintf(nbuf, "%X", wl); + octeon_led_write_string(nbuf); +} + + +void octeon_uart_write_hex2 (uint32_t wl, uint32_t wh) +{ + sprintf(wstr, "0x%X-0x%X ", wh, wl); + octeon_uart_write_string(0, wstr); +} + +void octeon_uart_write_hex (uint32_t wl) +{ + sprintf(wstr, " 0x%X ", wl); + octeon_uart_write_string(0, wstr); +} + + +#define OCT_CONS_BUFLEN 200 +static char console_str_buff0[OCT_CONS_BUFLEN + 1]; +#include + + +//#define USE_KERN_SUBR_PRINTF + +#ifndef USE_KERN_SUBR_PRINTF +static int oct_printf (const char *fmt, va_list ap); +#endif + +int kern_cons_printf (const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); +#ifndef USE_KERN_SUBR_PRINTF + oct_printf(fmt, ap); +#else + ker_printf(fmt, ap); +#endif + va_end(ap); + return (0); +} + +#ifndef USE_KERN_SUBR_PRINTF +static int oct_printf (const char *fmt, va_list ap) +{ + snprintf(console_str_buff0, OCT_CONS_BUFLEN, fmt, ap); + octeon_uart_write_string(0, console_str_buff0); + return (0); +} +#endif + + +int console_printf (const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + sprintf(console_str_buff0, fmt, ap); + va_end(ap); + octeon_uart_write_string(0, console_str_buff0); + return (0); +} + + + + +/* + * octeon_wait_uart_flush + */ +void octeon_wait_uart_flush (int uart_index, uint8_t ch) +{ + uint64_t val; + int64_t val3; + uint32_t cpu_status_bits; + + if ((uart_index < 0) || (uart_index > 1)) { + return; + } + + cpu_status_bits = octeon_disable_interrupts(); + /* Force Flush the IOBus */ + oct_read64(OCTEON_MIO_BOOT_BIST_STAT); + for (val3 = 0xfffffffff; val3 > 0; val3--) { + val = oct_read64(OCTEON_MIO_UART0_LSR + (uart_index * 0x400)); + if (((uint8_t) val) & LSR_TEMT) { + break; + } + } + octeon_set_interrupts(cpu_status_bits); +} + + +/* + * octeon_debug_symbol + * + * Does nothing. + * Used to mark the point for simulator to begin tracing + */ +void octeon_debug_symbol (void) +{ +} + +void octeon_ciu_stop_gtimer (int timer) +{ + oct_write64(OCTEON_CIU_GENTIMER_ADDR(timer), 0ll); +} + +void octeon_ciu_start_gtimer (int timer, u_int one_shot, uint64_t time_cycles) +{ + octeon_ciu_gentimer gentimer; + + gentimer.word64 = 0; + gentimer.bits.one_shot = one_shot; + gentimer.bits.len = time_cycles - 1; + oct_write64(OCTEON_CIU_GENTIMER_ADDR(timer), gentimer.word64); +} + +/* + * octeon_ciu_reset + * + * Shutdown all CIU to IP2, IP3 mappings + */ +void octeon_ciu_reset (void) +{ + + octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_0); + octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_1); + octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_2); + octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_3); + + ciu_disable_intr(CIU_THIS_CORE, CIU_INT_0, CIU_EN_0); + ciu_disable_intr(CIU_THIS_CORE, CIU_INT_0, CIU_EN_1); + ciu_disable_intr(CIU_THIS_CORE, CIU_INT_1, CIU_EN_0); + ciu_disable_intr(CIU_THIS_CORE, CIU_INT_1, CIU_EN_1); + + ciu_clear_int_summary(CIU_THIS_CORE, CIU_INT_0, CIU_EN_0, 0ll); + ciu_clear_int_summary(CIU_THIS_CORE, CIU_INT_1, CIU_EN_0, 0ll); + ciu_clear_int_summary(CIU_THIS_CORE, CIU_INT_1, CIU_EN_1, 0ll); +} + +/* + * mips_disable_interrupt_controllers + * + * Disable interrupts in the CPU controller + */ +void mips_disable_interrupt_controls (void) +{ + /* + * Disable interrupts in CIU. + */ + octeon_ciu_reset(); +} + +static uint64_t ciu_get_intr_sum_reg_addr(int core_num, int intx, int enx); + +/* + * ciu_get_intr_sum_reg_addr + */ +static uint64_t ciu_get_intr_sum_reg_addr (int core_num, int intx, int enx) +{ + uint64_t ciu_intr_sum_reg_addr; + + if (enx == CIU_EN_0) { + ciu_intr_sum_reg_addr = OCTEON_CIU_SUMMARY_BASE_ADDR + (core_num * 0x10) + + (intx * 0x8); + } else { + ciu_intr_sum_reg_addr = OCTEON_CIU_SUMMARY_INT1_ADDR; + } + + return (ciu_intr_sum_reg_addr); +} + + +static uint64_t ciu_get_intr_en_reg_addr(int core_num, int intx, int enx); + +/* + * ciu_get_intr_en_reg_addr + */ +static uint64_t ciu_get_intr_en_reg_addr (int core_num, int intx, int enx) +{ + uint64_t ciu_intr_reg_addr; + + + ciu_intr_reg_addr = OCTEON_CIU_ENABLE_BASE_ADDR + ((enx == 0) ? 0x0 : 0x8) + + (intx * 0x10) + (core_num * 0x20); + + return (ciu_intr_reg_addr); +} + + + + +uint64_t ciu_get_en_reg_addr_new (int corenum, int intx, int enx, int ciu_ip); + +/* + * ciu_get_intr_reg_addr + * + * 200 ---int0,en0 ip2 + * 208 ---int0,en1 ip2 ----> this is wrong... this is watchdog + * + * 210 ---int0,en0 ip3 -- + * 218 ---int0,en1 ip3 ----> same here.. .this is watchdog... right? + * + * 220 ---int1,en0 ip2 + * 228 ---int1,en1 ip2 + * 230 ---int1,en0 ip3 -- + * 238 ---int1,en1 ip3 + * + */ +uint64_t ciu_get_en_reg_addr_new (int corenum, int intx, int enx, int ciu_ip) +{ + uint64_t ciu_intr_reg_addr = OCTEON_CIU_ENABLE_BASE_ADDR; + + if (enx < CIU_EN_0 || enx > CIU_EN_1) { + printf("%s: invalid enx value %d, should be %d or %d\n", + __FUNCTION__, enx, CIU_EN_0, CIU_EN_1); + return 0; + } + if (intx < CIU_INT_0 || intx > CIU_INT_1) { + printf("%s: invalid intx value %d, should be %d or %d\n", + __FUNCTION__, enx, CIU_INT_0, CIU_INT_1); + return 0; + } + if (ciu_ip < CIU_MIPS_IP2 || ciu_ip > CIU_MIPS_IP3) { + printf("%s: invalid ciu_ip value %d, should be %d or %d\n", + __FUNCTION__, ciu_ip, CIU_MIPS_IP2, CIU_MIPS_IP3); + return 0; + } + + ciu_intr_reg_addr += (enx * 0x8); + ciu_intr_reg_addr += (ciu_ip * 0x10); + ciu_intr_reg_addr += (intx * 0x20); + + return (ciu_intr_reg_addr); +} + +/* + * ciu_get_int_summary + */ +uint64_t ciu_get_int_summary (int core_num, int intx, int enx) +{ + uint64_t ciu_intr_sum_reg_addr; + + if (core_num == CIU_THIS_CORE) { + core_num = octeon_get_core_num(); + } + ciu_intr_sum_reg_addr = ciu_get_intr_sum_reg_addr(core_num, intx, enx); + return (oct_read64(ciu_intr_sum_reg_addr)); +} + +//#define DEBUG_CIU 1 + +#ifdef DEBUG_CIU +#define DEBUG_CIU_SUM 1 +#define DEBUG_CIU_EN 1 +#endif + + +/* + * ciu_clear_int_summary + */ +void ciu_clear_int_summary (int core_num, int intx, int enx, uint64_t write_bits) +{ + uint32_t cpu_status_bits; + uint64_t ciu_intr_sum_reg_addr; + +//#define DEBUG_CIU_SUM 1 + +#ifdef DEBUG_CIU_SUM + uint64_t ciu_intr_sum_bits; +#endif + + + if (core_num == CIU_THIS_CORE) { + core_num = octeon_get_core_num(); + } + +#ifdef DEBUG_CIU_SUM + printf(" CIU: core %u clear sum IntX %u Enx %u Bits: 0x%llX\n", + core_num, intx, enx, write_bits); +#endif + + cpu_status_bits = octeon_disable_interrupts(); + + ciu_intr_sum_reg_addr = ciu_get_intr_sum_reg_addr(core_num, intx, enx); + +#ifdef DEBUG_CIU_SUM + ciu_intr_sum_bits = oct_read64(ciu_intr_sum_reg_addr); /* unneeded dummy read */ + printf(" CIU: status: 0x%X reg_addr: 0x%llX Val: 0x%llX -> 0x%llX", + cpu_status_bits, ciu_intr_sum_reg_addr, ciu_intr_sum_bits, + ciu_intr_sum_bits | write_bits); +#endif + + oct_write64(ciu_intr_sum_reg_addr, write_bits); + oct_read64(OCTEON_MIO_BOOT_BIST_STAT); /* Bus Barrier */ + +#ifdef DEBUG_CIU_SUM + printf(" Readback: 0x%llX\n\n ", (uint64_t) oct_read64(ciu_intr_sum_reg_addr)); +#endif + + octeon_set_interrupts(cpu_status_bits); +} + +/* + * ciu_disable_intr + */ +void ciu_disable_intr (int core_num, int intx, int enx) +{ + uint32_t cpu_status_bits; + uint64_t ciu_intr_reg_addr; + + if (core_num == CIU_THIS_CORE) { + core_num = octeon_get_core_num(); + } + + cpu_status_bits = octeon_disable_interrupts(); + + ciu_intr_reg_addr = ciu_get_intr_en_reg_addr(core_num, intx, enx); + + oct_read64(ciu_intr_reg_addr); /* Dummy read */ + + oct_write64(ciu_intr_reg_addr, 0LL); + oct_read64(OCTEON_MIO_BOOT_BIST_STAT); /* Bus Barrier */ + + octeon_set_interrupts(cpu_status_bits); +} + +void ciu_dump_interrutps_enabled (int core_num, int intx, int enx, int ciu_ip); +void ciu_dump_interrutps_enabled (int core_num, int intx, int enx, int ciu_ip) +{ + + uint64_t ciu_intr_reg_addr; + uint64_t ciu_intr_bits; + + if (core_num == CIU_THIS_CORE) { + core_num = octeon_get_core_num(); + } + +#ifndef OCTEON_SMP_1 + ciu_intr_reg_addr = ciu_get_intr_en_reg_addr(core_num, intx, enx); +#else + ciu_intr_reg_addr = ciu_get_en_reg_addr_new(core_num, intx, enx, ciu_ip); +#endif + + if (!ciu_intr_reg_addr) { + printf("Bad call to %s\n", __FUNCTION__); + while(1); + return; + } + + ciu_intr_bits = oct_read64(ciu_intr_reg_addr); + printf(" CIU core %d int: %d en: %d ip: %d Add: 0x%llX enabled: 0x%llX SR: %X\n", + core_num, intx, enx, ciu_ip, ciu_intr_reg_addr, ciu_intr_bits, mips_rd_status()); +} + + +/* + * ciu_enable_interrupts + */ +void ciu_enable_interrupts (int core_num, int intx, int enx, uint64_t set_these_interrupt_bits, + int ciu_ip) +{ + + uint32_t cpu_status_bits; + uint64_t ciu_intr_reg_addr; + uint64_t ciu_intr_bits; + + if (core_num == CIU_THIS_CORE) { + core_num = octeon_get_core_num(); + } + +//#define DEBUG_CIU_EN 1 + +#ifdef DEBUG_CIU_EN + printf(" CIU: core %u enabling Intx %u Enx %u IP %d Bits: 0x%llX\n", + core_num, intx, enx, ciu_ip, set_these_interrupt_bits); +#endif + + cpu_status_bits = octeon_disable_interrupts(); + +#ifndef OCTEON_SMP_1 + ciu_intr_reg_addr = ciu_get_intr_en_reg_addr(core_num, intx, enx); +#else + ciu_intr_reg_addr = ciu_get_en_reg_addr_new(core_num, intx, enx, ciu_ip); +#endif + + if (!ciu_intr_reg_addr) { + printf("Bad call to %s\n", __FUNCTION__); + while(1); + return; + } + + ciu_intr_bits = oct_read64(ciu_intr_reg_addr); + +#ifdef DEBUG_CIU_EN + printf(" CIU: status: 0x%X reg_addr: 0x%llX Val: 0x%llX -> 0x%llX", + cpu_status_bits, ciu_intr_reg_addr, ciu_intr_bits, ciu_intr_bits | set_these_interrupt_bits); +#endif + ciu_intr_bits |= set_these_interrupt_bits; + oct_write64(ciu_intr_reg_addr, ciu_intr_bits); +#ifdef OCTEON_SMP + mips_wbflush(); +#endif + oct_read64(OCTEON_MIO_BOOT_BIST_STAT); /* Bus Barrier */ + +#ifdef DEBUG_CIU_EN + printf(" Readback: 0x%llX\n\n ", (uint64_t) oct_read64(ciu_intr_reg_addr)); +#endif + + octeon_set_interrupts(cpu_status_bits); +} + + +extern void mips_platform_init(void); + +void mips_platform_init (void) +{ + octeon_ciu_reset(); + octeon_uart_write_string(0, "\nPlatform Starting"); +} + + + +/* + **************************************************************************************** + * + * APP/BOOT DESCRIPTOR STUFF + * + **************************************************************************************** + */ + +/* Define the struct that is initialized by the bootloader used by the + * startup code. + * + * Copyright (c) 2004, 2005, 2006 Cavium Networks. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#define OCTEON_CURRENT_DESC_VERSION 6 +#define OCTEON_ARGV_MAX_ARGS (64) +#define OCTOEN_SERIAL_LEN 20 + + +typedef struct { + /* Start of block referenced by assembly code - do not change! */ + uint32_t desc_version; + uint32_t desc_size; + + uint64_t stack_top; + uint64_t heap_base; + uint64_t heap_end; + uint64_t entry_point; /* Only used by bootloader */ + uint64_t desc_vaddr; + /* End of This block referenced by assembly code - do not change! */ + + uint32_t exception_base_addr; + uint32_t stack_size; + uint32_t heap_size; + uint32_t argc; /* Argc count for application */ + uint32_t argv[OCTEON_ARGV_MAX_ARGS]; + uint32_t flags; + uint32_t core_mask; + uint32_t dram_size; /**< DRAM size in megabyes */ + uint32_t phy_mem_desc_addr; /**< physical address of free memory descriptor block*/ + uint32_t debugger_flags_base_addr; /**< used to pass flags from app to debugger */ + uint32_t eclock_hz; /**< CPU clock speed, in hz */ + uint32_t dclock_hz; /**< DRAM clock speed, in hz */ + uint32_t spi_clock_hz; /**< SPI4 clock in hz */ + uint16_t board_type; + uint8_t board_rev_major; + uint8_t board_rev_minor; + uint16_t chip_type; + uint8_t chip_rev_major; + uint8_t chip_rev_minor; + char board_serial_number[OCTOEN_SERIAL_LEN]; + uint8_t mac_addr_base[6]; + uint8_t mac_addr_count; + uint64_t cvmx_desc_vaddr; + +} octeon_boot_descriptor_t; + + +typedef struct { + uint32_t major_version; + uint32_t minor_version; + + uint64_t stack_top; + uint64_t heap_base; + uint64_t heap_end; + uint64_t desc_vaddr; + + uint32_t exception_base_addr; + uint32_t stack_size; + uint32_t flags; + uint32_t core_mask; + uint32_t dram_size; /**< DRAM size in megabyes */ + uint32_t phy_mem_desc_addr; /**< physical address of free memory descriptor block*/ + uint32_t debugger_flags_base_addr; /**< used to pass flags from app to debugger */ + uint32_t eclock_hz; /**< CPU clock speed, in hz */ + uint32_t dclock_hz; /**< DRAM clock speed, in hz */ + uint32_t spi_clock_hz; /**< SPI4 clock in hz */ + uint16_t board_type; + uint8_t board_rev_major; + uint8_t board_rev_minor; + uint16_t chip_type; + uint8_t chip_rev_major; + uint8_t chip_rev_minor; + char board_serial_number[OCTOEN_SERIAL_LEN]; + uint8_t mac_addr_base[6]; + uint8_t mac_addr_count; + +} cvmx_bootinfo_t; + +uint32_t octeon_cpu_clock; +uint64_t octeon_dram; +uint32_t octeon_bd_ver = 0, octeon_cvmx_bd_ver = 0, octeon_board_rev_major, octeon_board_rev_minor, octeon_board_type; +uint8_t octeon_mac_addr[6] = { 0 }; +int octeon_core_mask, octeon_mac_addr_count; +int octeon_chip_rev_major = 0, octeon_chip_rev_minor = 0, octeon_chip_type = 0; + +#if defined(__mips_n64) +extern uint64_t app_descriptor_addr; +#else +extern uint32_t app_descriptor_addr; +#endif +static octeon_boot_descriptor_t *app_desc_ptr; +static cvmx_bootinfo_t *cvmx_desc_ptr; + +#define OCTEON_BOARD_TYPE_NONE 0 +#define OCTEON_BOARD_TYPE_SIM 1 + +#define OCTEON_CLOCK_MIN (100 * 1000 * 1000) +#define OCTEON_CLOCK_MAX (800 * 1000 * 1000) +#define OCTEON_DRAM_DEFAULT (256 * 1024 * 1024) +#define OCTEON_DRAM_MIN 30 +#define OCTEON_DRAM_MAX 3000 + + +int octeon_board_real (void) +{ + if ((octeon_board_type == OCTEON_BOARD_TYPE_NONE) || + (octeon_board_type == OCTEON_BOARD_TYPE_SIM) || + !octeon_board_rev_major) { + return 0; + } + return 1; +} + +static void octeon_process_app_desc_ver_unknown (void) +{ + printf(" Unknown Boot-Descriptor: Using Defaults\n"); + + octeon_cpu_clock = OCTEON_CLOCK_DEFAULT; + octeon_dram = OCTEON_DRAM_DEFAULT; + octeon_board_rev_major = octeon_board_rev_minor = octeon_board_type = 0; + + octeon_core_mask = 1; + octeon_cpu_clock = OCTEON_CLOCK_DEFAULT; + octeon_chip_type = octeon_chip_rev_major = octeon_chip_rev_minor = 0; + + octeon_mac_addr[0] = 0x00; octeon_mac_addr[1] = 0x0f; + octeon_mac_addr[2] = 0xb7; octeon_mac_addr[3] = 0x10; + octeon_mac_addr[4] = 0x09; octeon_mac_addr[5] = 0x06; + octeon_mac_addr_count = 1; +} + +static int octeon_process_app_desc_ver_6 (void) +{ + cvmx_desc_ptr = (cvmx_bootinfo_t *) ((long) app_desc_ptr->cvmx_desc_vaddr); + + if ((cvmx_desc_ptr == NULL) || (cvmx_desc_ptr == (cvmx_bootinfo_t *)0xffffffff)) { + printf ("Bad cvmx_desc_ptr 0x%X\n", cvmx_desc_ptr); + return 1; + } + + cvmx_desc_ptr = (cvmx_bootinfo_t *) (((long) cvmx_desc_ptr) | MIPS_KSEG0_START); + octeon_cvmx_bd_ver = (cvmx_desc_ptr->major_version * 100) + + cvmx_desc_ptr->minor_version; + + if (cvmx_desc_ptr->major_version != 1) { + printf("Incompatible CVMX descriptor from bootloader: %d.%d 0x%X\n", + (int) cvmx_desc_ptr->major_version, + (int) cvmx_desc_ptr->minor_version, cvmx_desc_ptr); + while (1); /* Never return */ + return 1; /* Satisfy the compiler */ + } + + octeon_core_mask = cvmx_desc_ptr->core_mask; + octeon_cpu_clock = cvmx_desc_ptr->eclock_hz; + octeon_board_type = cvmx_desc_ptr->board_type; + octeon_board_rev_major = cvmx_desc_ptr->board_rev_major; + octeon_board_rev_minor = cvmx_desc_ptr->board_rev_minor; + octeon_chip_type = cvmx_desc_ptr->chip_type; + octeon_chip_rev_major = cvmx_desc_ptr->chip_rev_major; + octeon_chip_rev_minor = cvmx_desc_ptr->chip_rev_minor; + octeon_mac_addr[0] = cvmx_desc_ptr->mac_addr_base[0]; + octeon_mac_addr[1] = cvmx_desc_ptr->mac_addr_base[1]; + octeon_mac_addr[2] = cvmx_desc_ptr->mac_addr_base[2]; + octeon_mac_addr[3] = cvmx_desc_ptr->mac_addr_base[3]; + octeon_mac_addr[4] = cvmx_desc_ptr->mac_addr_base[4]; + octeon_mac_addr[5] = cvmx_desc_ptr->mac_addr_base[5]; + octeon_mac_addr_count = cvmx_desc_ptr->mac_addr_count; + + if (app_desc_ptr->dram_size > 16*1024*1024) { + octeon_dram = (uint64_t)app_desc_ptr->dram_size; + } else { + octeon_dram = (uint64_t)app_desc_ptr->dram_size * 1024 * 1024; + } + return 0; +} + +static int octeon_process_app_desc_ver_3_4_5 (void) +{ + + octeon_cvmx_bd_ver = octeon_bd_ver; + octeon_core_mask = app_desc_ptr->core_mask; + + if (app_desc_ptr->desc_version > 3) { + octeon_cpu_clock = app_desc_ptr->eclock_hz; + } else { + octeon_cpu_clock = OCTEON_CLOCK_DEFAULT; + } + + if (app_desc_ptr->dram_size > 16*1024*1024) { + octeon_dram = (uint64_t)app_desc_ptr->dram_size; + } else { + octeon_dram = (uint64_t)app_desc_ptr->dram_size * 1024 * 1024; + } + + if (app_desc_ptr->desc_version > 4) { + octeon_board_type = app_desc_ptr->board_type; + octeon_board_rev_major = app_desc_ptr->board_rev_major; + octeon_board_rev_minor = app_desc_ptr->board_rev_minor; + octeon_chip_type = app_desc_ptr->chip_type; + octeon_chip_rev_major = app_desc_ptr->chip_rev_major; + octeon_chip_rev_minor = app_desc_ptr->chip_rev_minor; + + octeon_mac_addr[0] = app_desc_ptr->mac_addr_base[0]; + octeon_mac_addr[1] = app_desc_ptr->mac_addr_base[1]; + octeon_mac_addr[2] = app_desc_ptr->mac_addr_base[2]; + octeon_mac_addr[3] = app_desc_ptr->mac_addr_base[3]; + octeon_mac_addr[4] = app_desc_ptr->mac_addr_base[4]; + octeon_mac_addr[5] = app_desc_ptr->mac_addr_base[5]; + octeon_mac_addr_count = app_desc_ptr->mac_addr_count; + } + return 0; +} + + +void mips_boot_params_init(void); + +void mips_boot_params_init (void) +{ + int descriptor_not_parsed = 1; + + if ((app_descriptor_addr == 0) || (app_descriptor_addr >= MAX_APP_DESC_ADDR)) { + + } else { + + app_desc_ptr = (octeon_boot_descriptor_t *) app_descriptor_addr; + octeon_bd_ver = app_desc_ptr->desc_version; + + if ((octeon_bd_ver >= 3) && (octeon_bd_ver <= 5)) { + descriptor_not_parsed = octeon_process_app_desc_ver_3_4_5(); + + } else if (app_desc_ptr->desc_version == 6) { + descriptor_not_parsed = octeon_process_app_desc_ver_6(); + } + + } + + if (descriptor_not_parsed) { + octeon_process_app_desc_ver_unknown(); + } + + printf("Boot Descriptor Ver: %u -> %u/%u", + octeon_bd_ver, octeon_cvmx_bd_ver/100, octeon_cvmx_bd_ver%100); + printf(" CPU clock: %uMHz\n", octeon_cpu_clock/1000000); + printf(" Dram: %u MB", (uint32_t)(octeon_dram >> 20)); + printf(" Board Type: %u Revision: %u/%u\n", + octeon_board_type, octeon_board_rev_major, octeon_board_rev_minor); + printf(" Octeon Chip: %u Rev %u/%u", + octeon_chip_type, octeon_chip_rev_major, octeon_chip_rev_minor); + + printf(" Mac Address %02X.%02X.%02X.%02X.%02X.%02X\n", + octeon_mac_addr[0], octeon_mac_addr[1], octeon_mac_addr[2], + octeon_mac_addr[3], octeon_mac_addr[4], octeon_mac_addr[5]); +} diff --git a/sys/mips/mips4k/octeon32/octeonreg.h b/sys/mips/mips4k/octeon32/octeonreg.h new file mode 100644 index 00000000000..9373eb7a64b --- /dev/null +++ b/sys/mips/mips4k/octeon32/octeonreg.h @@ -0,0 +1,246 @@ +/* $NetBSD: octeonreg.h,v 1.1 2002/03/07 14:44:04 simonb Exp $ */ + +/* + * Copyright 2002 Wasabi Systems, Inc. + * All rights reserved. + * + * Written by Simon Burge for Wasabi Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project by + * Wasabi Systems, Inc. + * 4. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + Memory Map + + 0000.0000 * 128MB Typically SDRAM (on Core Board) + 0800.0000 * 256MB Typically PCI + 1800.0000 * 62MB Typically PCI + 1be0.0000 * 2MB Typically System controller's internal registers + 1c00.0000 * 32MB Typically not used + 1e00.0000 4MB Monitor Flash + 1e40.0000 12MB reserved + 1f00.0000 12MB Switches + LEDs + ASCII display + Soft reset + FPGA revision number + CBUS UART (tty2) + General Purpose I/O + I2C controller + 1f10.0000 * 11MB Typically System Controller specific + 1fc0.0000 4MB Maps to Monitor Flash + 1fd0.0000 * 3MB Typically System Controller specific + + * depends on implementation of the Core Board and of software + */ + +/* + CPU interrupts + + NMI South Bridge or NMI button + 0 South Bridge INTR + 1 South Bridge SMI + 2 CBUS UART (tty2) + 3 COREHI (Core Card) + 4 CORELO (Core Card) + 5 Not used, driven inactive (typically CPU internal timer interrupt + + IRQ mapping (as used by YAMON) + + 0 Timer South Bridge + 1 Keyboard SuperIO + 2 Reserved by South Bridge (for cascading) + 3 UART (tty1) SuperIO + 4 UART (tty0) SuperIO + 5 Not used + 6 Floppy Disk SuperIO + 7 Parallel Port SuperIO + 8 Real Time Clock South Bridge + 9 I2C bus South Bridge + 10 PCI A,B,eth PCI slot 1..4, Ethernet + 11 PCI C,audio PCI slot 1..4, Audio, USB (South Bridge) + PCI D,USB + 12 Mouse SuperIO + 13 Reserved by South Bridge + 14 Primary IDE Primary IDE slot + 15 Secondary IDE Secondary IDE slot/Compact flash connector + */ + +#define OCTEON_SYSTEMRAM_BASE 0x00000000 /* System RAM: */ +#define OCTEON_SYSTEMRAM_SIZE 0x08000000 /* 128 MByte */ + +#define OCTEON_PCIMEM1_BASE 0x08000000 /* PCI 1 memory: */ +#define OCTEON_PCIMEM1_SIZE 0x08000000 /* 128 MByte */ + +#define OCTEON_PCIMEM2_BASE 0x10000000 /* PCI 2 memory: */ +#define OCTEON_PCIMEM2_SIZE 0x08000000 /* 128 MByte */ + +#define OCTEON_PCIMEM3_BASE 0x18000000 /* PCI 3 memory */ +#define OCTEON_PCIMEM3_SIZE 0x03e00000 /* 62 MByte */ + +#define OCTEON_CORECTRL_BASE 0x1be00000 /* Core control: */ +#define OCTEON_CORECTRL_SIZE 0x00200000 /* 2 MByte */ + +#define OCTEON_RESERVED_BASE1 0x1c000000 /* Reserved: */ +#define OCTEON_RESERVED_SIZE1 0x02000000 /* 32 MByte */ + +#define OCTEON_MONITORFLASH_BASE 0x1e000000 /* Monitor Flash: */ +#define OCTEON_MONITORFLASH_SIZE 0x003e0000 /* 4 MByte */ +#define OCTEON_MONITORFLASH_SECTORSIZE 0x00010000 /* Sect. = 64 KB */ + +#define OCTEON_FILEFLASH_BASE 0x1e3e0000 /* File Flash (for monitor): */ +#define OCTEON_FILEFLASH_SIZE 0x00020000 /* 128 KByte */ + +#define OCTEON_FILEFLASH_SECTORSIZE 0x00010000 /* Sect. = 64 KB */ + +#define OCTEON_RESERVED_BASE2 0x1e400000 /* Reserved: */ +#define OCTEON_RESERVED_SIZE2 0x00c00000 /* 12 MByte */ + +#define OCTEON_FPGA_BASE 0x1f000000 /* FPGA: */ +#define OCTEON_FPGA_SIZE 0x00c00000 /* 12 MByte */ + +#define OCTEON_NMISTATUS (OCTEON_FPGA_BASE + 0x24) +#define OCTEON_NMI_SB 0x2 /* Pending NMI from the South Bridge */ +#define OCTEON_NMI_ONNMI 0x1 /* Pending NMI from the ON/NMI push button */ + +#define OCTEON_NMIACK (OCTEON_FPGA_BASE + 0x104) +#define OCTEON_NMIACK_ONNMI 0x1 /* Write 1 to acknowledge ON/NMI */ + +#define OCTEON_SWITCH (OCTEON_FPGA_BASE + 0x200) +#define OCTEON_SWITCH_MASK 0xff /* settings of DIP switch S2 */ + +#define OCTEON_STATUS (OCTEON_FPGA_BASE + 0x208) +#define OCTEON_ST_MFWR 0x10 /* Monitor Flash is write protected (JP1) */ +#define OCTEON_S54 0x08 /* switch S5-4 - set YAMON factory default mode */ +#define OCTEON_S53 0x04 /* switch S5-3 */ +#define OCTEON_BIGEND 0x02 /* switch S5-2 - big endian mode */ + +#define OCTEON_JMPRS (OCTEON_FPGA_BASE + 0x210) +#define OCTEON_JMPRS_PCICLK 0x1c /* PCI clock frequency */ +#define OCTEON_JMPRS_EELOCK 0x02 /* I2C EEPROM is write protected */ + +#define OCTEON_LEDBAR (OCTEON_FPGA_BASE + 0x408) +#define OCTEON_ASCIIWORD (OCTEON_FPGA_BASE + 0x410) +#define OCTEON_ASCII_BASE (OCTEON_FPGA_BASE + 0x418) +#define OCTEON_ASCIIPOS0 0x00 +#define OCTEON_ASCIIPOS1 0x08 +#define OCTEON_ASCIIPOS2 0x10 +#define OCTEON_ASCIIPOS3 0x18 +#define OCTEON_ASCIIPOS4 0x20 +#define OCTEON_ASCIIPOS5 0x28 +#define OCTEON_ASCIIPOS6 0x30 +#define OCTEON_ASCIIPOS7 0x38 + +#define OCTEON_SOFTRES (OCTEON_FPGA_BASE + 0x500) +#define OCTEON_GORESET 0x42 /* write this to OCTEON_SOFTRES for board reset */ + +/* + * BRKRES is the number of milliseconds before a "break" on tty will + * trigger a reset. A value of 0 will disable the reset. + */ +#define OCTEON_BRKRES (OCTEON_FPGA_BASE + 0x508) +#define OCTEON_BRKRES_MASK 0xff + +#define OCTEON_CBUSUART 0x8001180000000800ull +/* 16C550C UART, 8 bit registers on 8 byte boundaries */ +/* RXTX 0x00 */ +/* INTEN 0x08 */ +/* IIFIFO 0x10 */ +/* LCTRL 0x18 */ +/* MCTRL 0x20 */ +/* LSTAT 0x28 */ +/* MSTAT 0x30 */ +/* SCRATCH 0x38 */ +#define OCTEON_CBUSUART_INTR 2 + +#define OCTEON_GPIO_BASE (OCTEON_FPGA_BASE + 0xa00) +#define OCTEON_GPOUT 0x0 +#define OCTEON_GPINP 0x8 + +#define OCTEON_BOOTROM_BASE 0x1fc00000 /* Boot ROM: */ +#define OCTEON_BOOTROM_SIZE 0x00400000 /* 4 MByte */ + +#define OCTEON_REVISION 0x1fc00010 +#define OCTEON_REV_FPGRV 0xff0000 /* CBUS FPGA revision */ +#define OCTEON_REV_CORID 0x00fc00 /* Core Board ID */ +#define OCTEON_REV_CORRV 0x000300 /* Core Board Revision */ +#define OCTEON_REV_PROID 0x0000f0 /* Product ID */ +#define OCTEON_REV_PRORV 0x00000f /* Product Revision */ + +/* PCI definitions */ + +#define OCTEON_UART0ADR 0x8001180000000800ull +#define OCTEON_UART1ADR 0x8001180000000C00ull + +#define OCTEON_MIO_BOOT_BIST_STAT 0x80011800000000F8ull + + + +/************************** + * To Delete + */ +#define OCTEON_SOUTHBRIDGE_INTR 0 + +#define OCTEON_PCI0_IO_BASE OCTEON_PCIMEM3_BASE +#define OCTEON_PCI0_ADDR( addr ) (OCTEON_PCI0_IO_BASE + (addr)) + +#define OCTEON_RTCADR 0x70 // OCTEON_PCI_IO_ADDR8(0x70) +#define OCTEON_RTCDAT 0x71 // OCTEON_PCI_IO_ADDR8(0x71) + +#define OCTEON_SMSC_COM1_ADR 0x3f8 +#define OCTEON_SMSC_COM2_ADR 0x2f8 +#define OCTEON_UARTT0ADR OCTEON_PCI0_ADDR(OCTEON_SMSC_COM1_ADR) +#define OCTEON_UARTT1ADR OCTEON_SMSC_COM2_ADR // OCTEON_PCI0_ADDR(OCTEON_SMSC_COM2_ADR) + +#define OCTEON_SMSC_1284_ADR 0x378 +#define OCTEON_1284ADR OCTEON_SMSC_1284_ADR // OCTEON_PCI0_ADDR(OCTEON_SMSC_1284_ADR) + +#define OCTEON_SMSC_FDD_ADR 0x3f0 +#define OCTEON_FDDADR OCTEON_SMSC_FDD_ADR // OCTEON_PCI0_ADDR(OCTEON_SMSC_FDD_ADR) + +#define OCTEON_SMSC_KYBD_ADR 0x60 /* Fixed 0x60, 0x64 */ +#define OCTEON_KYBDADR OCTEON_SMSC_KYBD_ADR // OCTEON_PCI0_ADDR(OCTEON_SMSC_KYBD_ADR) +#define OCTEON_SMSC_MOUSE_ADR OCTEON_SMSC_KYBD_ADR +#define OCTEON_MOUSEADR OCTEON_KYBDADR + + +#define OCTEON_DMA_PCI_PCIBASE 0x00000000UL +#define OCTEON_DMA_PCI_PHYSBASE 0x00000000UL +#define OCTEON_DMA_PCI_SIZE (256 * 1024 * 1024) + +#define OCTEON_DMA_ISA_PCIBASE 0x00800000UL +#define OCTEON_DMA_ISA_PHYSBASE 0x00000000UL +#define OCTEON_DMA_ISA_SIZE (8 * 1024 * 1024) + +#ifndef _LOCORE +void led_bar(uint8_t); +void led_display_word(uint32_t); +void led_display_str(const char *); +void led_display_char(int, uint8_t); +#endif diff --git a/sys/mips/mips4k/octeon32/std.octeon32 b/sys/mips/mips4k/octeon32/std.octeon32 new file mode 100644 index 00000000000..29f481542aa --- /dev/null +++ b/sys/mips/mips4k/octeon32/std.octeon32 @@ -0,0 +1,21 @@ +# /* +# * This product includes software developed by the University of +# * California, Berkeley and its contributors." +# */ +# $FreeBSD$ +# +include "../mips4k/std.mips4k" +files "../mips4k/octeon32/files.octeon32" + +# +# +# +cpu CPU_MIPS4KC +#device pci +#device ata +#device atadisk + +#device clock +#device obio +#device uart + diff --git a/sys/mips/mips4k/octeon32/uart_bus_octeonusart.c b/sys/mips/mips4k/octeon32/uart_bus_octeonusart.c new file mode 100644 index 00000000000..0bb22d8789d --- /dev/null +++ b/sys/mips/mips4k/octeon32/uart_bus_octeonusart.c @@ -0,0 +1,119 @@ +/*- + * Copyright (c) 2006 Wojciech A. Koszek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * $Id$ + */ +/* + * Skeleton of this file was based on respective code for ARM + * code written by Olivier Houchard. + */ + +/* + * XXXMIPS: This file is hacked from arm/... . XXXMIPS here means this file is + * experimental and was written for MIPS32 port. + */ +#include "opt_uart.h" + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +/* + * XXXMIPS: + */ +#include + +#include "uart_if.h" + +static int uart_octeon_probe(device_t dev); +static void octeon_uart_identify(driver_t *drv, device_t parent); + +extern struct uart_class octeon_uart_class; + +static device_method_t uart_octeon_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, uart_octeon_probe), + DEVMETHOD(device_attach, uart_bus_attach), + DEVMETHOD(device_detach, uart_bus_detach), + DEVMETHOD(device_identify, octeon_uart_identify), + { 0, 0 } +}; + +static driver_t uart_octeon_driver = { + uart_driver_name, + uart_octeon_methods, + sizeof(struct uart_softc), +}; + +extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; +static int +uart_octeon_probe (device_t dev) +{ + struct uart_softc *sc; + int unit; + +/* + * Note that both tty0 & tty1 are viable consoles. We add child devices + * such that ttyu0 ends up front of queue. + */ + unit = device_get_unit(dev); + sc = device_get_softc(dev); + sc->sc_sysdev = NULL; + sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); + bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); + if (!unit) { + sc->sc_sysdev->bas.bst = 0; + sc->sc_sysdev->bas.bsh = OCTEON_UART0ADR; + } + sc->sc_class = &uart_oct16550_class; + sc->sc_bas.bst = 0; + sc->sc_bas.bsh = unit ? OCTEON_UART1ADR : OCTEON_UART0ADR; + sc->sc_bas.regshft = 0x3; + return (uart_bus_probe(dev, sc->sc_bas.regshft, 0, 0, unit)); +} + +static void +octeon_uart_identify (driver_t *drv, device_t parent) +{ + BUS_ADD_CHILD(parent, 0, "uart", 0); +} + + + +DRIVER_MODULE(uart, obio, uart_octeon_driver, uart_devclass, 0, 0); + diff --git a/sys/mips/mips4k/octeon32/uart_cpu_octeonusart.c b/sys/mips/mips4k/octeon32/uart_cpu_octeonusart.c new file mode 100644 index 00000000000..75bb3cf634f --- /dev/null +++ b/sys/mips/mips4k/octeon32/uart_cpu_octeonusart.c @@ -0,0 +1,83 @@ +/*- + * Copyright (c) 2006 Wojciech A. Koszek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ +/* + * Skeleton of this file was based on respective code for ARM + * code written by Olivier Houchard. + */ +/* + * XXXMIPS: This file is hacked from arm/... . XXXMIPS here means this file is + * experimental and was written for MIPS32 port. + */ +#include "opt_uart.h" + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include + +#include +#include + +#include + +bus_space_tag_t uart_bus_space_io; +bus_space_tag_t uart_bus_space_mem; + +extern struct uart_ops octeon_usart_ops; +extern struct bus_space octeon_bs_tag; + +int +uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) +{ + return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0); + return (0); +} + +int +uart_cpu_getdev(int devtype, struct uart_devinfo *di) +{ + di->ops = uart_getops(&uart_oct16550_class); + di->bas.chan = 0; + di->bas.bst = 0; + di->bas.regshft = 3; /* Each UART reg is 8 byte addresss apart. 1 << 3 */ + di->bas.rclk = 0; + di->baudrate = 115200; + di->databits = 8; + di->stopbits = 1; + di->parity = UART_PARITY_NONE; + + uart_bus_space_io = MIPS_PHYS_TO_KSEG1(OCTEON_UART0ADR); + uart_bus_space_mem = MIPS_PHYS_TO_KSEG1(OCTEON_UART0ADR); + di->bas.bsh = OCTEON_UART0ADR; + return (0); +} diff --git a/sys/mips/mips4k/std.mips4k b/sys/mips/mips4k/std.mips4k new file mode 100644 index 00000000000..13d30c3eff3 --- /dev/null +++ b/sys/mips/mips4k/std.mips4k @@ -0,0 +1,5 @@ +# /* +# * This product includes software developed by the University of +# * California, Berkeley and its contributors." +# */ +# $FreeBSD$ From b502e57d9e5fe257c3985f5f4d149ef4af0f3abd Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 03:01:39 +0000 Subject: [PATCH 101/380] Move the octeon port to its more correct location. Any port for the OCTEON2 family of processors should live in mips/octeon2. Not enough is know abotu the former to know if the same port can be used for both yet. --- sys/mips/conf/{OCTEON32 => OCTEON1} | 10 +++++----- sys/mips/{mips4k/octeon32 => octeon1}/asm_octeon.S | 0 sys/mips/{mips4k/octeon32 => octeon1}/files.octeon32 | 0 sys/mips/{mips4k/octeon32 => octeon1}/obio.c | 0 sys/mips/{mips4k/octeon32 => octeon1}/obiovar.h | 0 sys/mips/{mips4k/octeon32 => octeon1}/octeon_machdep.c | 0 sys/mips/{mips4k/octeon32 => octeon1}/octeonreg.h | 0 sys/mips/{mips4k/octeon32 => octeon1}/std.octeon32 | 0 .../octeon32 => octeon1}/uart_bus_octeonusart.c | 0 .../octeon32 => octeon1}/uart_cpu_octeonusart.c | 0 10 files changed, 5 insertions(+), 5 deletions(-) rename sys/mips/conf/{OCTEON32 => OCTEON1} (92%) rename sys/mips/{mips4k/octeon32 => octeon1}/asm_octeon.S (100%) rename sys/mips/{mips4k/octeon32 => octeon1}/files.octeon32 (100%) rename sys/mips/{mips4k/octeon32 => octeon1}/obio.c (100%) rename sys/mips/{mips4k/octeon32 => octeon1}/obiovar.h (100%) rename sys/mips/{mips4k/octeon32 => octeon1}/octeon_machdep.c (100%) rename sys/mips/{mips4k/octeon32 => octeon1}/octeonreg.h (100%) rename sys/mips/{mips4k/octeon32 => octeon1}/std.octeon32 (100%) rename sys/mips/{mips4k/octeon32 => octeon1}/uart_bus_octeonusart.c (100%) rename sys/mips/{mips4k/octeon32 => octeon1}/uart_cpu_octeonusart.c (100%) diff --git a/sys/mips/conf/OCTEON32 b/sys/mips/conf/OCTEON1 similarity index 92% rename from sys/mips/conf/OCTEON32 rename to sys/mips/conf/OCTEON1 index 65145353098..e79ebeeaab4 100644 --- a/sys/mips/conf/OCTEON32 +++ b/sys/mips/conf/OCTEON1 @@ -1,4 +1,4 @@ -# QEMU -- Generic kernel configuration file for FreeBSD/mips +# OCTEON1 -- Configuration kernel for all Octeon1 SoCs from Cavium Networks # # For more information on this file, please read the handbook section on # Kernel Configuration Files: @@ -19,7 +19,7 @@ machine mips cpu CPU_MIPS4KC -ident CAVIUM +ident OCTEON1 #makeoptions ARCH_FLAGS=-march=mips32 @@ -27,9 +27,9 @@ ident CAVIUM makeoptions MODULES_OVERRIDE="" options KERNVIRTADDR=0x80100000 -include "../mips4k/octeon32/std.octeon32" +include "../octeon1/std.octeon1" -hints "OCTEON.hints" #Default places to look for devices. +hints "OCTEON1.hints" #Default places to look for devices. makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols @@ -62,9 +62,9 @@ device genclock device loop device ether device md -device mem device uart device uart_oct16550 +nodevice uart_8250 device rgmii #options VERBOSE_SYSINIT diff --git a/sys/mips/mips4k/octeon32/asm_octeon.S b/sys/mips/octeon1/asm_octeon.S similarity index 100% rename from sys/mips/mips4k/octeon32/asm_octeon.S rename to sys/mips/octeon1/asm_octeon.S diff --git a/sys/mips/mips4k/octeon32/files.octeon32 b/sys/mips/octeon1/files.octeon32 similarity index 100% rename from sys/mips/mips4k/octeon32/files.octeon32 rename to sys/mips/octeon1/files.octeon32 diff --git a/sys/mips/mips4k/octeon32/obio.c b/sys/mips/octeon1/obio.c similarity index 100% rename from sys/mips/mips4k/octeon32/obio.c rename to sys/mips/octeon1/obio.c diff --git a/sys/mips/mips4k/octeon32/obiovar.h b/sys/mips/octeon1/obiovar.h similarity index 100% rename from sys/mips/mips4k/octeon32/obiovar.h rename to sys/mips/octeon1/obiovar.h diff --git a/sys/mips/mips4k/octeon32/octeon_machdep.c b/sys/mips/octeon1/octeon_machdep.c similarity index 100% rename from sys/mips/mips4k/octeon32/octeon_machdep.c rename to sys/mips/octeon1/octeon_machdep.c diff --git a/sys/mips/mips4k/octeon32/octeonreg.h b/sys/mips/octeon1/octeonreg.h similarity index 100% rename from sys/mips/mips4k/octeon32/octeonreg.h rename to sys/mips/octeon1/octeonreg.h diff --git a/sys/mips/mips4k/octeon32/std.octeon32 b/sys/mips/octeon1/std.octeon32 similarity index 100% rename from sys/mips/mips4k/octeon32/std.octeon32 rename to sys/mips/octeon1/std.octeon32 diff --git a/sys/mips/mips4k/octeon32/uart_bus_octeonusart.c b/sys/mips/octeon1/uart_bus_octeonusart.c similarity index 100% rename from sys/mips/mips4k/octeon32/uart_bus_octeonusart.c rename to sys/mips/octeon1/uart_bus_octeonusart.c diff --git a/sys/mips/mips4k/octeon32/uart_cpu_octeonusart.c b/sys/mips/octeon1/uart_cpu_octeonusart.c similarity index 100% rename from sys/mips/mips4k/octeon32/uart_cpu_octeonusart.c rename to sys/mips/octeon1/uart_cpu_octeonusart.c From 6aca1d2ff0ab55682b841deb91ea187f88d4f6a4 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 03:44:01 +0000 Subject: [PATCH 102/380] Now that the import is over, we can (re) delete this. --- sys/mips/mips4k/std.mips4k | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 sys/mips/mips4k/std.mips4k diff --git a/sys/mips/mips4k/std.mips4k b/sys/mips/mips4k/std.mips4k deleted file mode 100644 index 13d30c3eff3..00000000000 --- a/sys/mips/mips4k/std.mips4k +++ /dev/null @@ -1,5 +0,0 @@ -# /* -# * This product includes software developed by the University of -# * California, Berkeley and its contributors." -# */ -# $FreeBSD$ From b9bf0e01e94042ad06be2b3332d047316cd99d1b Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 03:44:43 +0000 Subject: [PATCH 103/380] Actually rename the files this time. Also, start to fix OCTEON1 so it can configure. --- sys/mips/conf/OCTEON1 | 5 ++--- sys/mips/octeon1/{files.octeon32 => files.octeon1} | 8 ++++---- sys/mips/octeon1/{std.octeon32 => std.octeon1} | 3 +-- 3 files changed, 7 insertions(+), 9 deletions(-) rename sys/mips/octeon1/{files.octeon32 => files.octeon1} (71%) rename sys/mips/octeon1/{std.octeon32 => std.octeon1} (77%) diff --git a/sys/mips/conf/OCTEON1 b/sys/mips/conf/OCTEON1 index e79ebeeaab4..af8abb0cd8e 100644 --- a/sys/mips/conf/OCTEON1 +++ b/sys/mips/conf/OCTEON1 @@ -58,13 +58,12 @@ options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required #options WITNESS #Enable checks to detect deadlocks and cycles #options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed -device genclock +#XXXimp device genclock device loop device ether device md device uart -device uart_oct16550 -nodevice uart_8250 +nodevice uart_ns8250 device rgmii #options VERBOSE_SYSINIT diff --git a/sys/mips/octeon1/files.octeon32 b/sys/mips/octeon1/files.octeon1 similarity index 71% rename from sys/mips/octeon1/files.octeon32 rename to sys/mips/octeon1/files.octeon1 index 7785a4ddbc1..848f86eb5dc 100644 --- a/sys/mips/octeon1/files.octeon32 +++ b/sys/mips/octeon1/files.octeon1 @@ -5,12 +5,12 @@ # $FreeBSD$ # Octeon Support Files # -mips/mips4k/octeon32/obio.c optional uart -mips/mips4k/octeon32/uart_cpu_octeonusart.c optional uart -mips/mips4k/octeon32/uart_bus_octeonusart.c optional uart +mips/octeon1/obio.c optional uart +mips/octeon1/uart_cpu_octeonusart.c optional uart +mips/octeon1/uart_bus_octeonusart.c optional uart dev/uart/uart_dev_oct16550.c optional uart mips/mips/mp_machdep.c optional smp -mips/mips4k/octeon32/octeon_machdep.c standard +mips/octeon1/octeon_machdep.c standard dev/flash/octeon_ebt3000_cf.c optional cf diff --git a/sys/mips/octeon1/std.octeon32 b/sys/mips/octeon1/std.octeon1 similarity index 77% rename from sys/mips/octeon1/std.octeon32 rename to sys/mips/octeon1/std.octeon1 index 29f481542aa..6c72febde98 100644 --- a/sys/mips/octeon1/std.octeon32 +++ b/sys/mips/octeon1/std.octeon1 @@ -4,8 +4,7 @@ # */ # $FreeBSD$ # -include "../mips4k/std.mips4k" -files "../mips4k/octeon32/files.octeon32" +files "../octeon1/files.octeon1" # # From 5be117dfacd8561e221e0f80f5bf02273f434348 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 03:47:44 +0000 Subject: [PATCH 104/380] Merge in Cavium's CF driver. This too is in the wrong place and will be moved. --- sys/dev/flash/octeon_ebt3000_cf.c | 619 ++++++++++++++++++++++++++++++ sys/dev/flash/octeon_ebt3000_cf.h | 35 ++ 2 files changed, 654 insertions(+) create mode 100644 sys/dev/flash/octeon_ebt3000_cf.c create mode 100644 sys/dev/flash/octeon_ebt3000_cf.h diff --git a/sys/dev/flash/octeon_ebt3000_cf.c b/sys/dev/flash/octeon_ebt3000_cf.c new file mode 100644 index 00000000000..f7dfd0d00ef --- /dev/null +++ b/sys/dev/flash/octeon_ebt3000_cf.c @@ -0,0 +1,619 @@ +/* + * octeon_ebt3000_cf.c + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "octeon_ebt3000_cf.h" +#include "driveid.h" + +/* ATA Commands */ +#define CMD_READ_SECTOR 0x20 +#define CMD_WRITE_SECTOR 0x30 +#define CMD_IDENTIFY 0xEC + +/* The ATA Task File */ +#define TF_DATA 0x00 +#define TF_ERROR 0x01 +#define TF_PRECOMP 0x01 +#define TF_SECTOR_COUNT 0x02 +#define TF_SECTOR_NUMBER 0x03 +#define TF_CYL_LSB 0x04 +#define TF_CYL_MSB 0x05 +#define TF_DRV_HEAD 0x06 +#define TF_STATUS 0x07 +#define TF_COMMAND 0x07 + +/* Status Register */ +#define STATUS_BSY 0x80 /* Drive is busy */ +#define STATUS_RDY 0x40 /* Drive is ready */ +#define STATUS_DRQ 0x08 /* Data can be transferred */ + +/* Miscelaneous */ +#define SECTOR_SIZE 512 +#define WAIT_DELAY 1000 +#define NR_TRIES 1000 +#define SWAP_SHORT(x) ((x << 8) | (x >> 8)) +#define SWAP_LONG(x) (((x << 24) & 0xFF000000) | ((x << 8) & 0x00FF0000) | \ + ((x >> 8) & 0x0000FF00) | ((x << 24) & 0x000000FF) ) +#define MODEL_STR_SIZE 40 + + +/* Globals */ +int bus_width; +void *base_addr; + +/* Device softc */ +struct cf_priv { + + device_t dev; + struct drive_param *drive_param; + + struct bio_queue_head cf_bq; + struct g_geom *cf_geom; + struct g_provider *cf_provider; + +}; + +/* Device parameters */ +struct drive_param{ + union { + char buf[SECTOR_SIZE]; + struct hd_driveid driveid; + } u; + + char model[MODEL_STR_SIZE]; + uint32_t nr_sectors; + uint16_t sector_size; + uint16_t heads; + uint16_t tracks; + uint16_t sec_track; + +} drive_param; + +/* GEOM class implementation */ +static g_access_t cf_access; +static g_start_t cf_start; +static g_ioctl_t cf_ioctl; + +struct g_class g_cf_class = { + .name = "CF", + .version = G_VERSION, + .start = cf_start, + .access = cf_access, + .ioctl = cf_ioctl, +}; + +/* Device methods */ +static int cf_probe(device_t); +static void cf_identify(driver_t *, device_t); +static int cf_attach(device_t); +static int cf_attach_geom(void *, int); + +/* ATA methods */ +static void cf_cmd_identify(void); +static void cf_cmd_write(uint32_t, uint32_t, void *); +static void cf_cmd_read(uint32_t, uint32_t, void *); +static void cf_wait_busy(void); +static void cf_send_cmd(uint32_t, uint8_t); +static void cf_attach_geom_proxy(void *arg, int flag); + +/* Miscelenous */ +static void cf_swap_ascii(unsigned char[], char[]); + + +/* ------------------------------------------------------------------- * + * cf_access() * + * ------------------------------------------------------------------- */ +static int cf_access (struct g_provider *pp, int r, int w, int e) +{ + + pp->sectorsize = drive_param.sector_size; + pp->stripesize = drive_param.heads * drive_param.sec_track * drive_param.sector_size; + pp->mediasize = pp->stripesize * drive_param.tracks; + + return (0); +} + + +/* ------------------------------------------------------------------- * + * cf_start() * + * ------------------------------------------------------------------- */ +static void cf_start (struct bio *bp) +{ + /* + * Handle actual I/O requests. The request is passed down through + * the bio struct. + */ + + if(bp->bio_cmd & BIO_GETATTR) { + if (g_handleattr_int(bp, "GEOM::fwsectors", drive_param.sec_track)) + return; + if (g_handleattr_int(bp, "GEOM::fwheads", drive_param.heads)) + return; + g_io_deliver(bp, ENOIOCTL); + return; + } + + if ((bp->bio_cmd & (BIO_READ | BIO_WRITE))) { + + if (bp->bio_cmd & BIO_READ) { + cf_cmd_read(bp->bio_length / drive_param.sector_size, + bp->bio_offset / drive_param.sector_size, bp->bio_data); + + } else if (bp->bio_cmd & BIO_WRITE) { + cf_cmd_write(bp->bio_length / drive_param.sector_size, + bp->bio_offset/drive_param.sector_size, bp->bio_data); + } + + bp->bio_resid = 0; + bp->bio_completed = bp->bio_length; + g_io_deliver(bp, 0); + } +} + + +static int cf_ioctl (struct g_provider *pp, u_long cmd, void *data, int fflag, struct thread *td) +{ + return (0); +} + + +/* ------------------------------------------------------------------- * + * cf_cmd_read() * + * ------------------------------------------------------------------- * + * + * Read nr_sectors from the device starting from start_sector. + */ +static void cf_cmd_read (uint32_t nr_sectors, uint32_t start_sector, void *buf) +{ + unsigned long lba; + uint32_t count; + uint16_t *ptr_16; + uint8_t *ptr_8; + +//#define OCTEON_VISUAL_CF_0 1 +#ifdef OCTEON_VISUAL_CF_0 + octeon_led_write_char(0, 'R'); +#endif + ptr_8 = (uint8_t*)buf; + ptr_16 = (uint16_t*)buf; + lba = start_sector; + + + while (nr_sectors--) { + + cf_send_cmd(lba, CMD_READ_SECTOR); + + if (bus_width == 8) { + volatile uint8_t *task_file = (volatile uint8_t*)base_addr; + volatile uint8_t dummy; + for (count = 0; count < SECTOR_SIZE; count++) { + *ptr_8++ = task_file[TF_DATA]; + if ((count & 0xf) == 0) dummy = task_file[TF_STATUS]; + } + } else { + volatile uint16_t *task_file = (volatile uint16_t*)base_addr; + volatile uint16_t dummy; + for (count = 0; count < SECTOR_SIZE; count+=2) { + uint16_t temp; + temp = task_file[TF_DATA]; + *ptr_16++ = SWAP_SHORT(temp); + if ((count & 0xf) == 0) dummy = task_file[TF_STATUS/2]; + } + } + + lba ++; + } +#ifdef OCTEON_VISUAL_CF_0 + octeon_led_write_char(0, ' '); +#endif +} + + +/* ------------------------------------------------------------------- * + * cf_cmd_write() * + * ------------------------------------------------------------------- * + * + * Write nr_sectors to the device starting from start_sector. + */ +static void cf_cmd_write (uint32_t nr_sectors, uint32_t start_sector, void *buf) +{ + uint32_t lba; + uint32_t count; + uint16_t *ptr_16; + uint8_t *ptr_8; + +//#define OCTEON_VISUAL_CF_1 1 +#ifdef OCTEON_VISUAL_CF_1 + octeon_led_write_char(1, 'W'); +#endif + lba = start_sector; + ptr_8 = (uint8_t*)buf; + ptr_16 = (uint16_t*)buf; + + while (nr_sectors--) { + + cf_send_cmd(lba, CMD_WRITE_SECTOR); + + if (bus_width == 8) { + volatile uint8_t *task_file; + volatile uint8_t dummy; + + task_file = (volatile uint8_t *) base_addr; + for (count = 0; count < SECTOR_SIZE; count++) { + task_file[TF_DATA] = *ptr_8++; + if ((count & 0xf) == 0) dummy = task_file[TF_STATUS]; + } + } else { + volatile uint16_t *task_file; + volatile uint16_t dummy; + + task_file = (volatile uint16_t *) base_addr; + for (count = 0; count < SECTOR_SIZE; count+=2) { + uint16_t temp = *ptr_16++; + task_file[TF_DATA] = SWAP_SHORT(temp); + if ((count & 0xf) == 0) dummy = task_file[TF_STATUS/2]; + } + } + + lba ++; + } +#ifdef OCTEON_VISUAL_CF_1 + octeon_led_write_char(1, ' '); +#endif +} + + +/* ------------------------------------------------------------------- * + * cf_cmd_identify() * + * ------------------------------------------------------------------- * + * + * Read parameters and other information from the drive and store + * it in the drive_param structure + * + */ +static void cf_cmd_identify (void) +{ + int count; + uint8_t status; + + if (bus_width == 8) { + volatile uint8_t *task_file; + + task_file = (volatile uint8_t *) base_addr; + + while ((status = task_file[TF_STATUS]) & STATUS_BSY) { + DELAY(WAIT_DELAY); + } + + task_file[TF_SECTOR_COUNT] = 0; + task_file[TF_SECTOR_NUMBER] = 0; + task_file[TF_CYL_LSB] = 0; + task_file[TF_CYL_MSB] = 0; + task_file[TF_DRV_HEAD] = 0; + task_file[TF_COMMAND] = CMD_IDENTIFY; + + cf_wait_busy(); + + for (count = 0; count < SECTOR_SIZE; count++) + drive_param.u.buf[count] = task_file[TF_DATA]; + + } else { + volatile uint16_t *task_file; + + task_file = (volatile uint16_t *) base_addr; + + while ((status = (task_file[TF_STATUS/2]>>8)) & STATUS_BSY) { + DELAY(WAIT_DELAY); + } + + task_file[TF_SECTOR_COUNT/2] = 0; /* this includes TF_SECTOR_NUMBER */ + task_file[TF_CYL_LSB/2] = 0; /* this includes TF_CYL_MSB */ + task_file[TF_DRV_HEAD/2] = 0 | (CMD_IDENTIFY<<8); /* this includes TF_COMMAND */ + + cf_wait_busy(); + + for (count = 0; count < SECTOR_SIZE; count+=2) { + uint16_t temp; + temp = task_file[TF_DATA]; + + /* endianess will be swapped below */ + drive_param.u.buf[count] = (temp & 0xff); + drive_param.u.buf[count+1] = (temp & 0xff00)>>8; + } + } + + cf_swap_ascii(drive_param.u.driveid.model, drive_param.model); + + drive_param.sector_size = 512; //= SWAP_SHORT (drive_param.u.driveid.sector_bytes); + drive_param.heads = SWAP_SHORT (drive_param.u.driveid.cur_heads); + drive_param.tracks = SWAP_SHORT (drive_param.u.driveid.cur_cyls); + drive_param.sec_track = SWAP_SHORT (drive_param.u.driveid.cur_sectors); + drive_param.nr_sectors = SWAP_LONG (drive_param.u.driveid.lba_capacity); + +} + + +/* ------------------------------------------------------------------- * + * cf_send_cmd() * + * ------------------------------------------------------------------- * + * + * Send command to read/write one sector specified by lba. + * + */ +static void cf_send_cmd (uint32_t lba, uint8_t cmd) +{ + uint8_t status; + + if (bus_width == 8) { + volatile uint8_t *task_file; + + task_file = (volatile uint8_t *) base_addr; + + while ( (status = task_file[TF_STATUS]) & STATUS_BSY) { + DELAY(WAIT_DELAY); + } + + task_file[TF_SECTOR_COUNT] = 1; + task_file[TF_SECTOR_NUMBER] = (lba & 0xff); + task_file[TF_CYL_LSB] = ((lba >> 8) & 0xff); + task_file[TF_CYL_MSB] = ((lba >> 16) & 0xff); + task_file[TF_DRV_HEAD] = ((lba >> 24) & 0xff) | 0xe0; + task_file[TF_COMMAND] = cmd; + + } else { + volatile uint16_t *task_file; + + task_file = (volatile uint16_t *) base_addr; + + while ( (status = (task_file[TF_STATUS/2]>>8)) & STATUS_BSY) { + DELAY(WAIT_DELAY); + } + + task_file[TF_SECTOR_COUNT/2] = 1 | ((lba & 0xff) << 8); + task_file[TF_CYL_LSB/2] = ((lba >> 8) & 0xff) | (((lba >> 16) & 0xff) << 8); + task_file[TF_DRV_HEAD/2] = (((lba >> 24) & 0xff) | 0xe0) | (cmd << 8); + + } + + cf_wait_busy(); +} + +/* ------------------------------------------------------------------- * + * cf_wait_busy() * + * ------------------------------------------------------------------- * + * + * Wait until the drive finishes a given command and data is + * ready to be transferred. This is done by repeatedly checking + * the BSY and DRQ bits of the status register. When the controller + * is ready for data transfer, it clears the BSY bit and sets the + * DRQ bit. + * + */ +static void cf_wait_busy (void) +{ + uint8_t status; + +//#define OCTEON_VISUAL_CF_2 1 +#ifdef OCTEON_VISUAL_CF_2 + static int where0 = 0; + + octeon_led_run_wheel(&where0, 2); +#endif + + if (bus_width == 8) { + volatile uint8_t *task_file; + task_file = (volatile uint8_t *)base_addr; + + status = task_file[TF_STATUS]; + while ((status & STATUS_BSY) == STATUS_BSY || (status & STATUS_DRQ) != STATUS_DRQ ) { + DELAY(WAIT_DELAY); + status = task_file[TF_STATUS]; + } + } else { + volatile uint16_t *task_file; + task_file = (volatile uint16_t *)base_addr; + + status = task_file[TF_STATUS/2]>>8; + while ((status & STATUS_BSY) == STATUS_BSY || (status & STATUS_DRQ) != STATUS_DRQ ) { + DELAY(WAIT_DELAY); + status = (uint8_t)(task_file[TF_STATUS/2]>>8); + } + } + +#ifdef OCTEON_VISUAL_CF_2 + octeon_led_write_char(2, ' '); +#endif +} + +/* ------------------------------------------------------------------- * + * cf_swap_ascii() * + * ------------------------------------------------------------------- * + * + * The ascii string returned by the controller specifying + * the model of the drive is byte-swaped. This routine + * corrects the byte ordering. + * + */ +static void cf_swap_ascii (unsigned char str1[], char str2[]) +{ + int i; + + for(i = 0; i < MODEL_STR_SIZE; i++) { + str2[i] = str1[i^1]; + } +} + + +/* ------------------------------------------------------------------- * + * cf_probe() * + * ------------------------------------------------------------------- */ + +static int cf_probe (device_t dev) +{ + if (!octeon_board_real()) return 1; + + if (device_get_unit(dev) != 0) { + panic("can't attach more devices\n"); + } + + device_set_desc(dev, "Octeon Compact Flash Driver"); + + cf_cmd_identify(); + + return (0); +} + +/* ------------------------------------------------------------------- * + * cf_identify() * + * ------------------------------------------------------------------- * + * + * Find the bootbus region for the CF to determine + * 16 or 8 bit and check to see if device is + * inserted. + * + */ +static void cf_identify (driver_t *drv, device_t parent) +{ + uint8_t status; + int bus_region; + int count = 0; + octeon_mio_boot_reg_cfgx_t cfg; + + + if (!octeon_board_real()) return 1; + + base_addr = (void *) OCTEON_PHYS2PTR(OCTEON_CF_COMMON_BASE_ADDR); + + for (bus_region = 0; bus_region < 8; bus_region++) + { + cfg.word64 = oct_read64(OCTEON_MIO_BOOT_REG_CFGX(bus_region)); + if (cfg.bits.base == OCTEON_CF_COMMON_BASE_ADDR >> 16) + { + bus_width = (cfg.bits.width) ? 16: 8; + printf("Compact flash found in bootbus region %d (%d bit).\n", bus_region, bus_width); + break; + } + } + + if (bus_width == 8) { + volatile uint8_t *task_file; + task_file = (volatile uint8_t *) base_addr; + /* Check if CF is inserted */ + while ( (status = task_file[TF_STATUS]) & STATUS_BSY){ + if ((count++) == NR_TRIES ) { + printf("Compact Flash not present\n"); + return; + } + DELAY(WAIT_DELAY); + } + } else { + volatile uint16_t *task_file; + task_file = (volatile uint16_t *) base_addr; + /* Check if CF is inserted */ + while ( (status = (task_file[TF_STATUS/2]>>8)) & STATUS_BSY){ + if ((count++) == NR_TRIES ) { + printf("Compact Flash not present\n"); + return; + } + DELAY(WAIT_DELAY); + } + } + + BUS_ADD_CHILD(parent, 0, "cf", 0); +} + + +/* ------------------------------------------------------------------- * + * cf_attach_geom() * + * ------------------------------------------------------------------- */ + +static int cf_attach_geom (void *arg, int flag) +{ + struct cf_priv *cf_priv; + + cf_priv = (struct cf_priv *) arg; + cf_priv->cf_geom = g_new_geomf(&g_cf_class, "cf%d", device_get_unit(cf_priv->dev)); + cf_priv->cf_provider = g_new_providerf(cf_priv->cf_geom, cf_priv->cf_geom->name); + cf_priv->cf_geom->softc = cf_priv; + g_error_provider(cf_priv->cf_provider, 0); + + return (0); +} + +/* ------------------------------------------------------------------- * + * cf_attach_geom() * + * ------------------------------------------------------------------- */ +static void cf_attach_geom_proxy (void *arg, int flag) +{ + cf_attach_geom(arg, flag); +} + + + +/* ------------------------------------------------------------------- * + * cf_attach() * + * ------------------------------------------------------------------- */ + +static int cf_attach (device_t dev) +{ + struct cf_priv *cf_priv; + + if (!octeon_board_real()) return 1; + + cf_priv = device_get_softc(dev); + cf_priv->dev = dev; + cf_priv->drive_param = &drive_param; + + g_post_event(cf_attach_geom_proxy, cf_priv, M_WAITOK, NULL); + bioq_init(&cf_priv->cf_bq); + + return 0; +} + + +static device_method_t cf_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, cf_probe), + DEVMETHOD(device_identify, cf_identify), + DEVMETHOD(device_attach, cf_attach), + DEVMETHOD(device_detach, bus_generic_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + + { 0, 0 } +}; + +static driver_t cf_driver = { + "cf", + cf_methods, + sizeof(struct cf_priv) +}; + +static devclass_t cf_devclass; + +DRIVER_MODULE(cf, nexus, cf_driver, cf_devclass, 0, 0); + diff --git a/sys/dev/flash/octeon_ebt3000_cf.h b/sys/dev/flash/octeon_ebt3000_cf.h new file mode 100644 index 00000000000..1e995128b96 --- /dev/null +++ b/sys/dev/flash/octeon_ebt3000_cf.h @@ -0,0 +1,35 @@ +/* + * octeon_ebt3000_cf.h + * + */ + + +#ifndef __OCTEON_EBT3000_H__ +#define __OCTEON_EBT3000_H__ + + + +#define OCTEON_CF_COMMON_BASE_ADDR (0x1d000000 | (1 << 11)) +#define OCTEON_MIO_BOOT_REG_CFGX(offset) (0x8001180000000000ull + ((offset) * 8)) + + +typedef union +{ + uint64_t word64; + struct + { + uint64_t reserved : 27; /**< Reserved */ + uint64_t sam : 1; /**< Region 0 SAM */ + uint64_t we_ext : 2; /**< Region 0 write enable count extension */ + uint64_t oe_ext : 2; /**< Region 0 output enable count extension */ + uint64_t en : 1; /**< Region 0 enable */ + uint64_t orbit : 1; /**< No function for region 0 */ + uint64_t ale : 1; /**< Region 0 ALE mode */ + uint64_t width : 1; /**< Region 0 bus width */ + uint64_t size : 12; /**< Region 0 size */ + uint64_t base : 16; /**< Region 0 base address */ + } bits; +} octeon_mio_boot_reg_cfgx_t; + + +#endif /* __OCTEON_EBT3000_H__ */ From b02713c7a49c2577d262e12ba7a6e7fcc1b40378 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 03:55:27 +0000 Subject: [PATCH 105/380] Move dev/flash/ cf driver into octeon dir where it belongs. --- sys/dev/uart/uart_dev_oct16550.c | 826 ++++++++++++++++++ sys/mips/octeon1/files.octeon1 | 9 +- .../octeon1}/octeon_ebt3000_cf.c | 0 .../octeon1}/octeon_ebt3000_cf.h | 0 4 files changed, 830 insertions(+), 5 deletions(-) create mode 100644 sys/dev/uart/uart_dev_oct16550.c rename sys/{dev/flash => mips/octeon1}/octeon_ebt3000_cf.c (100%) rename sys/{dev/flash => mips/octeon1}/octeon_ebt3000_cf.h (100%) diff --git a/sys/dev/uart/uart_dev_oct16550.c b/sys/dev/uart/uart_dev_oct16550.c new file mode 100644 index 00000000000..53c8ee2af62 --- /dev/null +++ b/sys/dev/uart/uart_dev_oct16550.c @@ -0,0 +1,826 @@ +/*- + * Copyright (c) 2003 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * uart_dev_oct16550.c + * + * Derived from uart_dev_ns8250.c + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + */ + + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + + +#include "uart_if.h" + +/* + * Clear pending interrupts. THRE is cleared by reading IIR. Data + * that may have been received gets lost here. + */ +static void +oct16550_clrint (struct uart_bas *bas) +{ + uint8_t iir; + + iir = uart_getreg(bas, REG_IIR); + while ((iir & IIR_NOPEND) == 0) { + iir &= IIR_IMASK; + if (iir == IIR_RLS) + (void)uart_getreg(bas, REG_LSR); + else if (iir == IIR_RXRDY || iir == IIR_RXTOUT) + (void)uart_getreg(bas, REG_DATA); + else if (iir == IIR_MLSC) + (void)uart_getreg(bas, REG_MSR); + else if (iir == IIR_BUSY) + (void) uart_getreg(bas, REG_USR); + uart_barrier(bas); + iir = uart_getreg(bas, REG_IIR); + } +} + +static int delay_changed = 1; + +static int +oct16550_delay (struct uart_bas *bas) +{ + int divisor; + u_char lcr; + static int delay = 0; + + if (!delay_changed) return delay; + delay_changed = 0; + lcr = uart_getreg(bas, REG_LCR); + uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); + uart_barrier(bas); + divisor = uart_getreg(bas, REG_DLL) | (uart_getreg(bas, REG_DLH) << 8); + uart_barrier(bas); + uart_setreg(bas, REG_LCR, lcr); + uart_barrier(bas); + + if(!bas->rclk) + return 10; /* return an approx delay value */ + + /* 1/10th the time to transmit 1 character (estimate). */ + if (divisor <= 134) + return (16000000 * divisor / bas->rclk); + return (16000 * divisor / (bas->rclk / 1000)); + +} + +static int +oct16550_divisor (int rclk, int baudrate) +{ + int actual_baud, divisor; + int error; + + if (baudrate == 0) + return (0); + + divisor = (rclk / (baudrate << 3) + 1) >> 1; + if (divisor == 0 || divisor >= 65536) + return (0); + actual_baud = rclk / (divisor << 4); + + /* 10 times error in percent: */ + error = ((actual_baud - baudrate) * 2000 / baudrate + 1) >> 1; + + /* 3.0% maximum error tolerance: */ + if (error < -30 || error > 30) + return (0); + + return (divisor); +} + +static int +oct16550_drain (struct uart_bas *bas, int what) +{ + int delay, limit; + + delay = oct16550_delay(bas); + + if (what & UART_DRAIN_TRANSMITTER) { + /* + * Pick an arbitrary high limit to avoid getting stuck in + * an infinite loop when the hardware is broken. Make the + * limit high enough to handle large FIFOs. + */ + limit = 10*10*10*1024; + while ((uart_getreg(bas, REG_LSR) & LSR_TEMT) == 0 && --limit) + DELAY(delay); + if (limit == 0) { + /* printf("oct16550: transmitter appears stuck... "); */ + return (0); + } + } + + if (what & UART_DRAIN_RECEIVER) { + /* + * Pick an arbitrary high limit to avoid getting stuck in + * an infinite loop when the hardware is broken. Make the + * limit high enough to handle large FIFOs and integrated + * UARTs. The HP rx2600 for example has 3 UARTs on the + * management board that tend to get a lot of data send + * to it when the UART is first activated. + */ + limit=10*4096; + while ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) && --limit) { + (void)uart_getreg(bas, REG_DATA); + uart_barrier(bas); + DELAY(delay << 2); + } + if (limit == 0) { + /* printf("oct16550: receiver appears broken... "); */ + return (EIO); + } + } + + return (0); +} + +/* + * We can only flush UARTs with FIFOs. UARTs without FIFOs should be + * drained. WARNING: this function clobbers the FIFO setting! + */ +static void +oct16550_flush (struct uart_bas *bas, int what) +{ + uint8_t fcr; + + fcr = FCR_ENABLE; + if (what & UART_FLUSH_TRANSMITTER) + fcr |= FCR_XMT_RST; + if (what & UART_FLUSH_RECEIVER) + fcr |= FCR_RCV_RST; + uart_setreg(bas, REG_FCR, fcr); + uart_barrier(bas); +} + +static int +oct16550_param (struct uart_bas *bas, int baudrate, int databits, int stopbits, + int parity) +{ + int divisor; + uint8_t lcr; + + lcr = 0; + if (databits >= 8) + lcr |= LCR_8BITS; + else if (databits == 7) + lcr |= LCR_7BITS; + else if (databits == 6) + lcr |= LCR_6BITS; + else + lcr |= LCR_5BITS; + if (stopbits > 1) + lcr |= LCR_STOPB; + lcr |= parity << 3; + + /* Set baudrate. */ + if (baudrate > 0) { + divisor = oct16550_divisor(bas->rclk, baudrate); + if (divisor == 0) + return (EINVAL); + uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); + uart_barrier(bas); + uart_setreg(bas, REG_DLL, divisor & 0xff); + uart_setreg(bas, REG_DLH, (divisor >> 8) & 0xff); + uart_barrier(bas); + delay_changed = 1; + } + + /* Set LCR and clear DLAB. */ + uart_setreg(bas, REG_LCR, lcr); + uart_barrier(bas); + return (0); +} + +/* + * Low-level UART interface. + */ +static int oct16550_probe(struct uart_bas *bas); +static void oct16550_init(struct uart_bas *bas, int, int, int, int); +static void oct16550_term(struct uart_bas *bas); +static void oct16550_putc(struct uart_bas *bas, int); +static int oct16550_rxready(struct uart_bas *bas); +static int oct16550_getc(struct uart_bas *bas, struct mtx *); + +struct uart_ops uart_oct16550_ops = { + .probe = oct16550_probe, + .init = oct16550_init, + .term = oct16550_term, + .putc = oct16550_putc, + .rxready = oct16550_rxready, + .getc = oct16550_getc, +}; + +static int +oct16550_probe (struct uart_bas *bas) +{ + u_char val; + + /* Check known 0 bits that don't depend on DLAB. */ + val = uart_getreg(bas, REG_IIR); + if (val & 0x30) + return (ENXIO); + val = uart_getreg(bas, REG_MCR); + if (val & 0xc0) + return (ENXIO); + val = uart_getreg(bas, REG_USR); + if (val & 0xe0) + return (ENXIO); + return (0); +} + +static void +oct16550_init (struct uart_bas *bas, int baudrate, int databits, int stopbits, + int parity) +{ + u_char ier; + + oct16550_param(bas, baudrate, databits, stopbits, parity); + + /* Disable all interrupt sources. */ + ier = uart_getreg(bas, REG_IER) & 0x0; + uart_setreg(bas, REG_IER, ier); + uart_barrier(bas); + + /* Disable the FIFO (if present). */ +// uart_setreg(bas, REG_FCR, 0); + uart_barrier(bas); + + /* Set RTS & DTR. */ + uart_setreg(bas, REG_MCR, MCR_RTS | MCR_DTR); + uart_barrier(bas); + + oct16550_clrint(bas); +} + +static void +oct16550_term (struct uart_bas *bas) +{ + + /* Clear RTS & DTR. */ + uart_setreg(bas, REG_MCR, 0); + uart_barrier(bas); +} + +static inline void oct16550_wait_txhr_empty (struct uart_bas *bas, int limit, int delay) +{ + while (((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0) && + ((uart_getreg(bas, REG_USR) & USR_TXFIFO_NOTFULL) == 0)) + DELAY(delay); +} + +static void +oct16550_putc (struct uart_bas *bas, int c) +{ + int delay; + + /* 1/10th the time to transmit 1 character (estimate). */ + delay = oct16550_delay(bas); + oct16550_wait_txhr_empty(bas, 100, delay); + uart_setreg(bas, REG_DATA, c); + uart_barrier(bas); + oct16550_wait_txhr_empty(bas, 100, delay); +} + +static int +oct16550_rxready (struct uart_bas *bas) +{ + + return ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) != 0 ? 1 : 0); +} + +static int +oct16550_getc (struct uart_bas *bas, struct mtx *hwmtx) +{ + int c, delay; + + uart_lock(hwmtx); + + /* 1/10th the time to transmit 1 character (estimate). */ + delay = oct16550_delay(bas); + + while ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) == 0) { + uart_unlock(hwmtx); + DELAY(delay); + uart_lock(hwmtx); + } + + c = uart_getreg(bas, REG_DATA); + + uart_unlock(hwmtx); + + return (c); +} + +/* + * High-level UART interface. + */ +struct oct16550_softc { + struct uart_softc base; + uint8_t fcr; + uint8_t ier; + uint8_t mcr; +}; + +static int oct16550_bus_attach(struct uart_softc *); +static int oct16550_bus_detach(struct uart_softc *); +static int oct16550_bus_flush(struct uart_softc *, int); +static int oct16550_bus_getsig(struct uart_softc *); +static int oct16550_bus_ioctl(struct uart_softc *, int, intptr_t); +static int oct16550_bus_ipend(struct uart_softc *); +static int oct16550_bus_param(struct uart_softc *, int, int, int, int); +static int oct16550_bus_probe(struct uart_softc *); +static int oct16550_bus_receive(struct uart_softc *); +static int oct16550_bus_setsig(struct uart_softc *, int); +static int oct16550_bus_transmit(struct uart_softc *); + +static kobj_method_t oct16550_methods[] = { + KOBJMETHOD(uart_attach, oct16550_bus_attach), + KOBJMETHOD(uart_detach, oct16550_bus_detach), + KOBJMETHOD(uart_flush, oct16550_bus_flush), + KOBJMETHOD(uart_getsig, oct16550_bus_getsig), + KOBJMETHOD(uart_ioctl, oct16550_bus_ioctl), + KOBJMETHOD(uart_ipend, oct16550_bus_ipend), + KOBJMETHOD(uart_param, oct16550_bus_param), + KOBJMETHOD(uart_probe, oct16550_bus_probe), + KOBJMETHOD(uart_receive, oct16550_bus_receive), + KOBJMETHOD(uart_setsig, oct16550_bus_setsig), + KOBJMETHOD(uart_transmit, oct16550_bus_transmit), + { 0, 0 } +}; + +struct uart_class uart_oct16550_class = { + "oct16550 class", + oct16550_methods, + sizeof(struct oct16550_softc), + .uc_ops = &uart_oct16550_ops, + .uc_range = 8, + .uc_rclk = 0 +}; + +#define SIGCHG(c, i, s, d) \ + if (c) { \ + i |= (i & s) ? s : s | d; \ + } else { \ + i = (i & s) ? (i & ~s) | d : i; \ + } + +static int +oct16550_bus_attach (struct uart_softc *sc) +{ + struct oct16550_softc *oct16550 = (struct oct16550_softc*)sc; + struct uart_bas *bas; + int unit; + + unit = device_get_unit(sc->sc_dev); + bas = &sc->sc_bas; + + oct16550_drain(bas, UART_DRAIN_TRANSMITTER); + oct16550->mcr = uart_getreg(bas, REG_MCR); + oct16550->fcr = FCR_ENABLE | FCR_RX_HIGH; + uart_setreg(bas, REG_FCR, oct16550->fcr); + uart_barrier(bas); + oct16550_bus_flush(sc, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER); + + if (oct16550->mcr & MCR_DTR) + sc->sc_hwsig |= SER_DTR; + if (oct16550->mcr & MCR_RTS) + sc->sc_hwsig |= SER_RTS; + oct16550_bus_getsig(sc); + + oct16550_clrint(bas); + oct16550->ier = uart_getreg(bas, REG_IER) & 0xf0; + oct16550->ier |= IER_EMSC | IER_ERLS | IER_ERXRDY; + uart_setreg(bas, REG_IER, oct16550->ier); + uart_barrier(bas); + + uint32_t status_bits = mips_rd_status(); + mips_wr_status(status_bits & ~MIPS_SR_INT_IE); + /* + * Enable the interrupt in CIU. // UART-x2 @ IP2 + */ + ciu_enable_interrupts(0, CIU_INT_0, CIU_EN_0, + (!unit) ? CIU_UART_BITS_UART0 : CIU_UART_BITS_UART1, CIU_MIPS_IP2); + return (0); +} + +static int +oct16550_bus_detach (struct uart_softc *sc) +{ + struct uart_bas *bas; + u_char ier; + + bas = &sc->sc_bas; + ier = uart_getreg(bas, REG_IER) & 0xf0; + uart_setreg(bas, REG_IER, ier); + uart_barrier(bas); + oct16550_clrint(bas); + return (0); +} + +static int +oct16550_bus_flush (struct uart_softc *sc, int what) +{ + struct oct16550_softc *oct16550 = (struct oct16550_softc*)sc; + struct uart_bas *bas; + int error; + + bas = &sc->sc_bas; + uart_lock(sc->sc_hwmtx); + if (sc->sc_rxfifosz > 1) { + oct16550_flush(bas, what); + uart_setreg(bas, REG_FCR, oct16550->fcr); + uart_barrier(bas); + error = 0; + } else + error = oct16550_drain(bas, what); + uart_unlock(sc->sc_hwmtx); + return (error); +} + +static int +oct16550_bus_getsig (struct uart_softc *sc) +{ + uint32_t new, old, sig; + uint8_t msr; + + do { + old = sc->sc_hwsig; + sig = old; + uart_lock(sc->sc_hwmtx); + msr = uart_getreg(&sc->sc_bas, REG_MSR); + uart_unlock(sc->sc_hwmtx); + SIGCHG(msr & MSR_DSR, sig, SER_DSR, SER_DDSR); + SIGCHG(msr & MSR_CTS, sig, SER_CTS, SER_DCTS); + SIGCHG(msr & MSR_DCD, sig, SER_DCD, SER_DDCD); + SIGCHG(msr & MSR_RI, sig, SER_RI, SER_DRI); + new = sig & ~SER_MASK_DELTA; + } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); + return (sig); +} + +static int +oct16550_bus_ioctl (struct uart_softc *sc, int request, intptr_t data) +{ + struct uart_bas *bas; + int baudrate, divisor, error; + uint8_t efr, lcr; + + bas = &sc->sc_bas; + error = 0; + uart_lock(sc->sc_hwmtx); + switch (request) { + case UART_IOCTL_BREAK: + lcr = uart_getreg(bas, REG_LCR); + if (data) + lcr |= LCR_SBREAK; + else + lcr &= ~LCR_SBREAK; + uart_setreg(bas, REG_LCR, lcr); + uart_barrier(bas); + break; + case UART_IOCTL_IFLOW: + lcr = uart_getreg(bas, REG_LCR); + uart_barrier(bas); + uart_setreg(bas, REG_LCR, 0xbf); + uart_barrier(bas); + efr = uart_getreg(bas, REG_EFR); + if (data) + efr |= EFR_RTS; + else + efr &= ~EFR_RTS; + uart_setreg(bas, REG_EFR, efr); + uart_barrier(bas); + uart_setreg(bas, REG_LCR, lcr); + uart_barrier(bas); + break; + case UART_IOCTL_OFLOW: + lcr = uart_getreg(bas, REG_LCR); + uart_barrier(bas); + uart_setreg(bas, REG_LCR, 0xbf); + uart_barrier(bas); + efr = uart_getreg(bas, REG_EFR); + if (data) + efr |= EFR_CTS; + else + efr &= ~EFR_CTS; + uart_setreg(bas, REG_EFR, efr); + uart_barrier(bas); + uart_setreg(bas, REG_LCR, lcr); + uart_barrier(bas); + break; + case UART_IOCTL_BAUD: + lcr = uart_getreg(bas, REG_LCR); + uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); + uart_barrier(bas); + divisor = uart_getreg(bas, REG_DLL) | + (uart_getreg(bas, REG_DLH) << 8); + uart_barrier(bas); + uart_setreg(bas, REG_LCR, lcr); + uart_barrier(bas); + baudrate = (divisor > 0) ? bas->rclk / divisor / 16 : 0; + delay_changed = 1; + if (baudrate > 0) + *(int*)data = baudrate; + else + error = ENXIO; + break; + default: + error = EINVAL; + break; + } + uart_unlock(sc->sc_hwmtx); + return (error); +} + + +static int +oct16550_bus_ipend(struct uart_softc *sc) +{ + struct uart_bas *bas; + int ipend = 0; + uint8_t iir, lsr; + + bas = &sc->sc_bas; + uart_lock(sc->sc_hwmtx); + + iir = uart_getreg(bas, REG_IIR) & IIR_IMASK; + if (iir != IIR_NOPEND) { + + if (iir == IIR_RLS) { + lsr = uart_getreg(bas, REG_LSR); + if (lsr & LSR_OE) + ipend |= SER_INT_OVERRUN; + if (lsr & LSR_BI) + ipend |= SER_INT_BREAK; + if (lsr & LSR_RXRDY) + ipend |= SER_INT_RXREADY; + + } else if (iir == IIR_RXRDY) { + ipend |= SER_INT_RXREADY; + + } else if (iir == IIR_RXTOUT) { + ipend |= SER_INT_RXREADY; + + } else if (iir == IIR_TXRDY) { + ipend |= SER_INT_TXIDLE; + + } else if (iir == IIR_MLSC) { + ipend |= SER_INT_SIGCHG; + + } else if (iir == IIR_BUSY) { + (void) uart_getreg(bas, REG_USR); + } + } + uart_unlock(sc->sc_hwmtx); + +//#define OCTEON_VISUAL_UART 1 +#ifdef OCTEON_VISUAL_UART + static int where1 = 0; + + if (ipend) octeon_led_run_wheel(&where1, 6 + device_get_unit(sc->sc_dev)); +#endif + + return ((sc->sc_leaving) ? 0 : ipend); +} + + + + +static int +oct16550_bus_param (struct uart_softc *sc, int baudrate, int databits, + int stopbits, int parity) +{ + struct uart_bas *bas; + int error; + + bas = &sc->sc_bas; + uart_lock(sc->sc_hwmtx); + error = oct16550_param(bas, baudrate, databits, stopbits, parity); + uart_unlock(sc->sc_hwmtx); + return (error); +} + +static int +oct16550_bus_probe (struct uart_softc *sc) +{ + struct uart_bas *bas; + int error; + + bas = &sc->sc_bas; + bas->rclk = uart_oct16550_class.uc_rclk = octeon_cpu_clock; + + error = oct16550_probe(bas); + if (error) { + return (error); + } + + uart_setreg(bas, REG_MCR, (MCR_DTR | MCR_RTS)); + + /* + * Enable FIFOs. And check that the UART has them. If not, we're + * done. Since this is the first time we enable the FIFOs, we reset + * them. + */ + oct16550_drain(bas, UART_DRAIN_TRANSMITTER); +#define ENABLE_OCTEON_FIFO 1 +#ifdef ENABLE_OCTEON_FIFO + uart_setreg(bas, REG_FCR, FCR_ENABLE | FCR_XMT_RST | FCR_RCV_RST); +#endif + uart_barrier(bas); + + oct16550_flush(bas, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER); + + if (device_get_unit(sc->sc_dev)) { + device_set_desc(sc->sc_dev, "Octeon-16550 channel 1"); + } else { + device_set_desc(sc->sc_dev, "Octeon-16550 channel 0"); + } +#ifdef ENABLE_OCTEON_FIFO + sc->sc_rxfifosz = 64; + sc->sc_txfifosz = 64; +#else + sc->sc_rxfifosz = 1; + sc->sc_txfifosz = 1; +#endif + + +#if 0 + /* + * XXX there are some issues related to hardware flow control and + * it's likely that uart(4) is the cause. This basicly needs more + * investigation, but we avoid using for hardware flow control + * until then. + */ + /* 16650s or higher have automatic flow control. */ + if (sc->sc_rxfifosz > 16) { + sc->sc_hwiflow = 1; + sc->sc_hwoflow = 1; + } +#endif + + return (0); +} + +static int +oct16550_bus_receive (struct uart_softc *sc) +{ + struct uart_bas *bas; + int xc; + uint8_t lsr; + + bas = &sc->sc_bas; + uart_lock(sc->sc_hwmtx); + lsr = uart_getreg(bas, REG_LSR); + + while (lsr & LSR_RXRDY) { + if (uart_rx_full(sc)) { + sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN; + break; + } + xc = uart_getreg(bas, REG_DATA); + if (lsr & LSR_FE) + xc |= UART_STAT_FRAMERR; + if (lsr & LSR_PE) + xc |= UART_STAT_PARERR; + uart_rx_put(sc, xc); + lsr = uart_getreg(bas, REG_LSR); + } + /* Discard everything left in the Rx FIFO. */ + /* + * First do a dummy read/discard anyway, in case the UART was lying to us. + * This problem was seen on board, when IIR said RBR, but LSR said no RXRDY + * Results in a stuck ipend loop. + */ + (void)uart_getreg(bas, REG_DATA); + while (lsr & LSR_RXRDY) { + (void)uart_getreg(bas, REG_DATA); + uart_barrier(bas); + lsr = uart_getreg(bas, REG_LSR); + } + uart_unlock(sc->sc_hwmtx); + return (0); +} + +static int +oct16550_bus_setsig (struct uart_softc *sc, int sig) +{ + struct oct16550_softc *oct16550 = (struct oct16550_softc*)sc; + struct uart_bas *bas; + uint32_t new, old; + + bas = &sc->sc_bas; + do { + old = sc->sc_hwsig; + new = old; + if (sig & SER_DDTR) { + SIGCHG(sig & SER_DTR, new, SER_DTR, + SER_DDTR); + } + if (sig & SER_DRTS) { + SIGCHG(sig & SER_RTS, new, SER_RTS, + SER_DRTS); + } + } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); + uart_lock(sc->sc_hwmtx); + oct16550->mcr &= ~(MCR_DTR|MCR_RTS); + if (new & SER_DTR) + oct16550->mcr |= MCR_DTR; + if (new & SER_RTS) + oct16550->mcr |= MCR_RTS; + uart_setreg(bas, REG_MCR, oct16550->mcr); + uart_barrier(bas); + uart_unlock(sc->sc_hwmtx); + return (0); +} + +static int +oct16550_bus_transmit (struct uart_softc *sc) +{ + struct oct16550_softc *oct16550 = (struct oct16550_softc*)sc; + struct uart_bas *bas; + int i; + + bas = &sc->sc_bas; + uart_lock(sc->sc_hwmtx); +#ifdef NO_UART_INTERRUPTS + for (i = 0; i < sc->sc_txdatasz; i++) { + oct16550_putc(bas, sc->sc_txbuf[i]); + } +#else + + oct16550_wait_txhr_empty(bas, 100, oct16550_delay(bas)); + uart_setreg(bas, REG_IER, oct16550->ier | IER_ETXRDY); + uart_barrier(bas); + + for (i = 0; i < sc->sc_txdatasz; i++) { + uart_setreg(bas, REG_DATA, sc->sc_txbuf[i]); + uart_barrier(bas); + } + sc->sc_txbusy = 1; +#endif + uart_unlock(sc->sc_hwmtx); + return (0); +} diff --git a/sys/mips/octeon1/files.octeon1 b/sys/mips/octeon1/files.octeon1 index 848f86eb5dc..120c62ef2e9 100644 --- a/sys/mips/octeon1/files.octeon1 +++ b/sys/mips/octeon1/files.octeon1 @@ -5,15 +5,14 @@ # $FreeBSD$ # Octeon Support Files # +mips/octeon1/octeon_machdep.c standard mips/octeon1/obio.c optional uart mips/octeon1/uart_cpu_octeonusart.c optional uart mips/octeon1/uart_bus_octeonusart.c optional uart -dev/uart/uart_dev_oct16550.c optional uart +mips/octeon1/octeon_ebt3000_cf.c optional cf + mips/mips/mp_machdep.c optional smp -mips/octeon1/octeon_machdep.c standard - -dev/flash/octeon_ebt3000_cf.c optional cf - +dev/uart/uart_dev_oct16550.c optional uart dev/le/octeon_fau.c optional rgmii dev/le/octeon_fpa.c optional rgmii dev/le/octeon_ipd.c optional rgmii diff --git a/sys/dev/flash/octeon_ebt3000_cf.c b/sys/mips/octeon1/octeon_ebt3000_cf.c similarity index 100% rename from sys/dev/flash/octeon_ebt3000_cf.c rename to sys/mips/octeon1/octeon_ebt3000_cf.c diff --git a/sys/dev/flash/octeon_ebt3000_cf.h b/sys/mips/octeon1/octeon_ebt3000_cf.h similarity index 100% rename from sys/dev/flash/octeon_ebt3000_cf.h rename to sys/mips/octeon1/octeon_ebt3000_cf.h From 5a2edc8c75caf8f7e3e2262328a52994b7ca105b Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 03:57:03 +0000 Subject: [PATCH 106/380] Import sgmii driver for Octeon from Cavium FreeBSD tree. --- sys/dev/le/octeon_fau.c | 44 + sys/dev/le/octeon_fau.h | 185 ++++ sys/dev/le/octeon_fpa.c | 186 ++++ sys/dev/le/octeon_fpa.h | 246 +++++ sys/dev/le/octeon_ipd.c | 106 ++ sys/dev/le/octeon_ipd.h | 164 +++ sys/dev/le/octeon_pip.h | 179 +++ sys/dev/le/octeon_pko.c | 335 ++++++ sys/dev/le/octeon_pko.h | 292 +++++ sys/dev/le/octeon_rgmx.c | 2215 ++++++++++++++++++++++++++++++++++++++ sys/dev/le/octeon_rgmx.h | 594 ++++++++++ 11 files changed, 4546 insertions(+) create mode 100644 sys/dev/le/octeon_fau.c create mode 100644 sys/dev/le/octeon_fau.h create mode 100644 sys/dev/le/octeon_fpa.c create mode 100644 sys/dev/le/octeon_fpa.h create mode 100644 sys/dev/le/octeon_ipd.c create mode 100644 sys/dev/le/octeon_ipd.h create mode 100644 sys/dev/le/octeon_pip.h create mode 100644 sys/dev/le/octeon_pko.c create mode 100644 sys/dev/le/octeon_pko.h create mode 100644 sys/dev/le/octeon_rgmx.c create mode 100644 sys/dev/le/octeon_rgmx.h diff --git a/sys/dev/le/octeon_fau.c b/sys/dev/le/octeon_fau.c new file mode 100644 index 00000000000..f51d6f9fb96 --- /dev/null +++ b/sys/dev/le/octeon_fau.c @@ -0,0 +1,44 @@ +/*------------------------------------------------------------------ + * octeon_fau.c Fetch & Add Block + * + *------------------------------------------------------------------ + */ + +#include +#include + +#include "octeon_fau.h" + +/* + * oct_fau_init + * + * How do we initialize FAU unit. I don't even think we can reset it. + */ +void octeon_fau_init (void) +{ +} + + +/* + * oct_fau_enable + * + * Let the Fetch/Add unit roll + */ +void octeon_fau_enable (void) +{ +} + + +/* + * oct_fau_disable + * + * disable fau + * + * Don't know if we can even do that. + */ +void octeon_fau_disable (void) +{ +} + + + diff --git a/sys/dev/le/octeon_fau.h b/sys/dev/le/octeon_fau.h new file mode 100644 index 00000000000..fc87395f024 --- /dev/null +++ b/sys/dev/le/octeon_fau.h @@ -0,0 +1,185 @@ +/*------------------------------------------------------------------ + * octeon_fau.h Fetch & Add Unit + * + *------------------------------------------------------------------ + */ + + +#ifndef ___OCTEON_FAU__H___ +#define ___OCTEON_FAU__H___ + + + + +typedef enum { + OCTEON_FAU_OP_SIZE_8 = 0, + OCTEON_FAU_OP_SIZE_16 = 1, + OCTEON_FAU_OP_SIZE_32 = 2, + OCTEON_FAU_OP_SIZE_64 = 3 +} octeon_fau_op_size_t; + + + +#define OCTEON_FAU_LOAD_IO_ADDRESS octeon_build_io_address(0x1e, 0) +#define OCTEON_FAU_BITS_SCRADDR 63,56 +#define OCTEON_FAU_BITS_LEN 55,48 +#define OCTEON_FAU_BITS_INEVAL 35,14 +#define OCTEON_FAU_BITS_TAGWAIT 13,13 +#define OCTEON_FAU_BITS_NOADD 13,13 +#define OCTEON_FAU_BITS_SIZE 12,11 +#define OCTEON_FAU_BITS_REGISTER 10,0 + +#define OCTEON_FAU_REG_64_ADDR(x) ((x <<3) + OCTEON_FAU_REG_64_START) +typedef enum +{ + OCTEON_FAU_REG_64_START = 0, + OCTEON_FAU_REG_OQ_ADDR_INDEX = OCTEON_FAU_REG_64_ADDR(0), + OCTEON_FAU_REG_OQ_ADDR_END = OCTEON_FAU_REG_64_ADDR(31), + OCTEON_FAU_REG_64_END = OCTEON_FAU_REG_64_ADDR(39), +} octeon_fau_reg_64_t; + +#define OCTEON_FAU_REG_32_ADDR(x) ((x <<2) + OCTEON_FAU_REG_32_START) +typedef enum +{ + OCTEON_FAU_REG_32_START = OCTEON_FAU_REG_64_END, + OCTEON_FAU_REG_32_END = OCTEON_FAU_REG_32_ADDR(0), +} octeon_fau_reg_32_t; + + + +/* + * octeon_fau_atomic_address + * + * Builds a I/O address for accessing the FAU + * + * @param tagwait Should the atomic add wait for the current tag switch + * operation to complete. + * - 0 = Don't wait + * - 1 = Wait for tag switch to complete + * @param reg FAU atomic register to access. 0 <= reg < 4096. + * - Step by 2 for 16 bit access. + * - Step by 4 for 32 bit access. + * - Step by 8 for 64 bit access. + * @param value Signed value to add. + * Note: When performing 32 and 64 bit access, only the low + * 22 bits are available. + * @return Address to read from for atomic update + */ +static inline uint64_t octeon_fau_atomic_address (uint64_t tagwait, uint64_t reg, + int64_t value) +{ + return (OCTEON_ADD_IO_SEG(OCTEON_FAU_LOAD_IO_ADDRESS) | + octeon_build_bits(OCTEON_FAU_BITS_INEVAL, value) | + octeon_build_bits(OCTEON_FAU_BITS_TAGWAIT, tagwait) | + octeon_build_bits(OCTEON_FAU_BITS_REGISTER, reg)); +} + + +/* + * octeon_fau_store_address + * + * Builds a store I/O address for writing to the FAU + * + * noadd 0 = Store value is atomically added to the current value + * 1 = Store value is atomically written over the current value + * reg FAU atomic register to access. 0 <= reg < 4096. + * - Step by 2 for 16 bit access. + * - Step by 4 for 32 bit access. + * - Step by 8 for 64 bit access. + * Returns Address to store for atomic update + */ +static inline uint64_t octeon_fau_store_address (uint64_t noadd, uint64_t reg) +{ + return (OCTEON_ADD_IO_SEG(OCTEON_FAU_LOAD_IO_ADDRESS) | + octeon_build_bits(OCTEON_FAU_BITS_NOADD, noadd) | + octeon_build_bits(OCTEON_FAU_BITS_REGISTER, reg)); +} + + +/* + * octeon_fau_atomic_add32 + * + * Perform an atomic 32 bit add + * + * @param reg FAU atomic register to access. 0 <= reg < 4096. + * - Step by 4 for 32 bit access. + * @param value Signed value to add. + */ +static inline void octeon_fau_atomic_add32 (octeon_fau_reg_32_t reg, int32_t value) +{ + oct_write32(octeon_fau_store_address(0, reg), value); +} + +/* + * octeon_fau_fetch_and_add + * + * reg FAU atomic register to access. 0 <= reg < 4096. + * - Step by 8 for 64 bit access. + * value Signed value to add. + * Note: Only the low 22 bits are available. + * returns Value of the register before the update + */ +static inline int64_t octeon_fau_fetch_and_add64 (octeon_fau_reg_64_t reg, + int64_t val64) +{ + + return (oct_read64(octeon_fau_atomic_address(0, reg, val64))); +} + +/* + * octeon_fau_fetch_and_add32 + * + * reg FAU atomic register to access. 0 <= reg < 4096. + * - Step by 8 for 64 bit access. + * value Signed value to add. + * Note: Only the low 22 bits are available. + * returns Value of the register before the update + */ +static inline int32_t octeon_fau_fetch_and_add32 (octeon_fau_reg_64_t reg, + int32_t val32) +{ + return (oct_read32(octeon_fau_atomic_address(0, reg, val32))); +} + +/* + * octeon_fau_atomic_write32 + * + * Perform an atomic 32 bit write + * + * @param reg FAU atomic register to access. 0 <= reg < 4096. + * - Step by 4 for 32 bit access. + * @param value Signed value to write. + */ +static inline void octeon_fau_atomic_write32(octeon_fau_reg_32_t reg, int32_t value) +{ + oct_write32(octeon_fau_store_address(1, reg), value); +} + + +/* + * octeon_fau_atomic_write64 + * + * Perform an atomic 32 bit write + * + * reg FAU atomic register to access. 0 <= reg < 4096. + * - Step by 8 for 64 bit access. + * value Signed value to write. + */ +static inline void octeon_fau_atomic_write64 (octeon_fau_reg_64_t reg, int64_t value) +{ + oct_write64(octeon_fau_store_address(1, reg), value); +} + + +static inline void octeon_fau_atomic_add64 (octeon_fau_reg_64_t reg, int64_t value) +{ + oct_write64_int64(octeon_fau_store_address(0, reg), value); +} + + +extern void octeon_fau_init(void); +extern void octeon_fau_enable(void); +extern void octeon_fau_disable(void); + + +#endif /* ___OCTEON_FAU__H___ */ diff --git a/sys/dev/le/octeon_fpa.c b/sys/dev/le/octeon_fpa.c new file mode 100644 index 00000000000..04cb19408aa --- /dev/null +++ b/sys/dev/le/octeon_fpa.c @@ -0,0 +1,186 @@ +/*------------------------------------------------------------------ + * octeon_fpa.c Free Pool Allocator + * + *------------------------------------------------------------------ + */ + +#include +#include +#include +#include +#include + + +#include "octeon_fpa.h" + + +//#define FPA_DEBUG 1 + +/* + * octeon_dump_fpa + * + */ +void octeon_dump_fpa (void) +{ + int i; + octeon_fpa_ctl_status_t status; + octeon_fpa_queue_available_t q_avail; + + status.word64 = oct_read64(OCTEON_FPA_CTL_STATUS); + if (!status.bits.enb) { + printf("\n FPA Disabled"); + /* + * No dumping if disabled + */ + return; + } + printf(" FPA Ctrl-Status-reg 0x%llX := 0x%llX EN %X M1_E %X M0_E %X\n", + OCTEON_FPA_CTL_STATUS, status.word64, + status.bits.enb, status.bits.mem1_err, status.bits.mem0_err); + for (i = 0; i < OCTEON_FPA_QUEUES; i++) { + printf(" Pool: %d\n", i); + + q_avail.word64 = oct_read64((OCTEON_FPA_QUEUE_AVAILABLE + (i)*8ull)); + printf(" Avail-reg 0x%llX := Size: 0x%X\n", + (OCTEON_FPA_QUEUE_AVAILABLE + (i)*8ull), q_avail.bits.queue_size); + } +} + +void octeon_dump_fpa_pool (u_int pool) +{ + octeon_fpa_ctl_status_t status; + octeon_fpa_queue_available_t q_avail; + + status.word64 = oct_read64(OCTEON_FPA_CTL_STATUS); + if (!status.bits.enb) { + printf("\n FPA Disabled"); + /* + * No dumping if disabled + */ + return; + } + printf(" FPA Ctrl-Status-reg 0x%llX := 0x%llX EN %X M1_E %X M0_E %X\n", + OCTEON_FPA_CTL_STATUS, status.word64, + status.bits.enb, status.bits.mem1_err, status.bits.mem0_err); + q_avail.word64 = oct_read64((OCTEON_FPA_QUEUE_AVAILABLE + (pool)*8ull)); + printf(" FPA Pool: %u Avail-reg 0x%llX := Size: 0x%X\n", pool, + (OCTEON_FPA_QUEUE_AVAILABLE + (pool)*8ull), q_avail.bits.queue_size); +} + + +u_int octeon_fpa_pool_size (u_int pool) +{ + octeon_fpa_queue_available_t q_avail; + u_int size = 0; + + if (pool < 7) { + q_avail.word64 = oct_read64((OCTEON_FPA_QUEUE_AVAILABLE + (pool)*8ull)); + size = q_avail.bits.queue_size; + } + return (size); +} + + +/* + * octeon_enable_fpa + * + * configure fpa with defaults and then mark it enabled. + */ +void octeon_enable_fpa (void) +{ + int i; + octeon_fpa_ctl_status_t status; + octeon_fpa_fpf_marks_t marks; + + for (i = 0; i < OCTEON_FPA_QUEUES; i++) { + marks.word64 = oct_read64((OCTEON_FPA_FPF_MARKS + (i)*8ull)); + + marks.bits.fpf_wr = 0xe0; + oct_write64((OCTEON_FPA_FPF_MARKS + (i)*8ull), marks.word64); + } + + /* Enforce a 10 cycle delay between config and enable */ + octeon_wait(10); + + status.word64 = 0; + status.bits.enb = 1; + oct_write64(OCTEON_FPA_CTL_STATUS, status.word64); +} + + +//#define FPA_DEBUG_TERSE 1 + +/* + * octeon_fpa_fill_pool_mem + * + * Fill the specified FPA pool with elem_num number of + * elements of size elem_size_words * 8 + */ +void octeon_fpa_fill_pool_mem (u_int pool, u_int elem_size_words, u_int elem_num) +{ + void *memory; + u_int bytes, elem_size_bytes; + u_int block_size; + +#ifdef FPA_DEBUG + u_int elems = elem_num; + printf(" FPA fill: Pool %u elem_size_words %u Num: %u\n", pool, elem_size_words, elem_num); +#endif + elem_size_bytes = elem_size_words * sizeof(uint64_t); + block_size = OCTEON_ALIGN(elem_size_bytes); + +// block_size = ((elem_size_bytes / OCTEON_FPA_POOL_ALIGNMENT) + 1) * OCTEON_FPA_POOL_ALIGNMENT; + + bytes = (elem_num * block_size); + +#ifdef FPA_DEBUG + printf(" elem_size_bytes = words * 8 = %u; block_size %u\n", elem_size_bytes, block_size); +#endif + + +#ifdef FPA_DEBUG + int block = 0; + + printf(" %% Filling Pool %u with %u blocks of %u bytes %u words\n", + pool, elem_num, elem_size_bytes, elem_size_words); +#endif + +// memory = malloc(bytes, M_DEVBUF, M_NOWAIT | M_ZERO); + memory = contigmalloc(bytes, M_DEVBUF, M_NOWAIT | M_ZERO, + 0, 0x20000000, + OCTEON_FPA_POOL_ALIGNMENT, 0); + + if (memory == NULL) { + printf(" %% FPA pool %u could not be filled with %u bytes\n", + pool, bytes); + return; + } + + /* + * Forward Align allocated mem to needed alignment. Don't worry about growth, we + * already preallocated extra + */ +#ifdef FPA_DEBUG + printf(" %% Huge MemBlock 0x%X Bytes %u\n", memory, bytes); +#endif + + memory = (void *) OCTEON_ALIGN(memory); + +#ifdef FPA_DEBUG_TERSE + printf("FPA fill: %u Count: %u SizeBytes: %u SizeBytesAligned: %u 1st: 0x%X = 0x%X\n", + pool, elem_num, elem_size_bytes, block_size, memory, OCTEON_PTR2PHYS(memory)); +#endif + +// memory = (void *) ((((u_int) memory / OCTEON_FPA_POOL_ALIGNMENT) + 1) * OCTEON_FPA_POOL_ALIGNMENT); + + while (elem_num--) { +#ifdef FPA_DEBUG + if (((elems - elem_num) < 4) || (elem_num < 4)) + printf(" %% Block %d: 0x%X Phys 0x%X Bytes %u\n", block, memory, OCTEON_PTR2PHYS(memory), elem_size_bytes); + block++; +#endif + octeon_fpa_free(memory, pool, 0); + memory = (void *) (((u_long) memory) + block_size); + } +} + diff --git a/sys/dev/le/octeon_fpa.h b/sys/dev/le/octeon_fpa.h new file mode 100644 index 00000000000..04cd98bbd26 --- /dev/null +++ b/sys/dev/le/octeon_fpa.h @@ -0,0 +1,246 @@ +/*------------------------------------------------------------------ + * octeon_fpa.h Free Pool Allocator + * + *------------------------------------------------------------------ + */ + + +#ifndef ___OCTEON_FPA__H___ +#define ___OCTEON_FPA__H___ + + +#define OCTEON_FPA_FPA_OUTPUT_BUFFER_POOL 2 /* Same in octeon_rgmx.h */ + + +/* + * OCTEON_FPA_FPF_MARKS = FPA's Queue Free Page FIFO Read Write Marks + * + * The high and low watermark register that determines when we write and + * read free pages from L2C for Queue. + */ +typedef union { + uint64_t word64; + struct { + uint64_t reserved : 42; /* Must be zero */ + uint64_t fpf_wr : 11; /* Write Hi Water mark */ + uint64_t fpf_rd : 11; /* Read Lo Water mark */ + } bits; +} octeon_fpa_fpf_marks_t; + + +/* + * OCTEON_FPA_CTL_STATUS = FPA's Control/Status Register + * + * The FPA's interrupt enable register. + * - Use with the CVMX_FPA_CTL_STATUS CSR. + */ +typedef union { + uint64_t word64; + struct { + uint64_t reserved : 49; /* Must be zero */ + uint64_t enb : 1; /* Enable */ + uint64_t mem1_err : 7; /* ECC flip 1 */ + uint64_t mem0_err : 7; /* ECC flip 0 */ + } bits; +} octeon_fpa_ctl_status_t; + + +/* + * OCTEON_FPA_FPF_SIZE = FPA's Queue N Free Page FIFO Size + * + * The number of page pointers that will be kept local to the FPA for + * this Queue. FPA Queues are assigned in order from Queue 0 to + * Queue 7, though only Queue 0 through Queue x can be used. + * The sum of the 8 (0-7)OCTEON_FPA_FPF#_SIZE registers must be limited to 2048. + * - Use with the CVMX_FPA_FPF0_SIZE CSR. + */ +typedef union { + uint64_t word64; + struct { + uint64_t reserved : 52; /* Must be zero */ + /* + * The number of entries assigned in the FPA FIFO (used to hold + * page-pointers) for this Queue. + * The value of this register must divisable by 2, and the FPA will + * ignore bit [0] of this register. + * The total of the FPF_SIZ field of the 8 (0-7)OCTEON_FPA_FPF#_MARKS + * registers must not exceed 2048. + * After writing this field the FPA will need 10 core clock cycles + * to be ready for operation. The assignment of location in + * the FPA FIFO must start with Queue 0, then 1, 2, etc. + * The number of useable entries will be FPF_SIZ-2. + */ + uint64_t fpf_siz : 12; + } bits; +} octeon_fpa_fpf_size_t; + +/* + *OCTEON_FPA_INT_ENB = FPA's Interrupt Enable + * + * The FPA's interrupt enable register. + * - Use with the CVMX_FPA_INT_ENB CSR. + */ +typedef union { + uint64_t word64; + struct { + uint64_t reserved : 60; /* Must be zero */ + uint64_t fed1_dbe : 1; /* Int iff bit3 Int-Sum set */ + uint64_t fed1_sbe : 1; /* Int iff bit2 Int-Sum set */ + uint64_t fed0_dbe : 1; /* Int iff bit1 Int-Sum set */ + uint64_t fed0_sbe : 1; /* Int iff bit0 Int-Sum set */ + } bits; +} octeon_fpa_int_enb_t; + +/** + *OCTEON_FPA_INT_SUM = FPA's Interrupt Summary Register + * + * Contains the diffrent interrupt summary bits of the FPA. + * - Use with the CVMX_FPA_INT_SUM CSR. + */ +typedef union { + uint64_t word64; + struct { + uint64_t reserved : 60; /**< Must be zero */ + uint64_t fed1_dbe : 1; + uint64_t fed1_sbe : 1; + uint64_t fed0_dbe : 1; + uint64_t fed0_sbe : 1; + } bits; +} octeon_fpa_int_sum_t; + + +/* + *OCTEON_FPA_QUEUE_PAGES_AVAILABLE = FPA's Queue 0-7 Free Page Available Register + * + * The number of page pointers that are available in the FPA and local DRAM. + * - Use with the CVMX_FPA_QUEX_AVAILABLE(0..7) CSR. + */ +typedef union { + uint64_t word64; + struct { + uint64_t reserved : 38; /* Must be zero */ + uint64_t queue_size : 26; /* free pages available */ + } bits; +} octeon_fpa_queue_available_t; + + +/* + *OCTEON_FPA_QUEUE_PAGE_INDEX + * + */ +typedef union { + uint64_t word64; + struct { + uint64_t reserved : 39; /* Must be zero */ + uint64_t page_index : 25; /* page_index */ + } bits; +} octeon_fpa_queue_page_index_t; + + +#define OCTEON_DID_FPA 5ULL + +#define OCTEON_FPA_POOL_ALIGNMENT (OCTEON_CACHE_LINE_SIZE) + + +/* + * Externs + */ +extern void octeon_dump_fpa(void); +extern void octeon_dump_fpa_pool(u_int pool); +extern u_int octeon_fpa_pool_size(u_int pool); +extern void octeon_enable_fpa(void); +extern void octeon_fpa_fill_pool_mem(u_int pool, + u_int block_size_words, + u_int block_num); + +/* + * octeon_fpa_free + * + * Free a mem-block to FPA pool. + * + * Takes away this 'buffer' from SW and passes it to FPA for management. + * + * pool is FPA pool num, ptr is block ptr, num_cache_lines is number of + * cache lines to invalidate (not written back). + */ +static inline void octeon_fpa_free (void *ptr, u_int pool, + u_int num_cache_lines) +{ + octeon_addr_t free_ptr; + + free_ptr.word64 = (uint64_t) OCTEON_PTR2PHYS(ptr); + + free_ptr.sfilldidspace.didspace = OCTEON_ADDR_DIDSPACE( + OCTEON_ADDR_FULL_DID(OCTEON_DID_FPA, pool)); + + /* + * Do not 'sync' + * asm volatile ("sync\n"); + */ + oct_write64(free_ptr.word64, num_cache_lines); +} + + + +/* + * octeon_fpa_alloc + * + * Allocate a new block from the FPA + * + * Buffer passes away from FPA management to SW control + */ +static inline void *octeon_fpa_alloc (u_int pool) +{ + uint64_t address; + + address = oct_read64(OCTEON_ADDR_DID(OCTEON_ADDR_FULL_DID(OCTEON_DID_FPA, + pool))); + if (address) { + +/* + * 32 bit FPA pointers only + */ + + /* + * We only use 32 bit pointers at this time + */ + return ((void *) OCTEON_PHYS2PTR(address & 0xffffffff)); + } + return (NULL); +} + + +static inline uint64_t octeon_fpa_alloc_phys (u_int pool) +{ + + return (oct_read64(OCTEON_ADDR_DID(OCTEON_ADDR_FULL_DID(OCTEON_DID_FPA, + pool)))); +} + + +#if 0 + +/* + * octeon_fpa_alloc + * + * Allocate a new block from the FPA + * + * Buffer passes away from FPA management to SW control + */ +static inline void *octeon_fpa_alloc (u_int pool) +{ + uint64_t address; + + address = oct_read64(OCTEON_ADDR_DID(OCTEON_ADDR_FULL_DID(OCTEON_DID_FPA, + pool))); + if (address) { + return ((void *) (oct_ptr_size) OCTEON_PHYS2PTR(address)); + } + return (NULL); +} + +#endif + + + +#endif /* ___OCTEON_FPA__H___ */ diff --git a/sys/dev/le/octeon_ipd.c b/sys/dev/le/octeon_ipd.c new file mode 100644 index 00000000000..d70758d4de9 --- /dev/null +++ b/sys/dev/le/octeon_ipd.c @@ -0,0 +1,106 @@ +/*------------------------------------------------------------------ + * octeon_ipd.c Input Packet Unit + * + *------------------------------------------------------------------ + */ + +#include +#include + +#include "octeon_ipd.h" + +/* + * octeon_ipd_enable + * + * enable ipd + */ +void octeon_ipd_enable (void) +{ + octeon_ipd_ctl_status_t octeon_ipd_reg; + + octeon_ipd_reg.word64 = oct_read64(OCTEON_IPD_CTL_STATUS); + octeon_ipd_reg.bits.ipd_en = 1; + oct_write64(OCTEON_IPD_CTL_STATUS, octeon_ipd_reg.word64); +} + + +/* + * octeon_ipd_disable + * + * disable ipd + */ +void octeon_ipd_disable (void) +{ + octeon_ipd_ctl_status_t octeon_ipd_reg; + + octeon_ipd_reg.word64 = oct_read64(OCTEON_IPD_CTL_STATUS); + octeon_ipd_reg.bits.ipd_en = 0; + oct_write64(OCTEON_IPD_CTL_STATUS, octeon_ipd_reg.word64); +} + + +/* + * octeon_ipd_config + * + * Configure IPD + * + * mbuff_size Packets buffer size in 8 byte words + * first_mbuff_skip + * Number of 8 byte words to skip in the first buffer + * not_first_mbuff_skip + * Number of 8 byte words to skip in each following buffer + * first_back Must be same as first_mbuff_skip / Cache_Line_size + * second_back + * Must be same as not_first_mbuff_skip / Cache_Line_Size + * wqe_fpa_pool + * FPA pool to get work entries from + * cache_mode + * back_pres_enable_flag + * Enable or disable port back pressure + */ +void octeon_ipd_config (u_int mbuff_size, + u_int first_mbuff_skip, + u_int not_first_mbuff_skip, + u_int first_back, + u_int second_back, + u_int wqe_fpa_pool, + octeon_ipd_mode_t cache_mode, + u_int back_pres_enable_flag) +{ + octeon_ipd_mbuff_first_skip_t first_skip; + octeon_ipd_mbuff_not_first_skip_t not_first_skip; + octeon_ipd_mbuff_size_t size; + octeon_ipd_first_next_ptr_back_t first_back_struct; + octeon_ipd_second_next_ptr_back_t second_back_struct; + octeon_ipd_wqe_fpa_pool_t wqe_pool; + octeon_ipd_ctl_status_t octeon_ipd_ctl_reg; + + first_skip.word64 = 0; + first_skip.bits.skip_sz = first_mbuff_skip; + oct_write64(OCTEON_IPD_1ST_MBUFF_SKIP, first_skip.word64); + + not_first_skip.word64 = 0; + not_first_skip.bits.skip_sz = not_first_mbuff_skip; + oct_write64(OCTEON_IPD_NOT_1ST_MBUFF_SKIP, not_first_skip.word64); + + size.word64 = 0; + size.bits.mb_size = mbuff_size; + oct_write64(OCTEON_IPD_PACKET_MBUFF_SIZE, size.word64); + + first_back_struct.word64 = 0; + first_back_struct.bits.back = first_back; + oct_write64(OCTEON_IPD_1ST_NEXT_PTR_BACK, first_back_struct.word64); + + second_back_struct.word64 = 0; + second_back_struct.bits.back = second_back; + oct_write64(OCTEON_IPD_2ND_NEXT_PTR_BACK, second_back_struct.word64); + + wqe_pool.word64 = 0; + wqe_pool.bits.wqe_pool = wqe_fpa_pool; + oct_write64(OCTEON_IPD_WQE_FPA_QUEUE, wqe_pool.word64); + + octeon_ipd_ctl_reg.word64 = 0; + octeon_ipd_ctl_reg.bits.opc_mode = cache_mode; + octeon_ipd_ctl_reg.bits.pbp_en = back_pres_enable_flag; + oct_write64(OCTEON_IPD_CTL_STATUS, octeon_ipd_ctl_reg.word64); +} diff --git a/sys/dev/le/octeon_ipd.h b/sys/dev/le/octeon_ipd.h new file mode 100644 index 00000000000..21e26c83e9f --- /dev/null +++ b/sys/dev/le/octeon_ipd.h @@ -0,0 +1,164 @@ +/*------------------------------------------------------------------ + * octeon_ipd.h Input Packet Unit + * + *------------------------------------------------------------------ + */ + + +#ifndef ___OCTEON_IPD__H___ +#define ___OCTEON_IPD__H___ + + + +typedef enum { + OCTEON_IPD_OPC_MODE_STT = 0LL, /* All blocks DRAM, not cached in L2 */ + OCTEON_IPD_OPC_MODE_STF = 1LL, /* All blocks into L2 */ + OCTEON_IPD_OPC_MODE_STF1_STT = 2LL, /* 1st block L2, rest DRAM */ + OCTEON_IPD_OPC_MODE_STF2_STT = 3LL /* 1st, 2nd blocks L2, rest DRAM */ +} octeon_ipd_mode_t; + + + + +/* + * IPD_CTL_STATUS = IPS'd Control Status Register + * The number of words in a MBUFF used for packet data store. + */ +typedef union { + uint64_t word64; + struct { + uint64_t reserved : 58; /* Reserved */ + uint64_t pkt_lend : 1; /* Pkt Lil-Endian Writes to L2C */ + uint64_t wqe_lend : 1; /* WQE Lik-Endian Writes to L2C */ + uint64_t pbp_en : 1; /* Enable Back-Pressure */ + octeon_ipd_mode_t opc_mode : 2; /* Pkt data in Mem/L2-cache ? */ + uint64_t ipd_en : 1; /* Enable IPD */ + } bits; +} octeon_ipd_ctl_status_t; + + +/* + * IPD_1ST_NEXT_PTR_BACK = IPD First Next Pointer Back Values + * + * Contains the Back Field for use in creating the Next Pointer Header + * for the First MBUF + */ +typedef union { + uint64_t word64; + struct { + uint64_t reserved : 60; /* Must be zero */ + uint64_t back : 4; /* Used to find head of buffer from the nxt-hdr-ptr. */ + } bits; +} octeon_ipd_first_next_ptr_back_t; + + +/* + * IPD_INTERRUPT_ENB = IPD Interrupt Enable Register + * + * Used to enable the various interrupting conditions of IPD + */ +typedef union { + uint64_t word64; + struct { + uint64_t reserved : 59; /* Must be zero */ + uint64_t bp_sub : 1; /* BP subtract is illegal val */ + uint64_t prc_par3 : 1; /* PBM Bits [127:96] Parity Err */ + uint64_t prc_par2 : 1; /* PBM Bits [ 95:64] Parity Err */ + uint64_t prc_par1 : 1; /* PBM Bits [ 63:32] Parity Err */ + uint64_t prc_par0 : 1; /* PBM Bits [ 31:0 ] Parity Err */ + } bits; +} octeon_ipd_int_enb_t; + + +/* + * IPD_INTERRUPT_SUM = IPD Interrupt Summary Register + * + * Set when an interrupt condition occurs, write '1' to clear. + */ +typedef union { + uint64_t word64; + struct { + uint64_t reserved : 59; /* Must be zero */ + uint64_t bp_sub : 1; /* BP subtract is illegal val */ + uint64_t prc_par3 : 1; /* PBM Bits [127:96] Parity Err */ + uint64_t prc_par2 : 1; /* PBM Bits [ 95:64] Parity Err */ + uint64_t prc_par1 : 1; /* PBM Bits [ 63:32] Parity Err */ + uint64_t prc_par0 : 1; /* PBM Bits [ 31:0 ] Parity Err */ + } bits; +} octeon_ipd_int_sum_t; + + +/** + * IPD_1ST_MBUFF_SKIP = IPD First MBUFF Word Skip Size + * + * The number of words that the IPD will skip when writing the first MBUFF. + */ +typedef union { + uint64_t word64; + struct { + uint64_t reserved : 58; /* Must be zero */ + uint64_t skip_sz : 6; /* 64bit words from the top of */ + /* 1st MBUFF that the IPD will */ + /* store the next-pointer. */ + /* [0..32] && */ + /* (skip_sz + 16) <= IPD_PACKET_MBUFF_SIZE[MB_SIZE]. */ + } bits; +} octeon_ipd_mbuff_first_skip_t; + + +/* + * IPD_PACKET_MBUFF_SIZE = IPD's PACKET MUBUF Size In Words + * + * The number of words in a MBUFF used for packet data store. + */ +typedef union { + uint64_t word64; + struct { + uint64_t reserved : 52; /* Must be zero */ + uint64_t mb_size : 12; /* 64bit words in a MBUF. */ + /* Must be [32..2048] */ + /* Is also the size of the FPA's */ + /* Queue-0 Free-Page */ + } bits; +} octeon_ipd_mbuff_size_t; + + +/* + * IPD_WQE_FPA_QUEUE = IPD Work-Queue-Entry FPA Page Size + * + * Which FPA Queue (0-7) to fetch page-pointers from for WQE's + */ +typedef union { + uint64_t word64; + struct { + uint64_t reserved : 61; /* Must be zero */ + uint64_t wqe_pool : 3; /* FPA Pool to fetch WQE Page-ptrs */ + } bits; +} octeon_ipd_wqe_fpa_pool_t; + + + + +/* End of Control and Status Register (CSR) definitions */ + +typedef octeon_ipd_mbuff_first_skip_t octeon_ipd_mbuff_not_first_skip_t; +typedef octeon_ipd_first_next_ptr_back_t octeon_ipd_second_next_ptr_back_t; + + +/* + * Externs + */ +extern void octeon_ipd_enable(void); +extern void octeon_ipd_disable(void); +extern void octeon_ipd_config(u_int mbuff_size, + u_int first_mbuff_skip, + u_int not_first_mbuff_skip, + u_int first_back, + u_int second_back, + u_int wqe_fpa_pool, + octeon_ipd_mode_t cache_mode, + u_int back_pres_enable_flag); + + + +#endif /* ___OCTEON_IPD__H___ */ diff --git a/sys/dev/le/octeon_pip.h b/sys/dev/le/octeon_pip.h new file mode 100644 index 00000000000..f474e5e80b6 --- /dev/null +++ b/sys/dev/le/octeon_pip.h @@ -0,0 +1,179 @@ +/* + * octeon_pip.h Packet Input Processing Block + * + */ + + + +#ifndef __OCTEON_PIP_H__ +#define __OCTEON_PIP_H__ + +/** + * Enumeration representing the amount of packet processing + * and validation performed by the input hardware. + */ +typedef enum +{ + OCTEON_PIP_PORT_CFG_MODE_NONE = 0ull, /**< Packet input doesn't perform any + processing of the input packet. */ + OCTEON_PIP_PORT_CFG_MODE_SKIPL2 = 1ull,/**< Full packet processing is performed + with pointer starting at the L2 + (ethernet MAC) header. */ + OCTEON_PIP_PORT_CFG_MODE_SKIPIP = 2ull /**< Input packets are assumed to be IP. + Results from non IP packets is + undefined. Pointers reference the + beginning of the IP header. */ +} octeon_pip_port_parse_mode_t; + + + +#define OCTEON_PIP_PRT_CFGX(offset) (0x80011800A0000200ull+((offset)*8)) +#define OCTEON_PIP_PRT_TAGX(offset) (0x80011800A0000400ull+((offset)*8)) +#define OCTEON_PIP_STAT_INB_PKTS(port) (0x80011800A0001A00ull+((port) * 32)) +#define OCTEON_PIP_STAT_INB_ERRS(port) (0x80011800A0001A10ull+((port) * 32)) + +/* + * PIP Global Config + */ +typedef union { + uint64_t word64; + struct { + uint64_t reserved2 : 45; /* Must be zero */ + uint64_t tag_syn : 1; /* Not Include src_crc in TCP..*/ + uint64_t ip6_udp : 1; /* IPv6/UDP checksum is mandatory */ + uint64_t max_l2 : 1; /* Largest L2 frame. 0/1 : 1500/1535 */ + uint64_t reserved1 : 5; /* Must be zero */ + uint64_t raw_shf : 3; /* PCI RAW Packet shift/pad amount */ + uint64_t reserved0 : 5; /* Must be zero */ + uint64_t nip_shf : 3; /* Non-IP shift/pad amount */ + } bits; +} octeon_pip_gbl_cfg_t; + + +typedef union { + uint64_t word64; + struct { + uint64_t reserved4 : 37; /* Must be zero */ + uint64_t qos : 3; /* Default POW QoS queue */ + uint64_t qos_wat : 4; /* Bitfield to enable QoS watcher */ + /* look up tables. 4 per port. */ + uint64_t reserved3 : 1; /* Must be zero */ + uint64_t spare : 1; /* Must be zero */ + uint64_t qos_diff : 1; /* Use IP diffserv to determine */ + /* the queue in the POW */ + uint64_t qos_vlan : 1; /* Use the VLAN tag to determine */ + /* the queue in the POW */ + uint64_t reserved2 : 3; /* Must be zero */ + uint64_t crc_en : 1; /* Enable HW checksum */ + uint64_t reserved1 : 2; /* Must be zero */ + octeon_pip_port_parse_mode_t mode : 2; /* Raw/Parsed/IP/etc */ + uint64_t reserved0 : 1; /* Must be zero */ + uint64_t skip : 7; /* 8 byte words to skip in the */ + /* beginning of a packet buffer */ + } bits; +} octeon_pip_port_cfg_t; + + + +/* + * Packet input to POW interface. How input packets are tagged for + * the POW is controlled here. + */ +typedef union { + uint64_t word64; + struct { + uint64_t reserved : 24; /**< Reserved */ + uint64_t grptagbase : 4; /**< Offset to use when computing group from tag bits + when GRPTAG is set. Only applies to IP packets. + (PASS2 only) */ + uint64_t grptagmask : 4; /**< Which bits of the tag to exclude when computing + group when GRPTAG is set. Only applies to IP packets. + (PASS2 only) */ + uint64_t grptag : 1; /**< When set, use the lower bit of the tag to compute + the group in the work queue entry + GRP = WQE[TAG[3:0]] & ~GRPTAGMASK + GRPTAGBASE. + Only applies to IP packets. (PASS2 only) */ + uint64_t spare : 1; /**< Spare bit + (PASS2 only) */ + uint64_t tag_mode : 2; /**< Which tag algorithm to use + 0 = always use tuple tag algorithm + 1 = always use mask tag algorithm + 2 = if packet is IP, use tuple else use mask + 3 = tuple XOR mask + (PASS2 only) */ + uint64_t inc_vs : 2; /**< determines the VLAN ID (VID) to be included in + tuple tag when VLAN stacking is detected + 0 = do not include VID in tuple tag generation + 1 = include VID (VLAN0) in hash + 2 = include VID (VLAN1) in hash + 3 = include VID ([VLAN0,VLAN1]) in hash + (PASS2 only) */ + uint64_t inc_vlan : 1; /**< when set, the VLAN ID is included in tuple tag + when VLAN stacking is not detected + 0 = do not include VID in tuple tag generation + 1 = include VID in hash + (PASS2 only) */ + uint64_t inc_prt_flag : 1; /**< sets whether the port is included in tuple tag */ + uint64_t ip6_dprt_flag : 1; /**< sets whether the TCP/UDP dst port is + included in tuple tag for IPv6 packets */ + uint64_t ip4_dprt_flag : 1; /**< sets whether the TCP/UDP dst port is + included in tuple tag for IPv4 */ + uint64_t ip6_sprt_flag : 1; /**< sets whether the TCP/UDP src port is + included in tuple tag for IPv6 packets */ + uint64_t ip4_sprt_flag : 1; /**< sets whether the TCP/UDP src port is + included in tuple tag for IPv4 */ + uint64_t ip6_nxth_flag : 1; /**< sets whether ipv6 includes next header in tuple + tag hash */ + uint64_t ip4_pctl_flag : 1; /**< sets whether ipv4 includes protocol in tuple + tag hash */ + uint64_t ip6_dst_flag : 1; /**< sets whether ipv6 includes dst address in tuple + tag hash */ + uint64_t ip4_dst_flag : 1; /**< sets whether ipv4 includes dst address in tuple + tag hash */ + uint64_t ip6_src_flag : 1; /**< sets whether ipv6 includes src address in tuple + tag hash */ + uint64_t ip4_src_flag : 1; /**< sets whether ipv4 includes src address in tuple + tag hash */ + uint64_t tcp6_tag_type : 2; /**< sets the tag_type of a TCP packet (IPv6) + 0 = ordered tags + 1 = atomic tags + 2 = Null tags */ + uint64_t tcp4_tag_type : 2; /**< sets the tag_type of a TCP packet (IPv4) + 0 = ordered tags + 1 = atomic tags + 2 = Null tags */ + uint64_t ip6_tag_type : 2; /**< sets whether IPv6 packet tag type + 0 = ordered tags + 1 = atomic tags + 2 = Null tags */ + uint64_t ip4_tag_type : 2; /**< sets whether IPv4 packet tag type + 0 = ordered tags + 1 = atomic tags + 2 = Null tags */ + uint64_t non_tag_type : 2; /**< sets whether non-IP packet tag type + 0 = ordered tags + 1 = atomic tags + 2 = Null tags */ + uint64_t grp : 4; /* POW group for input pkts */ + } bits; +} octeon_pip_port_tag_cfg_t; + + +/** + * Configure an ethernet input port + * + * @param port_num Port number to configure + * @param port_cfg Port hardware configuration + * @param port_tag_cfg + * Port POW tagging configuration + */ +static inline void octeon_pip_config_port(u_int port_num, + octeon_pip_port_cfg_t port_cfg, + octeon_pip_port_tag_cfg_t port_tag_cfg) +{ + oct_write64(OCTEON_PIP_PRT_CFGX(port_num), port_cfg.word64); + oct_write64(OCTEON_PIP_PRT_TAGX(port_num), port_tag_cfg.word64); +} + + +#endif /* __OCTEON_PIP_H__ */ diff --git a/sys/dev/le/octeon_pko.c b/sys/dev/le/octeon_pko.c new file mode 100644 index 00000000000..7d402c25da0 --- /dev/null +++ b/sys/dev/le/octeon_pko.c @@ -0,0 +1,335 @@ +/*------------------------------------------------------------------ + * octeon_pko.c Packet Output Unit + * + *------------------------------------------------------------------ + */ + +#include +#include +#include +#include + +#include "octeon_fau.h" +#include "octeon_fpa.h" +#include "octeon_pko.h" + + +/* + * + */ +static void octeon_pko_clear_port_counts (u_int port) +{ + u_int port_num; + octeon_pko_read_idx_t octeon_pko_idx; + + octeon_pko_idx.word64 = 0; + octeon_pko_idx.bits.idx = port; + octeon_pko_idx.bits.inc = 0; + oct_write64(OCTEON_PKO_REG_READ_IDX, octeon_pko_idx.word64); + + port_num = port; + oct_write64(OCTEON_PKO_MEM_COUNT0, port_num); + port_num = port; + oct_write64(OCTEON_PKO_MEM_COUNT1, port_num); +} + +/* + * octeon_pko_init + * + */ +void octeon_pko_init (void) +{ + u_int queue, port; + octeon_pko_read_idx_t octeon_pko_idx; + octeon_pko_queue_cfg_t octeon_pko_queue_cfg; + + for (port = 0; port < OCTEON_PKO_PORTS_MAX; port++) { + octeon_pko_clear_port_counts(port); + } + + octeon_pko_idx.word64 = 0; + octeon_pko_idx.bits.idx = 0; + octeon_pko_idx.bits.inc = 1; + oct_write64(OCTEON_PKO_REG_READ_IDX, octeon_pko_idx.word64); + for (queue = 0; queue < OCTEON_PKO_QUEUES_MAX; queue++) { + + octeon_pko_queue_cfg.word64 = 0; + octeon_pko_queue_cfg.bits.queue = queue; + octeon_pko_queue_cfg.bits.port = OCTEON_PKO_PORT_ILLEGAL; + octeon_pko_queue_cfg.bits.buf_ptr = 0; + oct_write64(OCTEON_PKO_MEM_QUEUE_PTRS, octeon_pko_queue_cfg.word64); + } +} + + +/* + * octeon_pko_enable + * + * enable pko + */ +void octeon_pko_enable (void) +{ + + /* + * PKO enable + */ + oct_write64(OCTEON_PKO_REG_FLAGS, 3); /* octeon_pko_enable() */ +} + + +/* + * octeon_pko_disable + * + * disable pko + */ +void octeon_pko_disable (void) +{ + + /* + * PKO disable + */ + oct_write64(OCTEON_PKO_REG_FLAGS, 0); /* pko_disable() */ +} + +/* + * octeon_pko_config_cmdbuf_global_defaults + * + */ +void octeon_pko_config_cmdbuf_global_defaults (u_int cmdbuf_pool, + u_int cmdbuf_pool_elem_size ) +{ + octeon_pko_pool_cfg_t octeon_pko_pool_config; + + octeon_pko_pool_config.word64 = 0; + octeon_pko_pool_config.bits.pool = cmdbuf_pool; + octeon_pko_pool_config.bits.size = cmdbuf_pool_elem_size; + oct_write64(OCTEON_PKO_CMD_BUF, octeon_pko_pool_config.word64); +} + +/* + * octeon_pko_config_rgmx_ports + * + * Configure rgmx pko. Always enables 4 + 4 ports + */ +void octeon_pko_config_rgmx_ports (void) +{ + octeon_pko_reg_gmx_port_mode_t octeon_pko_gmx_mode; + + octeon_pko_gmx_mode.word64 = 0; + octeon_pko_gmx_mode.bits.mode0 = 2; /* 16 >> 2 == 4 ports */ + octeon_pko_gmx_mode.bits.mode1 = 2; /* 16 >> 2 == 4 ports */ + oct_write64(OCTEON_PKO_GMX_PORT_MODE, octeon_pko_gmx_mode.word64); +} + + +/* + * octeon_pko_config + * + * Configure PKO + * + */ +void octeon_pko_config (void) +{ +} + +/* + * octeon_pko_get_port_status + * + * Get the status counters for a PKO port. + * + * port_num Port number to get statistics for. + * clear Set to 1 to clear the counters after they are read + * status Where to put the results. + */ +void octeon_pko_get_port_status (u_int port, u_int clear, + octeon_pko_port_status_t *status) +{ + octeon_word_t packet_num; + octeon_pko_read_idx_t octeon_pko_idx; + + packet_num.word64 = 0; + + octeon_pko_idx.word64 = 0; + octeon_pko_idx.bits.idx = port; + octeon_pko_idx.bits.inc = 0; + oct_write64(OCTEON_PKO_REG_READ_IDX, octeon_pko_idx.word64); + + packet_num.word64 = oct_read64(OCTEON_PKO_MEM_COUNT0); + status->packets = packet_num.bits.word32lo; + + status->octets = oct_read64(OCTEON_PKO_MEM_COUNT1); + status->doorbell = oct_read64(OCTEON_PKO_MEM_DEBUG9); + status->doorbell = (status->doorbell >> 8) & 0xfffff; + if (clear) { + octeon_pko_clear_port_counts(port); + } +} + +static void octeon_pko_doorbell_data_dump(uint64_t port); + +static void octeon_pko_doorbell_data_dump (uint64_t port) +{ + octeon_pko_port_status_t status; + + octeon_pko_get_port_status(port, 0, &status); + printf("\n Port #%d Pkts %d Bytes %lld DoorBell %lld", + port, status.packets, status.octets, status.doorbell); +} + +/* + * octeon_pko_show + * + * Show the OCTEON_PKO status & configs + */ +void octeon_pko_show (u_int start_port, u_int end_port) +{ + u_int queue, queue_max, gmx_int0_ports, gmx_int1_ports; + u_int port; + uint64_t val64; + octeon_pko_port_status_t status; + octeon_pko_pool_cfg_t octeon_pko_pool_config; + octeon_pko_read_idx_t octeon_pko_idx; + octeon_pko_queue_mode_t octeon_pko_queue_mode; + octeon_pko_reg_gmx_port_mode_t octeon_pko_gmx_mode; + octeon_pko_crc_ports_enable_t octeon_pko_crc_ports; + octeon_pko_queue_cfg_t octeon_pko_queue_cfg; + + printf("\n\nPKO Status:"); + val64 = oct_read64(OCTEON_PKO_REG_FLAGS); + if ((val64 & 0x3) != 0x3) { + printf(" Disabled"); + return; + } else { + printf(" Enabled"); + } + octeon_pko_queue_mode.word64 = oct_read64(OCTEON_PKO_QUEUE_MODE); + queue_max = (128 >> octeon_pko_queue_mode.bits.mode); + octeon_pko_gmx_mode.word64 = oct_read64(OCTEON_PKO_GMX_PORT_MODE); + gmx_int0_ports = (16 >> octeon_pko_gmx_mode.bits.mode0); + gmx_int1_ports = (16 >> octeon_pko_gmx_mode.bits.mode1); + octeon_pko_crc_ports.word64 = oct_read64(OCTEON_PKO_REG_CRC_ENABLE); + printf("\n Total Queues: 0..%d Ports GMX0 %d GMX1 %d CRC 0x%llX", + queue_max - 1, gmx_int0_ports, gmx_int1_ports, + octeon_pko_crc_ports.bits.crc_ports_mask); + + octeon_pko_pool_config.word64 = oct_read64(OCTEON_PKO_CMD_BUF); + printf("\n CmdBuf Pool: %d CmdBuf Size in Words: %d Bytes: %d", + octeon_pko_pool_config.bits.pool, octeon_pko_pool_config.bits.size, + octeon_pko_pool_config.bits.size * 8); + + octeon_pko_idx.word64 = 0; + octeon_pko_idx.bits.idx = 0; + octeon_pko_idx.bits.inc = 1; + oct_write64(OCTEON_PKO_REG_READ_IDX, octeon_pko_idx.word64); + for (queue = 0; queue < queue_max; queue++) { + + octeon_pko_queue_cfg.word64 = oct_read64(OCTEON_PKO_MEM_QUEUE_PTRS); + if (!octeon_pko_queue_cfg.bits.buf_ptr) continue; + printf("\n Port # %d Queue %3d [%d] BufPtr: 0x%llX Mask: %X%s", + octeon_pko_queue_cfg.bits.port, octeon_pko_queue_cfg.bits.queue, + octeon_pko_queue_cfg.bits.index, + octeon_pko_queue_cfg.bits.buf_ptr, octeon_pko_queue_cfg.bits.qos_mask, + (octeon_pko_queue_cfg.bits.tail)? " Last":""); + } + printf("\n"); + + for (port = start_port; port < (end_port + 1); port++) { + + octeon_pko_get_port_status(port, 0, &status); + printf("\n Port #%d Packets %d Bytes %lld DoorBell %lld", + port, status.packets, status.octets, status.doorbell); + octeon_pko_doorbell_data_dump(port); + + } +} + + + + +/* + * octeon_pko_config_port + * + * Configure a output port and the associated queues for use. + * + */ +octeon_pko_status_t octeon_pko_config_port (u_int port, + u_int base_queue, + u_int num_queues, + const u_int priority[], + u_int pko_output_cmdbuf_fpa_pool, + octeon_pko_sw_queue_info_t sw_queues[]) +{ + octeon_pko_status_t result_code; + u_int queue; + octeon_pko_queue_cfg_t qconfig; + + if ((port >= OCTEON_PKO_PORTS_MAX) && (port != OCTEON_PKO_PORT_ILLEGAL)) { + printf("\n%% Error: octeon_pko_config_port: Invalid port %llu", port); + return (OCTEON_PKO_INVALID_PORT); + } + + if ((base_queue + num_queues) > OCTEON_PKO_QUEUES_MAX) { + printf("\n%% Error: octeon_pko_config_port: Invalid queue range"); + return (OCTEON_PKO_INVALID_QUEUE); + } + + result_code = OCTEON_PKO_SUCCESS; + + for (queue = 0; queue < num_queues; queue++) { + uint64_t buf_ptr = 0; + + qconfig.word64 = 0; + qconfig.bits.tail = (queue == (num_queues - 1)) ? 1 : 0; + qconfig.bits.index = queue; + qconfig.bits.port = port; + qconfig.bits.queue = base_queue + queue; + + /* Convert the priority into an enable bit field. */ + /* Try to space the bits out evenly so the pkts don't get grouped up */ + switch ((int)priority[queue]) { + case 0: qconfig.bits.qos_mask = 0x00; break; + case 1: qconfig.bits.qos_mask = 0x01; break; + case 2: qconfig.bits.qos_mask = 0x11; break; + case 3: qconfig.bits.qos_mask = 0x49; break; + case 4: qconfig.bits.qos_mask = 0x55; break; + case 5: qconfig.bits.qos_mask = 0x57; break; + case 6: qconfig.bits.qos_mask = 0x77; break; + case 7: qconfig.bits.qos_mask = 0x7f; break; + case 8: qconfig.bits.qos_mask = 0xff; break; + default: + printf("\n%% Error: octeon_pko_config_port Invalid priority %llu", + (unsigned long long)priority[queue]); + qconfig.bits.qos_mask = 0xff; + result_code = OCTEON_PKO_INVALID_PRIORITY; + break; + } + if (port != OCTEON_PKO_PORT_ILLEGAL) { + + buf_ptr = octeon_fpa_alloc_phys(pko_output_cmdbuf_fpa_pool); + if (!buf_ptr) { + printf("\n%% Error: octeon_pko_config_port: Unable to allocate"); + return (OCTEON_PKO_NO_MEMORY); + } + + sw_queues[queue].xmit_command_state = (buf_ptr << OCTEON_PKO_INDEX_BITS); + octeon_spinlock_init(&(sw_queues[queue].lock)); + +//#define DEBUG_TX + +#ifdef DEBUG_TX + printf(" PKO: port %u pool: %u base+queue %u %u %u buf_ptr: 0x%llX\n", + port, + pko_output_cmdbuf_fpa_pool, + base_queue, queue, base_queue+queue, + buf_ptr); + +#endif + qconfig.bits.buf_ptr = buf_ptr; + oct_write64(OCTEON_PKO_MEM_QUEUE_PTRS, qconfig.word64); + + } + } + + return (result_code); +} + diff --git a/sys/dev/le/octeon_pko.h b/sys/dev/le/octeon_pko.h new file mode 100644 index 00000000000..4ecc3b9618d --- /dev/null +++ b/sys/dev/le/octeon_pko.h @@ -0,0 +1,292 @@ +/*------------------------------------------------------------------ + * octeon_pko.h Packet Output Block + * + *------------------------------------------------------------------ + */ + + +#ifndef ___OCTEON_PKO__H___ +#define ___OCTEON_PKO__H___ + + + +/* + * PKO Command Buffer Register. + * Specify Pool-# and Size of each entry in Pool. For Output Cmd Buffers. + */ +typedef union { + uint64_t word64; + struct { + uint64_t unused_mbz : 41; /* Must be zero */ + uint64_t pool : 3; /* FPA Pool to use */ + uint64_t unused_mbz2 : 7; /* Must be zero */ + uint64_t size : 13; /* Size of the pool blocks */ + } bits; +} octeon_pko_pool_cfg_t; + + +/* + * PKO GMX Mode Register + * Specify the # of GMX1 ports and GMX0 ports + */ +typedef union { + uint64_t word64; + struct { + uint64_t unused_mbz : 58; /* MBZ */ + uint64_t mode1 : 3; /* # GMX1 ports; */ + /* 16 >> MODE1, 0 <= MODE1 <=4 */ + uint64_t mode0 : 3; /* # GMX0 ports; */ + /* 16 >> MODE0, 0 <= MODE0 <=4 */ + } bits; +} octeon_pko_reg_gmx_port_mode_t; + + +typedef union { + uint64_t word64; + struct { + uint64_t unused_mbz : 62; /* MBZ */ + uint64_t mode : 2; /* Queues Mode */ + } bits; +} octeon_pko_queue_mode_t; + + +typedef union { + uint64_t word64; + struct { + uint64_t unused_mbz : 32; /* MBZ */ + uint64_t crc_ports_mask : 32; /* CRC Ports Enable mask */ + } bits; +} octeon_pko_crc_ports_enable_t; + + + +#define OCTEON_PKO_QUEUES_MAX 128 +#define OCTEON_PKO_PORTS_MAX 36 +#define OCTEON_PKO_PORT_ILLEGAL 63 + +/* Defines how the PKO command buffer FAU register is used */ + +#define OCTEON_PKO_INDEX_BITS 12 +#define OCTEON_PKO_INDEX_MASK ((1ull << OCTEON_PKO_INDEX_BITS) - 1) + + + +typedef enum { + OCTEON_PKO_SUCCESS, + OCTEON_PKO_INVALID_PORT, + OCTEON_PKO_INVALID_QUEUE, + OCTEON_PKO_INVALID_PRIORITY, + OCTEON_PKO_NO_MEMORY +} octeon_pko_status_t; + + +typedef struct { + long packets; + uint64_t octets; + uint64_t doorbell; +} octeon_pko_port_status_t; + + +typedef union { + uint64_t word64; + struct { + octeon_mips_space_t mem_space : 2; /* Octeon IO_SEG */ + uint64_t unused_mbz :13; /* Must be zero */ + uint64_t is_io : 1; /* Must be one */ + uint64_t did : 8; /* device-ID on non-coherent bus*/ + uint64_t unused_mbz2 : 4; /* Must be zero */ + uint64_t unused_mbz3 :18; /* Must be zero */ + uint64_t port : 6; /* output port */ + uint64_t queue : 9; /* output queue to send */ + uint64_t unused_mbz4 : 3; /* Must be zero */ + } bits; +} octeon_pko_doorbell_address_t; + +/* + * Structure of the first packet output command word. + */ +typedef union { + uint64_t word64; + struct { + octeon_fau_op_size_t size1 : 2; /* The size of reg1 operation */ + /* - could be 8, 16, 32, or 64 bits */ + octeon_fau_op_size_t size0 : 2; /* The size of the reg0 operation */ + /* - could be 8, 16, 32, or 64 bits */ + uint64_t subone1 : 1; /* Subtract 1, else sub pkt size */ + uint64_t reg1 :11; /* The register, subtract will be */ + /* done if reg1 is non-zero */ + uint64_t subone0 : 1; /* Subtract 1, else sub pkt size */ + uint64_t reg0 :11; /* The register, subtract will be */ + /* done if reg0 is non-zero */ + uint64_t unused : 2; /* Must be zero */ + uint64_t wqp : 1; /* If rsp, then word3 contains a */ + /* ptr to a work queue entry */ + uint64_t rsp : 1; /* HW will respond when done */ + uint64_t gather : 1; /* If set, the supplied pkt_ptr is */ + /* a ptr to a list of pkt_ptr's */ + uint64_t ipoffp1 : 7; /* Off to IP hdr. For HW checksum */ + uint64_t ignore_i : 1; /* Ignore I bit in all pointers */ + uint64_t dontfree : 1; /* Don't free buffs containing pkt */ + uint64_t segs : 6; /* Number of segs. If gather set, */ + /* also gather list length */ + uint64_t total_bytes :16; /* Includes L2, w/o trailing CRC */ + } bits; +} octeon_pko_command_word0_t; + + +typedef union { + void* ptr; + uint64_t word64; + struct { + uint64_t i : 1; /* Invert the "free" pick of the overall pkt. */ + /* For inbound pkts, HW always sets this to 0 */ + uint64_t back : 4; /* Amount to back up to get to buffer start */ + /* in cache lines. This is mostly less than 1 */ + /* complete cache line; so the value is zero */ + uint64_t pool : 3; /* FPA pool that the buffer belongs to */ + uint64_t size :16; /* segment size (bytes) pointed at by addr */ + uint64_t addr :40; /* Ptr to 1st data byte. NOT buffer */ + } bits; +} octeon_pko_packet_ptr_t; + + +/* + * Definition of the hardware structure used to configure an + * output queue. + */ +typedef union { + uint64_t word64; + struct { + uint64_t unused_mbz : 3; /* Must be zero */ + uint64_t qos_mask : 8; /* Control Mask priority */ + /* across 8 QOS levels */ + uint64_t buf_ptr : 36; /* Command buffer pointer, */ + /* 8 byte-aligned */ + uint64_t tail : 1; /* Set if this queue is the tail */ + /* of the port queue array */ + uint64_t index : 3; /* Index (distance from head) in */ + /* the port queue array */ + uint64_t port : 6; /* Port ID for this queue mapping */ + uint64_t queue : 7; /* Hardware queue number */ + } bits; +} octeon_pko_queue_cfg_t; + + +typedef union { + uint64_t word64; + struct { + uint64_t unused_mbz : 48; + uint64_t inc : 8; + uint64_t idx : 8; + } bits; +} octeon_pko_read_idx_t; + + +typedef struct octeon_pko_sw_queue_info_t_ +{ + uint64_t xmit_command_state; + octeon_spinlock_t lock; + uint32_t pad[29]; +} octeon_pko_sw_queue_info_t; + + + +#define OCTEON_DID_PKT 10ULL +#define OCTEON_DID_PKT_SEND OCTEON_ADDR_FULL_DID(OCTEON_DID_PKT,2ULL) + + +/* + * Ring the packet output doorbell. This tells the packet + * output hardware that "len" command words have been added + * to its pending list. This command includes the required + * SYNCW before the doorbell ring. + * + * @param port Port the packet is for + * @param queue Queue the packet is for + * @param len Length of the command in 64 bit words + */ +extern void octeon_pko_doorbell_data(u_int port); + +//#define CORE_0_ONLY 1 + +static inline void octeon_pko_ring_doorbell (u_int port, u_int queue, + u_int len) +{ + octeon_pko_doorbell_address_t ptr; + + ptr.word64 = 0; + ptr.bits.mem_space = OCTEON_IO_SEG; + ptr.bits.did = OCTEON_DID_PKT_SEND; + ptr.bits.is_io = 1; + ptr.bits.port = port; + ptr.bits.queue = queue; + OCTEON_SYNCWS; + oct_write64(ptr.word64, len); +} + + + +#define OCTEON_PKO_QUEUES_PER_PORT_INTERFACE0 1 +#define OCTEON_PKO_QUEUES_PER_PORT_INTERFACE1 1 +#define OCTEON_PKO_QUEUES_PER_PORT_PCI 1 + +/* + * octeon_pko_get_base_queue + * + * For a given port number, return the base pko output queue + * for the port. + */ +static inline u_int octeon_pko_get_base_queue (u_int port) +{ + if (port < 16) { + return (port * OCTEON_PKO_QUEUES_PER_PORT_INTERFACE0); + } + if (port < 32) { + return (16 * OCTEON_PKO_QUEUES_PER_PORT_INTERFACE0 + + (port - 16) * OCTEON_PKO_QUEUES_PER_PORT_INTERFACE1); + } + return (16 * OCTEON_PKO_QUEUES_PER_PORT_INTERFACE0 + + 16 * OCTEON_PKO_QUEUES_PER_PORT_INTERFACE1 + + (port - 32) * OCTEON_PKO_QUEUES_PER_PORT_PCI); +} + + +/* + * For a given port number, return the number of pko output queues. + * + * @param port Port number + * @return Number of output queues + */ +static inline u_int octeon_pko_get_num_queues(u_int port) +{ + if (port < 16) { + return (OCTEON_PKO_QUEUES_PER_PORT_INTERFACE0); + } else if (port<32) { + return (OCTEON_PKO_QUEUES_PER_PORT_INTERFACE1); + } + + return (OCTEON_PKO_QUEUES_PER_PORT_PCI); +} + + + +/* + * Externs + */ +extern void octeon_pko_init(void); +extern void octeon_pko_enable(void); +extern void octeon_pko_disable(void); +extern void octeon_pko_show(u_int start_port, u_int end_port); +extern void octeon_pko_config(void); +extern void octeon_pko_config_cmdbuf_global_defaults(u_int cmdbuf_pool, u_int elem_size); +extern void octeon_pko_config_rgmx_ports(void); +extern void octeon_pko_get_port_status(u_int, u_int, octeon_pko_port_status_t *status); +extern octeon_pko_status_t octeon_pko_config_port(u_int port, + u_int base_queue, + u_int num_queues, + const u_int priority[], + u_int pko_output_cmdbuf_fpa_pool, + octeon_pko_sw_queue_info_t sw_queues[]); + + +#endif /* ___OCTEON_PKO__H___ */ diff --git a/sys/dev/le/octeon_rgmx.c b/sys/dev/le/octeon_rgmx.c new file mode 100644 index 00000000000..29856d5c7ee --- /dev/null +++ b/sys/dev/le/octeon_rgmx.c @@ -0,0 +1,2215 @@ +/* + * octeon_rgmx.c RGMII Ethernet Interfaces on Octeon + * + */ + + +/* + * Driver for the Reduced Gigabit Media Independent Interface (RGMII) + * present on the Cavium Networks' Octeon chip. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include "octeon_fau.h" +#include "octeon_fpa.h" +#include "octeon_ipd.h" +#include "octeon_pko.h" +#include "octeon_pip.h" +#include "octeon_rgmx.h" + + +#define OCTEON_RGMX_NUM_PORTS_MAX 4 +#define NUM_TX_PACKETS 80 +#define NUM_RX_PACKETS 300 +#define MAX_RX_BUFS (NUM_RX_PACKETS) * (OCTEON_RGMX_NUM_PORTS_MAX) +#define MAX_TX_BUFS (NUM_TX_PACKETS) +#define OCTEON_RGMX_DEV_NAME "rgmx" +#define OCTEON_RGMX_MIN_PORT 0 +#define OCTEON_RGMX_MAX_PORT 19 +#define OCTEON_RGMX_OQUEUE_PER_PORT 8 + + +#define OCTEON_RGMX_SCHEDULED_ISRS 1 /* Use Scheduled ISRs from kernel tasks */ + + +#ifndef POW_MAX_LOOP +#define POW_MAX_LOOP 0x800 +#endif + + +/* + * CIU related stuff for enabling POW interrupts + */ +#define OCTEON_RGMX_CIU_INTX CIU_INT_0 +#define OCTEON_RGMX_CIU_ENX CIU_EN_0 + +MALLOC_DEFINE(M_RGMII_WQE, "rgmii_wqe", "FPA pool for WQEs"); + +/* Driver data */ + +struct rgmx_softc_dev { + device_t sc_dev; /* Device ID */ + uint64_t link_status; + struct ifnet *ifp; + int sc_unit; + + u_int port; + u_int idx; + u_char ieee[6]; + + char const * typestr; /* printable name of the interface. */ + u_short txb_size; /* size of TX buffer, in bytes */ + + /* Transmission buffer management. */ + u_short txb_free; /* free bytes in TX buffer */ + u_char txb_count; /* number of packets in TX buffer */ + u_char txb_sched; /* number of scheduled packets */ + + /* Media information. */ + struct ifmedia media; /* used by if_media. */ + u_short mbitmap; /* bitmap for supported media; see bit2media */ + int defmedia; /* default media */ + struct ifqueue tx_pending_queue; /* Queue of mbuf given to PKO currently */ + octeon_pko_sw_queue_info_t *outq_ptr; + + struct mtx mtx; +}; + + +/* + * Device methods + */ +static int rgmii_probe(device_t); +static void rgmii_identify(driver_t *, device_t); +static int rgmii_attach(device_t); + + + +/* + * Octeon specific routines + */ +static int octeon_has_4ports(void); +static void octeon_config_rgmii_port(u_int port); +static void octeon_rgmx_config_pip(u_int port); +static void octeon_line_status_loop(void *); +static void octeon_rx_loop(void *); +static void octeon_config_hw_units_post_ports(void); +static void octeon_config_hw_units_pre_ports(void); +static void octeon_config_hw_units_port(struct rgmx_softc_dev *sc, u_int port); +static struct rgmx_softc_dev *get_rgmx_softc(u_int port); +static void octeon_rgmx_start_port(u_int port); +static u_int octeon_rgmx_stop_port(u_int port); +static u_int get_rgmx_port_ordinal(u_int port); +static void octeon_rgmx_set_mac(u_int port); +static void octeon_rgmx_init_sc(struct rgmx_softc_dev *sc, device_t dev, u_int port, u_int num_devices); +static int octeon_rgmx_init_ifnet(struct rgmx_softc_dev *sc); +static void octeon_rgmx_mark_ready(struct rgmx_softc_dev *sc); +static void octeon_rgmx_stop(struct rgmx_softc_dev *sc); +static void octeon_rgmx_config_speed(u_int port, u_int); +static void octeon_dump_rgmx_stats(u_int port); +static void rgmx_timer_periodic(void); +static void octeon_rgmx_enable_RED_all(int, int); + +#ifdef OCTEON_RGMX_SCHEDULED_ISRS +static void octeon_rgmx_isr_link(void *context, int pending); +static void octeon_rgmx_isr_rxtx(void *context, int pending); +static int octeon_rgmx_intr_fast(void *arg); +#else +static int octeon_rgmx_intr(void *arg); +#endif + + + + + + + +/* Standard driver entry points. These can be static. */ +static void octeon_rgmx_init (void *); +//static driver_intr_t rgmx_intr; +static int octeon_rgmx_ioctl (struct ifnet *, u_long, caddr_t); +static void octeon_rgmx_output_start (struct ifnet *); +static void octeon_rgmx_output_start_locked (struct ifnet *); +#if 0 +static void octeon_rgmx_watchdog (struct ifnet *); +#endif +static int octeon_rgmx_medchange (struct ifnet *); +static void octeon_rgmx_medstat (struct ifnet *, struct ifmediareq *); + + +/* Mapping between media bitmap (in fe_softc.mbitmap) and ifm_media. */ +static int const bit2media [] = { + IFM_ETHER | IFM_AUTO, + IFM_ETHER | IFM_MANUAL, + IFM_ETHER | IFM_10_T, + IFM_ETHER | IFM_10_2, + IFM_ETHER | IFM_10_5, + IFM_ETHER | IFM_10_FL, + IFM_ETHER | IFM_10_T, + /* More can be added here... */ +}; + +/* Mapping between media bitmap (in fe_softc.mbitmap) and ifm_media. */ +#define MB_HA 0x0001 +#define MB_HM 0x0002 +#define MB_HT 0x0004 +#define MB_H2 0x0008 +#define MB_H5 0x0010 +#define MB_HF 0x0020 +#define MB_FT 0x0040 + +#define LEBLEN (ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN) + + +static struct rgmx_softc_dev *rgmx_scdev_array[OCTEON_RGMX_NUM_PORTS_MAX] = {NULL}; +static u_int port_array[OCTEON_RGMX_NUM_PORTS_MAX] = {0}; +static u_int num_devices = 0; +static octeon_pko_sw_queue_info_t output_queues_array[OCTEON_RGMX_NUM_PORTS_MAX * OCTEON_RGMX_OQUEUE_PER_PORT]; +static struct resource *irq_res; /* Interrupt resource. */ +static void *int_handler_tag; + + +#ifdef OCTEON_RGMX_SCHEDULED_ISRS + +struct task link_isr_task; +struct task rxtx_isr_task; +struct taskqueue *tq; /* private task queue */ + +#endif + + + +static u_int get_rgmx_port_ordinal (u_int port) +{ + u_int idx; + + for (idx = 0; idx < OCTEON_RGMX_NUM_PORTS_MAX; idx++) { + if (port_array[idx] == port) { + return (idx); + } + } + return (-1); +} + +static struct rgmx_softc_dev *get_rgmx_softc (u_int port) +{ + u_int idx; + + idx = get_rgmx_port_ordinal(port); + if (idx != -1) { + return (rgmx_scdev_array[idx]); + } + return (NULL); +} + + + +static void octeon_rgmx_init_sc (struct rgmx_softc_dev *sc, device_t dev, u_int port, u_int num_devices) +{ + int ii; + + /* No software-controllable media selection. */ + sc->mbitmap = MB_HM; + sc->defmedia = MB_HM; + + sc->sc_dev = dev; + sc->port = port; + sc->idx = num_devices; + sc->link_status = 0; + sc->sc_unit = num_devices; + sc->mbitmap = MB_HT; + sc->defmedia = MB_HT; + sc->tx_pending_queue.ifq_maxlen = NUM_TX_PACKETS; + sc->tx_pending_queue.ifq_head = sc->tx_pending_queue.ifq_tail = NULL; + sc->tx_pending_queue.ifq_len = sc->tx_pending_queue.ifq_drops = 0; + mtx_init(&sc->tx_pending_queue.ifq_mtx, "if->sc->txpq.ifqmtx", NULL, MTX_DEF); + + sc->outq_ptr = &(output_queues_array[num_devices * OCTEON_RGMX_OQUEUE_PER_PORT]); + + for (ii = 0; ii < 6; ii++) { + sc->ieee[ii] = octeon_mac_addr[ii]; + } + sc->ieee[5] += get_rgmx_port_ordinal(port); + +} + +static int octeon_rgmx_init_ifnet (struct rgmx_softc_dev *sc) +{ + struct ifnet *ifp; + + ifp = sc->ifp = if_alloc(IFT_ETHER); + if (NULL == ifp) { + device_printf(sc->sc_dev, "can not ifalloc for rgmx port\n"); + return (ENOSPC); + } + /* + * Initialize ifnet structure + */ + ifp->if_softc = sc; + if_initname(sc->ifp, device_get_name(sc->sc_dev), device_get_unit(sc->sc_dev)); + ifp->if_start = octeon_rgmx_output_start; + ifp->if_ioctl = octeon_rgmx_ioctl; + /* Watchdog interface is now deprecated. + ifp->if_watchdog = octeon_rgmx_watchdog; + */ + ifp->if_hwassist = CSUM_TCP | CSUM_UDP; + ifp->if_capabilities = IFCAP_HWCSUM; + ifp->if_capenable = ifp->if_capabilities; + ifp->if_init = octeon_rgmx_init; + ifp->if_linkmib = NULL; // &sc->mibdata; + ifp->if_linkmiblen = 0; // sizeof (sc->mibdata); + /* + * Set fixed interface flags. + */ + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; +// | IFF_NEEDSGIANT; + if (ifp->if_snd.ifq_maxlen == 0) + ifp->if_snd.ifq_maxlen = ifqmaxlen; + + ifmedia_init(&sc->media, 0, octeon_rgmx_medchange, octeon_rgmx_medstat); + ifmedia_add(&sc->media, bit2media[0], 0, NULL); + ifmedia_set(&sc->media, bit2media[0]); + + ether_ifattach(sc->ifp, sc->ieee); + /* Print additional info when attached. */ + device_printf(sc->sc_dev, "type %s, full duplex\n", sc->typestr); + + return (0); +} + + + +/* Driver methods */ + + +/* ------------------------------------------------------------------- * + * rgmii_identify() * + * ------------------------------------------------------------------- */ +static void rgmii_identify (driver_t *drv, device_t parent) +{ + BUS_ADD_CHILD(parent, 0, "rgmii", 0); +} + + +/* ------------------------------------------------------------------- * + * rgmii_probe() * + * ------------------------------------------------------------------- */ +static int rgmii_probe (device_t dev) +{ + if (device_get_unit(dev) != 0) + panic("can't probe/attach more rgmii devices\n"); + + device_set_desc(dev, "Octeon RGMII"); + return (0); +} + + + +/* ------------------------------------------------------------------- * + * rgmii_attach() * + * ------------------------------------------------------------------- */ +static int rgmii_attach (device_t dev) +{ + struct rgmx_softc_dev *sc; + device_t child; + int iface, port, nr_ports, error; + void *softc; + int irq_rid; + + octeon_config_hw_units_pre_ports(); + + /* Count interfaces and ports*/ + octeon_gmxx_inf_mode_t iface_mode; + iface_mode.word64 = 0; + + for (iface = 0; iface < 2; iface++) { + iface_mode.word64 = oct_read64(OCTEON_RGMX_INF_MODE(iface)); + + /* interface is either disabled or SPI */ + if (!iface_mode.bits.en) + continue; + if (octeon_get_chipid() == OCTEON_CN3020_CHIP) { + nr_ports = 2; + } else { + nr_ports = (octeon_has_4ports()) ? 4 : 3; + if (iface_mode.bits.type ) { + if (octeon_get_chipid() == OCTEON_CN5020_CHIP) + nr_ports = 2; + else + continue; + } + } + + oct_write64(OCTEON_RGMX_TX_PRTS(iface), nr_ports); + + for (port = iface * 16; port < iface * 16 + nr_ports; port++) { + + child = device_add_child(dev, OCTEON_RGMX_DEV_NAME, num_devices); + if (child == NULL) + panic("%s: device_add_child() failed\n", __func__); + + softc = malloc(sizeof(struct rgmx_softc_dev), M_DEVBUF, M_NOWAIT | M_ZERO); + if (!softc) { + panic("%s malloc failed for softc\n", __func__); + } + device_set_softc(child, softc); + device_set_desc(child, "Octeon RGMII"); + sc = device_get_softc(child); + if (!sc) { + printf(" No sc\n"); + num_devices++; + continue; + } + port_array[num_devices] = port; + rgmx_scdev_array[num_devices] = sc; + RGMX_LOCK_INIT(sc, device_get_nameunit(child)); + octeon_rgmx_init_sc(sc, child, port, num_devices); + octeon_config_hw_units_port(sc, port); + if (octeon_rgmx_init_ifnet(sc)) { + device_printf(dev, " ifinit failed for rgmx port %u\n", port); + return (ENOSPC); + } +/* + * Don't call octeon_rgmx_mark_ready() + * ifnet will call it indirectly via octeon_rgmx_init() + * + * octeon_rgmx_mark_ready(sc); + */ + num_devices++; + } + } + + octeon_config_hw_units_post_ports(); + + irq_rid = 0; + irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &irq_rid, 0, 0, 1, RF_SHAREABLE | RF_ACTIVE); + if (irq_res == NULL) { + device_printf(dev, "failed to allocate irq\n"); + return (ENXIO); + } + + +#ifdef OCTEON_RGMX_SCHEDULED_ISRS + /* + * Single task queues for all child devices. Since POW gives us a unified + * interrupt based on POW groups, not based on PORTs. + */ + TASK_INIT(&rxtx_isr_task, 0, octeon_rgmx_isr_rxtx, NULL); + TASK_INIT(&link_isr_task, 0, octeon_rgmx_isr_link, NULL); + tq = taskqueue_create_fast("octeon_rgmx_taskq", M_NOWAIT, + taskqueue_thread_enqueue, &tq); + taskqueue_start_threads(&tq, 1, PI_NET, "%s taskq", device_get_nameunit(dev)); + + error = bus_setup_intr(dev, irq_res, INTR_TYPE_NET, octeon_rgmx_intr_fast, NULL, + NULL, &int_handler_tag); + if (error != 0) { + device_printf(dev, "bus_setup_intr returned %d\n", error); + taskqueue_free(tq); + tq = NULL; + return (error); + } + +#else /* OCTEON_RGMX_SCHEDULED_ISRS */ + + error = bus_setup_intr(dev, irq_res, INTR_TYPE_NET, octeon_rgmx_intr, NULL, + NULL, &int_handler_tag); + + if (error != 0) { + device_printf(dev, "bus_setup_intr returned %d\n", error); + tq = NULL; + return (error); + } + +#endif /* OCTEON_RGMX_SCHEDULED_ISRS */ + + return (bus_generic_attach(dev)); +} + + + + +#define OCTEON_MAX_RGMX_PORT_NUMS 32 + + + +#define OCTEON_POW_RX_GROUP_NUM 0 +#define OCTEON_POW_TX_GROUP_NUM 1 /* If using TX WQE from PKO */ + +#define OCTEON_POW_RX_GROUP_MASK (1 << OCTEON_POW_RX_GROUP_NUM) +#define OCTEON_POW_TX_GROUP_MASK (1 << OCTEON_POW_TX_GROUP_NUM) +#define OCTEON_POW_ALL_OUR_GROUPS_MASK (OCTEON_POW_RX_GROUP_MASK | OCTEON_POW_RX_GROUP_MASK) +#define OCTEON_POW_ALL_GROUPS_MASK 0xffff +#define OCTEON_POW_WORKQUEUE_INT (0x8001670000000200ull) +#define OCTEON_POW_WORKQUEUE_INT_PC (0x8001670000000208ull) +#define OCTEON_POW_WORKQUEUE_INT_THRESHOLD(group_num) ((0x8001670000000080ull+((group_num)*0x8))) +#define OCTEON_RGMX_POW_NOS_CNT (0x8001670000000228ull) +#define OCTEON_POW_INT_CNTR(core) (0x8001670000000100ull+((core)*0x8)) +#define OCTEON_POW_INPT_Q_ALL_QOS (0x8001670000000388ull) +#define OCTEON_POW_INPT_QOS_GRP(grp) (0x8001670000000340ull + ((grp) * 0x8)) + + + + +#define NUM_RX_PACKETS_CTL (MAX_RX_BUFS + 3000) +#define NUM_TX_PACKETS_CTL 40 + +#define FPA_NOPOOL 0 + +#define OCTEON_FPA_RX_PACKET_POOL 0 +#define OCTEON_FPA_RX_PACKET_POOL_WORDS 208 /* 2048 bytes */ +#define OCTEON_FPA_RX_PACKET_POOL_ELEM_SIZE (OCTEON_FPA_RX_PACKET_POOL_WORDS) +#define OCTEON_FPA_RX_PACKET_POOL_ELEMENTS (MAX_RX_BUFS) +#define OCTEON_RX_MAX_SIZE (OCTEON_FPA_RX_PACKET_POOL_WORDS * sizeof(uint64_t)) + +#define OCTEON_FPA_WQE_RX_POOL 1 +#define OCTEON_FPA_WQE_RX_WORDS (OCTEON_CACHE_LINE_SIZE/8) +#define OCTEON_FPA_WQE_RX_POOL_ELEM_SIZE (OCTEON_FPA_WQE_RX_WORDS) +#define OCTEON_FPA_WQE_RX_POOL_ELEMENTS (NUM_RX_PACKETS_CTL) + +#define OCTEON_FPA_TX_PACKET_POOL 2 +#define OCTEON_FPA_TX_PACKET_POOL_WORDS 208 /* 2048 bytes */ +#define OCTEON_FPA_TX_PACKET_POOL_ELEM_SIZE (OCTEON_FPA_TX_PACKET_POOL_WORDS) +#define OCTEON_FPA_TX_PACKET_POOL_ELEMENTS (MAX_TX_BUFS) +#define OCTEON_TX_MAX_SIZE (OCTEON_FPA_TX_PACKET_POOL_WORDS * sizeof(uint64_t)) + +#define OCTEON_FPA_TX_CMDBUF_POOL 3 +#define OCTEON_FPA_TX_CMD_SIZE 2 +#define OCTEON_FPA_TX_CMD_NUM 300 +#define OCTEON_FPA_TX_CMDBUF_POOL_WORDS (OCTEON_FPA_TX_CMD_SIZE * OCTEON_FPA_TX_CMD_NUM) +#define OCTEON_FPA_TX_CMDBUF_POOL_ELEM_SIZE (OCTEON_FPA_TX_CMDBUF_POOL_WORDS +1) +#define OCTEON_FPA_TX_CMDBUF_POOL_ELEMENTS (30 * OCTEON_RGMX_NUM_PORTS_MAX) + +#define FIRST_PARTICLE_SKIP 0 +#define NOT_FIRST_PARTICLE_SKIP 0 + +#define ENABLE_BACK_PRESSURE 0 +#define RGMX_MAX_PAK_RECEIVE 5000000 + + +static void octeon_dump_pow_stats (void); + + + +#ifdef OCTEON_RGMX_SCHEDULED_ISRS + + +static void octeon_rgmx_isr_link (void *context, int pending) +{ + octeon_line_status_loop(NULL); +} + + +static void octeon_rgmx_isr_rxtx (void *context, int pending) +{ + NET_LOCK_GIANT(); + octeon_rx_loop(NULL); + NET_UNLOCK_GIANT(); +} + + +/********************************************************************* + * + * Fast Interrupt Service routine + * + *********************************************************************/ + +//#define OCTEON_RGMX_POW_TIME_THR_INTS 1 + + +static int octeon_rgmx_intr_fast(void *arg) +{ + + int handled_flag = 0; + uint64_t ciu_summary; + + ciu_summary = ciu_get_int_summary(CIU_THIS_CORE, OCTEON_RGMX_CIU_INTX, + OCTEON_RGMX_CIU_ENX); + + if (ciu_summary & CIU_GENTIMER_BITS_ENABLE(CIU_GENTIMER_NUM_1)) { + + /* + * Timer Interrupt for link status checks + * Acknowledging it will mask it for this cycle. + */ + ciu_clear_int_summary(CIU_THIS_CORE, OCTEON_RGMX_CIU_INTX, + OCTEON_RGMX_CIU_ENX, + CIU_GENTIMER_BITS_ENABLE(CIU_GENTIMER_NUM_1)); + + taskqueue_enqueue(taskqueue_fast, &link_isr_task); + handled_flag = 1; + } + + if (ciu_summary & OCTEON_POW_ALL_GROUPS_MASK) { +#ifndef OCTEON_RGMX_POW_TIME_THR_INTS + /* + * When using POW IQ/DSQ size based interrupts, then + * ack the interrupts right away. So they don't interrupt + * until the queue size goes to 0 again. + */ + oct_write64(OCTEON_POW_WORKQUEUE_INT, + 0x10001 << OCTEON_POW_RX_GROUP_NUM); + +#else + /* + * We use POW thresholds based interrupt signalled on timer + * countdown. Acknowledge it now so that it doesn't + * interrupt us until next countdown to zero. + */ + oct_write64(OCTEON_POW_WORKQUEUE_INT, + 0x1 << OCTEON_POW_RX_GROUP_NUM); +#endif + + taskqueue_enqueue(tq, &rxtx_isr_task); + handled_flag = 1; + } + + return ((handled_flag) ? FILTER_HANDLED : FILTER_STRAY); +} + + +#else /* ! OCTEON_RGMX_SCHEDULED_ISRS */ + + +/* + * octeon_rgmx_intr + * + * This is direct inline isr. Will do all its work and heavy-lifting in interrupt context. + * + * Also note that the RGMX_LOCK/UNLOCK code will have to checked/added, since that is new and + * was not supported with this model. + */ +static int octeon_rgmx_intr (void *arg) +{ + int flag = 0; + uint64_t ciu_summary; + + /* + * read ciu to see if any bits are pow + */ + while (1) { + ciu_summary = ciu_get_int_summary(CIU_THIS_CORE, OCTEON_RGMX_CIU_INTX, + OCTEON_RGMX_CIU_ENX); + + if ((ciu_summary & (OCTEON_POW_ALL_GROUPS_MASK | CIU_GENTIMER_BITS_ENABLE(CIU_GENTIMER_NUM_1))) == 0) { + break; + } + + flag = 1; + + if (ciu_summary & OCTEON_POW_ALL_GROUPS_MASK) { + octeon_rx_loop(NULL); + /* + * Acknowledge the interrupt after processing queues. + */ + oct_write64(OCTEON_POW_WORKQUEUE_INT, OCTEON_POW_RX_GROUP_MASK); + } + if (ciu_summary & CIU_GENTIMER_BITS_ENABLE(CIU_GENTIMER_NUM_1)) { + octeon_line_status_loop(NULL); + ciu_clear_int_summary(CIU_THIS_CORE, OCTEON_RGMX_CIU_INTX, + OCTEON_RGMX_CIU_ENX, + CIU_GENTIMER_BITS_ENABLE(CIU_GENTIMER_NUM_1)); + } + } + + return ((flag) ? FILTER_HANDLED : FILTER_STRAY); +} + + +#endif /* OCTEON_RGMX_SCHEDULED_ISRS */ + + + +static struct mbuf *octeon_rgmx_build_new_rx_mbuf(struct ifnet *ifp, void *data_start, u_int totlen); + +static struct mbuf *octeon_rgmx_build_new_rx_mbuf (struct ifnet *ifp, void *data_start, u_int totlen) +{ + struct mbuf *m, *m0, *newm; + caddr_t newdata; + int len; + + if (totlen <= ETHER_HDR_LEN || totlen > LEBLEN - ETHER_CRC_LEN) { +#ifdef LEDEBUG + if_printf(ifp, "invalid packet size %d; dropping\n", totlen); +#endif + return (NULL); + } + + MGETHDR(m0, M_DONTWAIT, MT_DATA); + if (m0 == NULL) { + return (NULL); + } + + /* Initialize packet header info. */ + m0->m_pkthdr.rcvif = ifp; + m0->m_pkthdr.len = totlen; + m0->m_pkthdr.csum_flags = CSUM_IP_CHECKED | CSUM_IP_VALID | CSUM_DATA_VALID | CSUM_PSEUDO_HDR; + m0->m_pkthdr.csum_data = 0xffff; + len = MHLEN; + m = m0; + + while (totlen > 0) { + if (totlen >= MINCLSIZE) { + MCLGET(m, M_DONTWAIT); + if ((m->m_flags & M_EXT) == 0) + goto octeon_rgmx_build_new_rx_mbuf_bad; + len = MCLBYTES; + } + + if (m == m0) { + newdata = (caddr_t) ALIGN(m->m_data + ETHER_HDR_LEN) - ETHER_HDR_LEN; + len -= newdata - m->m_data; + m->m_data = newdata; + } + + /* Set the length of this mbuf. */ + m->m_len = len = min(totlen, len); + bcopy(data_start, mtod(m, caddr_t), len); + data_start = (void *) (((u_long) (data_start)) + len); + + totlen -= len; + if (totlen > 0) { + MGET(newm, M_DONTWAIT, MT_DATA); + if (newm == 0) + goto octeon_rgmx_build_new_rx_mbuf_bad; + len = MLEN; + m = m->m_next = newm; + } + } + + return (m0); + +octeon_rgmx_build_new_rx_mbuf_bad: + + m_freem(m0); + return (NULL); +} + + + +//#define DEBUG_RX 1 + +static void octeon_rgmx_rx_process_work (octeon_wqe_t *work, u_int port) +{ + struct rgmx_softc_dev *sc; + struct ifnet *ifp; + u_int len; + void *data_start, *new_data_start; + struct mbuf *mbuf; + +//#define DEBUG_RX_PKT_DUMP 1 +#ifdef DEBUG_RX_PKT_DUMP + int i; u_char *dc; +#endif + + data_start = octeon_pow_pktptr_to_kbuffer(work->packet_ptr); + +//#define DEBUG_RX2 +#ifdef DEBUG_RX2 + printf(" WQE 0x%X: port:%u ", work, port); + printf(" Grp: %u, %llX Tag: %u %llX type: %u 0x%llx\n", + work->grp, work->grp, work->tag, work->tag, work->tag_type, work->tag_type); +#endif + + if ((port >= OCTEON_RGMX_MIN_PORT) || (port <= OCTEON_RGMX_MAX_PORT)) { + + sc = get_rgmx_softc(port); + + if (!sc || !sc->ifp) { + + printf(" octeon_rgmx_rx_process_work No sc or sc->ifp - port:%u", port); + } else { + + ifp = sc->ifp; + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + + if (!work->word2.bits.rcv_error) { + + len = work->len; + + /* + * We cannot pass the same FPA phys-buffer higher up. + * User space will not be able to use this phys-buffer. + * + * Start building a mbuf packet here using data_start & len. + */ + + new_data_start = data_start; + if (!work->word2.bits.not_IP) { + new_data_start = (void *) (((unsigned long) (new_data_start)) + 14); + /* mark it as checksum checked */ + } else { + new_data_start = (void *) (((unsigned long) (new_data_start)) + 8); + } + +#ifdef DEBUG_RX_PKT_DUMP + dc = new_data_start; printf("In:\n"); + for (i = 0; i < len; i++) { if (!(i % 16)) printf ("\n"); printf(" %02X", dc[i]); } +#endif + + mbuf = octeon_rgmx_build_new_rx_mbuf(ifp, new_data_start, len); + if (mbuf) { +// printf(" Passing pkt to ifp: pkt_len: %u len: %u ", mbuf->m_pkthdr.len, mbuf->m_len); +#ifdef DEBUG_RX_PKT_DUMP + + dc = mtod(mbuf, u_char *); printf("\n"); printf("In: "); + for (i = 0; i < mbuf->m_len; i++) { if (!(i % 16)) printf ("\n"); printf(" %02X", dc[i]); } + +#endif + + /* Feed the packet to upper layer. */ + (*ifp->if_input)(ifp, mbuf); + ifp->if_ipackets++; + + } else { /* mbuf error */ + if_printf(ifp, "mbuf rx construct error\n"); + printf(" mbuf rx construct error\n"); + ifp->if_ierrors++; + } /* mbuf error */ + + } else { /* rcv_error */ + ifp->if_ierrors++; + } /* rcv_error */ + + } /* IFF_DRV_RUNNING */ + + } /* sc && sc->ifp */ + + } else { /* port number */ + printf(" rgmx_rx:%u bad port\n", port); + } + + octeon_fpa_free(data_start, OCTEON_FPA_RX_PACKET_POOL, 0); + octeon_fpa_free((void *)work, OCTEON_FPA_WQE_RX_POOL, 0); +} + + + + +/* ------------------------------------------------------------------- * + * octeon_rx_loop() * + * ------------------------------------------------------------------- */ + + +//#define OCTEON_VISUAL_RGMX 1 +#ifdef OCTEON_VISUAL_RGMX +static int where0 = 0; +static int where1 = 0; +#endif + +static void octeon_rx_loop (void *unused) +{ + u_int core_id; + uint64_t prev_grp_mask; + u_int pak_count; + octeon_wqe_t *work; + + core_id = octeon_get_core_num(); + pak_count = 0; + + /* Only allow work for our group */ + prev_grp_mask = oct_read64(OCTEON_POW_CORE_GROUP_MASK(core_id)); + oct_write64(OCTEON_POW_CORE_GROUP_MASK(core_id), OCTEON_POW_ALL_GROUPS_MASK); + + +#ifdef OCTEON_VISUAL_RGMX + octeon_led_run_wheel(&where0, 3); +#endif + while(1) { + + if (pak_count++ > RGMX_MAX_PAK_RECEIVE) { + break; + } + + work = octeon_pow_work_request_sync(OCTEON_POW_WAIT); + + if (work == NULL) { + /* + * No more incoming packets. We can take a break now. + */ + break; + } + +#ifdef OCTEON_VISUAL_RGMX + octeon_led_run_wheel(&where1, 4); +#endif + octeon_rgmx_rx_process_work(work, work->ipprt); + + } + + oct_write64(OCTEON_POW_CORE_GROUP_MASK(core_id), prev_grp_mask); +} + + +static void *octeon_rgmx_write_mbufs_to_fpa_buff (struct rgmx_softc_dev *sc, struct mbuf *m, u_int len) +{ + struct mbuf *mp; + void *data_area; + u_char *write_offset; + + /* + * FIXME + * + * Compare len with max FPA-tx-packet size. Or else we will possibly corrupt the next pkt. + */ + + + /* + * Get an FPA buffer from Xmit-packets FPA pool + */ + data_area = octeon_fpa_alloc(OCTEON_FPA_TX_PACKET_POOL); + if (!data_area) { + /* + * Fail. No room. No resources. + */ + return (NULL); + } + + /* + * Transfer the data from mbuf chain to the transmission buffer. + */ + write_offset = data_area; + for (mp = m; mp != 0; mp = mp->m_next) { + if (mp->m_len) { + bcopy(mtod(mp, caddr_t), write_offset, mp->m_len); + write_offset = (u_char *) (((u_long) write_offset) + mp->m_len); + } + } + return (data_area); +} + + +static u_int octeon_rgmx_pko_xmit_packet (struct rgmx_softc_dev *sc, void *out_buff, u_int len, u_int checksum) +{ + octeon_pko_command_word0_t pko_cmd; + octeon_pko_packet_ptr_t pko_pkt_word; + u_long temp; + u_short xmit_cmd_index; + uint64_t *xmit_cmd_ptr; + uint64_t xmit_cmd_state; + int queue = 0; // we should randomize queue # based on core num. Using same + // queue 0 for this port, by all cores on is less efficient. + + /* + * Prepare the PKO buffer and command word. + * Cmd Buf Word 0 + * No FAU + * Set #-segs and #-bytes + */ + pko_cmd.word64 = 0; + pko_cmd.bits.segs = 1; + pko_cmd.bits.total_bytes = len; + if (checksum) { + pko_cmd.bits.ipoffp1 = ETHER_HDR_LEN + 1; /* IPOffP1 is +1 based. 1 means offset 0 */ + } + + /* + * Build the PKO buffer pointer. PKO Cmd Buf Word 1 + */ + pko_pkt_word.word64 = 0; + pko_pkt_word.bits.addr = OCTEON_PTR2PHYS(out_buff); + pko_pkt_word.bits.pool = OCTEON_FPA_TX_PACKET_POOL; + pko_pkt_word.bits.size = 2048; // dummy. Actual len is above. + +#ifdef DEBUG_TX + printf(" PKO: 0x%llX 0x%llX ", pko_cmd.word64, pko_pkt_word.word64); +#endif + + /* + * Get the queue command ptr location from the per port per queue, pko info struct. + */ + octeon_spinlock_lock(&(sc->outq_ptr[queue].lock)); +#ifdef DEBUG_TX + printf(" xmit: sc->outq_ptr[queue].xmit_command_state: 0x%llX ", sc->outq_ptr[queue].xmit_command_state); +#endif + xmit_cmd_state = sc->outq_ptr[queue].xmit_command_state; + sc->outq_ptr[queue].xmit_command_state = xmit_cmd_state + 2; + + temp = (u_long) (xmit_cmd_state >> OCTEON_PKO_INDEX_BITS); +#ifdef DEBUG_TX + printf(" temp: 0x%X ", temp); +#endif + xmit_cmd_ptr = (uint64_t *) OCTEON_PHYS2PTR(temp); + xmit_cmd_index = xmit_cmd_state & OCTEON_PKO_INDEX_MASK; + xmit_cmd_ptr += xmit_cmd_index; + + /* + * We end the PKO cmd buffer at odd boundary. Towards the end we will have + * 4 or 3 or 2 or 1 or 0 word remaining. Case of 4, 2, or 0 can never happen. + * We only care when we have 3 words remaining. In this case we write our 2 words + * for PKO command and 3rd word as chain for next PKO cmd buffer. + */ + xmit_cmd_ptr[0] = pko_cmd.word64; + + if (xmit_cmd_index < (OCTEON_FPA_TX_CMDBUF_POOL_WORDS - 2)) { + /* + * Plenty of space left. Write our 2nd word and worry the next time. + */ + xmit_cmd_ptr[1] = pko_pkt_word.word64; + + } else { + /* + * 3 words or less are left. We write our 2nd word now and then put in a chain link + * to new PKO cmd buf. + */ + void *pko_cmd_buf = octeon_fpa_alloc(OCTEON_FPA_TX_CMDBUF_POOL); + uint64_t phys_cmd_buf; + + if (!pko_cmd_buf) { + /* + * FPA pool for xmit-buffer-commands is empty. + */ + sc->outq_ptr[queue].xmit_command_state -= 2; + octeon_spinlock_unlock(&(sc->outq_ptr[queue].lock)); + return (0); + } + phys_cmd_buf = OCTEON_PTR2PHYS(pko_cmd_buf); + + xmit_cmd_ptr[1] = pko_pkt_word.word64; + xmit_cmd_ptr[2] = phys_cmd_buf; + + sc->outq_ptr[queue].xmit_command_state = (phys_cmd_buf << OCTEON_PKO_INDEX_BITS); + } + /* + * Unlock queue structures. + */ + octeon_spinlock_unlock(&(sc->outq_ptr[queue].lock)); + + /* + * 2 words incremented in PKO. Ring the doorbell. + */ +#ifdef DEBUG_TX + printf(" Ringing doorbell: Port %u Queue %u words 2", sc->port, octeon_pko_get_base_queue(sc->port) + queue); +#endif + octeon_pko_ring_doorbell(sc->port, octeon_pko_get_base_queue(sc->port) + queue, 2); + + return (1); +} + + +static void octeon_rgmx_xmit_mark_buffers_done(struct rgmx_softc_dev *sc, u_int n); + +static void octeon_rgmx_xmit_mark_buffers_done (struct rgmx_softc_dev *sc, u_int n) +{ + struct mbuf *m; + u_int i; + + for (i = 0; i < n; i++) { + /* + * Remove packets in queue. Leaving a lag of 3, to allow for PKO in-flight xmission + */ + if (_IF_QLEN(&sc->tx_pending_queue) > 4) { + IF_DEQUEUE(&sc->tx_pending_queue, m); + if (!m) { + break; // Queue became empty now. Break out. + } + /* + * Return the mbuf to system. + */ + m_freem(m); + } + } + if (!i) { + return; // Nothing removed from queue. + } + + /* + * The transmitter is no more active. + * Reset output active flag and watchdog timer. + */ + sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + sc->ifp->if_timer = 0; +} + + +#define OCTEON_RGMX_FLUSH_N_XMIT_MBUFS_EACH_LOOP 5 +#define OCTEON_RGMX_FLUSH_PENDING_MBUFS_MAX 1000 + +/* + * octeon_rgmx_output_flush + * + * Drop all packets queued at ifnet layer. + */ +static void octeon_rgmx_output_flush (struct ifnet *ifp) +{ + struct mbuf *m; + u_int max_flush = OCTEON_RGMX_FLUSH_PENDING_MBUFS_MAX; /* Arbitrarily high number */ + + while (max_flush-- && _IF_QLEN(&ifp->if_snd)) { + /* + * Get the next mbuf Packet chain to flush. + */ + IF_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) { + /* No more packets to flush */ + break; + } + _IF_DROP(&ifp->if_snd); + m_freem(m); + ifp->if_oerrors++; + } +} + + +/* + * octeon_rgmx_output_start + * + * Start output on interface. + */ +static void octeon_rgmx_output_start (struct ifnet *ifp) +{ + struct rgmx_softc_dev *sc = ifp->if_softc; + + RGMX_LOCK(sc); + octeon_rgmx_output_start_locked(ifp); + RGMX_UNLOCK(sc); +} + + + +/* + * octeon_rgmx_output_start_locked + * + * Start output on interface. Assume Driver locked + */ +static void octeon_rgmx_output_start_locked (struct ifnet *ifp) +{ + struct rgmx_softc_dev *sc = ifp->if_softc; + struct mbuf *m; + u_int len, need_l4_checksum; + void *out_buff; + + /* + * Take out some of the last queued mbuf's from xmit-pending queue + */ + octeon_rgmx_xmit_mark_buffers_done(sc, OCTEON_RGMX_FLUSH_N_XMIT_MBUFS_EACH_LOOP); + + while (1) { + /* + * See if there is room to put another packet in the buffer. + * We *could* do better job by peeking the send queue to + * know the length of the next packet. Current version just + * tests against the worst case (i.e., longest packet). FIXME. + * + * When adding the packet-peek feature, don't forget adding a + * test on txb_count against QUEUEING_MAX. + * There is a little chance the packet count exceeds + * the limit. Assume transmission buffer is 8KB (2x8KB + * configuration) and an application sends a bunch of small + * (i.e., minimum packet sized) packets rapidly. An 8KB + * buffer can hold 130 blocks of 62 bytes long... + */ + + /* + * If unable to send more. + */ + if (_IF_QLEN(&sc->tx_pending_queue) >= MAX_TX_BUFS) { + printf(" Xmit not possible. NO room %u", _IF_QLEN(&sc->tx_pending_queue)); + goto indicate_active; + } + + + /* + * Get the next mbuf chain for a packet to send. + */ + IF_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) { + /* No more packets to send. */ + goto indicate_inactive; + } + + len = m->m_pkthdr.len; + /* + * Should never send big packets. If such a packet is passed, + * it should be a bug of upper layer. We just ignore it. + * ... Partial (too short) packets, neither. + */ + if (len < ETHER_HDR_LEN || + len > ETHER_MAX_LEN - ETHER_CRC_LEN) { + /* + * Fail. Bad packet size. Return the mbuf to system. + */ + if_printf(ifp, + "got an out-of-spec packet (%u bytes) to send\n", len); + m_freem(m); + goto indicate_active; + } + + /* + * Copy the mbuf chain into the transmission buffer. + * txb_* variables are updated as necessary. + */ + out_buff = octeon_rgmx_write_mbufs_to_fpa_buff(sc, m, len); + if (!out_buff) { + /* + * No FPA physical buf resource. + * Let's requeue it back. And slow it down for a while. + */ + IF_PREPEND(&ifp->if_snd, m); + goto indicate_active; + } + + need_l4_checksum = (m->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP)) ? 1 : 0; + + /* + * put the mbuf onto pending queue + */ +//#define DEBUG_TX_PKT_DUMP 1 +#ifdef DEBUG_TX_PKT_DUMP + int ii; + u_char *dc = out_buff; + + printf("\n"); printf("Out: "); + for (ii = 0; ii < len; ii++) printf(" %X", dc[ii]); printf("\n"); +#endif + + IF_ENQUEUE(&sc->tx_pending_queue, m); + + /* + * Pass the mbuf data packet to PKO for xmission. + */ + octeon_rgmx_pko_xmit_packet(sc, out_buff, len, need_l4_checksum); + + ifp->if_opackets++; + } + +indicate_inactive: + /* + * We are using the !OACTIVE flag to indicate to + * the outside world that we can accept an + * additional packet rather than that the + * transmitter is _actually_ active. Indeed, the + * transmitter may be active, but if we haven't + * filled all the buffers with data then we still + * want to accept more. + */ + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + return; + + +indicate_active: + /* + * The transmitter is active, and there are no room for + * more outgoing packets in the transmission buffer. + */ + ifp->if_oerrors++; +// sc->mibdata.dot3StatsInternalMacTransmitErrors++; + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + return; +} + + + + +/* ------------------------------------------------------------------- * + * octeon_config_hw_units() * + * ------------------------------------------------------------------- * + * + * Initialize Octeon hardware components. To get the RGMX going. + * + */ +static void octeon_config_hw_units_pre_ports (void) +{ + + /* Enable FPA */ + octeon_enable_fpa(); + + /* Enable PKO */ + octeon_pko_enable(); + + /* Init PKO */ + octeon_pko_init(); + + + /* Fill FPA */ + + /* + * Input Buffers Pool + * Pool 0 + */ + octeon_fpa_fill_pool_mem(OCTEON_FPA_RX_PACKET_POOL, OCTEON_FPA_RX_PACKET_POOL_ELEM_SIZE, + OCTEON_FPA_RX_PACKET_POOL_ELEMENTS); + + /* + * WQE Blocks Pool + * Pool 1 + */ + octeon_fpa_fill_pool_mem(OCTEON_FPA_WQE_RX_POOL, OCTEON_FPA_WQE_RX_POOL_ELEM_SIZE, + OCTEON_FPA_WQE_RX_POOL_ELEMENTS); + + /* + * PKO Command Pool + * Pool 3 + */ + octeon_fpa_fill_pool_mem(OCTEON_FPA_TX_CMDBUF_POOL, OCTEON_FPA_TX_CMDBUF_POOL_ELEM_SIZE, + OCTEON_FPA_TX_CMDBUF_POOL_ELEMENTS); + + /* + * Output Buffers Pool + * Pool 2 + */ + octeon_fpa_fill_pool_mem(OCTEON_FPA_TX_PACKET_POOL, OCTEON_FPA_TX_PACKET_POOL_ELEM_SIZE, + OCTEON_FPA_TX_PACKET_POOL_ELEMENTS); + + + + octeon_rgmx_enable_RED_all(OCTEON_FPA_RX_PACKET_POOL_ELEMENTS >> 2, OCTEON_FPA_RX_PACKET_POOL_ELEMENTS >> 3); + + /* Configure IPD */ + octeon_ipd_config(OCTEON_FPA_RX_PACKET_POOL_WORDS, + FIRST_PARTICLE_SKIP / 8, + NOT_FIRST_PARTICLE_SKIP / 8, + FIRST_PARTICLE_SKIP / 128, + NOT_FIRST_PARTICLE_SKIP / 128, + OCTEON_FPA_WQE_RX_POOL, + OCTEON_IPD_OPC_MODE_STF, + ENABLE_BACK_PRESSURE); + + /* + * PKO setup Output Command Buffers + */ + octeon_pko_config_cmdbuf_global_defaults(OCTEON_FPA_TX_CMDBUF_POOL, + OCTEON_FPA_TX_CMDBUF_POOL_ELEM_SIZE); + +} + + + +static void octeon_config_hw_units_port (struct rgmx_softc_dev *sc, u_int port) +{ + const u_int priorities[8] = {8,8,8,8,8,8,8,8}; + u_int total_queues, base_queue; + + octeon_config_rgmii_port(port); + + total_queues = octeon_pko_get_num_queues(port); + base_queue = octeon_pko_get_base_queue(port); + /* Packet output configures Queue and Ports */ + octeon_pko_config_port(port, base_queue, + total_queues, + priorities, + OCTEON_FPA_TX_CMDBUF_POOL, + sc->outq_ptr); + + octeon_rgmx_set_mac(port); + + /* Setup Port input tagging */ + octeon_rgmx_config_pip(port); +} + + +typedef union +{ + uint64_t word64; + struct + { + uint64_t rsvd3 : 35; + uint64_t enable : 1; + uint64_t time_thr : 4; + uint64_t rsvd2 : 1; + uint64_t ds_thr : 11; + uint64_t rsvd : 1; + uint64_t iq_thr : 11; + } bits; +} octeon_rgmx_pow_int_threshold_t; + +typedef union +{ + uint64_t word64; + struct + { + uint64_t rsvd : 36; + uint64_t tc_cnt : 4; + uint64_t ds_cnt : 12; + uint64_t iq_cnt : 12; + } bits; +} octeon_rgmx_pow_int_cnt_t; + +typedef union +{ + uint64_t word64; + struct + { + uint64_t rsvd3 : 4; + uint64_t thr_freq : 28; // R/O + uint64_t rsvd2 : 4; + uint64_t thr_period : 20; + uint64_t rsvd : 8; + } bits; +} octeon_rgmx_pow_int_pc_t; + + +typedef union +{ + uint64_t word64; + struct + { + uint64_t rsvd : 52; + uint64_t nos_cnt : 12; + } bits; +} octeon_rgmx_pow_nos_cnt; + + + +typedef union +{ + uint64_t word64; + struct + { + uint64_t rsvd : 32; + uint64_t inb_pkts : 32; + } bits; +} octeon_rgmx_pip_inb_pkts; + +typedef union +{ + uint64_t word64; + struct + { + uint64_t rsvd : 48; + uint64_t inb_errs : 16; + } bits; +} octeon_rgmx_pip_inb_errs; + + + +typedef union +{ + uint64_t word64; + struct + { + uint64_t rsvd : 32; + uint64_t iq_cnt : 32; + } bits; +} octeon_pow_inpt_q_all_qos; + + + +typedef union +{ + uint64_t word64; + struct + { + uint64_t rsvd : 32; + uint64_t iq_cnt : 32; + } bits; +} octeon_pow_inpt_q_grp_qos; + + +static void octeon_config_hw_units_post_ports (void) +{ + + octeon_rgmx_pow_int_threshold_t thr; + octeon_rgmx_pow_int_pc_t intpc; + + thr.word64 = 0; + intpc.word64 = 0; + intpc.bits.thr_freq = (500 * 1000 * 1000) / (1000 * 16 * 256); + +#ifdef OCTEON_RGMX_POW_TIME_THR_INTS + thr.bits.enable = 1; + thr.bits.time_thr = 0xf; + oct_write64(OCTEON_POW_WORKQUEUE_INT_THRESHOLD(OCTEON_POW_RX_GROUP_NUM), thr.word64); + + oct_write64(OCTEON_POW_WORKQUEUE_INT_PC, intpc.word64); + +#else + thr.bits.ds_thr = thr.bits.iq_thr = 1; // Only if doing absolute queue-cnt interrupts. + oct_write64(OCTEON_POW_WORKQUEUE_INT_THRESHOLD(OCTEON_POW_RX_GROUP_NUM), thr.word64); +#endif + + ciu_enable_interrupts(OCTEON_CORE_ID, OCTEON_RGMX_CIU_INTX, OCTEON_RGMX_CIU_ENX, + (OCTEON_POW_RX_GROUP_MASK | + CIU_GENTIMER_BITS_ENABLE(CIU_GENTIMER_NUM_1)), CIU_MIPS_IP2); + + ciu_clear_int_summary(CIU_THIS_CORE, OCTEON_RGMX_CIU_INTX, + OCTEON_RGMX_CIU_ENX, CIU_GENTIMER_BITS_ENABLE(CIU_GENTIMER_NUM_1)); + + octeon_ciu_start_gtimer(CIU_GENTIMER_NUM_1, OCTEON_GENTIMER_PERIODIC, + OCTEON_GENTIMER_LEN_1SEC); + /* + * Enable IPD + */ + octeon_ipd_enable(); +} + + + + + +static void octeon_rgmx_config_pip (u_int port) +{ + octeon_pip_gbl_cfg_t pip_config; + octeon_pip_port_cfg_t pip_port_config; + octeon_pip_port_tag_cfg_t pip_tag_config; + + /* + * PIP Global config + */ + pip_config.word64 = 0; + pip_config.bits.max_l2 = 1; + oct_write64(OCTEON_PIP_GBL_CFG, pip_config.word64); + + /* + * PIP Port config + */ + pip_port_config.word64 = 0; + pip_port_config.bits.mode = OCTEON_PIP_PORT_CFG_MODE_SKIPL2; + pip_port_config.bits.qos = port & 0x7; + pip_port_config.bits.crc_en = 1; + + + /* + * PIP -> POW tags config + * + * We don't use any pkt input fields for tag hash, except for Port# + */ + pip_tag_config.word64 = 0; + + pip_tag_config.bits.grptag = 0; + pip_tag_config.bits.grptagmask = 0xf; + pip_tag_config.bits.grptagbase = 1; + + pip_tag_config.bits.ip6_src_flag = 0; + pip_tag_config.bits.ip6_dst_flag = 0; + pip_tag_config.bits.ip6_sprt_flag = 0; + pip_tag_config.bits.ip6_dprt_flag = 0; + pip_tag_config.bits.ip6_nxth_flag = 0; + + pip_tag_config.bits.ip4_src_flag = 1; + pip_tag_config.bits.ip4_dst_flag = 1; + pip_tag_config.bits.ip4_sprt_flag = 1; + pip_tag_config.bits.ip4_dprt_flag = 1; + pip_tag_config.bits.ip4_pctl_flag = 1; + + pip_tag_config.bits.tcp6_tag_type = 0; + pip_tag_config.bits.tcp4_tag_type = 0; + pip_tag_config.bits.ip6_tag_type = 0; + pip_tag_config.bits.ip4_tag_type = 0; + pip_tag_config.bits.inc_prt_flag = 1; + pip_tag_config.bits.non_tag_type = OCTEON_POW_TAG_TYPE_NULL; + pip_tag_config.bits.grp = OCTEON_POW_RX_GROUP_NUM; + + octeon_pip_config_port(port, pip_port_config, pip_tag_config); + + oct_write64(OCTEON_POW_CORE_GROUP_MASK(OUR_CORE), OCTEON_POW_ALL_GROUPS_MASK); + +} + + +/* + * octeon_rgmx_stop_port + * + */ +static u_int octeon_rgmx_stop_port (u_int port) +{ + int interface = INTERFACE(port); + int index = INDEX(port); + octeon_rgmx_prtx_cfg_t gmx_cfg; + u_int last_enabled = 0; + + gmx_cfg.word64 = oct_read64(OCTEON_RGMX_PRTX_CFG(index, interface)); + last_enabled = (gmx_cfg.bits.en == 1); + gmx_cfg.bits.en = 0; + oct_write64(OCTEON_RGMX_PRTX_CFG(index, interface), gmx_cfg.word64); + return (last_enabled); +} + +static void octeon_rgmx_start_port(u_int port) +{ + int interface = INTERFACE(port); + int index = INDEX(port); + octeon_rgmx_prtx_cfg_t gmx_cfg; + + gmx_cfg.word64 = oct_read64(OCTEON_RGMX_PRTX_CFG(index, interface)); + gmx_cfg.bits.en = 1; + oct_write64(OCTEON_RGMX_PRTX_CFG(index, interface), gmx_cfg.word64); +} + + +static void octeon_rgmx_stop (struct rgmx_softc_dev *sc) +{ + octeon_rgmx_stop_port(sc->port); + + /* Reset transmitter variables and interface flags. */ + sc->ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE | IFF_DRV_RUNNING); + sc->ifp->if_timer = 0; + sc->txb_count = 0; + sc->txb_sched = 0; +} + + +/* Change the media selection. */ +static int octeon_rgmx_medchange (struct ifnet *ifp) +{ + struct rgmx_softc_dev *sc = ifp->if_softc; + +#ifdef DIAGNOSTIC + /* If_media should not pass any request for a media which this + interface doesn't support. */ + int b; + + for (b = 0; bit2media[b] != 0; b++) { + if (bit2media[b] == sc->media.ifm_media) break; + } + if (((1 << b) & sc->mbitmap) == 0) { + if_printf(sc->ifp, + "got an unsupported media request (0x%x)\n", + sc->media.ifm_media); + return EINVAL; + } +#endif + + /* We don't actually change media when the interface is down. + fe_init() will do the job, instead. Should we also wait + until the transmission buffer being empty? Changing the + media when we are sending a frame will cause two garbages + on wires, one on old media and another on new. FIXME */ + if (sc->ifp->if_flags & IFF_UP) { + printf(" Media change requested while IF is up\n"); + } else { + printf(" Media change requested while IF is Down\n"); + } + + return 0; +} + + +static void octeon_rgmx_medstat (struct ifnet *ifp, struct ifmediareq *ifm) +{ + /* + * No support for Media Status callback + */ +} + +static int octeon_rgmx_ioctl (struct ifnet * ifp, u_long command, caddr_t data) +{ + struct rgmx_softc_dev *sc = ifp->if_softc; + struct ifreq *ifr = (struct ifreq *)data; + int error = 0; + + if (!sc) { + printf(" octeon_rgmx_ioctl. No sc\n"); + return (0); + } + switch (command) { + + case SIOCSIFFLAGS: + /* + * Switch interface state between "running" and + * "stopped", reflecting the UP flag. + */ + if (ifp->if_flags & IFF_UP) { + + + /* + * New state is IFF_UP + * Restart or Start now, if driver is not running currently. + */ + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + printf(" SIOCSTIFFLAGS UP/Not-running\n"); break; + octeon_rgmx_init(sc); + } else { + printf(" SIOCSTIFFLAGS UP/Running\n"); break; + } + } else { + /* + * New state is IFF_DOWN. + * Stop & shut it down now, if driver is running currently. + */ + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { + printf(" SIOCSTIFFLAGS Down/Running\n"); break; + octeon_rgmx_stop(sc); + } else { + printf(" SIOCSTIFFLAGS Down/Not-Running\n"); break; + } + } + break; + + case SIOCADDMULTI: + case SIOCDELMULTI: + break; + + case SIOCSIFMEDIA: + case SIOCGIFMEDIA: + /* Let if_media to handle these commands and to call + us back. */ + error = ifmedia_ioctl(ifp, ifr, &sc->media, command); + break; + + case SIOCSIFCAP: + { + int mask; + + ifp->if_hwassist &= ~CSUM_TSO; + ifp->if_capenable &= ~IFCAP_VLAN_HWTAGGING; + mask = ifr->ifr_reqcap ^ ifp->if_capenable; + if (mask & IFCAP_HWCSUM) { + ifp->if_capenable ^= IFCAP_HWCSUM; + if (ifp->if_capenable & IFCAP_TXCSUM) { + ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP); + } else { + ifp->if_hwassist &= ~(CSUM_TCP | CSUM_UDP); + } + } + } + break; + + default: + error = ether_ioctl(ifp, command, data); + break; + } + + return (error); +} + + + + +/* + * octeon_rgmx_mark_ready + * + * Initialize the rgmx driver for this instance + * Initialize device. + */ +static void octeon_rgmx_mark_ready (struct rgmx_softc_dev *sc) +{ + + /* Enable interrupts. */ + /* For RGMX they are already enabled earlier */ + + /* Enable transmitter and receiver. */ + /* For RGMX they are already enabled earlier */ + + /* Flush out all HW receive buffers for this interface. */ + /* For RGMX, no means to flush an individual port */ + + /* Set 'running' flag, because we are now running. */ + sc->ifp->if_drv_flags |= IFF_DRV_RUNNING; + + /* Set the HW Address filter. aka program Mac-addr & Multicast filters */ + /* For RGMX this was taken care of via set_mac_addr() */ + + /* Kick start the output */ + /* Hopefully PKO is running and will pick up packets via the timer or receive loop */ +} + + +static void octeon_rgmx_init (void *xsc) +{ + + /* + * Called mostly from ifnet interface ifp->if_init(); + * I think we can anchor most of our iniialization here and + * not do it in different places from driver_attach(). + */ + /* + * For now, we only mark the interface ready + */ + octeon_rgmx_mark_ready((struct rgmx_softc_dev *) xsc); +} + + + +static void octeon_rgmx_config_speed (u_int port, u_int report_link) +{ + int index = INDEX(port); + int iface = INTERFACE(port); + struct rgmx_softc_dev *sc; + octeon_rgmx_rxx_rx_inbnd_t link_status, old_link_status; + octeon_rgmx_prtx_cfg_t gmx_cfg; + uint64_t val64_tx_clk, val64_tx_slot, val64_tx_burst; + u_int last_enabled; + + + sc = get_rgmx_softc(port); + if (!sc) { + printf(" config_speed didn't find sc int:%u port:%u", iface, port); + return; + } + + /* + * Look up interface-port speed params + */ + link_status.word64 = oct_read64(OCTEON_RGMX_RXX_RX_INBND(index, iface)); + + /* + * Compre to prev known state. If same then nothing to do. + */ + if (link_status.word64 == sc->link_status) { + return; + } + + RGMX_LOCK(sc); + + old_link_status.word64 = sc->link_status; + + sc->link_status = link_status.word64; + + last_enabled = octeon_rgmx_stop_port(port); + + gmx_cfg.word64 = oct_read64(OCTEON_RGMX_PRTX_CFG(index, iface)); + + /* + * Duplex + */ + gmx_cfg.bits.duplex = 1; + + switch (link_status.bits.speed) { + case 0: /* 10Mbps */ + gmx_cfg.bits.speed = 0; + gmx_cfg.bits.slottime = 0; + val64_tx_clk = 50; val64_tx_slot = 0x40; val64_tx_burst = 0; + break; + case 1: /* 100Mbps */ + gmx_cfg.bits.speed = 0; + gmx_cfg.bits.slottime = 0; + val64_tx_clk = 5; val64_tx_slot = 0x40; val64_tx_burst = 0; + break; + + case 2: /* 1Gbps */ + gmx_cfg.bits.speed = 1; + gmx_cfg.bits.slottime = 1; + val64_tx_clk = 1; val64_tx_slot = 0x200; val64_tx_burst = 0x2000; + break; + + case 3: /* ?? */ + default: + gmx_cfg.bits.speed = 1; + gmx_cfg.bits.slottime = 1; + val64_tx_clk = 1; val64_tx_slot = 0x200; val64_tx_burst = 0x2000; + break; + } + + oct_write64(OCTEON_RGMX_TXX_CLK(index, iface), val64_tx_clk); + oct_write64(OCTEON_RGMX_TXX_SLOT(index, iface), val64_tx_slot); + oct_write64(OCTEON_RGMX_TXX_BURST(index, iface), val64_tx_burst); + + oct_write64(OCTEON_RGMX_PRTX_CFG(index, iface), gmx_cfg.word64); + + if (last_enabled) octeon_rgmx_start_port(port); + + if (link_status.bits.status != old_link_status.bits.status) { + +//#define DEBUG_LINESTATUS + if (link_status.bits.status) { +#ifdef DEBUG_LINESTATUS + printf(" %u/%u: Interface is now alive\n", iface, port); +#endif + if (report_link) if_link_state_change(sc->ifp, LINK_STATE_UP); + } else { +#ifdef DEBUG_LINESTATUS + printf(" %u/%u: Interface went down\n", iface, port); +#endif + if (report_link) if_link_state_change(sc->ifp, LINK_STATE_DOWN); + } + } + RGMX_UNLOCK(sc); + +} + + + +static void octeon_dump_rgmx_stats (u_int port) +{ + +} + + +static void rgmx_timer_periodic (void) +{ + u_int port; + int index; + struct rgmx_softc_dev *sc; + struct ifnet *ifp; + + for (index = 0; index < OCTEON_RGMX_NUM_PORTS_MAX; index ++) { + + port = port_array[index]; + sc = rgmx_scdev_array[index]; + + /* + * Skip over ports/slots not in service. + */ + if ((port < OCTEON_RGMX_MIN_PORT) || (port > OCTEON_RGMX_MAX_PORT)) { + continue; + } + if ((NULL == sc) || (((struct rgmx_softc_dev *)-1) == sc)) { + continue; + } + + /* + * Now look for anamolous conditions + */ + if (sc != get_rgmx_softc(port)) { + printf(" port %u sc 0x%X not in sync with index: %u\n", + port, sc, index); + continue; + } + + if (sc->port != port) { + printf(" port %u sc 0x%X port-> %u not in sync with index: %u\n", + port, sc, sc->port, index); + continue; + } + + ifp = sc->ifp; + if (ifp == NULL) { + printf(" port %u sc 0x%X . Bad ifp 0x%X\n", port, sc, ifp); + continue; + } + + /* + * Check if packets queued at ifnet layer. Kick start output if we can. + */ + if (sc->ifp->if_flags & IFF_UP) { + octeon_rgmx_output_start(ifp); + } else { + octeon_rgmx_output_flush(ifp); + } + + /* + * Check if line status changed ? Adjust ourselves. + */ + octeon_rgmx_config_speed(port, 1); + } +} + + +static void octeon_dump_pow_stats (void) +{ + octeon_rgmx_pow_nos_cnt nos_cnt; + octeon_rgmx_pow_int_pc_t intpc; + octeon_rgmx_pow_int_threshold_t thr; + octeon_rgmx_pow_int_cnt_t int_cnt; + int core = octeon_get_core_num(); + octeon_pow_inpt_q_all_qos inpt_q_all; + octeon_pow_inpt_q_grp_qos inpt_q_grp; + octeon_rgmx_pip_inb_pkts pkts; + octeon_rgmx_pip_inb_errs errs; + static u_int pkts0 = 0; + static u_int pkts1 = 0; + static u_int errs0 = 0; + static u_int errs1 = 0; + int i; + + + nos_cnt.word64 = oct_read64(OCTEON_RGMX_POW_NOS_CNT); + if (nos_cnt.bits.nos_cnt) printf(" *** No sched cnt %u\n", nos_cnt.bits.nos_cnt); + printf(" \nGroup mask: 0x%llX WorkQueue Int : 0x%llX\n", oct_read64(OCTEON_POW_CORE_GROUP_MASK(OUR_CORE)), oct_read64(OCTEON_POW_WORKQUEUE_INT)); + intpc.word64 = oct_read64(OCTEON_POW_WORKQUEUE_INT_PC); + printf(" Intr Periodic Cntr: PC %u thr: %u\n", intpc.bits.thr_freq, intpc.bits.thr_period); + thr.word64 = oct_read64(OCTEON_POW_WORKQUEUE_INT_THRESHOLD(OCTEON_POW_RX_GROUP_NUM)); + printf(" Thresholds iq %u ds %u time %u enable %u\n", + thr.bits.iq_thr, thr.bits.ds_thr, thr.bits.time_thr, thr.bits.enable); + int_cnt.word64 = oct_read64(OCTEON_POW_INT_CNTR(core)); + printf(" Int_cnt iq_cnt %u ds_cnt %u tc_cnt %u\n", + int_cnt.bits.iq_cnt, int_cnt.bits.ds_cnt, int_cnt.bits.tc_cnt); + pkts.word64 = oct_read64(OCTEON_PIP_STAT_INB_PKTS(16)); pkts0 += pkts.bits.inb_pkts; + errs.word64 = oct_read64(OCTEON_PIP_STAT_INB_ERRS(16)); errs0 += errs.bits.inb_errs; + pkts.word64 = oct_read64(OCTEON_PIP_STAT_INB_PKTS(17)); pkts1 += pkts.bits.inb_pkts; + errs.word64 = oct_read64(OCTEON_PIP_STAT_INB_ERRS(17)); errs1 += errs.bits.inb_errs; + printf(" PIP inbound pkts(16): %u Errors: %u inbound(17): %u Errors: %u\n", pkts0, errs0, pkts1, errs1); + inpt_q_all.word64 = oct_read64(OCTEON_POW_INPT_Q_ALL_QOS); + printf(" All queued pkt in qos Levels: %u -- ", inpt_q_all.bits.iq_cnt); + for (i = 0 ; i < 7; i++) { + inpt_q_grp.word64 = oct_read64(OCTEON_POW_INPT_QOS_GRP(i)); + if (inpt_q_grp.bits.iq_cnt) printf(" Grp-%u: %u ", i, inpt_q_grp.bits.iq_cnt); + } +} + + +/* ------------------------------------------------------------------- * + * octeon_line_status_loop() * + * ------------------------------------------------------------------- */ +static void octeon_line_status_loop (void *unused) +{ + struct rgmx_softc_dev *sc; + u_int idx; + + for (idx = 0; idx < num_devices; idx++) { + sc = rgmx_scdev_array[idx]; + if (sc && sc->ifp) { + if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING)) { + octeon_rgmx_config_speed(sc->port, 1); + + octeon_rgmx_output_start(sc->ifp); + } + } + } + +//#define DEBUG_RGMX_DUMP +#ifdef DEBUG_RGMX_DUMP + static int count = 0; + + if (++count > 5) { + count = 0; +// octeon_dump_fpa_pool(OCTEON_FPA_RX_PACKET_POOL); +// octeon_dump_fpa_pool(OCTEON_FPA_WQE_RX_POOL); +// octeon_dump_fpa_pool(OCTEON_FPA_TX_PACKET_POOL); + octeon_dump_rgmx_stats(16); + octeon_dump_pow_stats(); + } +#endif +} + + +/* ------------------------------------------------------------------- * + * octeon_rgmx_set_mac * + * ------------------------------------------------------------------- * + * + * octeon_rgmx_set_mac + * + * Program the ethernet HW address + * + */ +static void octeon_rgmx_set_mac (u_int port) +{ + struct rgmx_softc_dev *sc; + u_int iface = INTERFACE(port); + u_int index = INDEX(port); + int ii; + uint64_t mac = 0; + u_int last_enabled; + + sc = get_rgmx_softc(port); + if (!sc) { + printf(" octeon_rgmx_set_mac Missing sc. port:%u", port); + return; + } + + for (ii = 0; ii < 6; ii++) { + mac = (mac << 8) | (uint64_t)(sc->ieee[ii]); + } + + last_enabled = octeon_rgmx_stop_port(port); + + oct_write64(OCTEON_RGMX_SMACX(index, iface), mac); + oct_write64(OCTEON_RGMX_RXX_ADR_CAM0(index, iface), sc->ieee[0]); + oct_write64(OCTEON_RGMX_RXX_ADR_CAM1(index, iface), sc->ieee[1]); + oct_write64(OCTEON_RGMX_RXX_ADR_CAM2(index, iface), sc->ieee[2]); + oct_write64(OCTEON_RGMX_RXX_ADR_CAM3(index, iface), sc->ieee[3]); + oct_write64(OCTEON_RGMX_RXX_ADR_CAM4(index, iface), sc->ieee[4]); + oct_write64(OCTEON_RGMX_RXX_ADR_CAM5(index, iface), sc->ieee[5]); + oct_write64(OCTEON_RGMX_RXX_ADR_CTL(index, iface), + OCTEON_RGMX_ADRCTL_ACCEPT_BROADCAST | + OCTEON_RGMX_ADRCTL_ACCEPT_ALL_MULTICAST | + OCTEON_RGMX_ADRCTL_CAM_MODE_ACCEPT_DMAC); + oct_write64(OCTEON_RGMX_RXX_ADR_CAM_EN(index, iface), 1); + if (last_enabled) octeon_rgmx_start_port(port); +} + + +/* ------------------------------------------------------------------- * + * octeon_config_rgmii_port() * + * ------------------------------------------------------------------- */ +static void octeon_config_rgmii_port (u_int port) +{ + u_int iface = INTERFACE(port); + u_int index = INDEX(port); + + /* + * Configure an RGMII port + */ + octeon_rgmx_prtx_cfg_t gmx_cfg; + + /* Enable ASX */ + oct_write64(OCTEON_ASXX_RX_PRT_EN(iface), oct_read64(OCTEON_ASXX_RX_PRT_EN(iface)) | (1<sc_dev; + + /* + * Make sure that sc/dev are the parent Root structs. Not one + * of the rgmxN childs. + */ + if (int_handler_tag != NULL) { + bus_teardown_intr(dev, irq_res, int_handler_tag); + int_handler_tag = NULL; + } + +#ifdef OCTEON_RGMX_SCHEDULED_ISRS + if (tq != NULL) { + taskqueue_drain(tq, &rxtx_isr_task); + taskqueue_drain(taskqueue_fast, &link_isr_task); + taskqueue_free(tq); + tq = NULL; + } +#endif + +} + + +static device_method_t rgmii_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, rgmii_probe), + DEVMETHOD(device_identify, rgmii_identify), + DEVMETHOD(device_attach, rgmii_attach), + DEVMETHOD(device_detach, bus_generic_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + + { 0, 0 } +}; + +static driver_t rgmii_driver = { + "rgmii", rgmii_methods, sizeof(struct rgmx_softc_dev) +}; + +static devclass_t rgmii_devclass; + +DRIVER_MODULE(rgmii, nexus, rgmii_driver, rgmii_devclass, 0, 0); diff --git a/sys/dev/le/octeon_rgmx.h b/sys/dev/le/octeon_rgmx.h new file mode 100644 index 00000000000..8e446ec47d9 --- /dev/null +++ b/sys/dev/le/octeon_rgmx.h @@ -0,0 +1,594 @@ +/*------------------------------------------------------------------ + * octeon_rgmx.h RGMII Ethernet Interfaces + * + *------------------------------------------------------------------ + */ + + +#ifndef ___OCTEON_RGMX__H___ +#define ___OCTEON_RGMX__H___ + + + +#define OCTEON_FPA_PACKET_POOL 0 +#define OCTEON_FPA_WQE_RX_POOL 1 +#define OCTEON_FPA_OUTPUT_BUFFER_POOL 2 +#define OCTEON_FPA_WQE_POOL_SIZE (1 * OCTEON_CACHE_LINE_SIZE) +#define OCTEON_FPA_OUTPUT_BUFFER_POOL_SIZE (8 * OCTEON_CACHE_LINE_SIZE) +#define OCTEON_FPA_PACKET_POOL_SIZE (16 * OCTEON_CACHE_LINE_SIZE) + +#define OCTEON_POW_WORK_REQUEST(wait) (0x8001600000000000ull | (wait<<3)) + +typedef union +{ + void* ptr; + uint64_t word64; + struct + { + uint64_t i : 1; + uint64_t back : 4; + uint64_t pool : 3; + uint64_t size :16; + uint64_t addr :40; + } bits; +} octeon_buf_ptr_t; + +/** + * Work queue entry format + */ +typedef struct +{ + uint16_t hw_chksum; + uint8_t unused; + uint64_t next_ptr : 40; + uint64_t len :16; + uint64_t ipprt : 6; + uint64_t qos : 3; + uint64_t grp : 4; + uint64_t tag_type : 3; + uint64_t tag :32; + union + { + uint64_t word64; + struct + { + uint64_t bufs : 8; + uint64_t ip_offset : 8; + uint64_t vlan_valid : 1; + uint64_t unassigned : 2; + uint64_t vlan_cfi : 1; + uint64_t vlan_id :12; + uint64_t unassigned2 :12; + uint64_t dec_ipcomp : 1; + uint64_t tcp_or_udp : 1; + uint64_t dec_ipsec : 1; + uint64_t is_v6 : 1; + uint64_t software : 1; + uint64_t L4_error : 1; + uint64_t is_frag : 1; + uint64_t IP_exc : 1; + uint64_t is_bcast : 1; + uint64_t is_mcast : 1; + uint64_t not_IP : 1; + uint64_t rcv_error : 1; + uint64_t err_code : 8; + } bits; + struct + { + uint64_t bufs : 8; + uint64_t unused : 8; + uint64_t vlan_valid : 1; + uint64_t unassigned : 2; + uint64_t vlan_cfi : 1; + uint64_t vlan_id :12; + uint64_t unassigned2 :16; + uint64_t software : 1; + uint64_t unassigned3 : 1; + uint64_t is_rarp : 1; + uint64_t is_arp : 1; + uint64_t is_bcast : 1; + uint64_t is_mcast : 1; + uint64_t not_IP : 1; + uint64_t rcv_error : 1; + uint64_t err_code : 8; + } snoip; + } word2; + octeon_buf_ptr_t packet_ptr; + uint8_t packet_data[96]; +} octeon_wqe_t; + +typedef union { + uint64_t word64; + + struct { + uint64_t scraddr : 8; /**< the (64-bit word) location in scratchpad to write to (if len != 0) */ + uint64_t len : 8; /**< the number of words in the response (0 => no response) */ + uint64_t did : 8; /**< the ID of the device on the non-coherent bus */ + uint64_t unused :36; + uint64_t wait : 1; /**< if set, don't return load response until work is available */ + uint64_t unused2 : 3; + } bits; + +} octeon_pow_iobdma_store_t; + + +/** + * Wait flag values for pow functions. + */ +typedef enum +{ + OCTEON_POW_WAIT = 1, + OCTEON_POW_NO_WAIT = 0, +} octeon_pow_wait_t; + + + +static inline void * phys_to_virt (unsigned long address) +{ + return (void *)(address + 0x80000000UL); +} + +// decode within DMA space +typedef enum { + OCTEON_ADD_WIN_DMA_ADD = 0L, // add store data to the write buffer entry, allocating it if necessary + OCTEON_ADD_WIN_DMA_SENDMEM = 1L, // send out the write buffer entry to DRAM + // store data must be normal DRAM memory space address in this case + OCTEON_ADD_WIN_DMA_SENDDMA = 2L, // send out the write buffer entry as an IOBDMA command + // see OCTEON_ADD_WIN_DMA_SEND_DEC for data contents + OCTEON_ADD_WIN_DMA_SENDIO = 3L, // send out the write buffer entry as an IO write + // store data must be normal IO space address in this case + OCTEON_ADD_WIN_DMA_SENDSINGLE = 4L, // send out a single-tick command on the NCB bus + // no write buffer data needed/used +} octeon_add_win_dma_dec_t; + + +#define OCTEON_OCT_DID_FPA 5ULL +#define OCTEON_OCT_DID_TAG 12ULL +#define OCTEON_OCT_DID_TAG_SWTAG OCTEON_ADDR_FULL_DID(OCTEON_OCT_DID_TAG, 0ULL) + + +#define OCTEON_IOBDMA_OFFSET (-3*1024ll) +#define OCTEON_IOBDMA_SEP 16 +#define OCTEON_IOBDMA_SENDSINGLE (OCTEON_IOBDMA_OFFSET + \ + (OCTEON_ADD_WIN_DMA_SENDSINGLE *\ + OCTEON_IOBDMA_SEP)) + +static inline void octeon_send_single (uint64_t data) +{ + oct_write64((uint64_t)(OCTEON_IOBDMA_SENDSINGLE * (long long)8), data); +} + + +static inline void octeon_pow_work_request_async_nocheck (int scratch_addr, + octeon_pow_wait_t wait) +{ + octeon_pow_iobdma_store_t data; + + /* scratch_addr must be 8 byte aligned */ + data.bits.scraddr = scratch_addr >> 3; + data.bits.len = 1; + data.bits.did = OCTEON_OCT_DID_TAG_SWTAG; + data.bits.wait = wait; + octeon_send_single(data.word64); +} + + + +/** + * octeon_gmx_inf_mode + * + * GMX_INF_MODE = Interface Mode + * + */ +typedef union +{ + uint64_t word64; + struct gmxx_inf_mode_s + { + uint64_t reserved_3_63 : 61; + uint64_t p0mii : 1; /**< Port 0 Interface Mode + 0: Port 0 is RGMII + 1: Port 0 is MII */ + uint64_t en : 1; /**< Interface Enable */ + uint64_t type : 1; /**< Interface Mode + 0: RGMII Mode + 1: Spi4 Mode */ + } bits; + struct gmxx_inf_mode_cn3020 + { + uint64_t reserved_2_63 : 62; + uint64_t en : 1; /**< Interface Enable */ + uint64_t type : 1; /**< Interface Mode + 0: All three ports are RGMII ports + 1: prt0 is RGMII, prt1 is GMII, and prt2 is unused */ + } cn3020; + struct gmxx_inf_mode_s cn30xx; + struct gmxx_inf_mode_cn3020 cn31xx; + struct gmxx_inf_mode_cn3020 cn36xx; + struct gmxx_inf_mode_cn3020 cn38xx; + struct gmxx_inf_mode_cn3020 cn38xxp2; + struct gmxx_inf_mode_cn3020 cn56xx; + struct gmxx_inf_mode_cn3020 cn58xx; +} octeon_gmxx_inf_mode_t; + + + + +typedef union { + uint64_t word64; + struct { + uint64_t reserved : 60; /* Reserved */ + uint64_t slottime : 1; /* Slot Time for Half-Duplex */ + /* operation - 0 = 512 bitimes (10/100Mbs operation) */ + /* - 1 = 4096 bitimes (1000Mbs operation) */ + uint64_t duplex : 1; /* Duplex - 0 = Half Duplex */ + /* (collisions/extentions/bursts) - 1 = Full Duplex */ + uint64_t speed : 1; /* Link Speed - 0 = 10/100Mbs */ + /* operation - 1 = 1000Mbs operation */ + uint64_t en : 1; /* Link Enable */ + } bits; +} octeon_rgmx_prtx_cfg_t; + + +/* + * GMX_RX_INBND = RGMX InBand Link Status + * + */ +typedef union { + uint64_t word64; + struct { + uint64_t reserved : 60; /* Reserved */ + uint64_t duplex : 1; /* 0 = Half, 1 = Full */ + uint64_t speed : 2; /* Inbound Link Speed */ + /* 00 = 2.5Mhz, 01 = 25Mhz */ + /* 10 = 125MHz, 11 = Reserved */ + uint64_t status : 1; /* Inbound Status Up/Down */ + } bits; +} octeon_rgmx_rxx_rx_inbnd_t; + + + +typedef union +{ + uint64_t word64; + struct { + uint64_t all_drop : 32; + uint64_t slow_drop : 32; + } bits; +} octeon_rgmx_ipd_queue_red_marks_t; + + +typedef union +{ + uint64_t word64; + struct { + uint64_t reserved : 15; + uint64_t use_pagecount : 1; + uint64_t new_con : 8; + uint64_t avg_con : 8; + uint64_t prb_con : 32; + } bits; +} octeon_rgmx_ipd_red_q_param_t; + + + +typedef union +{ + uint64_t word64; + struct { + uint64_t reserved : 46; + uint64_t bp_enable : 1; + uint64_t page_count : 17; + } bits; +} octeon_ipd_port_bp_page_count_t; + + +typedef union +{ + uint64_t word64; + struct { + uint64_t prb_dly : 14; + uint64_t avg_dly : 14; + uint64_t port_enable : 36; + } bits; +} octeon_ipd_red_port_enable_t; + + +/** + * Tag type definitions + */ +typedef enum +{ + OCTEON_POW_TAG_TYPE_ORDERED = 0L, /**< Tag ordering is maintained */ + OCTEON_POW_TAG_TYPE_ATOMIC = 1L, /**< Tag ordering is maintained, and at most one PP has the tag */ + OCTEON_POW_TAG_TYPE_NULL = 2L, /**< The work queue entry from the order + - NEVER tag switch from NULL to NULL */ + OCTEON_POW_TAG_TYPE_NULL_NULL = 3L /**< A tag switch to NULL, and there is no space reserved in POW + - NEVER tag switch to NULL_NULL + - NEVER tag switch from NULL_NULL + - NULL_NULL is entered at the beginning of time and on a deschedule. + - NULL_NULL can be exited by a new work request. A NULL_SWITCH load can also switch the state to NULL */ +} octeon_pow_tag_type_t ; + +/** + * This structure defines the response to a load/SENDSINGLE to POW (except CSR reads) + */ +typedef union { + uint64_t word64; + + octeon_wqe_t *wqp; + + // response to new work request loads + struct { + uint64_t no_work : 1; // set when no new work queue entry was returned + // If there was de-scheduled work, the HW will definitely + // return it. When this bit is set, it could mean + // either mean: + // - There was no work, or + // - There was no work that the HW could find. This + // case can happen, regardless of the wait bit value + // in the original request, when there is work + // in the IQ's that is too deep down the list. + uint64_t unused : 23; + uint64_t addr : 40; // 36 in O1 -- the work queue pointer + } s_work; + + // response to NULL_RD request loads + struct { + uint64_t unused : 62; + uint64_t state : 2; // of type octeon_pow_tag_type_t + // state is one of the following: + // OCTEON_POW_TAG_TYPE_ORDERED + // OCTEON_POW_TAG_TYPE_ATOMIC + // OCTEON_POW_TAG_TYPE_NULL + // OCTEON_POW_TAG_TYPE_NULL_NULL + } s_null_rd; + +} octeon_pow_tag_load_resp_t; + + +/* + * This structure describes the address to load stuff from POW + */ +typedef union { + uint64_t word64; + + // address for new work request loads (did<2:0> == 0) + struct { + uint64_t mem_region :2; + uint64_t mbz :13; + uint64_t is_io : 1; // must be one + uint64_t did : 8; // the ID of POW -- did<2:0> == 0 in this case + uint64_t unaddr : 4; + uint64_t unused :32; + uint64_t wait : 1; // if set, don't return load response until work is available + uint64_t mbzl : 3; // must be zero + } swork; // physical address + + + // address for NULL_RD request (did<2:0> == 4) + // when this is read, HW attempts to change the state to NULL if it is NULL_NULL + // (the hardware cannot switch from NULL_NULL to NULL if a POW entry is not available - + // software may need to recover by finishing another piece of work before a POW + // entry can ever become available.) + struct { + uint64_t mem_region :2; + uint64_t mbz :13; + uint64_t is_io : 1; // must be one + uint64_t did : 8; // the ID of POW -- did<2:0> == 4 in this case + uint64_t unaddr : 4; + uint64_t unused :33; + uint64_t mbzl : 3; // must be zero + } snull_rd; // physical address + + // address for CSR accesses + struct { + uint64_t mem_region :2; + uint64_t mbz :13; + uint64_t is_io : 1; // must be one + uint64_t did : 8; // the ID of POW -- did<2:0> == 7 in this case + uint64_t unaddr : 4; + uint64_t csraddr:36; // only 36 bits in O1, addr<2:0> must be zero + } stagcsr; // physical address + +} octeon_pow_load_addr_t; + + +static inline void octeon_pow_tag_switch_wait (void) +{ + uint64_t switch_complete; + + do + { + OCTEON_CHORD_HEX(&switch_complete); + } while (!switch_complete); + + return; +} + + +static inline octeon_wqe_t *octeon_pow_work_request_sync_nocheck (octeon_pow_wait_t wait) +{ + octeon_pow_load_addr_t ptr; + octeon_pow_tag_load_resp_t result; + + ptr.word64 = 0; + ptr.swork.mem_region = OCTEON_IO_SEG; + ptr.swork.is_io = 1; + ptr.swork.did = OCTEON_OCT_DID_TAG_SWTAG; + ptr.swork.wait = wait; + + result.word64 = oct_read64(ptr.word64); + + if (result.s_work.no_work || !result.s_work.addr) { + return NULL; + } + return (octeon_wqe_t *) OCTEON_PHYS2PTR(result.s_work.addr); +} + +static inline octeon_wqe_t *octeon_pow_work_request_sync_nocheck_debug (octeon_pow_wait_t wait) +{ + octeon_pow_load_addr_t ptr; + octeon_pow_tag_load_resp_t result; + + ptr.word64 = 0; + ptr.swork.mem_region = OCTEON_IO_SEG; + ptr.swork.is_io = 1; + ptr.swork.did = OCTEON_OCT_DID_TAG_SWTAG; + ptr.swork.wait = wait; + + result.word64 = oct_read64(ptr.word64); + + printf("WQE Result: 0x%llX No-work %llX Addr %llX Ptr: %llX\n", + result.word64, result.s_work.no_work, result.s_work.addr, OCTEON_PHYS2PTR(result.s_work.addr)); + + if (result.s_work.no_work || !result.s_work.addr) { + return NULL; + } + return (octeon_wqe_t *) OCTEON_PHYS2PTR(result.s_work.addr); +} + +static inline octeon_wqe_t *octeon_pow_work_request_sync (octeon_pow_wait_t wait) +{ + octeon_pow_tag_switch_wait(); + return (octeon_pow_work_request_sync_nocheck(wait)); +} + + +static inline octeon_wqe_t *octeon_pow_work_request_sync_debug (octeon_pow_wait_t wait) +{ + octeon_pow_tag_switch_wait(); + return (octeon_pow_work_request_sync_nocheck_debug(wait)); +} + + + +/** + * Gets result of asynchronous work request. Performs a IOBDMA sync + * to wait for the response. + * + * @param scratch_addr Scratch memory address to get result from + * Byte address, must be 8 byte aligned. + * @return Returns the WQE from the scratch register, or NULL if no work was available. + */ +static inline octeon_wqe_t *octeon_pow_work_response_async(int scratch_addr) +{ + octeon_pow_tag_load_resp_t result; + + OCTEON_SYNCIOBDMA; + result.word64 = oct_scratch_read64(scratch_addr); + + if (result.s_work.no_work) { + return NULL; + } + return (octeon_wqe_t*) OCTEON_PHYS2PTR(result.s_work.addr); +} + + + +/* + * The address from POW is a physical address. Adjust for back ptr, as well as + * make it accessible using KSEG0. + */ +static inline void *octeon_pow_pktptr_to_kbuffer (octeon_buf_ptr_t pkt_ptr) +{ + return (OCTEON_PHYS2PTR(((pkt_ptr.bits.addr >> 7) - pkt_ptr.bits.back) << 7)); +} + + + + +#define INTERFACE(port) (port >> 4) /* Ports 0-15 are interface 0, 16-31 are interface 1 */ +#define INDEX(port) (port & 0xf) + + + + +#define OCTEON_RGMX_PRTX_CFG(index,interface) (0x8001180008000010ull+((index)*2048)+((interface)*0x8000000ull)) +#define OCTEON_RGMX_SMACX(offset,block_id) (0x8001180008000230ull+((offset)*2048)+((block_id)*0x8000000ull)) +#define OCTEON_RGMX_RXX_ADR_CAM0(offset,block_id) (0x8001180008000180ull+((offset)*2048)+((block_id)*0x8000000ull)) +#define OCTEON_RGMX_RXX_ADR_CAM1(offset,block_id) (0x8001180008000188ull+((offset)*2048)+((block_id)*0x8000000ull)) +#define OCTEON_RGMX_RXX_ADR_CAM2(offset,block_id) (0x8001180008000190ull+((offset)*2048)+((block_id)*0x8000000ull)) +#define OCTEON_RGMX_RXX_ADR_CAM3(offset,block_id) (0x8001180008000198ull+((offset)*2048)+((block_id)*0x8000000ull)) +#define OCTEON_RGMX_RXX_ADR_CAM4(offset,block_id) (0x80011800080001A0ull+((offset)*2048)+((block_id)*0x8000000ull)) +#define OCTEON_RGMX_RXX_ADR_CAM5(offset,block_id) (0x80011800080001A8ull+((offset)*2048)+((block_id)*0x8000000ull)) +#define OCTEON_RGMX_RXX_ADR_CTL(offset,block_id) (0x8001180008000100ull+((offset)*2048)+((block_id)*0x8000000ull)) +#define OCTEON_RGMX_RXX_ADR_CAM_EN(offset,block_id) (0x8001180008000108ull+((offset)*2048)+((block_id)*0x8000000ull)) +#define OCTEON_RGMX_INF_MODE(block_id) (0x80011800080007F8ull+((block_id)*0x8000000ull)) +#define OCTEON_RGMX_TX_PRTS(block_id) (0x8001180008000480ull+((block_id)*0x8000000ull)) +#define OCTEON_ASXX_RX_PRT_EN(block_id) (0x80011800B0000000ull+((block_id)*0x8000000ull)) +#define OCTEON_ASXX_TX_PRT_EN(block_id) (0x80011800B0000008ull+((block_id)*0x8000000ull)) +#define OCTEON_RGMX_TXX_THRESH(offset,block_id) (0x8001180008000210ull+((offset)*2048)+((block_id)*0x8000000ull)) +#define OCTEON_ASXX_TX_HI_WATERX(offset,block_id) (0x80011800B0000080ull+((offset)*8)+((block_id)*0x8000000ull)) +#define OCTEON_ASXX_RX_CLK_SETX(offset,block_id) (0x80011800B0000020ull+((offset)*8)+((block_id)*0x8000000ull)) +#define OCTEON_ASXX_TX_CLK_SETX(offset,block_id) (0x80011800B0000048ull+((offset)*8)+((block_id)*0x8000000ull)) +#define OCTEON_RGMX_RXX_RX_INBND(offset,block_id) (0x8001180008000060ull+((offset)*2048)+((block_id)*0x8000000ull)) +#define OCTEON_RGMX_TXX_CLK(offset,block_id) (0x8001180008000208ull+((offset)*2048)+((block_id)*0x8000000ull)) +#define OCTEON_RGMX_TXX_SLOT(offset,block_id) (0x8001180008000220ull+((offset)*2048)+((block_id)*0x8000000ull)) +#define OCTEON_RGMX_TXX_BURST(offset,block_id) (0x8001180008000228ull+((offset)*2048)+((block_id)*0x8000000ull)) +#define OCTEON_PIP_GBL_CTL (0x80011800A0000020ull) +#define OCTEON_PIP_GBL_CFG (0x80011800A0000028ull) +#define OCTEON_PIP_PRT_CFGX(offset) (0x80011800A0000200ull+((offset)*8)) +#define OCTEON_PIP_PRT_TAGX(offset) (0x80011800A0000400ull+((offset)*8)) + + + +#define OUR_CORE 0 +#define IP2 0 +#define IP3 1 +#define CIU_TIMERS 4 +#define OCTEON_POW_CORE_GROUP_MASK(core) (0x8001670000000000ull + (8 * core)) + +#define OCTEON_CIU_INT_EN0(CORE,IP) (0x8001070000000200ull + (IP * 16) + \ + ((CORE) * 32)) +#define OCTEON_CIU_INT_SUM0(CORE,IP) (0x8001070000000000ull + (IP * 8) + \ + ((CORE) * 32)) +#define OCTEON_CIU_TIMX(offset) (0x8001070000000480ull+((offset)*8)) + +#define OCTEON_POW_WQ_INT_THRX(offset) ((0x8001670000000080ull+((offset)*8))) +#define OCTEON_POW_WQ_INT_CNTX(offset) ((0x8001670000000100ull+((offset)*8))) +#define OCTEON_POW_QOS_THRX(offset) ((0x8001670000000180ull+((offset)*8))) +#define OCTEON_POW_QOS_RNDX(offset) ((0x80016700000001C0ull+((offset)*8))) +#define OCTEON_POW_WQ_INT_PC (0x8001670000000208ull) +#define OCTEON_POW_NW_TIM (0x8001670000000210ull) +#define OCTEON_POW_ECC_ERR (0x8001670000000218ull) +#define OCTEON_POW_INT_CTL (0x8001670000000220ull) +#define OCTEON_POW_NOS_CNT (0x8001670000000228ull) +#define OCTEON_POW_WS_PCX(offset) ((0x8001670000000280ull+((offset)*8))) +#define OCTEON_POW_WA_PCX(offset) ((0x8001670000000300ull+((offset)*8))) +#define OCTEON_POW_IQ_CNTX(offset) ((0x8001670000000340ull+((offset)*8))) +#define OCTEON_POW_WA_COM_PC (0x8001670000000380ull) +#define OCTEON_POW_IQ_COM_CNT (0x8001670000000388ull) +#define OCTEON_POW_TS_PC (0x8001670000000390ull) +#define OCTEON_POW_DS_PC (0x8001670000000398ull) +#define OCTEON_POW_BIST_STAT (0x80016700000003F8ull) + + +#define OCTEON_POW_WQ_INT (0x8001670000000200ull) + +#define OCTEON_IPD_PORT_BP_COUNTERS_PAIRX(offset) (0x80014F00000001B8ull+((offset)*8)) + +/* + * Current Counts that triggered interrupt + */ +#define OCTEON_POW_WQ_INT_CNTX(offset) ((0x8001670000000100ull+((offset)*8))) + + + +#define OCTEON_RGMX_ADRCTL_CAM_MODE_REJECT_DMAC 0 +#define OCTEON_RGMX_ADRCTL_ACCEPT_BROADCAST 1 +#define OCTEON_RGMX_ADRCTL_REJECT_ALL_MULTICAST 2 +#define OCTEON_RGMX_ADRCTL_ACCEPT_ALL_MULTICAST 4 +#define OCTEON_RGMX_ADRCTL_CAM_MODE_ACCEPT_DMAC 8 + + + +#define RGMX_LOCK_INIT(_sc, _name) \ + mtx_init(&(_sc)->mtx, _name, MTX_NETWORK_LOCK, MTX_DEF) +#define RGMX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->mtx) +#define RGMX_LOCK(_sc) mtx_lock(&(_sc)->mtx) +#define RGMX_UNLOCK(_sc) mtx_unlock(&(_sc)->mtx) +#define RGMX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->mtx, MA_OWNED) + + +#endif /* ___OCTEON_RGMX__H___ */ From 654d4c24962cffd4953d0c74c42943105e348ce9 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 04:10:27 +0000 Subject: [PATCH 107/380] Move octeon rgmii driver to is more correct new home. --- .../octeon1/dev/rgmii}/octeon_fau.c | 0 .../octeon1/dev/rgmii}/octeon_fau.h | 0 .../octeon1/dev/rgmii}/octeon_fpa.c | 0 .../octeon1/dev/rgmii}/octeon_fpa.h | 0 .../octeon1/dev/rgmii}/octeon_ipd.c | 0 .../octeon1/dev/rgmii}/octeon_ipd.h | 0 .../octeon1/dev/rgmii}/octeon_pip.h | 0 .../octeon1/dev/rgmii}/octeon_pko.c | 0 .../octeon1/dev/rgmii}/octeon_pko.h | 0 .../octeon1/dev/rgmii}/octeon_rgmx.c | 0 .../octeon1/dev/rgmii}/octeon_rgmx.h | 0 sys/mips/octeon1/files.octeon1 | 27 ++++++++----------- 12 files changed, 11 insertions(+), 16 deletions(-) rename sys/{dev/le => mips/octeon1/dev/rgmii}/octeon_fau.c (100%) rename sys/{dev/le => mips/octeon1/dev/rgmii}/octeon_fau.h (100%) rename sys/{dev/le => mips/octeon1/dev/rgmii}/octeon_fpa.c (100%) rename sys/{dev/le => mips/octeon1/dev/rgmii}/octeon_fpa.h (100%) rename sys/{dev/le => mips/octeon1/dev/rgmii}/octeon_ipd.c (100%) rename sys/{dev/le => mips/octeon1/dev/rgmii}/octeon_ipd.h (100%) rename sys/{dev/le => mips/octeon1/dev/rgmii}/octeon_pip.h (100%) rename sys/{dev/le => mips/octeon1/dev/rgmii}/octeon_pko.c (100%) rename sys/{dev/le => mips/octeon1/dev/rgmii}/octeon_pko.h (100%) rename sys/{dev/le => mips/octeon1/dev/rgmii}/octeon_rgmx.c (100%) rename sys/{dev/le => mips/octeon1/dev/rgmii}/octeon_rgmx.h (100%) diff --git a/sys/dev/le/octeon_fau.c b/sys/mips/octeon1/dev/rgmii/octeon_fau.c similarity index 100% rename from sys/dev/le/octeon_fau.c rename to sys/mips/octeon1/dev/rgmii/octeon_fau.c diff --git a/sys/dev/le/octeon_fau.h b/sys/mips/octeon1/dev/rgmii/octeon_fau.h similarity index 100% rename from sys/dev/le/octeon_fau.h rename to sys/mips/octeon1/dev/rgmii/octeon_fau.h diff --git a/sys/dev/le/octeon_fpa.c b/sys/mips/octeon1/dev/rgmii/octeon_fpa.c similarity index 100% rename from sys/dev/le/octeon_fpa.c rename to sys/mips/octeon1/dev/rgmii/octeon_fpa.c diff --git a/sys/dev/le/octeon_fpa.h b/sys/mips/octeon1/dev/rgmii/octeon_fpa.h similarity index 100% rename from sys/dev/le/octeon_fpa.h rename to sys/mips/octeon1/dev/rgmii/octeon_fpa.h diff --git a/sys/dev/le/octeon_ipd.c b/sys/mips/octeon1/dev/rgmii/octeon_ipd.c similarity index 100% rename from sys/dev/le/octeon_ipd.c rename to sys/mips/octeon1/dev/rgmii/octeon_ipd.c diff --git a/sys/dev/le/octeon_ipd.h b/sys/mips/octeon1/dev/rgmii/octeon_ipd.h similarity index 100% rename from sys/dev/le/octeon_ipd.h rename to sys/mips/octeon1/dev/rgmii/octeon_ipd.h diff --git a/sys/dev/le/octeon_pip.h b/sys/mips/octeon1/dev/rgmii/octeon_pip.h similarity index 100% rename from sys/dev/le/octeon_pip.h rename to sys/mips/octeon1/dev/rgmii/octeon_pip.h diff --git a/sys/dev/le/octeon_pko.c b/sys/mips/octeon1/dev/rgmii/octeon_pko.c similarity index 100% rename from sys/dev/le/octeon_pko.c rename to sys/mips/octeon1/dev/rgmii/octeon_pko.c diff --git a/sys/dev/le/octeon_pko.h b/sys/mips/octeon1/dev/rgmii/octeon_pko.h similarity index 100% rename from sys/dev/le/octeon_pko.h rename to sys/mips/octeon1/dev/rgmii/octeon_pko.h diff --git a/sys/dev/le/octeon_rgmx.c b/sys/mips/octeon1/dev/rgmii/octeon_rgmx.c similarity index 100% rename from sys/dev/le/octeon_rgmx.c rename to sys/mips/octeon1/dev/rgmii/octeon_rgmx.c diff --git a/sys/dev/le/octeon_rgmx.h b/sys/mips/octeon1/dev/rgmii/octeon_rgmx.h similarity index 100% rename from sys/dev/le/octeon_rgmx.h rename to sys/mips/octeon1/dev/rgmii/octeon_rgmx.h diff --git a/sys/mips/octeon1/files.octeon1 b/sys/mips/octeon1/files.octeon1 index 120c62ef2e9..858a1888544 100644 --- a/sys/mips/octeon1/files.octeon1 +++ b/sys/mips/octeon1/files.octeon1 @@ -1,20 +1,15 @@ -# /* -# * This product includes software developed by the University of -# * California, Berkeley and its contributors." -# */ # $FreeBSD$ # Octeon Support Files # -mips/octeon1/octeon_machdep.c standard -mips/octeon1/obio.c optional uart -mips/octeon1/uart_cpu_octeonusart.c optional uart -mips/octeon1/uart_bus_octeonusart.c optional uart -mips/octeon1/octeon_ebt3000_cf.c optional cf - -mips/mips/mp_machdep.c optional smp dev/uart/uart_dev_oct16550.c optional uart -dev/le/octeon_fau.c optional rgmii -dev/le/octeon_fpa.c optional rgmii -dev/le/octeon_ipd.c optional rgmii -dev/le/octeon_pko.c optional rgmii -dev/le/octeon_rgmx.c optional rgmii +mips/mips/mp_machdep.c optional smp +mips/octeon1/dev/rgmii/octeon_fau.c optional rgmii +mips/octeon1/dev/rgmii/octeon_fpa.c optional rgmii +mips/octeon1/dev/rgmii/octeon_ipd.c optional rgmii +mips/octeon1/dev/rgmii/octeon_pko.c optional rgmii +mips/octeon1/dev/rgmii/octeon_rgmx.c optional rgmii +mips/octeon1/obio.c optional uart +mips/octeon1/octeon_ebt3000_cf.c optional cf +mips/octeon1/octeon_machdep.c standard +mips/octeon1/uart_bus_octeonusart.c optional uart +mips/octeon1/uart_cpu_octeonusart.c optional uart From d0b7b80503483f23baa8d9e0bb981ce5c139fa81 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 04:16:58 +0000 Subject: [PATCH 108/380] Part of the cf driver missed. --- sys/dev/flash/driveid.h | 259 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 sys/dev/flash/driveid.h diff --git a/sys/dev/flash/driveid.h b/sys/dev/flash/driveid.h new file mode 100644 index 00000000000..b7befea1170 --- /dev/null +++ b/sys/dev/flash/driveid.h @@ -0,0 +1,259 @@ + +/* + * driveid.h + * + */ + +#ifndef __DRIVEID_H__ +#define __DRIVEID_H__ + + +struct hd_driveid { + unsigned short config; /* lots of obsolete bit flags */ + unsigned short cyls; /* Obsolete, "physical" cyls */ + unsigned short reserved2; /* reserved (word 2) */ + unsigned short heads; /* Obsolete, "physical" heads */ + unsigned short track_bytes; /* unformatted bytes per track */ + unsigned short sector_bytes; /* unformatted bytes per sector */ + unsigned short sectors; /* Obsolete, "physical" sectors per track */ + unsigned short vendor0; /* vendor unique */ + unsigned short vendor1; /* vendor unique */ + unsigned short vendor2; /* Retired vendor unique */ + unsigned char serial_no[20]; /* 0 = not_specified */ + unsigned short buf_type; /* Retired */ + unsigned short buf_size; /* Retired, 512 byte increments + * 0 = not_specified + */ + unsigned short ecc_bytes; /* for r/w long cmds; 0 = not_specified */ + unsigned char fw_rev[8]; /* 0 = not_specified */ + unsigned char model[40]; /* 0 = not_specified */ + unsigned char max_multsect; /* 0=not_implemented */ + unsigned char vendor3; /* vendor unique */ + unsigned short dword_io; /* 0=not_implemented; 1=implemented */ + unsigned char vendor4; /* vendor unique */ + unsigned char capability; /* (upper byte of word 49) + * 3: IORDYsup + * 2: IORDYsw + * 1: LBA + * 0: DMA + */ + unsigned short reserved50; /* reserved (word 50) */ + unsigned char vendor5; /* Obsolete, vendor unique */ + unsigned char tPIO; /* Obsolete, 0=slow, 1=medium, 2=fast */ + unsigned char vendor6; /* Obsolete, vendor unique */ + unsigned char tDMA; /* Obsolete, 0=slow, 1=medium, 2=fast */ + unsigned short field_valid; /* (word 53) + * 2: ultra_ok word 88 + * 1: eide_ok words 64-70 + * 0: cur_ok words 54-58 + */ + unsigned short cur_cyls; /* Obsolete, logical cylinders */ + unsigned short cur_heads; /* Obsolete, l heads */ + unsigned short cur_sectors; /* Obsolete, l sectors per track */ + unsigned short cur_capacity0; /* Obsolete, l total sectors on drive */ + unsigned short cur_capacity1; /* Obsolete, (2 words, misaligned int) */ + unsigned char multsect; /* current multiple sector count */ + unsigned char multsect_valid; /* when (bit0==1) multsect is ok */ + unsigned int lba_capacity; /* Obsolete, total number of sectors */ + unsigned short dma_1word; /* Obsolete, single-word dma info */ + unsigned short dma_mword; /* multiple-word dma info */ + unsigned short eide_pio_modes; /* bits 0:mode3 1:mode4 */ + unsigned short eide_dma_min; /* min mword dma cycle time (ns) */ + unsigned short eide_dma_time; /* recommended mword dma cycle time (ns) */ + unsigned short eide_pio; /* min cycle time (ns), no IORDY */ + unsigned short eide_pio_iordy; /* min cycle time (ns), with IORDY */ + unsigned short words69_70[2]; /* reserved words 69-70 + * future command overlap and queuing + */ + /* HDIO_GET_IDENTITY currently returns only words 0 through 70 */ + unsigned short words71_74[4]; /* reserved words 71-74 + * for IDENTIFY PACKET DEVICE command + */ + unsigned short queue_depth; /* (word 75) + * 15:5 reserved + * 4:0 Maximum queue depth -1 + */ + unsigned short words76_79[4]; /* reserved words 76-79 */ + unsigned short major_rev_num; /* (word 80) */ + unsigned short minor_rev_num; /* (word 81) */ + unsigned short command_set_1; /* (word 82) supported + * 15: Obsolete + * 14: NOP command + * 13: READ_BUFFER + * 12: WRITE_BUFFER + * 11: Obsolete + * 10: Host Protected Area + * 9: DEVICE Reset + * 8: SERVICE Interrupt + * 7: Release Interrupt + * 6: look-ahead + * 5: write cache + * 4: PACKET Command + * 3: Power Management Feature Set + * 2: Removable Feature Set + * 1: Security Feature Set + * 0: SMART Feature Set + */ + unsigned short command_set_2; /* (word 83) + * 15: Shall be ZERO + * 14: Shall be ONE + * 13: FLUSH CACHE EXT + * 12: FLUSH CACHE + * 11: Device Configuration Overlay + * 10: 48-bit Address Feature Set + * 9: Automatic Acoustic Management + * 8: SET MAX security + * 7: reserved 1407DT PARTIES + * 6: SetF sub-command Power-Up + * 5: Power-Up in Standby Feature Set + * 4: Removable Media Notification + * 3: APM Feature Set + * 2: CFA Feature Set + * 1: READ/WRITE DMA QUEUED + * 0: Download MicroCode + */ + unsigned short cfsse; /* (word 84) + * cmd set-feature supported extensions + * 15: Shall be ZERO + * 14: Shall be ONE + * 13:6 reserved + * 5: General Purpose Logging + * 4: Streaming Feature Set + * 3: Media Card Pass Through + * 2: Media Serial Number Valid + * 1: SMART selt-test supported + * 0: SMART error logging + */ + unsigned short cfs_enable_1; /* (word 85) + * command set-feature enabled + * 15: Obsolete + * 14: NOP command + * 13: READ_BUFFER + * 12: WRITE_BUFFER + * 11: Obsolete + * 10: Host Protected Area + * 9: DEVICE Reset + * 8: SERVICE Interrupt + * 7: Release Interrupt + * 6: look-ahead + * 5: write cache + * 4: PACKET Command + * 3: Power Management Feature Set + * 2: Removable Feature Set + * 1: Security Feature Set + * 0: SMART Feature Set + */ + unsigned short cfs_enable_2; /* (word 86) + * command set-feature enabled + * 15: Shall be ZERO + * 14: Shall be ONE + * 13: FLUSH CACHE EXT + * 12: FLUSH CACHE + * 11: Device Configuration Overlay + * 10: 48-bit Address Feature Set + * 9: Automatic Acoustic Management + * 8: SET MAX security + * 7: reserved 1407DT PARTIES + * 6: SetF sub-command Power-Up + * 5: Power-Up in Standby Feature Set + * 4: Removable Media Notification + * 3: APM Feature Set + * 2: CFA Feature Set + * 1: READ/WRITE DMA QUEUED + * 0: Download MicroCode + */ + unsigned short csf_default; /* (word 87) + * command set-feature default + * 15: Shall be ZERO + * 14: Shall be ONE + * 13:6 reserved + * 5: General Purpose Logging enabled + * 4: Valid CONFIGURE STREAM executed + * 3: Media Card Pass Through enabled + * 2: Media Serial Number Valid + * 1: SMART selt-test supported + * 0: SMART error logging + */ + unsigned short dma_ultra; /* (word 88) */ + unsigned short trseuc; /* time required for security erase */ + unsigned short trsEuc; /* time required for enhanced erase */ + unsigned short CurAPMvalues; /* current APM values */ + unsigned short mprc; /* master password revision code */ + unsigned short hw_config; /* hardware config (word 93) + * 15: Shall be ZERO + * 14: Shall be ONE + * 13: + * 12: + * 11: + * 10: + * 9: + * 8: + * 7: + * 6: + * 5: + * 4: + * 3: + * 2: + * 1: + * 0: Shall be ONE + */ + unsigned short acoustic; /* (word 94) + * 15:8 Vendor's recommended value + * 7:0 current value + */ + unsigned short msrqs; /* min stream request size */ + unsigned short sxfert; /* stream transfer time */ + unsigned short sal; /* stream access latency */ + unsigned int spg; /* stream performance granularity */ + unsigned long long lba_capacity_2;/* 48-bit total number of sectors */ + unsigned short words104_125[22];/* reserved words 104-125 */ + unsigned short last_lun; /* (word 126) */ + unsigned short word127; /* (word 127) Feature Set + * Removable Media Notification + * 15:2 reserved + * 1:0 00 = not supported + * 01 = supported + * 10 = reserved + * 11 = reserved + */ + unsigned short dlf; /* (word 128) + * device lock function + * 15:9 reserved + * 8 security level 1:max 0:high + * 7:6 reserved + * 5 enhanced erase + * 4 expire + * 3 frozen + * 2 locked + * 1 en/disabled + * 0 capability + */ + unsigned short csfo; /* (word 129) + * current set features options + * 15:4 reserved + * 3: auto reassign + * 2: reverting + * 1: read-look-ahead + * 0: write cache + */ + unsigned short words130_155[26];/* reserved vendor words 130-155 */ + unsigned short word156; /* reserved vendor word 156 */ + unsigned short words157_159[3];/* reserved vendor words 157-159 */ + unsigned short cfa_power; /* (word 160) CFA Power Mode + * 15 word 160 supported + * 14 reserved + * 13 + * 12 + * 11:0 + */ + unsigned short words161_175[15];/* Reserved for CFA */ + unsigned short words176_205[30];/* Current Media Serial Number */ + unsigned short words206_254[49];/* reserved words 206-254 */ + unsigned short integrity_word; /* (word 255) + * 15:8 Checksum + * 7:0 Signature + */ +}; + +#endif /* __DRIVEID_H__ */ + From 0d633f654dfe20f05881f44058485bcfe1b5e7ed Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 04:26:56 +0000 Subject: [PATCH 109/380] o Move the driveid.h file o lots of tweaks to header paths. o comment out SMP for the moment # we now make it through the .c make depend, the .s needs more work. --- sys/mips/conf/OCTEON1 | 3 ++- sys/{dev/flash => mips/octeon1}/driveid.h | 0 sys/mips/octeon1/obio.c | 4 ++-- sys/mips/octeon1/octeon_machdep.c | 2 +- sys/mips/octeon1/uart_bus_octeonusart.c | 5 +---- sys/mips/octeon1/uart_cpu_octeonusart.c | 2 +- 6 files changed, 7 insertions(+), 9 deletions(-) rename sys/{dev/flash => mips/octeon1}/driveid.h (100%) diff --git a/sys/mips/conf/OCTEON1 b/sys/mips/conf/OCTEON1 index af8abb0cd8e..957cae2c217 100644 --- a/sys/mips/conf/OCTEON1 +++ b/sys/mips/conf/OCTEON1 @@ -79,4 +79,5 @@ options ROOTDEVNAME = \"ufs:cf0s2\" # Unmask if compact flash is needed #options ROOTDEVNAME = \"ufs:md0\" #options MD_ROOT_SIZE = 21264 -options SMP +#XXX: Bring up UP first, then generalize. +#options SMP diff --git a/sys/dev/flash/driveid.h b/sys/mips/octeon1/driveid.h similarity index 100% rename from sys/dev/flash/driveid.h rename to sys/mips/octeon1/driveid.h diff --git a/sys/mips/octeon1/obio.c b/sys/mips/octeon1/obio.c index 3fa125012a4..7f573c29e0b 100644 --- a/sys/mips/octeon1/obio.c +++ b/sys/mips/octeon1/obio.c @@ -53,8 +53,8 @@ __FBSDID("$FreeBSD$"); #include -#include -#include +#include +#include int obio_probe(device_t); int obio_attach(device_t); diff --git a/sys/mips/octeon1/octeon_machdep.c b/sys/mips/octeon1/octeon_machdep.c index 10f80b835a9..f0f6bded0a1 100644 --- a/sys/mips/octeon1/octeon_machdep.c +++ b/sys/mips/octeon1/octeon_machdep.c @@ -32,7 +32,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #include diff --git a/sys/mips/octeon1/uart_bus_octeonusart.c b/sys/mips/octeon1/uart_bus_octeonusart.c index 0bb22d8789d..f70307cfbe6 100644 --- a/sys/mips/octeon1/uart_bus_octeonusart.c +++ b/sys/mips/octeon1/uart_bus_octeonusart.c @@ -53,10 +53,7 @@ __FBSDID("$FreeBSD$"); #include #include -/* - * XXXMIPS: - */ -#include +#include #include "uart_if.h" diff --git a/sys/mips/octeon1/uart_cpu_octeonusart.c b/sys/mips/octeon1/uart_cpu_octeonusart.c index 75bb3cf634f..4e9ffb269d7 100644 --- a/sys/mips/octeon1/uart_cpu_octeonusart.c +++ b/sys/mips/octeon1/uart_cpu_octeonusart.c @@ -48,7 +48,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include +#include bus_space_tag_t uart_bus_space_io; bus_space_tag_t uart_bus_space_mem; From f7edf224654d9d0441c9e3c778c279694f9ac095 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 05:29:13 +0000 Subject: [PATCH 110/380] Bring this in from the cavium port. --- sys/mips/include/octeon_pcmap_regs.h | 1104 ++++++++++++++++++++++++++ 1 file changed, 1104 insertions(+) create mode 100644 sys/mips/include/octeon_pcmap_regs.h diff --git a/sys/mips/include/octeon_pcmap_regs.h b/sys/mips/include/octeon_pcmap_regs.h new file mode 100644 index 00000000000..4bee9844aad --- /dev/null +++ b/sys/mips/include/octeon_pcmap_regs.h @@ -0,0 +1,1104 @@ +/* + * This product includes software developed by the University of + * California, Berkeley and its contributors." +*/ + +#ifndef __OCTEON_PCMAP_REGS_H__ +#define __OCTEON_PCMAP_REGS_H__ + + +#define OCTEON_CACHE_LINE_SIZE 0x80 /* 128 bytes cache line size */ +#define IS_OCTEON_ALIGNED(p) (!((u_long)(p) & 0x7f)) +#define OCTEON_ALIGN(p) (((u_long)(p) + ((OCTEON_CACHE_LINE_SIZE) - 1)) & ~((OCTEON_CACHE_LINE_SIZE) - 1)) + +#ifndef LOCORE + +/* + * Utility inlines & macros + */ + +/* turn the variable name into a string */ +#define OCTEON_TMP_STR(x) OCTEON_TMP_STR2(x) +#define OCTEON_TMP_STR2(x) #x + +#define OCTEON_PREFETCH_PREF0(address, offset) \ + __asm __volatile ( ".set mips64\n" \ + ".set noreorder\n" \ + "pref 0, " OCTEON_TMP_STR(offset) "(%0)\n" \ + ".set reorder\n" \ + ".set mips0\n" \ + : \ + : "r" (address) ); + +#define OCTEON_PREFETCH(address, offset) OCTEON_PREFETCH_PREF0(address,offset) + +#define OCTEON_PREFETCH0(address) OCTEON_PREFETCH(address, 0) +#define OCTEON_PREFETCH128(address) OCTEON_PREFETCH(address, 128) + +#define OCTEON_SYNCIOBDMA __asm __volatile (".word 0x8f" : : :"memory") + +#define OCTEON_SYNCW __asm __volatile (".word 0x10f" : : ) +#define OCTEON_SYNCW __asm __volatile (".word 0x10f" : : ) +#define OCTEON_SYNCWS __asm __volatile (".word 0x14f" : : ) + +//#if defined(__mips_n32) || defined(__mips_n64) +#if defined(__not_used) + +static inline void oct_write64 (uint64_t csr_addr, uint64_t val64) +{ + uint64_t *ptr = (uint64_t *) csr_addr; + *ptr = val64; +} + +static inline void oct_write64_int64 (uint64_t csr_addr, int64_t val64i) +{ + int64_t *ptr = (int64_t *) csr_addr; + *ptr = val64i; +} + +static inline void oct_write8_x8 (uint64_t csr_addr, uint8_t val8) +{ + uint64_t *ptr = (uint64_t *) csr_addr; + *ptr = (uint64_t) val8; +} + +static inline void oct_write8 (uint64_t csr_addr, uint8_t val8) +{ + oct_write64(csr_addr, (uint64_t) val8); +} + +static inline void oct_write16 (uint64_t csr_addr, uint16_t val16) +{ + oct_write64(csr_addr, (uint64_t) val16); +} + +static inline void oct_write32 (uint64_t csr_addr, uint32_t val32) +{ + oct_write64(csr_addr, (uint64_t) val32); +} + +static inline uint8_t oct_read8 (uint64_t csr_addr) +{ + uint8_t *ptr = (uint8_t *) csr_addr; + return (*ptr); +} + +static inline uint8_t oct_read16 (uint64_t csr_addr) +{ + uint16_t *ptr = (uint16_t *) csr_addr; + return (*ptr); +} + + +static inline uint32_t oct_read32 (uint64_t csr_addr) +{ + uint32_t *ptr = (uint32_t *) csr_addr; + return (*ptr); +} + +static inline uint64_t oct_read64 (uint64_t csr_addr) +{ + uint64_t *ptr = (uint64_t *) csr_addr; + return (*ptr); +} + +static inline int32_t oct_readint32 (uint64_t csr_addr) +{ + int32_t *ptr = (int32_t *) csr_addr; + return (*ptr); +} + + + +#else + + +/* ABI o32 */ + + +/* + * Read/write functions + */ +static inline void oct_write64 (uint64_t csr_addr, uint64_t val64) +{ + uint32_t csr_addrh = csr_addr >> 32; + uint32_t csr_addrl = csr_addr; + uint32_t valh = (uint64_t)val64 >> 32; + uint32_t vall = val64; + uint32_t tmp1; + uint32_t tmp2; + uint32_t tmp3; + + __asm __volatile ( + ".set mips64\n" + "dsll %0, %3, 32\n" + "dsll %1, %5, 32\n" + "dsll %2, %4, 32\n" + "dsrl %2, %2, 32\n" + "or %0, %0, %2\n" + "dsll %2, %6, 32\n" + "dsrl %2, %2, 32\n" + "or %1, %1, %2\n" + "sd %0, 0(%1)\n" + ".set mips0\n" + : "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3) + : "r" (valh), "r" (vall), + "r" (csr_addrh), "r" (csr_addrl) + ); +} + +static inline void oct_write64_int64 (uint64_t csr_addr, int64_t val64i) +{ + uint32_t csr_addrh = csr_addr >> 32; + uint32_t csr_addrl = csr_addr; + int32_t valh = (uint64_t)val64i >> 32; + int32_t vall = val64i; + uint32_t tmp1; + uint32_t tmp2; + uint32_t tmp3; + + __asm __volatile ( + ".set mips64\n" + "dsll %0, %3, 32\n" + "dsll %1, %5, 32\n" + "dsll %2, %4, 32\n" + "dsrl %2, %2, 32\n" + "or %0, %0, %2\n" + "dsll %2, %6, 32\n" + "dsrl %2, %2, 32\n" + "or %1, %1, %2\n" + "sd %0, 0(%1)\n" + ".set mips0\n" + : "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3) + : "r" (valh), "r" (vall), + "r" (csr_addrh), "r" (csr_addrl) + ); +} + + +/* + * oct_write8_x8 + * + * 8 bit data write into IO Space. Written using an 8 bit bus io transaction + */ +static inline void oct_write8_x8 (uint64_t csr_addr, uint8_t val8) +{ + uint32_t csr_addrh = csr_addr>>32; + uint32_t csr_addrl = csr_addr; + uint32_t tmp1; + uint32_t tmp2; + + __asm __volatile ( + ".set mips64\n" + "dsll %0, %3, 32\n" + "dsll %1, %4, 32\n" + "dsrl %1, %1, 32\n" + "or %0, %0, %1\n" + "sb %2, 0(%0)\n" + ".set mips0\n" + : "=&r" (tmp1), "=&r" (tmp2) + : "r" (val8), "r" (csr_addrh), "r" (csr_addrl) ); +} + +/* + * oct_write8 + * + * 8 bit data write into IO Space. Written using a 64 bit bus io transaction + */ +static inline void oct_write8 (uint64_t csr_addr, uint8_t val8) +{ +#if 1 + oct_write64(csr_addr, (uint64_t) val8); +#else + + uint32_t csr_addrh = csr_addr>>32; + uint32_t csr_addrl = csr_addr; + uint32_t tmp1; + uint32_t tmp2; + + __asm __volatile ( + ".set mips64\n" + "dsll %0, %3, 32\n" + "dsll %1, %4, 32\n" + "dsrl %1, %1, 32\n" + "or %0, %0, %1\n" + "sb %2, 0(%0)\n" + ".set mips0\n" + : "=&r" (tmp1), "=&r" (tmp2) + : "r" (val8), "r" (csr_addrh), "r" (csr_addrl) ); +#endif +} + +static inline void oct_write16 (uint64_t csr_addr, uint16_t val16) +{ +#if 1 + oct_write64(csr_addr, (uint64_t) val16); + +#else + uint32_t csr_addrh = csr_addr>>32; + uint32_t csr_addrl = csr_addr; + uint32_t tmp1; + uint32_t tmp2; + + __asm __volatile ( + ".set mips64\n" + "dsll %0, %3, 32\n" + "dsll %1, %4, 32\n" + "dsrl %1, %1, 32\n" + "or %0, %0, %1\n" + "sh %2, 0(%0)\n" + ".set mips0\n" + : "=&r" (tmp1), "=&r" (tmp2) + : "r" (val16), "r" (csr_addrh), "r" (csr_addrl) ); +#endif +} + +static inline void oct_write32 (uint64_t csr_addr, uint32_t val32) +{ +#if 1 + oct_write64(csr_addr, (uint64_t) val32); +#else + + uint32_t csr_addrh = csr_addr>>32; + uint32_t csr_addrl = csr_addr; + uint32_t tmp1; + uint32_t tmp2; + + __asm __volatile ( + ".set mips64\n" + "dsll %0, %3, 32\n" + "dsll %1, %4, 32\n" + "dsrl %1, %1, 32\n" + "or %0, %0, %1\n" + "sw %2, 0(%0)\n" + ".set mips0\n" + : "=&r" (tmp1), "=&r" (tmp2) + : "r" (val32), "r" (csr_addrh), "r" (csr_addrl) ); +#endif +} + + + +static inline uint8_t oct_read8 (uint64_t csr_addr) +{ + uint32_t csr_addrh = csr_addr>>32; + uint32_t csr_addrl = csr_addr; + uint32_t tmp1, tmp2; + + __asm __volatile ( + ".set mips64\n" + "dsll %1, %2, 32\n" + "dsll %0, %3, 32\n" + "dsrl %0, %0, 32\n" + "or %1, %1, %0\n" + "lb %1, 0(%1)\n" + ".set mips0\n" + : "=&r" (tmp1), "=&r" (tmp2) + : "r" (csr_addrh), "r" (csr_addrl) ); + return ((uint8_t) tmp2); +} + +static inline uint8_t oct_read16 (uint64_t csr_addr) +{ + uint32_t csr_addrh = csr_addr>>32; + uint32_t csr_addrl = csr_addr; + uint32_t tmp1, tmp2; + + __asm __volatile ( + ".set mips64\n" + "dsll %1, %2, 32\n" + "dsll %0, %3, 32\n" + "dsrl %0, %0, 32\n" + "or %1, %1, %0\n" + "lh %1, 0(%1)\n" + ".set mips0\n" + : "=&r" (tmp1), "=&r" (tmp2) + : "r" (csr_addrh), "r" (csr_addrl) ); + return ((uint16_t) tmp2); +} + + +static inline uint32_t oct_read32 (uint64_t csr_addr) +{ + uint32_t csr_addrh = csr_addr>>32; + uint32_t csr_addrl = csr_addr; + uint32_t val32; + uint32_t tmp; + + __asm __volatile ( + ".set mips64\n" + "dsll %0, %2, 32\n" + "dsll %1, %3, 32\n" + "dsrl %1, %1, 32\n" + "or %0, %0, %1\n" + "lw %0, 0(%0)\n" + ".set mips0\n" + : "=&r" (val32), "=&r" (tmp) + : "r" (csr_addrh), "r" (csr_addrl) ); + return (val32); +} + + +static inline uint64_t oct_read64 (uint64_t csr_addr) +{ + uint32_t csr_addrh = csr_addr >> 32; + uint32_t csr_addrl = csr_addr; + uint32_t valh; + uint32_t vall; + + __asm __volatile ( + ".set mips64\n" + "dsll %0, %2, 32\n" + "dsll %1, %3, 32\n" + "dsrl %1, %1, 32\n" + "or %0, %0, %1\n" + "ld %1, 0(%0)\n" + "dsrl %0, %1, 32\n" + "dsll %1, %1, 32\n" + "dsrl %1, %1, 32\n" + ".set mips0\n" + : "=&r" (valh), "=&r" (vall) + : "r" (csr_addrh), "r" (csr_addrl) + ); + return ((uint64_t)valh << 32) | vall; +} + + +static inline int32_t oct_readint32 (uint64_t csr_addr) +{ + uint32_t csr_addrh = csr_addr>>32; + uint32_t csr_addrl = csr_addr; + int32_t val32; + uint32_t tmp; + + __asm __volatile ( + ".set mips64\n" + "dsll %0, %2, 32\n" + "dsll %1, %3, 32\n" + "dsrl %1, %1, 32\n" + "or %0, %0, %1\n" + "lw %0, 0(%0)\n" + : "=&r" (val32), "=&r" (tmp) + : "r" (csr_addrh), "r" (csr_addrl) ); + return (val32); +} + + +#endif + + +#define OCTEON_HW_BASE ((volatile uint64_t *) 0L) +#define OCTEON_REG_OFFSET (-4 * 1024ll) /* local scratchpad reg base */ +#define OCTEON_SCRATCH_BASE ((volatile uint8_t *)(OCTEON_HW_BASE + \ + OCTEON_REG_OFFSET)) + +#define OCTEON_SCR_SCRATCH 8 +#define OCTEON_SCRATCH_0 16 +#define OCTEON_SCRATCH_1 24 +#define OCTEON_SCRATCH_2 32 + + +static inline uint64_t oct_mf_chord (void) +{ + uint64_t dest; + + __asm __volatile ( ".set push\n" + ".set noreorder\n" + ".set noat\n" + ".set mips64\n" + "dmfc2 $1, 0x400\n" + "move %0, $1\n" + ".set pop\n" + : "=r" (dest) : : "$1"); + return dest; +} + + +#define MIPS64_DMFCz(cop,regnum,cp0reg,select) \ + .word (0x40200000 | (cop << 25) | (regnum << 16) | (cp0reg << 11) | select) + + +#define mips64_getcpz_xstr(s) mips64_getcpz_str(s) +#define mips64_getcpz_str(s) #s + +#define mips64_dgetcpz(cop,cpzreg,sel,val_ptr) \ + ({ __asm __volatile( \ + ".set push\n" \ + ".set mips3\n" \ + ".set noreorder\n" \ + ".set noat\n" \ + mips64_getcpz_xstr(MIPS64_DMFCz(cop,1,cpzreg,sel)) "\n" \ + "nop\n" \ + "nop\n" \ + "nop\n" \ + "nop\n" \ + "sd $1,0(%0)\n" \ + ".set pop" \ + : /* no outputs */ : "r" (val_ptr) : "$1"); \ + }) + + +#define mips64_dgetcp2(cp2reg,sel,retval_ptr) \ + mips64_dgetcpz(2,cp2reg,sel,retval_ptr) + + +#define OCTEON_MF_CHORD(dest) mips64_dgetcp2(0x400, 0, &dest) + + + +#define OCTEON_RDHWR(result, regstr) \ + __asm __volatile ( \ + ".set mips3\n" \ + "rdhwr %0,$" OCTEON_TMP_STR(regstr) "\n" \ + ".set mips\n" \ + : "=d" (result)); + +#define CVMX_MF_CHORD(dest) OCTEON_RDHWR(dest, 30) + +#define OCTEON_CHORD_HEX(dest_ptr) \ + ({ __asm __volatile( \ + ".set push\n" \ + ".set mips3\n" \ + ".set noreorder\n" \ + ".set noat\n" \ + ".word 0x7c02f03b \n"\ + "nop\n" \ + "nop\n" \ + "nop\n" \ + "nop\n" \ + "sd $2,0(%0)\n" \ + ".set pop" \ + : /* no outputs */ : "r" (dest_ptr) : "$2"); \ + }) + + + +#define OCTEON_MF_CHORD_BAD(dest) \ + __asm __volatile ( \ + ".set mips3\n" \ + "dmfc2 %0, 0x400\n" \ + ".set mips0\n" \ + : "=&r" (dest) : ) + +static inline uint64_t oct_scratch_read64 (uint64_t address) +{ + return(*((volatile uint64_t *)(OCTEON_SCRATCH_BASE + address))); +} + +static inline void oct_scratch_write64 (uint64_t address, uint64_t value) +{ + *((volatile uint64_t *)(OCTEON_SCRATCH_BASE + address)) = value; +} + + +#define OCTEON_READ_CSR32(addr, val) \ + addr_ptr = addr; \ + oct_read_32_ptr(&addr_ptr, &val); + +#define OCTEON_WRITE_CSR32(addr, val, val_dummy) \ + addr_ptr = addr; \ + oct_write_32_ptr(&addr_ptr, &val); \ + oct_read64(OCTEON_MIO_BOOT_BIST_STAT); + + + +/* + * Octeon Address Space Definitions + */ +typedef enum { + OCTEON_MIPS_SPACE_XKSEG = 3LL, + OCTEON_MIPS_SPACE_XKPHYS = 2LL, + OCTEON_MIPS_SPACE_XSSEG = 1LL, + OCTEON_MIPS_SPACE_XUSEG = 0LL +} octeon_mips_space_t; + +typedef enum { + OCTEON_MIPS_XKSEG_SPACE_KSEG0 = 0LL, + OCTEON_MIPS_XKSEG_SPACE_KSEG1 = 1LL, + OCTEON_MIPS_XKSEG_SPACE_SSEG = 2LL, + OCTEON_MIPS_XKSEG_SPACE_KSEG3 = 3LL +} octeon_mips_xkseg_space_t; + + +/* +*********************************************************************** + * 32 bit mode alert + * The kseg0 calc below might fail in xkphys. + */ + +/* + * We limit the allocated device physical blocks to low mem. So use Kseg0 + */ + +#ifndef AVOID_CODE_NOT_64_BIT /* #ifdef PTR_SIZE == sizeof(u_int32) */ +//#define OCTEON_PHYS2PTR(addr) ((void *) (((uint32_t) addr) | 0x80000000)) +#define OCTEON_PHYS2PTR(addr) ((void *) (((vm_offset_t) addr) | MIPS_KSEG0_START)) +#endif + +#ifdef IN_FUTURE_64_BIT +#ifdef PTR_SIZE == sizeof(u_int64) +#define OCTEON_PHYS2PTR(addr) ((void *) (((uint64_t) addr) | (1ul << 63)) +#endif +#endif + +/* + * Need to go back to kernel to find v->p mappings & vice-versa + * We are getting non 1-1 mappings. + * #define OCTEON_PTR2PHYS(addr) ((unsigned long) addr & 0x7fffffff) + */ +#define OCTEON_PTR2PHYS(addr) octeon_ptr_to_phys(addr) + + + +/* PTR_SIZE == sizeof(uint32_t) */ + +#define mipsx_addr_size uint32_t // u_int64 +#define MIPSX_ADDR_SIZE_KSEGX_BIT_SHIFT 30 // 62 +#define MIPSX_ADDR_SIZE_KSEGX_MASK_REMOVED 0x1fffffff // 0x1fffffff + + +#ifdef CODE_FOR_64_BIT_NEEDED +#ifdef PTR_SIZE == sizeof(uint64_t) +#define mipsx_addr_size uint64_t +#define MIPSX_ADDR_SIZE_KSEGX_BIT_SHIFT 62 +#define MIPSX_ADDR_SIZE_KSEGX_MASK_REMOVED 0x1fffffff ffff ffff +#endif +#endif + + +#define octeon_ptr_to_phys(ptr) \ + ((((mipsx_addr_size) ptr) >> MIPSX_ADDR_SIZE_KSEGX_BIT_SHIFT) == 2) ? \ + ((mipsx_addr_size) ptr & MIPSX_ADDR_SIZE_KSEGX_MASK_REMOVED) : \ + (vtophys(ptr)) + + +#ifdef CODE_FOR_64_BIT_NEEDED +static inline mipsx_addr_size octeon_ptr_to_phys (void *ptr) +{ + if ((((mipsx_addr_size) ptr) >> MIPSX_ADDR_SIZE_KSEGX_BIT_SHIFT) == 2) { + /* + * KSEG0 based address ? + */ + return ((mipsx_addr_size) ptr & MIPSX_ADDR_SIZE_KSEGX_MASK_REMOVED); + } else { + /* + * Ask kernel/vm to give us the phys translation. + */ + return (vtophys(ptr)); + } +} +#endif + +#define OCTEON_IO_SEG OCTEON_MIPS_SPACE_XKPHYS + + +#define OCTEON_ADD_SEG(segment, add) ((((uint64_t)segment) << 62) | (add)) + +#define OCTEON_ADD_IO_SEG(add) OCTEON_ADD_SEG(OCTEON_IO_SEG, (add)) +#define OCTEON_ADDR_DID(did) (OCTEON_ADDR_DIDSPACE(did) << 40) +#define OCTEON_ADDR_DIDSPACE(did) (((OCTEON_IO_SEG) << 22) | ((1ULL) << 8) | (did)) +#define OCTEON_ADDR_FULL_DID(did,subdid) (((did) << 3) | (subdid)) + + +#define OCTEON_CIU_PP_RST OCTEON_ADD_IO_SEG(0x0001070000000700ull) +#define OCTEON_OCTEON_DID_TAG 12ULL + + + + +/* + * octeon_addr_t + */ +typedef union { + uint64_t word64; + + struct { + octeon_mips_space_t R : 2; + uint64_t offset :62; + } sva; // mapped or unmapped virtual address + + struct { + uint64_t zeroes :33; + uint64_t offset :31; + } suseg; // mapped USEG virtual addresses (typically) + + struct { + uint64_t ones :33; + octeon_mips_xkseg_space_t sp : 2; + uint64_t offset :29; + } sxkseg; // mapped or unmapped virtual address + + struct { + octeon_mips_space_t R :2; // CVMX_MIPS_SPACE_XKPHYS in this case + uint64_t cca : 3; // ignored by octeon + uint64_t mbz :10; + uint64_t pa :49; // physical address + } sxkphys; // physical address accessed through xkphys unmapped virtual address + + struct { + uint64_t mbz :15; + uint64_t is_io : 1; // if set, the address is uncached and resides on MCB bus + uint64_t did : 8; // the hardware ignores this field when is_io==0, else device ID + uint64_t unaddr: 4; // the hardware ignores <39:36> in Octeon I + uint64_t offset :36; + } sphys; // physical address + + struct { + uint64_t zeroes :24; // techically, <47:40> are dont-cares + uint64_t unaddr: 4; // the hardware ignores <39:36> in Octeon I + uint64_t offset :36; + } smem; // physical mem address + + struct { + uint64_t mem_region :2; + uint64_t mbz :13; + uint64_t is_io : 1; // 1 in this case + uint64_t did : 8; // the hardware ignores this field when is_io==0, else device ID + uint64_t unaddr: 4; // the hardware ignores <39:36> in Octeon I + uint64_t offset :36; + } sio; // physical IO address + + struct { + uint64_t didspace : 24; + uint64_t unused : 40; + } sfilldidspace; + +} octeon_addr_t; + + +typedef union { + uint64_t word64; + struct { + uint32_t word32hi; + uint32_t word32lo; + } bits; +} octeon_word_t; + + + + +/* + * octeon_build_io_address + * + * Builds a memory address for I/O based on the Major 5bits and Sub DID 3bits + */ +static inline uint64_t octeon_build_io_address (uint64_t major_did, + uint64_t sub_did) +{ + return ((0x1ull << 48) | (major_did << 43) | (sub_did << 40)); +} + +/* + * octeon_build_mask + * + * Builds a bit mask given the required size in bits. + * + * @param bits Number of bits in the mask + * @return The mask + */ +static inline uint64_t octeon_build_mask (uint64_t bits) +{ + return ~((~0x0ull) << bits); +} + +/* + * octeon_build_bits + * + * Perform mask and shift to place the supplied value into + * the supplied bit rage. + * + * Example: octeon_build_bits(39,24,value) + *
+ * 6       5       4       3       3       2       1
+ * 3       5       7       9       1       3       5       7      0
+ * +-------+-------+-------+-------+-------+-------+-------+------+
+ * 000000000000000000000000___________value000000000000000000000000
+ * 
+ * + * @param high_bit Highest bit value can occupy (inclusive) 0-63 + * @param low_bit Lowest bit value can occupy inclusive 0-high_bit + * @param value Value to use + * @return Value masked and shifted + */ +static inline uint64_t octeon_build_bits (uint64_t high_bit, uint64_t low_bit, + uint64_t value) +{ + return ((value & octeon_build_mask(high_bit - low_bit + 1)) << low_bit); +} + + +/********************** simple spinlocks ***************/ +typedef struct { + volatile uint32_t value; +} octeon_spinlock_t; + +// note - macros not expanded in inline ASM, so values hardcoded +#define OCTEON_SPINLOCK_UNLOCKED_VAL 0 +#define OCTEON_SPINLOCK_LOCKED_VAL 1 + +/** + * Initialize a spinlock + * + * @param lock Lock to initialize + */ +static inline void octeon_spinlock_init(octeon_spinlock_t *lock) +{ + lock->value = OCTEON_SPINLOCK_UNLOCKED_VAL; +} +/** + * Releases lock + * + * @param lock pointer to lock structure + */ +static inline void octeon_spinlock_unlock(octeon_spinlock_t *lock) +{ + OCTEON_SYNCWS; + + lock->value = 0; + OCTEON_SYNCWS; +} + +/** + * Gets lock, spins until lock is taken + * + * @param lock pointer to lock structure + */ +static inline void octeon_spinlock_lock(octeon_spinlock_t *lock) +{ + unsigned int tmp; + __asm __volatile( + ".set noreorder \n" + "1: ll %1, %0 \n" + " bnez %1, 1b \n" + " li %1, 1 \n" + " sc %1, %0 \n" + " beqz %1, 1b \n" + " nop \n" + ".set reorder \n" + : "+m" (lock->value), "=&r" (tmp ) + : + : "memory"); +} + +/********************** end simple spinlocks ***************/ + + + +/* ------------------------------------------------------------------- * + * octeon_get_chipid() * + * ------------------------------------------------------------------- */ +#define OCTEON_CN31XX_CHIP 0x000d0100 +#define OCTEON_CN30XX_CHIP 0x000d0200 +#define OCTEON_CN3020_CHIP 0x000d0112 +#define OCTEON_CN5020_CHIP 0x000d0601 + +static inline uint32_t octeon_get_chipid(void) +{ + uint32_t id; + + __asm __volatile ("mfc0 %0, $15,0" : "=r" (id)); + + return (id); +} + + +static inline uint32_t octeon_get_except_base_reg (void) +{ + uint32_t tmp; + + __asm volatile ( + " .set mips64r2 \n" + " .set noreorder \n" + " mfc0 %0, $15, 1 \n" + " .set reorder \n" + : "=&r" (tmp) : ); + + return(tmp); +} + + + + +static inline unsigned int get_coremask (void) +{ + return(~(oct_read64(OCTEON_CIU_PP_RST)) & 0xffff); +} + + +static inline uint32_t octeon_get_core_num (void) +{ + + return (0x3FF & octeon_get_except_base_reg()); +} + + +static inline uint64_t octeon_get_cycle(void) +{ + +/* ABI == 32 */ + + uint32_t tmp_low, tmp_hi; + + __asm __volatile ( + " .set push \n" + " .set mips64r2 \n" + " .set noreorder \n" + " rdhwr %[tmpl], $31 \n" + " dadd %[tmph], %[tmpl], $0 \n" + " dsrl %[tmph], 32 \n" + " dsll %[tmpl], 32 \n" + " dsrl %[tmpl], 32 \n" + " .set pop \n" + : [tmpl] "=&r" (tmp_low), [tmph] "=&r" (tmp_hi) : ); + + return(((uint64_t)tmp_hi << 32) + tmp_low); +} + + +/** + * Wait for the specified number of cycle + * + * @param cycles + */ +static inline void octeon_wait (uint64_t cycles) +{ + uint64_t done = octeon_get_cycle() + cycles; + + while (octeon_get_cycle() < done) + { + /* Spin */ + } +} + + + +/* + * octeon_machdep.c + * + * Direct to Board Support level. + */ +extern void octeon_led_write_char(int char_position, char val); +extern void octeon_led_write_hexchar(int char_position, char hexval); +extern void octeon_led_write_hex(uint32_t wl); +extern void octeon_led_write_string(const char *str); +extern void octeon_reset(void); +extern void octeon_uart_write_byte(int uart_index, uint8_t ch); +extern void octeon_uart_write_string(int uart_index, const char *str); +extern void octeon_uart_write_hex(uint32_t wl); +extern void octeon_uart_write_hex2(uint32_t wl, uint32_t wh); +extern void octeon_wait_uart_flush(int uart_index, uint8_t ch); +extern void octeon_uart_write_byte0(uint8_t ch); +extern void octeon_led_write_char0(char val); +extern void octeon_led_run_wheel(int *pos, int led_position); +extern void octeon_debug_symbol(void); +extern void mips_disable_interrupt_controls(void); +extern uint32_t octeon_cpu_clock; +extern uint64_t octeon_dram; +extern uint32_t octeon_bd_ver, octeon_board_rev_major, octeon_board_rev_minor, octeon_board_type; +extern uint8_t octeon_mac_addr[6]; +extern int octeon_core_mask, octeon_mac_addr_count, octeon_chip_rev_major, octeon_chip_rev_minor, octeon_chip_type; +extern void bzero_64(void *str, size_t len); +extern void bzero_32(void *str, size_t len); +extern void bzero_16(void *str, size_t len); +extern void bzero_old(void *str, size_t len); +extern void octeon_ciu_reset(void); +extern void ciu_disable_intr(int core_num, int intx, int enx); +extern void ciu_enable_interrupts (int core_num, int intx, int enx, uint64_t set_these_interrupt_bits, int ciu_ip); +extern void ciu_clear_int_summary(int core_num, int intx, int enx, uint64_t write_bits); +extern uint64_t ciu_get_int_summary(int core_num, int intx, int enx); +extern void octeon_ciu_start_gtimer(int timer, u_int one_shot, uint64_t time_cycles); +extern void octeon_ciu_stop_gtimer(int timer); +extern int octeon_board_real(void); + + + +typedef union { + uint64_t word64; + struct { + uint64_t reserved : 27; /* Not used */ + uint64_t one_shot : 1; /* Oneshot ? */ + uint64_t len : 36; /* len of timer in clock cycles - 1 */ + } bits; +} octeon_ciu_gentimer; + + + +#endif /* LOCORE */ + + +/* + * R4K Address space definitions + */ +#define ADRSPC_K0BASE (0x80000000) +#define ADRSPC_K0SIZE (0x20000000) +#define ADRSPC_K1BASE (0xA0000000) +#define ADRSPC_K1SIZE (0x20000000) +#define ADRSPC_KSBASE (0xC0000000) +#define ADRSPC_KSSIZE (0x20000000) +#define ADRSPC_K3BASE (0xE0000000) +#define ADRSPC_K3SIZE (0x20000000) +#define ADRSPC_KUBASE (0x00000000) +#define ADRSPC_KUSIZE (0x80000000) +#define KSEG_MSB_ADDR 0xFFFFFFFF + + + +#define OCTEON_CLOCK_DEFAULT (500 * 1000 * 1000) + + +/* + * Octeon Boot Bus BIST Status + * Mostly used for dummy read to ensure all prev I/Os are write-complete. + */ +#define OCTEON_MIO_BOOT_BIST_STAT 0x80011800000000F8ull + +/* + * Octeon UART unit + */ +#define OCTEON_MIO_UART0_THR 0x8001180000000840ull +#define OCTEON_MIO_UART1_THR 0x8001180000000C40ull +#define OCTEON_MIO_UART0_LSR 0x8001180000000828ull +#define OCTEON_MIO_UART1_LSR 0x8001180000000C28ull +#define OCTEON_MIO_UART0_RBR 0x8001180000000800ull +#define OCTEON_MIO_UART1_RBR 0x8001180000000C00ull +#define OCTEON_MIO_UART0_USR 0x8001180000000938ull +#define OCTEON_MIO_UART1_USR 0x8001180000000D38ull +#define OCTEON_MIO_ADDR_HI24 0x800118 + + +/* + * EBT3000 LED Unit + */ +#define OCTEON_CHAR_LED_BASE_ADDR (0x1d020000 | (0x1ffffffffull << 31)) + +#define OCTEON_FPA_QUEUES 8 + +/* + * Octeon FPA I/O Registers + */ +#define OCTEON_FPA_CTL_STATUS 0x8001180028000050ull +#define OCTEON_FPA_FPF_SIZE 0x8001180028000058ull +#define OCTEON_FPA_FPF_MARKS 0x8001180028000000ull +#define OCTEON_FPA_INT_SUMMARY 0x8001180028000040ull +#define OCTEON_FPA_INT_ENABLE 0x8001180028000048ull +#define OCTEON_FPA_QUEUE_AVAILABLE 0x8001180028000098ull +#define OCTEON_FPA_PAGE_INDEX 0x80011800280000f0ull + +/* + * Octeon PKO Unit + */ +#define OCTEON_PKO_REG_FLAGS 0x8001180050000000ull +#define OCTEON_PKO_REG_READ_IDX 0x8001180050000008ull +#define OCTEON_PKO_CMD_BUF 0x8001180050000010ull +#define OCTEON_PKO_GMX_PORT_MODE 0x8001180050000018ull +#define OCTEON_PKO_REG_CRC_ENABLE 0x8001180050000020ull +#define OCTEON_PKO_QUEUE_MODE 0x8001180050000048ull +#define OCTEON_PKO_MEM_QUEUE_PTRS 0x8001180050001000ull +#define OCTEON_PKO_MEM_COUNT0 0x8001180050001080ull +#define OCTEON_PKO_MEM_COUNT1 0x8001180050001088ull +#define OCTEON_PKO_MEM_DEBUG0 0x8001180050001100ull +#define OCTEON_PKO_MEM_DEBUG1 0x8001180050001108ull +#define OCTEON_PKO_MEM_DEBUG2 0x8001180050001110ull +#define OCTEON_PKO_MEM_DEBUG3 0x8001180050001118ull +#define OCTEON_PKO_MEM_DEBUG4 0x8001180050001120ull +#define OCTEON_PKO_MEM_DEBUG5 0x8001180050001128ull +#define OCTEON_PKO_MEM_DEBUG6 0x8001180050001130ull +#define OCTEON_PKO_MEM_DEBUG7 0x8001180050001138ull +#define OCTEON_PKO_MEM_DEBUG8 0x8001180050001140ull +#define OCTEON_PKO_MEM_DEBUG9 0x8001180050001148ull + + +/* + * Octeon IPD Unit + */ +#define OCTEON_IPD_1ST_MBUFF_SKIP 0x80014F0000000000ull +#define OCTEON_IPD_NOT_1ST_MBUFF_SKIP 0x80014F0000000008ull +#define OCTEON_IPD_PACKET_MBUFF_SIZE 0x80014F0000000010ull +#define OCTEON_IPD_1ST_NEXT_PTR_BACK 0x80014F0000000150ull +#define OCTEON_IPD_2ND_NEXT_PTR_BACK 0x80014F0000000158ull +#define OCTEON_IPD_WQE_FPA_QUEUE 0x80014F0000000020ull +#define OCTEON_IPD_CTL_STATUS 0x80014F0000000018ull +#define OCTEON_IPD_QOSX_RED_MARKS(queue) (0x80014F0000000178ull + ((queue) * 8)) +#define OCTEON_IPD_RED_Q_PARAM(queue) (0x80014F00000002E0ull + ((queue) * 8)) +#define OCTEON_IPD_PORT_BP_PAGE_COUNT(port) (0x80014F0000000028ull + ((port) * 8)) +#define OCTEON_IPD_BP_PORT_RED_END 0x80014F0000000328ull +#define OCTEON_IPD_RED_PORT_ENABLE 0x80014F00000002D8ull + +/* + * Octeon CIU Unit + */ +#define OCTEON_CIU_ENABLE_BASE_ADDR 0x8001070000000200ull +#define OCTEON_CIU_SUMMARY_BASE_ADDR 0x8001070000000000ull +#define OCTEON_CIU_SUMMARY_INT1_ADDR 0x8001070000000108ull + +#define OCTEON_CIU_MBOX_SETX(offset) (0x8001070000000600ull+((offset)*8)) +#define OCTEON_CIU_MBOX_CLRX(offset) (0x8001070000000680ull+((offset)*8)) +#define OCTEON_CIU_ENABLE_MBOX_INTR 0x0000000300000000ull /* bits 32, 33 */ + +#define CIU_MIPS_IP2 0 +#define CIU_MIPS_IP3 1 + +#define CIU_INT_0 CIU_MIPS_IP2 +#define CIU_INT_1 CIU_MIPS_IP3 + +#define CIU_EN_0 0 +#define CIU_EN_1 1 + +#define CIU_THIS_CORE -1 + +#define CIU_UART_BITS_UART0 (0x1ull << 34) // Bit 34 +#define CIU_UART_BITS_UART1 (0x1ull << 35) // Bit 35 +#define CIU_GENTIMER_BITS_ENABLE(timer) (0x1ull << (52 + (timer))) // Bit 52..55 + +#define CIU_GENTIMER_NUM_0 0 +#define CIU_GENTIMER_NUM_1 1 +#define CIU_GENTIMER_NUM_2 2 +#define CIU_GENTIMER_NUM_3 3 +#define OCTEON_GENTIMER_ONESHOT 1 +#define OCTEON_GENTIMER_PERIODIC 0 + +#define OCTEON_CIU_GENTIMER_ADDR(timer) (0x8001070000000480ull + ((timer) * 0x8)) + + +#define OCTEON_GENTIMER_LEN_1MS (0x7a120ull) /* Back of envelope. 500Mhz Octeon */ // FIXME IF WRONG +#define OCTEON_GENTIMER_LEN_1SEC ((OCTEON_GENTIMER_LEN_1MS) * 1000) + + + + + + +/* + * Physical Memory Banks + */ +/* 1st BANK */ +#define OCTEON_DRAM_FIRST_256_START 0x00000000ull +#define OCTEON_DRAM_FIRST_256_END (0x10000000ull - 1ull) +#define OCTEON_DRAM_RESERVED_END 0X1FFF000ULL /* 32 Meg Reserved for Mips Kernel MD Ops */ +#define OCTEON_DRAM_FIRST_BANK_SIZE (OCTEON_DRAM_FIRST_256_END - OCTEON_DRAM_FIRST_256_START + 1) + +/* 2nd BANK */ +#define OCTEON_DRAM_SECOND_256_START (0x0000000410000000ull) +#define OCTEON_DRAM_SECOND_256_END (0x0000000420000000ull - 1ull) /* Requires 64 bit paddr */ +#define OCTEON_DRAM_SECOND_BANK_SIZE (OCTEON_DRAM_SECOND_256_END - OCTEON_DRAM_SECOND_256_START + 1ull) + +/* 3rd BANK */ +#define OCTEON_DRAM_ABOVE_512_START 0x20000000ull +#define OCTEON_DRAM_ABOVE_512_END (0x0000000300000000ull - 1ull) /* To be calculated as remaining */ +#define OCTEON_DRAM_THIRD_BANK_SIZE (OCTEON_DRAM_ABOVE_512_END - OCTEON_DRAM_ABOVE_512_START + 1ull) + + +/* + * Mips Address Range conversions + */ +#define PHY_TO_KSEG1(x) ((x)+0xA0000000) +#define PHY_TO_KSEG0(x) ((x)+0x80000000) +#define PHY_ADDR(x) ((x)&0x1FFFFFFF) +#define ROM_OFFSET(x) ((x)&0x000FFFFF) +#define KSEG1_TO_KSEG0(x) ((x)-0x20000000) + + + + +#endif /* !OCTEON_PCMAP_REGS_H__ */ + From 558955d6a8bf0df2da36a7ed6017d165daa7a79f Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 06:01:46 +0000 Subject: [PATCH 111/380] Move this to a more approrpiate plae. --- sys/mips/{include => octeon1}/octeon_pcmap_regs.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename sys/mips/{include => octeon1}/octeon_pcmap_regs.h (100%) diff --git a/sys/mips/include/octeon_pcmap_regs.h b/sys/mips/octeon1/octeon_pcmap_regs.h similarity index 100% rename from sys/mips/include/octeon_pcmap_regs.h rename to sys/mips/octeon1/octeon_pcmap_regs.h From 29854186d2e7e7a5a66cd6a9a1dde3f5d3fa44d4 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 06:09:33 +0000 Subject: [PATCH 112/380] Move octeon specific uart goo here, per SOP for other MIPS ports. --- sys/mips/octeon1/files.octeon1 | 2 +- sys/mips/octeon1/uart_dev_oct16550.c | 826 +++++++++++++++++++++++++++ 2 files changed, 827 insertions(+), 1 deletion(-) create mode 100644 sys/mips/octeon1/uart_dev_oct16550.c diff --git a/sys/mips/octeon1/files.octeon1 b/sys/mips/octeon1/files.octeon1 index 858a1888544..6e7d658f247 100644 --- a/sys/mips/octeon1/files.octeon1 +++ b/sys/mips/octeon1/files.octeon1 @@ -1,7 +1,6 @@ # $FreeBSD$ # Octeon Support Files # -dev/uart/uart_dev_oct16550.c optional uart mips/mips/mp_machdep.c optional smp mips/octeon1/dev/rgmii/octeon_fau.c optional rgmii mips/octeon1/dev/rgmii/octeon_fpa.c optional rgmii @@ -13,3 +12,4 @@ mips/octeon1/octeon_ebt3000_cf.c optional cf mips/octeon1/octeon_machdep.c standard mips/octeon1/uart_bus_octeonusart.c optional uart mips/octeon1/uart_cpu_octeonusart.c optional uart +mips/octeon1/uart_dev_oct16550.c optional uart diff --git a/sys/mips/octeon1/uart_dev_oct16550.c b/sys/mips/octeon1/uart_dev_oct16550.c new file mode 100644 index 00000000000..53c8ee2af62 --- /dev/null +++ b/sys/mips/octeon1/uart_dev_oct16550.c @@ -0,0 +1,826 @@ +/*- + * Copyright (c) 2003 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * uart_dev_oct16550.c + * + * Derived from uart_dev_ns8250.c + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + */ + + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + + +#include "uart_if.h" + +/* + * Clear pending interrupts. THRE is cleared by reading IIR. Data + * that may have been received gets lost here. + */ +static void +oct16550_clrint (struct uart_bas *bas) +{ + uint8_t iir; + + iir = uart_getreg(bas, REG_IIR); + while ((iir & IIR_NOPEND) == 0) { + iir &= IIR_IMASK; + if (iir == IIR_RLS) + (void)uart_getreg(bas, REG_LSR); + else if (iir == IIR_RXRDY || iir == IIR_RXTOUT) + (void)uart_getreg(bas, REG_DATA); + else if (iir == IIR_MLSC) + (void)uart_getreg(bas, REG_MSR); + else if (iir == IIR_BUSY) + (void) uart_getreg(bas, REG_USR); + uart_barrier(bas); + iir = uart_getreg(bas, REG_IIR); + } +} + +static int delay_changed = 1; + +static int +oct16550_delay (struct uart_bas *bas) +{ + int divisor; + u_char lcr; + static int delay = 0; + + if (!delay_changed) return delay; + delay_changed = 0; + lcr = uart_getreg(bas, REG_LCR); + uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); + uart_barrier(bas); + divisor = uart_getreg(bas, REG_DLL) | (uart_getreg(bas, REG_DLH) << 8); + uart_barrier(bas); + uart_setreg(bas, REG_LCR, lcr); + uart_barrier(bas); + + if(!bas->rclk) + return 10; /* return an approx delay value */ + + /* 1/10th the time to transmit 1 character (estimate). */ + if (divisor <= 134) + return (16000000 * divisor / bas->rclk); + return (16000 * divisor / (bas->rclk / 1000)); + +} + +static int +oct16550_divisor (int rclk, int baudrate) +{ + int actual_baud, divisor; + int error; + + if (baudrate == 0) + return (0); + + divisor = (rclk / (baudrate << 3) + 1) >> 1; + if (divisor == 0 || divisor >= 65536) + return (0); + actual_baud = rclk / (divisor << 4); + + /* 10 times error in percent: */ + error = ((actual_baud - baudrate) * 2000 / baudrate + 1) >> 1; + + /* 3.0% maximum error tolerance: */ + if (error < -30 || error > 30) + return (0); + + return (divisor); +} + +static int +oct16550_drain (struct uart_bas *bas, int what) +{ + int delay, limit; + + delay = oct16550_delay(bas); + + if (what & UART_DRAIN_TRANSMITTER) { + /* + * Pick an arbitrary high limit to avoid getting stuck in + * an infinite loop when the hardware is broken. Make the + * limit high enough to handle large FIFOs. + */ + limit = 10*10*10*1024; + while ((uart_getreg(bas, REG_LSR) & LSR_TEMT) == 0 && --limit) + DELAY(delay); + if (limit == 0) { + /* printf("oct16550: transmitter appears stuck... "); */ + return (0); + } + } + + if (what & UART_DRAIN_RECEIVER) { + /* + * Pick an arbitrary high limit to avoid getting stuck in + * an infinite loop when the hardware is broken. Make the + * limit high enough to handle large FIFOs and integrated + * UARTs. The HP rx2600 for example has 3 UARTs on the + * management board that tend to get a lot of data send + * to it when the UART is first activated. + */ + limit=10*4096; + while ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) && --limit) { + (void)uart_getreg(bas, REG_DATA); + uart_barrier(bas); + DELAY(delay << 2); + } + if (limit == 0) { + /* printf("oct16550: receiver appears broken... "); */ + return (EIO); + } + } + + return (0); +} + +/* + * We can only flush UARTs with FIFOs. UARTs without FIFOs should be + * drained. WARNING: this function clobbers the FIFO setting! + */ +static void +oct16550_flush (struct uart_bas *bas, int what) +{ + uint8_t fcr; + + fcr = FCR_ENABLE; + if (what & UART_FLUSH_TRANSMITTER) + fcr |= FCR_XMT_RST; + if (what & UART_FLUSH_RECEIVER) + fcr |= FCR_RCV_RST; + uart_setreg(bas, REG_FCR, fcr); + uart_barrier(bas); +} + +static int +oct16550_param (struct uart_bas *bas, int baudrate, int databits, int stopbits, + int parity) +{ + int divisor; + uint8_t lcr; + + lcr = 0; + if (databits >= 8) + lcr |= LCR_8BITS; + else if (databits == 7) + lcr |= LCR_7BITS; + else if (databits == 6) + lcr |= LCR_6BITS; + else + lcr |= LCR_5BITS; + if (stopbits > 1) + lcr |= LCR_STOPB; + lcr |= parity << 3; + + /* Set baudrate. */ + if (baudrate > 0) { + divisor = oct16550_divisor(bas->rclk, baudrate); + if (divisor == 0) + return (EINVAL); + uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); + uart_barrier(bas); + uart_setreg(bas, REG_DLL, divisor & 0xff); + uart_setreg(bas, REG_DLH, (divisor >> 8) & 0xff); + uart_barrier(bas); + delay_changed = 1; + } + + /* Set LCR and clear DLAB. */ + uart_setreg(bas, REG_LCR, lcr); + uart_barrier(bas); + return (0); +} + +/* + * Low-level UART interface. + */ +static int oct16550_probe(struct uart_bas *bas); +static void oct16550_init(struct uart_bas *bas, int, int, int, int); +static void oct16550_term(struct uart_bas *bas); +static void oct16550_putc(struct uart_bas *bas, int); +static int oct16550_rxready(struct uart_bas *bas); +static int oct16550_getc(struct uart_bas *bas, struct mtx *); + +struct uart_ops uart_oct16550_ops = { + .probe = oct16550_probe, + .init = oct16550_init, + .term = oct16550_term, + .putc = oct16550_putc, + .rxready = oct16550_rxready, + .getc = oct16550_getc, +}; + +static int +oct16550_probe (struct uart_bas *bas) +{ + u_char val; + + /* Check known 0 bits that don't depend on DLAB. */ + val = uart_getreg(bas, REG_IIR); + if (val & 0x30) + return (ENXIO); + val = uart_getreg(bas, REG_MCR); + if (val & 0xc0) + return (ENXIO); + val = uart_getreg(bas, REG_USR); + if (val & 0xe0) + return (ENXIO); + return (0); +} + +static void +oct16550_init (struct uart_bas *bas, int baudrate, int databits, int stopbits, + int parity) +{ + u_char ier; + + oct16550_param(bas, baudrate, databits, stopbits, parity); + + /* Disable all interrupt sources. */ + ier = uart_getreg(bas, REG_IER) & 0x0; + uart_setreg(bas, REG_IER, ier); + uart_barrier(bas); + + /* Disable the FIFO (if present). */ +// uart_setreg(bas, REG_FCR, 0); + uart_barrier(bas); + + /* Set RTS & DTR. */ + uart_setreg(bas, REG_MCR, MCR_RTS | MCR_DTR); + uart_barrier(bas); + + oct16550_clrint(bas); +} + +static void +oct16550_term (struct uart_bas *bas) +{ + + /* Clear RTS & DTR. */ + uart_setreg(bas, REG_MCR, 0); + uart_barrier(bas); +} + +static inline void oct16550_wait_txhr_empty (struct uart_bas *bas, int limit, int delay) +{ + while (((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0) && + ((uart_getreg(bas, REG_USR) & USR_TXFIFO_NOTFULL) == 0)) + DELAY(delay); +} + +static void +oct16550_putc (struct uart_bas *bas, int c) +{ + int delay; + + /* 1/10th the time to transmit 1 character (estimate). */ + delay = oct16550_delay(bas); + oct16550_wait_txhr_empty(bas, 100, delay); + uart_setreg(bas, REG_DATA, c); + uart_barrier(bas); + oct16550_wait_txhr_empty(bas, 100, delay); +} + +static int +oct16550_rxready (struct uart_bas *bas) +{ + + return ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) != 0 ? 1 : 0); +} + +static int +oct16550_getc (struct uart_bas *bas, struct mtx *hwmtx) +{ + int c, delay; + + uart_lock(hwmtx); + + /* 1/10th the time to transmit 1 character (estimate). */ + delay = oct16550_delay(bas); + + while ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) == 0) { + uart_unlock(hwmtx); + DELAY(delay); + uart_lock(hwmtx); + } + + c = uart_getreg(bas, REG_DATA); + + uart_unlock(hwmtx); + + return (c); +} + +/* + * High-level UART interface. + */ +struct oct16550_softc { + struct uart_softc base; + uint8_t fcr; + uint8_t ier; + uint8_t mcr; +}; + +static int oct16550_bus_attach(struct uart_softc *); +static int oct16550_bus_detach(struct uart_softc *); +static int oct16550_bus_flush(struct uart_softc *, int); +static int oct16550_bus_getsig(struct uart_softc *); +static int oct16550_bus_ioctl(struct uart_softc *, int, intptr_t); +static int oct16550_bus_ipend(struct uart_softc *); +static int oct16550_bus_param(struct uart_softc *, int, int, int, int); +static int oct16550_bus_probe(struct uart_softc *); +static int oct16550_bus_receive(struct uart_softc *); +static int oct16550_bus_setsig(struct uart_softc *, int); +static int oct16550_bus_transmit(struct uart_softc *); + +static kobj_method_t oct16550_methods[] = { + KOBJMETHOD(uart_attach, oct16550_bus_attach), + KOBJMETHOD(uart_detach, oct16550_bus_detach), + KOBJMETHOD(uart_flush, oct16550_bus_flush), + KOBJMETHOD(uart_getsig, oct16550_bus_getsig), + KOBJMETHOD(uart_ioctl, oct16550_bus_ioctl), + KOBJMETHOD(uart_ipend, oct16550_bus_ipend), + KOBJMETHOD(uart_param, oct16550_bus_param), + KOBJMETHOD(uart_probe, oct16550_bus_probe), + KOBJMETHOD(uart_receive, oct16550_bus_receive), + KOBJMETHOD(uart_setsig, oct16550_bus_setsig), + KOBJMETHOD(uart_transmit, oct16550_bus_transmit), + { 0, 0 } +}; + +struct uart_class uart_oct16550_class = { + "oct16550 class", + oct16550_methods, + sizeof(struct oct16550_softc), + .uc_ops = &uart_oct16550_ops, + .uc_range = 8, + .uc_rclk = 0 +}; + +#define SIGCHG(c, i, s, d) \ + if (c) { \ + i |= (i & s) ? s : s | d; \ + } else { \ + i = (i & s) ? (i & ~s) | d : i; \ + } + +static int +oct16550_bus_attach (struct uart_softc *sc) +{ + struct oct16550_softc *oct16550 = (struct oct16550_softc*)sc; + struct uart_bas *bas; + int unit; + + unit = device_get_unit(sc->sc_dev); + bas = &sc->sc_bas; + + oct16550_drain(bas, UART_DRAIN_TRANSMITTER); + oct16550->mcr = uart_getreg(bas, REG_MCR); + oct16550->fcr = FCR_ENABLE | FCR_RX_HIGH; + uart_setreg(bas, REG_FCR, oct16550->fcr); + uart_barrier(bas); + oct16550_bus_flush(sc, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER); + + if (oct16550->mcr & MCR_DTR) + sc->sc_hwsig |= SER_DTR; + if (oct16550->mcr & MCR_RTS) + sc->sc_hwsig |= SER_RTS; + oct16550_bus_getsig(sc); + + oct16550_clrint(bas); + oct16550->ier = uart_getreg(bas, REG_IER) & 0xf0; + oct16550->ier |= IER_EMSC | IER_ERLS | IER_ERXRDY; + uart_setreg(bas, REG_IER, oct16550->ier); + uart_barrier(bas); + + uint32_t status_bits = mips_rd_status(); + mips_wr_status(status_bits & ~MIPS_SR_INT_IE); + /* + * Enable the interrupt in CIU. // UART-x2 @ IP2 + */ + ciu_enable_interrupts(0, CIU_INT_0, CIU_EN_0, + (!unit) ? CIU_UART_BITS_UART0 : CIU_UART_BITS_UART1, CIU_MIPS_IP2); + return (0); +} + +static int +oct16550_bus_detach (struct uart_softc *sc) +{ + struct uart_bas *bas; + u_char ier; + + bas = &sc->sc_bas; + ier = uart_getreg(bas, REG_IER) & 0xf0; + uart_setreg(bas, REG_IER, ier); + uart_barrier(bas); + oct16550_clrint(bas); + return (0); +} + +static int +oct16550_bus_flush (struct uart_softc *sc, int what) +{ + struct oct16550_softc *oct16550 = (struct oct16550_softc*)sc; + struct uart_bas *bas; + int error; + + bas = &sc->sc_bas; + uart_lock(sc->sc_hwmtx); + if (sc->sc_rxfifosz > 1) { + oct16550_flush(bas, what); + uart_setreg(bas, REG_FCR, oct16550->fcr); + uart_barrier(bas); + error = 0; + } else + error = oct16550_drain(bas, what); + uart_unlock(sc->sc_hwmtx); + return (error); +} + +static int +oct16550_bus_getsig (struct uart_softc *sc) +{ + uint32_t new, old, sig; + uint8_t msr; + + do { + old = sc->sc_hwsig; + sig = old; + uart_lock(sc->sc_hwmtx); + msr = uart_getreg(&sc->sc_bas, REG_MSR); + uart_unlock(sc->sc_hwmtx); + SIGCHG(msr & MSR_DSR, sig, SER_DSR, SER_DDSR); + SIGCHG(msr & MSR_CTS, sig, SER_CTS, SER_DCTS); + SIGCHG(msr & MSR_DCD, sig, SER_DCD, SER_DDCD); + SIGCHG(msr & MSR_RI, sig, SER_RI, SER_DRI); + new = sig & ~SER_MASK_DELTA; + } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); + return (sig); +} + +static int +oct16550_bus_ioctl (struct uart_softc *sc, int request, intptr_t data) +{ + struct uart_bas *bas; + int baudrate, divisor, error; + uint8_t efr, lcr; + + bas = &sc->sc_bas; + error = 0; + uart_lock(sc->sc_hwmtx); + switch (request) { + case UART_IOCTL_BREAK: + lcr = uart_getreg(bas, REG_LCR); + if (data) + lcr |= LCR_SBREAK; + else + lcr &= ~LCR_SBREAK; + uart_setreg(bas, REG_LCR, lcr); + uart_barrier(bas); + break; + case UART_IOCTL_IFLOW: + lcr = uart_getreg(bas, REG_LCR); + uart_barrier(bas); + uart_setreg(bas, REG_LCR, 0xbf); + uart_barrier(bas); + efr = uart_getreg(bas, REG_EFR); + if (data) + efr |= EFR_RTS; + else + efr &= ~EFR_RTS; + uart_setreg(bas, REG_EFR, efr); + uart_barrier(bas); + uart_setreg(bas, REG_LCR, lcr); + uart_barrier(bas); + break; + case UART_IOCTL_OFLOW: + lcr = uart_getreg(bas, REG_LCR); + uart_barrier(bas); + uart_setreg(bas, REG_LCR, 0xbf); + uart_barrier(bas); + efr = uart_getreg(bas, REG_EFR); + if (data) + efr |= EFR_CTS; + else + efr &= ~EFR_CTS; + uart_setreg(bas, REG_EFR, efr); + uart_barrier(bas); + uart_setreg(bas, REG_LCR, lcr); + uart_barrier(bas); + break; + case UART_IOCTL_BAUD: + lcr = uart_getreg(bas, REG_LCR); + uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); + uart_barrier(bas); + divisor = uart_getreg(bas, REG_DLL) | + (uart_getreg(bas, REG_DLH) << 8); + uart_barrier(bas); + uart_setreg(bas, REG_LCR, lcr); + uart_barrier(bas); + baudrate = (divisor > 0) ? bas->rclk / divisor / 16 : 0; + delay_changed = 1; + if (baudrate > 0) + *(int*)data = baudrate; + else + error = ENXIO; + break; + default: + error = EINVAL; + break; + } + uart_unlock(sc->sc_hwmtx); + return (error); +} + + +static int +oct16550_bus_ipend(struct uart_softc *sc) +{ + struct uart_bas *bas; + int ipend = 0; + uint8_t iir, lsr; + + bas = &sc->sc_bas; + uart_lock(sc->sc_hwmtx); + + iir = uart_getreg(bas, REG_IIR) & IIR_IMASK; + if (iir != IIR_NOPEND) { + + if (iir == IIR_RLS) { + lsr = uart_getreg(bas, REG_LSR); + if (lsr & LSR_OE) + ipend |= SER_INT_OVERRUN; + if (lsr & LSR_BI) + ipend |= SER_INT_BREAK; + if (lsr & LSR_RXRDY) + ipend |= SER_INT_RXREADY; + + } else if (iir == IIR_RXRDY) { + ipend |= SER_INT_RXREADY; + + } else if (iir == IIR_RXTOUT) { + ipend |= SER_INT_RXREADY; + + } else if (iir == IIR_TXRDY) { + ipend |= SER_INT_TXIDLE; + + } else if (iir == IIR_MLSC) { + ipend |= SER_INT_SIGCHG; + + } else if (iir == IIR_BUSY) { + (void) uart_getreg(bas, REG_USR); + } + } + uart_unlock(sc->sc_hwmtx); + +//#define OCTEON_VISUAL_UART 1 +#ifdef OCTEON_VISUAL_UART + static int where1 = 0; + + if (ipend) octeon_led_run_wheel(&where1, 6 + device_get_unit(sc->sc_dev)); +#endif + + return ((sc->sc_leaving) ? 0 : ipend); +} + + + + +static int +oct16550_bus_param (struct uart_softc *sc, int baudrate, int databits, + int stopbits, int parity) +{ + struct uart_bas *bas; + int error; + + bas = &sc->sc_bas; + uart_lock(sc->sc_hwmtx); + error = oct16550_param(bas, baudrate, databits, stopbits, parity); + uart_unlock(sc->sc_hwmtx); + return (error); +} + +static int +oct16550_bus_probe (struct uart_softc *sc) +{ + struct uart_bas *bas; + int error; + + bas = &sc->sc_bas; + bas->rclk = uart_oct16550_class.uc_rclk = octeon_cpu_clock; + + error = oct16550_probe(bas); + if (error) { + return (error); + } + + uart_setreg(bas, REG_MCR, (MCR_DTR | MCR_RTS)); + + /* + * Enable FIFOs. And check that the UART has them. If not, we're + * done. Since this is the first time we enable the FIFOs, we reset + * them. + */ + oct16550_drain(bas, UART_DRAIN_TRANSMITTER); +#define ENABLE_OCTEON_FIFO 1 +#ifdef ENABLE_OCTEON_FIFO + uart_setreg(bas, REG_FCR, FCR_ENABLE | FCR_XMT_RST | FCR_RCV_RST); +#endif + uart_barrier(bas); + + oct16550_flush(bas, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER); + + if (device_get_unit(sc->sc_dev)) { + device_set_desc(sc->sc_dev, "Octeon-16550 channel 1"); + } else { + device_set_desc(sc->sc_dev, "Octeon-16550 channel 0"); + } +#ifdef ENABLE_OCTEON_FIFO + sc->sc_rxfifosz = 64; + sc->sc_txfifosz = 64; +#else + sc->sc_rxfifosz = 1; + sc->sc_txfifosz = 1; +#endif + + +#if 0 + /* + * XXX there are some issues related to hardware flow control and + * it's likely that uart(4) is the cause. This basicly needs more + * investigation, but we avoid using for hardware flow control + * until then. + */ + /* 16650s or higher have automatic flow control. */ + if (sc->sc_rxfifosz > 16) { + sc->sc_hwiflow = 1; + sc->sc_hwoflow = 1; + } +#endif + + return (0); +} + +static int +oct16550_bus_receive (struct uart_softc *sc) +{ + struct uart_bas *bas; + int xc; + uint8_t lsr; + + bas = &sc->sc_bas; + uart_lock(sc->sc_hwmtx); + lsr = uart_getreg(bas, REG_LSR); + + while (lsr & LSR_RXRDY) { + if (uart_rx_full(sc)) { + sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN; + break; + } + xc = uart_getreg(bas, REG_DATA); + if (lsr & LSR_FE) + xc |= UART_STAT_FRAMERR; + if (lsr & LSR_PE) + xc |= UART_STAT_PARERR; + uart_rx_put(sc, xc); + lsr = uart_getreg(bas, REG_LSR); + } + /* Discard everything left in the Rx FIFO. */ + /* + * First do a dummy read/discard anyway, in case the UART was lying to us. + * This problem was seen on board, when IIR said RBR, but LSR said no RXRDY + * Results in a stuck ipend loop. + */ + (void)uart_getreg(bas, REG_DATA); + while (lsr & LSR_RXRDY) { + (void)uart_getreg(bas, REG_DATA); + uart_barrier(bas); + lsr = uart_getreg(bas, REG_LSR); + } + uart_unlock(sc->sc_hwmtx); + return (0); +} + +static int +oct16550_bus_setsig (struct uart_softc *sc, int sig) +{ + struct oct16550_softc *oct16550 = (struct oct16550_softc*)sc; + struct uart_bas *bas; + uint32_t new, old; + + bas = &sc->sc_bas; + do { + old = sc->sc_hwsig; + new = old; + if (sig & SER_DDTR) { + SIGCHG(sig & SER_DTR, new, SER_DTR, + SER_DDTR); + } + if (sig & SER_DRTS) { + SIGCHG(sig & SER_RTS, new, SER_RTS, + SER_DRTS); + } + } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); + uart_lock(sc->sc_hwmtx); + oct16550->mcr &= ~(MCR_DTR|MCR_RTS); + if (new & SER_DTR) + oct16550->mcr |= MCR_DTR; + if (new & SER_RTS) + oct16550->mcr |= MCR_RTS; + uart_setreg(bas, REG_MCR, oct16550->mcr); + uart_barrier(bas); + uart_unlock(sc->sc_hwmtx); + return (0); +} + +static int +oct16550_bus_transmit (struct uart_softc *sc) +{ + struct oct16550_softc *oct16550 = (struct oct16550_softc*)sc; + struct uart_bas *bas; + int i; + + bas = &sc->sc_bas; + uart_lock(sc->sc_hwmtx); +#ifdef NO_UART_INTERRUPTS + for (i = 0; i < sc->sc_txdatasz; i++) { + oct16550_putc(bas, sc->sc_txbuf[i]); + } +#else + + oct16550_wait_txhr_empty(bas, 100, oct16550_delay(bas)); + uart_setreg(bas, REG_IER, oct16550->ier | IER_ETXRDY); + uart_barrier(bas); + + for (i = 0; i < sc->sc_txdatasz; i++) { + uart_setreg(bas, REG_DATA, sc->sc_txbuf[i]); + uart_barrier(bas); + } + sc->sc_txbusy = 1; +#endif + uart_unlock(sc->sc_hwmtx); + return (0); +} From 55f888f68d2d54e63636ba2e229e355004a14f38 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 06:10:36 +0000 Subject: [PATCH 113/380] Cavium-specific goo is no longer necessary here. Of course, I now have to write a bus space for cavium, but that shouldn't be too hard. --- sys/mips/include/_bus.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sys/mips/include/_bus.h b/sys/mips/include/_bus.h index d29a9dce0d6..df6169a2f4e 100644 --- a/sys/mips/include/_bus.h +++ b/sys/mips/include/_bus.h @@ -31,9 +31,6 @@ #ifndef MIPS_INCLUDE__BUS_H #define MIPS_INCLUDE__BUS_H -#ifdef TARGET_OCTEON -#include "_bus_octeon.h" -#else /* * Bus address and size types */ @@ -45,5 +42,4 @@ typedef uintptr_t bus_size_t; */ typedef struct bus_space *bus_space_tag_t; typedef u_long bus_space_handle_t; -#endif #endif /* MIPS_INCLUDE__BUS_H */ From 8c29759b4ac2d18fe76e5d086de2134c5554a4aa Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 06:11:13 +0000 Subject: [PATCH 114/380] Bring back the TARGET_OCTEON kludge for a bit. We need to kill it, but it is useful for the moment. --- sys/mips/octeon1/std.octeon1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/mips/octeon1/std.octeon1 b/sys/mips/octeon1/std.octeon1 index 6c72febde98..c46d0c770a5 100644 --- a/sys/mips/octeon1/std.octeon1 +++ b/sys/mips/octeon1/std.octeon1 @@ -18,3 +18,5 @@ cpu CPU_MIPS4KC #device obio #device uart +# Kludge +options TARGET_OCTEON From 2acee4de5c9a7a501d9bef2d516b792d7112461d Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 06:11:51 +0000 Subject: [PATCH 115/380] First pass to make compile. It doesn't completely yet, but it's a start. --- sys/mips/octeon1/dev/rgmii/octeon_fau.c | 4 +--- sys/mips/octeon1/dev/rgmii/octeon_fpa.c | 1 + sys/mips/octeon1/dev/rgmii/octeon_ipd.c | 1 + sys/mips/octeon1/dev/rgmii/octeon_pko.c | 12 +++++++----- sys/mips/octeon1/dev/rgmii/octeon_rgmx.c | 8 +++++--- sys/mips/octeon1/dev/rgmii/octeon_rgmx.h | 5 +++-- 6 files changed, 18 insertions(+), 13 deletions(-) diff --git a/sys/mips/octeon1/dev/rgmii/octeon_fau.c b/sys/mips/octeon1/dev/rgmii/octeon_fau.c index f51d6f9fb96..849ffd43799 100644 --- a/sys/mips/octeon1/dev/rgmii/octeon_fau.c +++ b/sys/mips/octeon1/dev/rgmii/octeon_fau.c @@ -7,6 +7,7 @@ #include #include +#include #include "octeon_fau.h" /* @@ -39,6 +40,3 @@ void octeon_fau_enable (void) void octeon_fau_disable (void) { } - - - diff --git a/sys/mips/octeon1/dev/rgmii/octeon_fpa.c b/sys/mips/octeon1/dev/rgmii/octeon_fpa.c index 04cb19408aa..0f456984b3a 100644 --- a/sys/mips/octeon1/dev/rgmii/octeon_fpa.c +++ b/sys/mips/octeon1/dev/rgmii/octeon_fpa.c @@ -11,6 +11,7 @@ #include +#include #include "octeon_fpa.h" diff --git a/sys/mips/octeon1/dev/rgmii/octeon_ipd.c b/sys/mips/octeon1/dev/rgmii/octeon_ipd.c index d70758d4de9..069b5376edb 100644 --- a/sys/mips/octeon1/dev/rgmii/octeon_ipd.c +++ b/sys/mips/octeon1/dev/rgmii/octeon_ipd.c @@ -7,6 +7,7 @@ #include #include +#include #include "octeon_ipd.h" /* diff --git a/sys/mips/octeon1/dev/rgmii/octeon_pko.c b/sys/mips/octeon1/dev/rgmii/octeon_pko.c index 7d402c25da0..2b2cb5ea3ee 100644 --- a/sys/mips/octeon1/dev/rgmii/octeon_pko.c +++ b/sys/mips/octeon1/dev/rgmii/octeon_pko.c @@ -9,6 +9,7 @@ #include #include +#include #include "octeon_fau.h" #include "octeon_fpa.h" #include "octeon_pko.h" @@ -172,7 +173,7 @@ static void octeon_pko_doorbell_data_dump (uint64_t port) octeon_pko_port_status_t status; octeon_pko_get_port_status(port, 0, &status); - printf("\n Port #%d Pkts %d Bytes %lld DoorBell %lld", + printf("\n Port #%lld Pkts %ld Bytes %lld DoorBell %lld", port, status.packets, status.octets, status.doorbell); } @@ -208,7 +209,7 @@ void octeon_pko_show (u_int start_port, u_int end_port) gmx_int0_ports = (16 >> octeon_pko_gmx_mode.bits.mode0); gmx_int1_ports = (16 >> octeon_pko_gmx_mode.bits.mode1); octeon_pko_crc_ports.word64 = oct_read64(OCTEON_PKO_REG_CRC_ENABLE); - printf("\n Total Queues: 0..%d Ports GMX0 %d GMX1 %d CRC 0x%llX", + printf("\n Total Queues: 0..%d Ports GMX0 %d GMX1 %d CRC 0x%X", queue_max - 1, gmx_int0_ports, gmx_int1_ports, octeon_pko_crc_ports.bits.crc_ports_mask); @@ -228,7 +229,8 @@ void octeon_pko_show (u_int start_port, u_int end_port) printf("\n Port # %d Queue %3d [%d] BufPtr: 0x%llX Mask: %X%s", octeon_pko_queue_cfg.bits.port, octeon_pko_queue_cfg.bits.queue, octeon_pko_queue_cfg.bits.index, - octeon_pko_queue_cfg.bits.buf_ptr, octeon_pko_queue_cfg.bits.qos_mask, + (uint64_t)octeon_pko_queue_cfg.bits.buf_ptr, + octeon_pko_queue_cfg.bits.qos_mask, (octeon_pko_queue_cfg.bits.tail)? " Last":""); } printf("\n"); @@ -236,7 +238,7 @@ void octeon_pko_show (u_int start_port, u_int end_port) for (port = start_port; port < (end_port + 1); port++) { octeon_pko_get_port_status(port, 0, &status); - printf("\n Port #%d Packets %d Bytes %lld DoorBell %lld", + printf("\n Port #%d Packets %ld Bytes %lld DoorBell %lld", port, status.packets, status.octets, status.doorbell); octeon_pko_doorbell_data_dump(port); @@ -264,7 +266,7 @@ octeon_pko_status_t octeon_pko_config_port (u_int port, octeon_pko_queue_cfg_t qconfig; if ((port >= OCTEON_PKO_PORTS_MAX) && (port != OCTEON_PKO_PORT_ILLEGAL)) { - printf("\n%% Error: octeon_pko_config_port: Invalid port %llu", port); + printf("\n%% Error: octeon_pko_config_port: Invalid port %u", port); return (OCTEON_PKO_INVALID_PORT); } diff --git a/sys/mips/octeon1/dev/rgmii/octeon_rgmx.c b/sys/mips/octeon1/dev/rgmii/octeon_rgmx.c index 29856d5c7ee..f37fa090eb9 100644 --- a/sys/mips/octeon1/dev/rgmii/octeon_rgmx.c +++ b/sys/mips/octeon1/dev/rgmii/octeon_rgmx.c @@ -48,6 +48,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include "octeon_fau.h" #include "octeon_fpa.h" #include "octeon_ipd.h" @@ -1880,20 +1882,20 @@ static void rgmx_timer_periodic (void) * Now look for anamolous conditions */ if (sc != get_rgmx_softc(port)) { - printf(" port %u sc 0x%X not in sync with index: %u\n", + printf(" port %u sc %p not in sync with index: %u\n", port, sc, index); continue; } if (sc->port != port) { - printf(" port %u sc 0x%X port-> %u not in sync with index: %u\n", + printf(" port %u sc %p port-> %u not in sync with index: %u\n", port, sc, sc->port, index); continue; } ifp = sc->ifp; if (ifp == NULL) { - printf(" port %u sc 0x%X . Bad ifp 0x%X\n", port, sc, ifp); + printf(" port %u sc %p . Bad ifp %p\n", port, sc, ifp); continue; } diff --git a/sys/mips/octeon1/dev/rgmii/octeon_rgmx.h b/sys/mips/octeon1/dev/rgmii/octeon_rgmx.h index 8e446ec47d9..8b74db23ef3 100644 --- a/sys/mips/octeon1/dev/rgmii/octeon_rgmx.h +++ b/sys/mips/octeon1/dev/rgmii/octeon_rgmx.h @@ -439,8 +439,9 @@ static inline octeon_wqe_t *octeon_pow_work_request_sync_nocheck_debug (octeon_p result.word64 = oct_read64(ptr.word64); - printf("WQE Result: 0x%llX No-work %llX Addr %llX Ptr: %llX\n", - result.word64, result.s_work.no_work, result.s_work.addr, OCTEON_PHYS2PTR(result.s_work.addr)); + printf("WQE Result: 0x%llX No-work %X Addr %llX Ptr: %p\n", + result.word64, result.s_work.no_work, (uint64_t)result.s_work.addr, + OCTEON_PHYS2PTR(result.s_work.addr)); if (result.s_work.no_work || !result.s_work.addr) { return NULL; From 78e0ef6f04f52f0f2ce6bce5c41aeac0d3ced2ef Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 06:12:21 +0000 Subject: [PATCH 116/380] Kludge: pretend to be ISA_MIPS32 for the moment. --- sys/mips/conf/OCTEON1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/mips/conf/OCTEON1 b/sys/mips/conf/OCTEON1 index 957cae2c217..4d96e5b28b2 100644 --- a/sys/mips/conf/OCTEON1 +++ b/sys/mips/conf/OCTEON1 @@ -25,6 +25,7 @@ ident OCTEON1 # Don't build any modules yet. makeoptions MODULES_OVERRIDE="" +makeoptions TARGET_BIG_ENDIAN=defined options KERNVIRTADDR=0x80100000 include "../octeon1/std.octeon1" @@ -33,6 +34,9 @@ hints "OCTEON1.hints" #Default places to look for devices. makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols +#XXXimp: Need to make work with 64-bit too +options ISA_MIPS32 + options DDB options KDB From 2e24c40fec028f34cb1e88826e2c6ce327381174 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 06:14:25 +0000 Subject: [PATCH 117/380] bye bye. This is no longer referenced, but much code from it will resurface for a bus-space implementation. --- sys/mips/include/bus_octeon.h | 883 ---------------------------------- 1 file changed, 883 deletions(-) delete mode 100644 sys/mips/include/bus_octeon.h diff --git a/sys/mips/include/bus_octeon.h b/sys/mips/include/bus_octeon.h deleted file mode 100644 index be538ba825c..00000000000 --- a/sys/mips/include/bus_octeon.h +++ /dev/null @@ -1,883 +0,0 @@ -/*- - * Copyright (c) 2006 Oleksandr Tymoshenko. - * Copyright (c) KATO Takenori, 1999. - * - * All rights reserved. Unpublished rights reserved under the copyright - * laws of Japan. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer as - * the first lines of this file unmodified. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $ */ - -/*- - * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, - * NASA Ames Research Center. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/*- - * Copyright (c) 1996 Charles M. Hannum. All rights reserved. - * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Christopher G. Demetriou - * for the NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _MIPS_BUS_OCTEON_H_ -#define _MIPS_BUS_OCTEON_H_ - -#include "../../mips32/octeon32/octeon_pcmap_regs.h" -#include -#include - -/* - * Values for the mips64 bus space tag, not to be used directly by MI code. - */ -#define MIPS_BUS_SPACE_IO 0 /* space is i/o space */ -#define MIPS_BUS_SPACE_MEM 1 /* space is mem space */ - -#define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF -#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF -#define BUS_SPACE_MAXSIZE 0xFFFFFFFF -#define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF -#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF -#define BUS_SPACE_MAXADDR 0xFFFFFFFF - -#define BUS_SPACE_UNRESTRICTED (~0) - -/* - * Map a region of device bus space into CPU virtual address space. - */ - -static __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr, - bus_size_t size, int flags, - bus_space_handle_t *bshp); - -static __inline int -bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr, - bus_size_t size __unused, int flags __unused, - bus_space_handle_t *bshp) -{ - - *bshp = addr; - return (0); -} - -/* - * Unmap a region of device bus space. - */ - -static __inline void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, - bus_size_t size); - -static __inline void -bus_space_unmap(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused, - bus_size_t size __unused) -{ -} - -/* - * Get a new handle for a subregion of an already-mapped area of bus space. - */ - -static __inline int bus_space_subregion(bus_space_tag_t t, - bus_space_handle_t bsh, - bus_size_t offset, bus_size_t size, - bus_space_handle_t *nbshp); - -static __inline int -bus_space_subregion(bus_space_tag_t t __unused, bus_space_handle_t bsh, - bus_size_t offset, bus_size_t size __unused, - bus_space_handle_t *nbshp) -{ - *nbshp = bsh + offset; - return (0); -} - -/* - * Allocate a region of memory that is accessible to devices in bus space. - */ - -int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, - bus_addr_t rend, bus_size_t size, bus_size_t align, - bus_size_t boundary, int flags, bus_addr_t *addrp, - bus_space_handle_t *bshp); - -/* - * Free a region of bus space accessible memory. - */ - -static __inline void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh, - bus_size_t size); - -static __inline void -bus_space_free(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused, - bus_size_t size __unused) -{ -} - - -/* - * Read a 1, 2, 4, or 8 byte quantity from bus space - * described by tag/handle/offset. - */ -static __inline u_int8_t bus_space_read_1(bus_space_tag_t tag, - bus_space_handle_t handle, - bus_size_t offset); - -static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag, - bus_space_handle_t handle, - bus_size_t offset); - -static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag, - bus_space_handle_t handle, - bus_size_t offset); - -static __inline u_int8_t -bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset) -{ - uint64_t ret_val; - uint64_t oct64_addr; - - oct64_addr = handle + offset; - ret_val = oct_read8(oct64_addr); - return ((u_int8_t) ret_val); -} - -static __inline u_int16_t -bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset) -{ - uint64_t ret_val; - uint64_t oct64_addr; - - oct64_addr = handle + offset; - ret_val = oct_read16(oct64_addr); - return ((u_int16_t) ret_val); -} - -static __inline u_int32_t -bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset) -{ - uint64_t ret_val; - uint64_t oct64_addr; - - oct64_addr = handle + offset; - ret_val = oct_read32(oct64_addr); - return ((u_int32_t) ret_val); -} - - -static __inline u_int64_t -bus_space_read_8(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset) -{ - uint64_t ret_val; - uint64_t oct64_addr; - - oct64_addr = handle + offset; - ret_val = oct_read64(oct64_addr); - return (ret_val); -} - - -/* - * Read `count' 1, 2, 4, or 8 byte quantities from bus space - * described by tag/handle/offset and copy into buffer provided. - */ -static __inline void bus_space_read_region_1(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int8_t *addr, - size_t count); - -static __inline void bus_space_read_region_2(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int16_t *addr, - size_t count); - -static __inline void bus_space_read_region_4(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int32_t *addr, - size_t count); - -static __inline void -bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t *addr, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--, addr++, ptr++) { - *addr = oct_read8(ptr); - } -} - -static __inline void -bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t *addr, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--, addr++, ptr+=2) { - *addr = oct_read16(ptr); - } -} - -static __inline void -bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t *addr, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--, addr++, ptr+=4) { - *addr = oct_read32(ptr); - } -} - -static __inline void -bus_space_read_region_8(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int64_t *addr, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--, addr++, ptr+=4) { - *addr = oct_read64(ptr); - } -} - -/* - * Read `count' 1, 2, 4, or 8 byte quantities from bus space - * described by tag/handle and starting at `offset' and copy into - * buffer provided. - */ -static __inline void bus_space_read_multi_1(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int8_t *addr, - size_t count); - -static __inline void bus_space_read_multi_2(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int16_t *addr, - size_t count); - -static __inline void bus_space_read_multi_4(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int32_t *addr, - size_t count); - - -static __inline void -bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t *addr, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--, addr++) { - *addr = oct_read8(ptr); - } -} - -static __inline void -bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t *addr, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--, addr++) { - *addr = oct_read16(ptr); - } -} - -static __inline void -bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t *addr, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--, addr++) { - *addr = oct_read32(ptr); - } -} - -static __inline void -bus_space_read_multi_8(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int64_t *addr, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--, addr++) { - *addr = oct_read64(ptr); - } -} - - -/* - * Write the 1, 2, 4, or 8 byte value `value' to bus space - * described by tag/handle/offset. - */ - -static __inline void bus_space_write_1(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int8_t value); - -static __inline void bus_space_write_2(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int16_t value); - -static __inline void bus_space_write_4(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int32_t value); - -static __inline void -bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t value) -{ - oct_write8(bsh+offset, value); -} - -static __inline void -bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t value) -{ - oct_write16(bsh+offset, value); -} - -static __inline void -bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t value) -{ - oct_write32(bsh+offset, value); -} - -static __inline void -bus_space_write_8(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int64_t value) -{ - oct_write64(bsh+offset, value); -} - -/* - * Write `count' 1, 2, 4, or 8 byte quantities from the buffer - * provided to bus space described by tag/handle/offset. - */ - -static __inline void bus_space_write_region_1(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - const u_int8_t *addr, - size_t count); -static __inline void bus_space_write_region_2(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - const u_int16_t *addr, - size_t count); - -static __inline void bus_space_write_region_4(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - const u_int32_t *addr, - size_t count); - -static __inline void -bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int8_t *addr, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--, addr++, ptr++) { - oct_write8(ptr, *addr); - } -} - -static __inline void -bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int16_t *addr, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--, addr++, ptr++) { - oct_write16(ptr, *addr); - } -} - -static __inline void -bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int32_t *addr, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--, addr++, ptr++) { - oct_write32(ptr, *addr); - } -} - -static __inline void -bus_space_write_region_8(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int64_t *addr, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--, addr++, ptr++) { - oct_write64(ptr, *addr); - } -} - -/* - * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided - * to bus space described by tag/handle starting at `offset'. - */ - -static __inline void bus_space_write_multi_1(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - const u_int8_t *addr, - size_t count); -static __inline void bus_space_write_multi_2(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - const u_int16_t *addr, - size_t count); -static __inline void bus_space_write_multi_4(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - const u_int32_t *addr, - size_t count); - -static __inline void -bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int8_t *addr, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--, addr++) { - oct_write8(ptr, *addr); - } -} - -static __inline void -bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int16_t *addr, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--, addr++) { - oct_write16(ptr, *addr); - } -} - -static __inline void -bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int32_t *addr, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--, addr++) { - oct_write32(ptr, *addr); - } -} - -static __inline void -bus_space_write_multi_8(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, const u_int64_t *addr, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--, addr++) { - oct_write64(ptr, *addr); - } -} - -/* - * Write the 1, 2, 4, or 8 byte value `val' to bus space described - * by tag/handle/offset `count' times. - */ - -static __inline void bus_space_set_multi_1(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - u_int8_t value, size_t count); -static __inline void bus_space_set_multi_2(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - u_int16_t value, size_t count); -static __inline void bus_space_set_multi_4(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, - u_int32_t value, size_t count); - -static __inline void -bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t value, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--) { - oct_write8(ptr, value); - } -} - -static __inline void -bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t value, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--) { - oct_write16(ptr, value); - } -} - -static __inline void -bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t value, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--) { - oct_write32(ptr, value); - } -} - -static __inline void -bus_space_set_multi_8(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int64_t value, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--) { - oct_write64(ptr, value); - } -} - -/* - * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described - * by tag/handle starting at `offset'. - */ - -static __inline void bus_space_set_region_1(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int8_t value, - size_t count); -static __inline void bus_space_set_region_2(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int16_t value, - size_t count); -static __inline void bus_space_set_region_4(bus_space_tag_t tag, - bus_space_handle_t bsh, - bus_size_t offset, u_int32_t value, - size_t count); - -static __inline void -bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t value, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--, ptr++) { - oct_write8(ptr, value); - } -} - -static __inline void -bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t value, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--, ptr++) { - oct_write16(ptr, value); - } -} - -static __inline void -bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t value, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--, ptr++) { - oct_write32(ptr, value); - } -} - -static __inline void -bus_space_set_region_8(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, u_int64_t value, size_t count) -{ - uint64_t ptr = ((uint64_t) bsh + (uint64_t) offset); - - for(; count > 0; count--, ptr++) { - oct_write64(ptr, value); - } -} - -/* - * Copy `count' 1, 2, 4, or 8 byte values from bus space starting - * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. - */ - -static __inline void bus_space_copy_region_1(bus_space_tag_t tag, - bus_space_handle_t bsh1, - bus_size_t off1, - bus_space_handle_t bsh2, - bus_size_t off2, size_t count); - -static __inline void bus_space_copy_region_2(bus_space_tag_t tag, - bus_space_handle_t bsh1, - bus_size_t off1, - bus_space_handle_t bsh2, - bus_size_t off2, size_t count); - -static __inline void bus_space_copy_region_4(bus_space_tag_t tag, - bus_space_handle_t bsh1, - bus_size_t off1, - bus_space_handle_t bsh2, - bus_size_t off2, size_t count); - -static __inline void -bus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1, - bus_size_t off1, bus_space_handle_t bsh2, - bus_size_t off2, size_t count) -{ - uint64_t ptr1 = ((uint64_t) bsh1 + (uint64_t) off1); - uint64_t ptr2 = ((uint64_t) bsh2 + (uint64_t) off2); - uint8_t val; - - for(; count > 0; count--, ptr1++, ptr2++) { - val = oct_read8(ptr1); - oct_write8(ptr2, val); - } -} - -static __inline void -bus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1, - bus_size_t off1, bus_space_handle_t bsh2, - bus_size_t off2, size_t count) -{ - uint64_t ptr1 = ((uint64_t) bsh1 + (uint64_t) off1); - uint64_t ptr2 = ((uint64_t) bsh2 + (uint64_t) off2); - uint16_t val; - - for(; count > 0; count--, ptr1++, ptr2++) { - val = oct_read16(ptr1); - oct_write16(ptr2, val); - } -} - -static __inline void -bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1, - bus_size_t off1, bus_space_handle_t bsh2, - bus_size_t off2, size_t count) -{ - uint64_t ptr1 = ((uint64_t) bsh1 + (uint64_t) off1); - uint64_t ptr2 = ((uint64_t) bsh2 + (uint64_t) off2); - uint32_t val; - - for(; count > 0; count--, ptr1++, ptr2++) { - val = oct_read32(ptr1); - oct_write32(ptr2, val); - } -} - -static __inline void -bus_space_copy_region_8(bus_space_tag_t tag, bus_space_handle_t bsh1, - bus_size_t off1, bus_space_handle_t bsh2, - bus_size_t off2, size_t count) -{ - uint64_t ptr1 = ((uint64_t) bsh1 + (uint64_t) off1); - uint64_t ptr2 = ((uint64_t) bsh2 + (uint64_t) off2); - uint64_t val; - - for(; count > 0; count--, ptr1++, ptr2++) { - val = oct_read64(ptr1); - oct_write64(ptr2, val); - } -} - -/* - * Bus read/write barrier methods. - * - * void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh, - * bus_size_t offset, bus_size_t len, int flags); - * - * - * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than - * prevent reordering by the compiler; all Intel x86 processors currently - * retire operations outside the CPU in program order. - */ -#define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ -#define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ - -static __inline void -bus_space_barrier(bus_space_tag_t tag __unused, bus_space_handle_t bsh __unused, - bus_size_t offset __unused, bus_size_t len __unused, int flags) -{ -#if 0 -#ifdef __GNUCLIKE_ASM - if (flags & BUS_SPACE_BARRIER_READ) - __asm __volatile("lock; addl $0,0(%%rsp)" : : : "memory"); - else - __asm __volatile("" : : : "memory"); -#endif -#endif - oct_read64(OCTEON_MIO_BOOT_BIST_STAT); -} - -#ifdef BUS_SPACE_NO_LEGACY -#undef inb -#undef outb -#define inb(a) compiler_error -#define inw(a) compiler_error -#define inl(a) compiler_error -#define outb(a, b) compiler_error -#define outw(a, b) compiler_error -#define outl(a, b) compiler_error -#endif - -#include - -/* - * Stream accesses are the same as normal accesses on amd64; there are no - * supported bus systems with an endianess different from the host one. - */ -#define bus_space_read_stream_1(t, h, o) bus_space_read_1((t), (h), (o)) -#define bus_space_read_stream_2(t, h, o) bus_space_read_2((t), (h), (o)) -#define bus_space_read_stream_4(t, h, o) bus_space_read_4((t), (h), (o)) - -#define bus_space_read_multi_stream_1(t, h, o, a, c) \ - bus_space_read_multi_1((t), (h), (o), (a), (c)) -#define bus_space_read_multi_stream_2(t, h, o, a, c) \ - bus_space_read_multi_2((t), (h), (o), (a), (c)) -#define bus_space_read_multi_stream_4(t, h, o, a, c) \ - bus_space_read_multi_4((t), (h), (o), (a), (c)) - -#define bus_space_write_stream_1(t, h, o, v) \ - bus_space_write_1((t), (h), (o), (v)) -#define bus_space_write_stream_2(t, h, o, v) \ - bus_space_write_2((t), (h), (o), (v)) -#define bus_space_write_stream_4(t, h, o, v) \ - bus_space_write_4((t), (h), (o), (v)) - -#define bus_space_write_multi_stream_1(t, h, o, a, c) \ - bus_space_write_multi_1((t), (h), (o), (a), (c)) -#define bus_space_write_multi_stream_2(t, h, o, a, c) \ - bus_space_write_multi_2((t), (h), (o), (a), (c)) -#define bus_space_write_multi_stream_4(t, h, o, a, c) \ - bus_space_write_multi_4((t), (h), (o), (a), (c)) - -#define bus_space_set_multi_stream_1(t, h, o, v, c) \ - bus_space_set_multi_1((t), (h), (o), (v), (c)) -#define bus_space_set_multi_stream_2(t, h, o, v, c) \ - bus_space_set_multi_2((t), (h), (o), (v), (c)) -#define bus_space_set_multi_stream_4(t, h, o, v, c) \ - bus_space_set_multi_4((t), (h), (o), (v), (c)) - -#define bus_space_read_region_stream_1(t, h, o, a, c) \ - bus_space_read_region_1((t), (h), (o), (a), (c)) -#define bus_space_read_region_stream_2(t, h, o, a, c) \ - bus_space_read_region_2((t), (h), (o), (a), (c)) -#define bus_space_read_region_stream_4(t, h, o, a, c) \ - bus_space_read_region_4((t), (h), (o), (a), (c)) - -#define bus_space_write_region_stream_1(t, h, o, a, c) \ - bus_space_write_region_1((t), (h), (o), (a), (c)) -#define bus_space_write_region_stream_2(t, h, o, a, c) \ - bus_space_write_region_2((t), (h), (o), (a), (c)) -#define bus_space_write_region_stream_4(t, h, o, a, c) \ - bus_space_write_region_4((t), (h), (o), (a), (c)) - -#define bus_space_set_region_stream_1(t, h, o, v, c) \ - bus_space_set_region_1((t), (h), (o), (v), (c)) -#define bus_space_set_region_stream_2(t, h, o, v, c) \ - bus_space_set_region_2((t), (h), (o), (v), (c)) -#define bus_space_set_region_stream_4(t, h, o, v, c) \ - bus_space_set_region_4((t), (h), (o), (v), (c)) - -#define bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \ - bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c)) -#define bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \ - bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c)) -#define bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \ - bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c)) - -#endif /* _MIPS_BUS_OCTEON_H_ */ From c453afd1133d508a43fc5a6d0436ced7270c6170 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 06:26:33 +0000 Subject: [PATCH 118/380] this was actually deleted earlier, but I bogusly neglected to commit it. --- sys/dev/uart/uart_dev_oct16550.c | 826 ------------------------------- 1 file changed, 826 deletions(-) delete mode 100644 sys/dev/uart/uart_dev_oct16550.c diff --git a/sys/dev/uart/uart_dev_oct16550.c b/sys/dev/uart/uart_dev_oct16550.c deleted file mode 100644 index 53c8ee2af62..00000000000 --- a/sys/dev/uart/uart_dev_oct16550.c +++ /dev/null @@ -1,826 +0,0 @@ -/*- - * Copyright (c) 2003 Marcel Moolenaar - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * uart_dev_oct16550.c - * - * Derived from uart_dev_ns8250.c - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - */ - - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - - -#include "uart_if.h" - -/* - * Clear pending interrupts. THRE is cleared by reading IIR. Data - * that may have been received gets lost here. - */ -static void -oct16550_clrint (struct uart_bas *bas) -{ - uint8_t iir; - - iir = uart_getreg(bas, REG_IIR); - while ((iir & IIR_NOPEND) == 0) { - iir &= IIR_IMASK; - if (iir == IIR_RLS) - (void)uart_getreg(bas, REG_LSR); - else if (iir == IIR_RXRDY || iir == IIR_RXTOUT) - (void)uart_getreg(bas, REG_DATA); - else if (iir == IIR_MLSC) - (void)uart_getreg(bas, REG_MSR); - else if (iir == IIR_BUSY) - (void) uart_getreg(bas, REG_USR); - uart_barrier(bas); - iir = uart_getreg(bas, REG_IIR); - } -} - -static int delay_changed = 1; - -static int -oct16550_delay (struct uart_bas *bas) -{ - int divisor; - u_char lcr; - static int delay = 0; - - if (!delay_changed) return delay; - delay_changed = 0; - lcr = uart_getreg(bas, REG_LCR); - uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); - uart_barrier(bas); - divisor = uart_getreg(bas, REG_DLL) | (uart_getreg(bas, REG_DLH) << 8); - uart_barrier(bas); - uart_setreg(bas, REG_LCR, lcr); - uart_barrier(bas); - - if(!bas->rclk) - return 10; /* return an approx delay value */ - - /* 1/10th the time to transmit 1 character (estimate). */ - if (divisor <= 134) - return (16000000 * divisor / bas->rclk); - return (16000 * divisor / (bas->rclk / 1000)); - -} - -static int -oct16550_divisor (int rclk, int baudrate) -{ - int actual_baud, divisor; - int error; - - if (baudrate == 0) - return (0); - - divisor = (rclk / (baudrate << 3) + 1) >> 1; - if (divisor == 0 || divisor >= 65536) - return (0); - actual_baud = rclk / (divisor << 4); - - /* 10 times error in percent: */ - error = ((actual_baud - baudrate) * 2000 / baudrate + 1) >> 1; - - /* 3.0% maximum error tolerance: */ - if (error < -30 || error > 30) - return (0); - - return (divisor); -} - -static int -oct16550_drain (struct uart_bas *bas, int what) -{ - int delay, limit; - - delay = oct16550_delay(bas); - - if (what & UART_DRAIN_TRANSMITTER) { - /* - * Pick an arbitrary high limit to avoid getting stuck in - * an infinite loop when the hardware is broken. Make the - * limit high enough to handle large FIFOs. - */ - limit = 10*10*10*1024; - while ((uart_getreg(bas, REG_LSR) & LSR_TEMT) == 0 && --limit) - DELAY(delay); - if (limit == 0) { - /* printf("oct16550: transmitter appears stuck... "); */ - return (0); - } - } - - if (what & UART_DRAIN_RECEIVER) { - /* - * Pick an arbitrary high limit to avoid getting stuck in - * an infinite loop when the hardware is broken. Make the - * limit high enough to handle large FIFOs and integrated - * UARTs. The HP rx2600 for example has 3 UARTs on the - * management board that tend to get a lot of data send - * to it when the UART is first activated. - */ - limit=10*4096; - while ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) && --limit) { - (void)uart_getreg(bas, REG_DATA); - uart_barrier(bas); - DELAY(delay << 2); - } - if (limit == 0) { - /* printf("oct16550: receiver appears broken... "); */ - return (EIO); - } - } - - return (0); -} - -/* - * We can only flush UARTs with FIFOs. UARTs without FIFOs should be - * drained. WARNING: this function clobbers the FIFO setting! - */ -static void -oct16550_flush (struct uart_bas *bas, int what) -{ - uint8_t fcr; - - fcr = FCR_ENABLE; - if (what & UART_FLUSH_TRANSMITTER) - fcr |= FCR_XMT_RST; - if (what & UART_FLUSH_RECEIVER) - fcr |= FCR_RCV_RST; - uart_setreg(bas, REG_FCR, fcr); - uart_barrier(bas); -} - -static int -oct16550_param (struct uart_bas *bas, int baudrate, int databits, int stopbits, - int parity) -{ - int divisor; - uint8_t lcr; - - lcr = 0; - if (databits >= 8) - lcr |= LCR_8BITS; - else if (databits == 7) - lcr |= LCR_7BITS; - else if (databits == 6) - lcr |= LCR_6BITS; - else - lcr |= LCR_5BITS; - if (stopbits > 1) - lcr |= LCR_STOPB; - lcr |= parity << 3; - - /* Set baudrate. */ - if (baudrate > 0) { - divisor = oct16550_divisor(bas->rclk, baudrate); - if (divisor == 0) - return (EINVAL); - uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); - uart_barrier(bas); - uart_setreg(bas, REG_DLL, divisor & 0xff); - uart_setreg(bas, REG_DLH, (divisor >> 8) & 0xff); - uart_barrier(bas); - delay_changed = 1; - } - - /* Set LCR and clear DLAB. */ - uart_setreg(bas, REG_LCR, lcr); - uart_barrier(bas); - return (0); -} - -/* - * Low-level UART interface. - */ -static int oct16550_probe(struct uart_bas *bas); -static void oct16550_init(struct uart_bas *bas, int, int, int, int); -static void oct16550_term(struct uart_bas *bas); -static void oct16550_putc(struct uart_bas *bas, int); -static int oct16550_rxready(struct uart_bas *bas); -static int oct16550_getc(struct uart_bas *bas, struct mtx *); - -struct uart_ops uart_oct16550_ops = { - .probe = oct16550_probe, - .init = oct16550_init, - .term = oct16550_term, - .putc = oct16550_putc, - .rxready = oct16550_rxready, - .getc = oct16550_getc, -}; - -static int -oct16550_probe (struct uart_bas *bas) -{ - u_char val; - - /* Check known 0 bits that don't depend on DLAB. */ - val = uart_getreg(bas, REG_IIR); - if (val & 0x30) - return (ENXIO); - val = uart_getreg(bas, REG_MCR); - if (val & 0xc0) - return (ENXIO); - val = uart_getreg(bas, REG_USR); - if (val & 0xe0) - return (ENXIO); - return (0); -} - -static void -oct16550_init (struct uart_bas *bas, int baudrate, int databits, int stopbits, - int parity) -{ - u_char ier; - - oct16550_param(bas, baudrate, databits, stopbits, parity); - - /* Disable all interrupt sources. */ - ier = uart_getreg(bas, REG_IER) & 0x0; - uart_setreg(bas, REG_IER, ier); - uart_barrier(bas); - - /* Disable the FIFO (if present). */ -// uart_setreg(bas, REG_FCR, 0); - uart_barrier(bas); - - /* Set RTS & DTR. */ - uart_setreg(bas, REG_MCR, MCR_RTS | MCR_DTR); - uart_barrier(bas); - - oct16550_clrint(bas); -} - -static void -oct16550_term (struct uart_bas *bas) -{ - - /* Clear RTS & DTR. */ - uart_setreg(bas, REG_MCR, 0); - uart_barrier(bas); -} - -static inline void oct16550_wait_txhr_empty (struct uart_bas *bas, int limit, int delay) -{ - while (((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0) && - ((uart_getreg(bas, REG_USR) & USR_TXFIFO_NOTFULL) == 0)) - DELAY(delay); -} - -static void -oct16550_putc (struct uart_bas *bas, int c) -{ - int delay; - - /* 1/10th the time to transmit 1 character (estimate). */ - delay = oct16550_delay(bas); - oct16550_wait_txhr_empty(bas, 100, delay); - uart_setreg(bas, REG_DATA, c); - uart_barrier(bas); - oct16550_wait_txhr_empty(bas, 100, delay); -} - -static int -oct16550_rxready (struct uart_bas *bas) -{ - - return ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) != 0 ? 1 : 0); -} - -static int -oct16550_getc (struct uart_bas *bas, struct mtx *hwmtx) -{ - int c, delay; - - uart_lock(hwmtx); - - /* 1/10th the time to transmit 1 character (estimate). */ - delay = oct16550_delay(bas); - - while ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) == 0) { - uart_unlock(hwmtx); - DELAY(delay); - uart_lock(hwmtx); - } - - c = uart_getreg(bas, REG_DATA); - - uart_unlock(hwmtx); - - return (c); -} - -/* - * High-level UART interface. - */ -struct oct16550_softc { - struct uart_softc base; - uint8_t fcr; - uint8_t ier; - uint8_t mcr; -}; - -static int oct16550_bus_attach(struct uart_softc *); -static int oct16550_bus_detach(struct uart_softc *); -static int oct16550_bus_flush(struct uart_softc *, int); -static int oct16550_bus_getsig(struct uart_softc *); -static int oct16550_bus_ioctl(struct uart_softc *, int, intptr_t); -static int oct16550_bus_ipend(struct uart_softc *); -static int oct16550_bus_param(struct uart_softc *, int, int, int, int); -static int oct16550_bus_probe(struct uart_softc *); -static int oct16550_bus_receive(struct uart_softc *); -static int oct16550_bus_setsig(struct uart_softc *, int); -static int oct16550_bus_transmit(struct uart_softc *); - -static kobj_method_t oct16550_methods[] = { - KOBJMETHOD(uart_attach, oct16550_bus_attach), - KOBJMETHOD(uart_detach, oct16550_bus_detach), - KOBJMETHOD(uart_flush, oct16550_bus_flush), - KOBJMETHOD(uart_getsig, oct16550_bus_getsig), - KOBJMETHOD(uart_ioctl, oct16550_bus_ioctl), - KOBJMETHOD(uart_ipend, oct16550_bus_ipend), - KOBJMETHOD(uart_param, oct16550_bus_param), - KOBJMETHOD(uart_probe, oct16550_bus_probe), - KOBJMETHOD(uart_receive, oct16550_bus_receive), - KOBJMETHOD(uart_setsig, oct16550_bus_setsig), - KOBJMETHOD(uart_transmit, oct16550_bus_transmit), - { 0, 0 } -}; - -struct uart_class uart_oct16550_class = { - "oct16550 class", - oct16550_methods, - sizeof(struct oct16550_softc), - .uc_ops = &uart_oct16550_ops, - .uc_range = 8, - .uc_rclk = 0 -}; - -#define SIGCHG(c, i, s, d) \ - if (c) { \ - i |= (i & s) ? s : s | d; \ - } else { \ - i = (i & s) ? (i & ~s) | d : i; \ - } - -static int -oct16550_bus_attach (struct uart_softc *sc) -{ - struct oct16550_softc *oct16550 = (struct oct16550_softc*)sc; - struct uart_bas *bas; - int unit; - - unit = device_get_unit(sc->sc_dev); - bas = &sc->sc_bas; - - oct16550_drain(bas, UART_DRAIN_TRANSMITTER); - oct16550->mcr = uart_getreg(bas, REG_MCR); - oct16550->fcr = FCR_ENABLE | FCR_RX_HIGH; - uart_setreg(bas, REG_FCR, oct16550->fcr); - uart_barrier(bas); - oct16550_bus_flush(sc, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER); - - if (oct16550->mcr & MCR_DTR) - sc->sc_hwsig |= SER_DTR; - if (oct16550->mcr & MCR_RTS) - sc->sc_hwsig |= SER_RTS; - oct16550_bus_getsig(sc); - - oct16550_clrint(bas); - oct16550->ier = uart_getreg(bas, REG_IER) & 0xf0; - oct16550->ier |= IER_EMSC | IER_ERLS | IER_ERXRDY; - uart_setreg(bas, REG_IER, oct16550->ier); - uart_barrier(bas); - - uint32_t status_bits = mips_rd_status(); - mips_wr_status(status_bits & ~MIPS_SR_INT_IE); - /* - * Enable the interrupt in CIU. // UART-x2 @ IP2 - */ - ciu_enable_interrupts(0, CIU_INT_0, CIU_EN_0, - (!unit) ? CIU_UART_BITS_UART0 : CIU_UART_BITS_UART1, CIU_MIPS_IP2); - return (0); -} - -static int -oct16550_bus_detach (struct uart_softc *sc) -{ - struct uart_bas *bas; - u_char ier; - - bas = &sc->sc_bas; - ier = uart_getreg(bas, REG_IER) & 0xf0; - uart_setreg(bas, REG_IER, ier); - uart_barrier(bas); - oct16550_clrint(bas); - return (0); -} - -static int -oct16550_bus_flush (struct uart_softc *sc, int what) -{ - struct oct16550_softc *oct16550 = (struct oct16550_softc*)sc; - struct uart_bas *bas; - int error; - - bas = &sc->sc_bas; - uart_lock(sc->sc_hwmtx); - if (sc->sc_rxfifosz > 1) { - oct16550_flush(bas, what); - uart_setreg(bas, REG_FCR, oct16550->fcr); - uart_barrier(bas); - error = 0; - } else - error = oct16550_drain(bas, what); - uart_unlock(sc->sc_hwmtx); - return (error); -} - -static int -oct16550_bus_getsig (struct uart_softc *sc) -{ - uint32_t new, old, sig; - uint8_t msr; - - do { - old = sc->sc_hwsig; - sig = old; - uart_lock(sc->sc_hwmtx); - msr = uart_getreg(&sc->sc_bas, REG_MSR); - uart_unlock(sc->sc_hwmtx); - SIGCHG(msr & MSR_DSR, sig, SER_DSR, SER_DDSR); - SIGCHG(msr & MSR_CTS, sig, SER_CTS, SER_DCTS); - SIGCHG(msr & MSR_DCD, sig, SER_DCD, SER_DDCD); - SIGCHG(msr & MSR_RI, sig, SER_RI, SER_DRI); - new = sig & ~SER_MASK_DELTA; - } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); - return (sig); -} - -static int -oct16550_bus_ioctl (struct uart_softc *sc, int request, intptr_t data) -{ - struct uart_bas *bas; - int baudrate, divisor, error; - uint8_t efr, lcr; - - bas = &sc->sc_bas; - error = 0; - uart_lock(sc->sc_hwmtx); - switch (request) { - case UART_IOCTL_BREAK: - lcr = uart_getreg(bas, REG_LCR); - if (data) - lcr |= LCR_SBREAK; - else - lcr &= ~LCR_SBREAK; - uart_setreg(bas, REG_LCR, lcr); - uart_barrier(bas); - break; - case UART_IOCTL_IFLOW: - lcr = uart_getreg(bas, REG_LCR); - uart_barrier(bas); - uart_setreg(bas, REG_LCR, 0xbf); - uart_barrier(bas); - efr = uart_getreg(bas, REG_EFR); - if (data) - efr |= EFR_RTS; - else - efr &= ~EFR_RTS; - uart_setreg(bas, REG_EFR, efr); - uart_barrier(bas); - uart_setreg(bas, REG_LCR, lcr); - uart_barrier(bas); - break; - case UART_IOCTL_OFLOW: - lcr = uart_getreg(bas, REG_LCR); - uart_barrier(bas); - uart_setreg(bas, REG_LCR, 0xbf); - uart_barrier(bas); - efr = uart_getreg(bas, REG_EFR); - if (data) - efr |= EFR_CTS; - else - efr &= ~EFR_CTS; - uart_setreg(bas, REG_EFR, efr); - uart_barrier(bas); - uart_setreg(bas, REG_LCR, lcr); - uart_barrier(bas); - break; - case UART_IOCTL_BAUD: - lcr = uart_getreg(bas, REG_LCR); - uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); - uart_barrier(bas); - divisor = uart_getreg(bas, REG_DLL) | - (uart_getreg(bas, REG_DLH) << 8); - uart_barrier(bas); - uart_setreg(bas, REG_LCR, lcr); - uart_barrier(bas); - baudrate = (divisor > 0) ? bas->rclk / divisor / 16 : 0; - delay_changed = 1; - if (baudrate > 0) - *(int*)data = baudrate; - else - error = ENXIO; - break; - default: - error = EINVAL; - break; - } - uart_unlock(sc->sc_hwmtx); - return (error); -} - - -static int -oct16550_bus_ipend(struct uart_softc *sc) -{ - struct uart_bas *bas; - int ipend = 0; - uint8_t iir, lsr; - - bas = &sc->sc_bas; - uart_lock(sc->sc_hwmtx); - - iir = uart_getreg(bas, REG_IIR) & IIR_IMASK; - if (iir != IIR_NOPEND) { - - if (iir == IIR_RLS) { - lsr = uart_getreg(bas, REG_LSR); - if (lsr & LSR_OE) - ipend |= SER_INT_OVERRUN; - if (lsr & LSR_BI) - ipend |= SER_INT_BREAK; - if (lsr & LSR_RXRDY) - ipend |= SER_INT_RXREADY; - - } else if (iir == IIR_RXRDY) { - ipend |= SER_INT_RXREADY; - - } else if (iir == IIR_RXTOUT) { - ipend |= SER_INT_RXREADY; - - } else if (iir == IIR_TXRDY) { - ipend |= SER_INT_TXIDLE; - - } else if (iir == IIR_MLSC) { - ipend |= SER_INT_SIGCHG; - - } else if (iir == IIR_BUSY) { - (void) uart_getreg(bas, REG_USR); - } - } - uart_unlock(sc->sc_hwmtx); - -//#define OCTEON_VISUAL_UART 1 -#ifdef OCTEON_VISUAL_UART - static int where1 = 0; - - if (ipend) octeon_led_run_wheel(&where1, 6 + device_get_unit(sc->sc_dev)); -#endif - - return ((sc->sc_leaving) ? 0 : ipend); -} - - - - -static int -oct16550_bus_param (struct uart_softc *sc, int baudrate, int databits, - int stopbits, int parity) -{ - struct uart_bas *bas; - int error; - - bas = &sc->sc_bas; - uart_lock(sc->sc_hwmtx); - error = oct16550_param(bas, baudrate, databits, stopbits, parity); - uart_unlock(sc->sc_hwmtx); - return (error); -} - -static int -oct16550_bus_probe (struct uart_softc *sc) -{ - struct uart_bas *bas; - int error; - - bas = &sc->sc_bas; - bas->rclk = uart_oct16550_class.uc_rclk = octeon_cpu_clock; - - error = oct16550_probe(bas); - if (error) { - return (error); - } - - uart_setreg(bas, REG_MCR, (MCR_DTR | MCR_RTS)); - - /* - * Enable FIFOs. And check that the UART has them. If not, we're - * done. Since this is the first time we enable the FIFOs, we reset - * them. - */ - oct16550_drain(bas, UART_DRAIN_TRANSMITTER); -#define ENABLE_OCTEON_FIFO 1 -#ifdef ENABLE_OCTEON_FIFO - uart_setreg(bas, REG_FCR, FCR_ENABLE | FCR_XMT_RST | FCR_RCV_RST); -#endif - uart_barrier(bas); - - oct16550_flush(bas, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER); - - if (device_get_unit(sc->sc_dev)) { - device_set_desc(sc->sc_dev, "Octeon-16550 channel 1"); - } else { - device_set_desc(sc->sc_dev, "Octeon-16550 channel 0"); - } -#ifdef ENABLE_OCTEON_FIFO - sc->sc_rxfifosz = 64; - sc->sc_txfifosz = 64; -#else - sc->sc_rxfifosz = 1; - sc->sc_txfifosz = 1; -#endif - - -#if 0 - /* - * XXX there are some issues related to hardware flow control and - * it's likely that uart(4) is the cause. This basicly needs more - * investigation, but we avoid using for hardware flow control - * until then. - */ - /* 16650s or higher have automatic flow control. */ - if (sc->sc_rxfifosz > 16) { - sc->sc_hwiflow = 1; - sc->sc_hwoflow = 1; - } -#endif - - return (0); -} - -static int -oct16550_bus_receive (struct uart_softc *sc) -{ - struct uart_bas *bas; - int xc; - uint8_t lsr; - - bas = &sc->sc_bas; - uart_lock(sc->sc_hwmtx); - lsr = uart_getreg(bas, REG_LSR); - - while (lsr & LSR_RXRDY) { - if (uart_rx_full(sc)) { - sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN; - break; - } - xc = uart_getreg(bas, REG_DATA); - if (lsr & LSR_FE) - xc |= UART_STAT_FRAMERR; - if (lsr & LSR_PE) - xc |= UART_STAT_PARERR; - uart_rx_put(sc, xc); - lsr = uart_getreg(bas, REG_LSR); - } - /* Discard everything left in the Rx FIFO. */ - /* - * First do a dummy read/discard anyway, in case the UART was lying to us. - * This problem was seen on board, when IIR said RBR, but LSR said no RXRDY - * Results in a stuck ipend loop. - */ - (void)uart_getreg(bas, REG_DATA); - while (lsr & LSR_RXRDY) { - (void)uart_getreg(bas, REG_DATA); - uart_barrier(bas); - lsr = uart_getreg(bas, REG_LSR); - } - uart_unlock(sc->sc_hwmtx); - return (0); -} - -static int -oct16550_bus_setsig (struct uart_softc *sc, int sig) -{ - struct oct16550_softc *oct16550 = (struct oct16550_softc*)sc; - struct uart_bas *bas; - uint32_t new, old; - - bas = &sc->sc_bas; - do { - old = sc->sc_hwsig; - new = old; - if (sig & SER_DDTR) { - SIGCHG(sig & SER_DTR, new, SER_DTR, - SER_DDTR); - } - if (sig & SER_DRTS) { - SIGCHG(sig & SER_RTS, new, SER_RTS, - SER_DRTS); - } - } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); - uart_lock(sc->sc_hwmtx); - oct16550->mcr &= ~(MCR_DTR|MCR_RTS); - if (new & SER_DTR) - oct16550->mcr |= MCR_DTR; - if (new & SER_RTS) - oct16550->mcr |= MCR_RTS; - uart_setreg(bas, REG_MCR, oct16550->mcr); - uart_barrier(bas); - uart_unlock(sc->sc_hwmtx); - return (0); -} - -static int -oct16550_bus_transmit (struct uart_softc *sc) -{ - struct oct16550_softc *oct16550 = (struct oct16550_softc*)sc; - struct uart_bas *bas; - int i; - - bas = &sc->sc_bas; - uart_lock(sc->sc_hwmtx); -#ifdef NO_UART_INTERRUPTS - for (i = 0; i < sc->sc_txdatasz; i++) { - oct16550_putc(bas, sc->sc_txbuf[i]); - } -#else - - oct16550_wait_txhr_empty(bas, 100, oct16550_delay(bas)); - uart_setreg(bas, REG_IER, oct16550->ier | IER_ETXRDY); - uart_barrier(bas); - - for (i = 0; i < sc->sc_txdatasz; i++) { - uart_setreg(bas, REG_DATA, sc->sc_txbuf[i]); - uart_barrier(bas); - } - sc->sc_txbusy = 1; -#endif - uart_unlock(sc->sc_hwmtx); - return (0); -} From 00e1958bd482ef34bed054634f44f77549329615 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 06:27:11 +0000 Subject: [PATCH 119/380] Add bogus OCTEON_CORE_ID here. Really should integrate the pcpu.h stuff that is in Cavium's base port. --- sys/mips/octeon1/octeon_pcmap_regs.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sys/mips/octeon1/octeon_pcmap_regs.h b/sys/mips/octeon1/octeon_pcmap_regs.h index 4bee9844aad..282e15e6f7e 100644 --- a/sys/mips/octeon1/octeon_pcmap_regs.h +++ b/sys/mips/octeon1/octeon_pcmap_regs.h @@ -13,6 +13,14 @@ #ifndef LOCORE +/* XXXimp: From Cavium's include/pcpu.h, need to port that over */ +#ifndef OCTEON_SMP +#define OCTEON_CORE_ID 0 +#else +extern struct pcpu *cpuid_to_pcpu[]; +#define OCTEON_CORE_ID (mips_rd_coreid()) +#endif + /* * Utility inlines & macros */ From db9c08f280ecceecda80cc2e0bd35121ef7297c3 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 06:35:02 +0000 Subject: [PATCH 120/380] Stylish nits --- sys/mips/octeon1/dev/rgmii/octeon_rgmx.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sys/mips/octeon1/dev/rgmii/octeon_rgmx.h b/sys/mips/octeon1/dev/rgmii/octeon_rgmx.h index 8b74db23ef3..d1eb8b9171a 100644 --- a/sys/mips/octeon1/dev/rgmii/octeon_rgmx.h +++ b/sys/mips/octeon1/dev/rgmii/octeon_rgmx.h @@ -583,13 +583,11 @@ static inline void *octeon_pow_pktptr_to_kbuffer (octeon_buf_ptr_t pkt_ptr) #define OCTEON_RGMX_ADRCTL_CAM_MODE_ACCEPT_DMAC 8 - #define RGMX_LOCK_INIT(_sc, _name) \ mtx_init(&(_sc)->mtx, _name, MTX_NETWORK_LOCK, MTX_DEF) #define RGMX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->mtx) #define RGMX_LOCK(_sc) mtx_lock(&(_sc)->mtx) -#define RGMX_UNLOCK(_sc) mtx_unlock(&(_sc)->mtx) +#define RGMX_UNLOCK(_sc) mtx_unlock(&(_sc)->mtx) #define RGMX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->mtx, MA_OWNED) - #endif /* ___OCTEON_RGMX__H___ */ From bafe55344b1836049afb6b799705c1ec6842bd31 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 06:35:21 +0000 Subject: [PATCH 121/380] Compile out unreferenced code. --- sys/mips/octeon1/dev/rgmii/octeon_rgmx.c | 28 ++++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/sys/mips/octeon1/dev/rgmii/octeon_rgmx.c b/sys/mips/octeon1/dev/rgmii/octeon_rgmx.c index f37fa090eb9..989b7d4cd05 100644 --- a/sys/mips/octeon1/dev/rgmii/octeon_rgmx.c +++ b/sys/mips/octeon1/dev/rgmii/octeon_rgmx.c @@ -146,8 +146,13 @@ static int octeon_rgmx_init_ifnet(struct rgmx_softc_dev *sc); static void octeon_rgmx_mark_ready(struct rgmx_softc_dev *sc); static void octeon_rgmx_stop(struct rgmx_softc_dev *sc); static void octeon_rgmx_config_speed(u_int port, u_int); +#ifdef DEBUG_RGMX_DUMP static void octeon_dump_rgmx_stats(u_int port); +static void octeon_dump_pow_stats(void); +#endif +#ifdef __not_used__ static void rgmx_timer_periodic(void); +#endif static void octeon_rgmx_enable_RED_all(int, int); #ifdef OCTEON_RGMX_SCHEDULED_ISRS @@ -526,10 +531,6 @@ static int rgmii_attach (device_t dev) #define RGMX_MAX_PAK_RECEIVE 5000000 -static void octeon_dump_pow_stats (void); - - - #ifdef OCTEON_RGMX_SCHEDULED_ISRS @@ -541,9 +542,7 @@ static void octeon_rgmx_isr_link (void *context, int pending) static void octeon_rgmx_isr_rxtx (void *context, int pending) { - NET_LOCK_GIANT(); octeon_rx_loop(NULL); - NET_UNLOCK_GIANT(); } @@ -1065,6 +1064,7 @@ static void octeon_rgmx_xmit_mark_buffers_done (struct rgmx_softc_dev *sc, u_int #define OCTEON_RGMX_FLUSH_N_XMIT_MBUFS_EACH_LOOP 5 #define OCTEON_RGMX_FLUSH_PENDING_MBUFS_MAX 1000 +#ifdef __not_used__ /* * octeon_rgmx_output_flush * @@ -1089,7 +1089,7 @@ static void octeon_rgmx_output_flush (struct ifnet *ifp) ifp->if_oerrors++; } } - +#endif /* * octeon_rgmx_output_start @@ -1850,12 +1850,14 @@ static void octeon_rgmx_config_speed (u_int port, u_int report_link) +#ifdef DEBUG_RGMX_DUMP static void octeon_dump_rgmx_stats (u_int port) { } +#endif - +#ifdef __not_used__ static void rgmx_timer_periodic (void) { u_int port; @@ -1914,9 +1916,10 @@ static void rgmx_timer_periodic (void) octeon_rgmx_config_speed(port, 1); } } +#endif - -static void octeon_dump_pow_stats (void) +#ifdef DEBUG_RGMX_DUMP +static void octeon_dump_pow_stats(void) { octeon_rgmx_pow_nos_cnt nos_cnt; octeon_rgmx_pow_int_pc_t intpc; @@ -1957,7 +1960,7 @@ static void octeon_dump_pow_stats (void) if (inpt_q_grp.bits.iq_cnt) printf(" Grp-%u: %u ", i, inpt_q_grp.bits.iq_cnt); } } - +#endif /* ------------------------------------------------------------------- * * octeon_line_status_loop() * @@ -2163,6 +2166,7 @@ static int octeon_has_4ports (void) } +#ifdef __not_used__ /* * octeon_rgmx_free_intr * @@ -2195,7 +2199,7 @@ static void octeon_rgmx_free_intr (struct rgmx_softc_dev *sc) #endif } - +#endif static device_method_t rgmii_methods[] = { /* Device interface */ From 67b401589c2f81aa84e96893ea33e7e02281e52b Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 06:36:50 +0000 Subject: [PATCH 122/380] Hack for the 'battleship' boards that have 8 ports rather than 4. --- sys/mips/octeon1/dev/rgmii/octeon_rgmx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/mips/octeon1/dev/rgmii/octeon_rgmx.c b/sys/mips/octeon1/dev/rgmii/octeon_rgmx.c index 989b7d4cd05..aca755da65a 100644 --- a/sys/mips/octeon1/dev/rgmii/octeon_rgmx.c +++ b/sys/mips/octeon1/dev/rgmii/octeon_rgmx.c @@ -58,7 +58,8 @@ __FBSDID("$FreeBSD$"); #include "octeon_rgmx.h" -#define OCTEON_RGMX_NUM_PORTS_MAX 4 +/* The "battleship" boards have 8 ports */ +#define OCTEON_RGMX_NUM_PORTS_MAX 8 #define NUM_TX_PACKETS 80 #define NUM_RX_PACKETS 300 #define MAX_RX_BUFS (NUM_RX_PACKETS) * (OCTEON_RGMX_NUM_PORTS_MAX) From 24277e95bb3f8dc3cc67a3faf15599d6e42980ae Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 06:49:13 +0000 Subject: [PATCH 123/380] Make compile. --- sys/mips/octeon1/octeon_ebt3000_cf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/mips/octeon1/octeon_ebt3000_cf.c b/sys/mips/octeon1/octeon_ebt3000_cf.c index f7dfd0d00ef..a776a4046f7 100644 --- a/sys/mips/octeon1/octeon_ebt3000_cf.c +++ b/sys/mips/octeon1/octeon_ebt3000_cf.c @@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$"); #include "octeon_ebt3000_cf.h" #include "driveid.h" +#include /* ATA Commands */ #define CMD_READ_SECTOR 0x20 @@ -505,7 +506,8 @@ static void cf_identify (driver_t *drv, device_t parent) octeon_mio_boot_reg_cfgx_t cfg; - if (!octeon_board_real()) return 1; + if (!octeon_board_real()) + return; base_addr = (void *) OCTEON_PHYS2PTR(OCTEON_CF_COMMON_BASE_ADDR); From c839424d34009d1ad3dc4daf0d8acd516cfc8925 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 06:53:55 +0000 Subject: [PATCH 124/380] Various nits to make this compile. --- sys/mips/octeon1/octeon_machdep.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/sys/mips/octeon1/octeon_machdep.c b/sys/mips/octeon1/octeon_machdep.c index f0f6bded0a1..a8d05a8bd34 100644 --- a/sys/mips/octeon1/octeon_machdep.c +++ b/sys/mips/octeon1/octeon_machdep.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -231,19 +232,17 @@ void octeon_uart_write_hex (uint32_t wl) octeon_uart_write_string(0, wstr); } - +#ifdef __not_used__ #define OCT_CONS_BUFLEN 200 static char console_str_buff0[OCT_CONS_BUFLEN + 1]; #include - //#define USE_KERN_SUBR_PRINTF - #ifndef USE_KERN_SUBR_PRINTF static int oct_printf (const char *fmt, va_list ap); #endif -int kern_cons_printf (const char *fmt, ...) +int kern_cons_printf(const char *fmt, ...) { va_list ap; @@ -258,7 +257,7 @@ int kern_cons_printf (const char *fmt, ...) } #ifndef USE_KERN_SUBR_PRINTF -static int oct_printf (const char *fmt, va_list ap) +static int oct_printf(const char *fmt, va_list ap) { snprintf(console_str_buff0, OCT_CONS_BUFLEN, fmt, ap); octeon_uart_write_string(0, console_str_buff0); @@ -266,8 +265,7 @@ static int oct_printf (const char *fmt, va_list ap) } #endif - -int console_printf (const char *fmt, ...) +int console_printf(const char *fmt, ...) { va_list ap; @@ -277,8 +275,7 @@ int console_printf (const char *fmt, ...) octeon_uart_write_string(0, console_str_buff0); return (0); } - - +#endif /* @@ -795,7 +792,7 @@ static int octeon_process_app_desc_ver_6 (void) cvmx_desc_ptr = (cvmx_bootinfo_t *) ((long) app_desc_ptr->cvmx_desc_vaddr); if ((cvmx_desc_ptr == NULL) || (cvmx_desc_ptr == (cvmx_bootinfo_t *)0xffffffff)) { - printf ("Bad cvmx_desc_ptr 0x%X\n", cvmx_desc_ptr); + printf ("Bad cvmx_desc_ptr %p\n", cvmx_desc_ptr); return 1; } @@ -804,7 +801,7 @@ static int octeon_process_app_desc_ver_6 (void) cvmx_desc_ptr->minor_version; if (cvmx_desc_ptr->major_version != 1) { - printf("Incompatible CVMX descriptor from bootloader: %d.%d 0x%X\n", + printf("Incompatible CVMX descriptor from bootloader: %d.%d %p\n", (int) cvmx_desc_ptr->major_version, (int) cvmx_desc_ptr->minor_version, cvmx_desc_ptr); while (1); /* Never return */ From 72bd8c62f6d3729502ae3d645b5ee58ccb97c36b Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Jun 2009 07:01:22 +0000 Subject: [PATCH 125/380] Minor formatting changes. Also, elimiante a couple of unused variables. --- sys/mips/octeon1/uart_bus_octeonusart.c | 48 ++++++++++++++----------- sys/mips/octeon1/uart_cpu_octeonusart.c | 19 +++++----- 2 files changed, 37 insertions(+), 30 deletions(-) diff --git a/sys/mips/octeon1/uart_bus_octeonusart.c b/sys/mips/octeon1/uart_bus_octeonusart.c index f70307cfbe6..63b5e9b5e29 100644 --- a/sys/mips/octeon1/uart_bus_octeonusart.c +++ b/sys/mips/octeon1/uart_bus_octeonusart.c @@ -53,22 +53,28 @@ __FBSDID("$FreeBSD$"); #include #include +/* + * XXXMIPS: + */ #include #include "uart_if.h" +extern struct uart_class uart_oct16550_class; + + static int uart_octeon_probe(device_t dev); -static void octeon_uart_identify(driver_t *drv, device_t parent); +static void octeon_uart_identify(driver_t * drv, device_t parent); extern struct uart_class octeon_uart_class; static device_method_t uart_octeon_methods[] = { /* Device interface */ - DEVMETHOD(device_probe, uart_octeon_probe), - DEVMETHOD(device_attach, uart_bus_attach), - DEVMETHOD(device_detach, uart_bus_detach), - DEVMETHOD(device_identify, octeon_uart_identify), - { 0, 0 } + DEVMETHOD(device_probe, uart_octeon_probe), + DEVMETHOD(device_attach, uart_bus_attach), + DEVMETHOD(device_detach, uart_bus_detach), + DEVMETHOD(device_identify, octeon_uart_identify), + {0, 0} }; static driver_t uart_octeon_driver = { @@ -77,35 +83,36 @@ static driver_t uart_octeon_driver = { sizeof(struct uart_softc), }; -extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; -static int -uart_octeon_probe (device_t dev) +extern +SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; + static int + uart_octeon_probe(device_t dev) { struct uart_softc *sc; - int unit; + int unit; /* * Note that both tty0 & tty1 are viable consoles. We add child devices * such that ttyu0 ends up front of queue. */ - unit = device_get_unit(dev); + unit = device_get_unit(dev); sc = device_get_softc(dev); - sc->sc_sysdev = NULL; - sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); - bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); - if (!unit) { - sc->sc_sysdev->bas.bst = 0; - sc->sc_sysdev->bas.bsh = OCTEON_UART0ADR; - } + sc->sc_sysdev = NULL; + sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); + bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); + if (!unit) { + sc->sc_sysdev->bas.bst = 0; + sc->sc_sysdev->bas.bsh = OCTEON_UART0ADR; + } sc->sc_class = &uart_oct16550_class; sc->sc_bas.bst = 0; sc->sc_bas.bsh = unit ? OCTEON_UART1ADR : OCTEON_UART0ADR; sc->sc_bas.regshft = 0x3; - return (uart_bus_probe(dev, sc->sc_bas.regshft, 0, 0, unit)); + return (uart_bus_probe(dev, sc->sc_bas.regshft, 0, 0, unit)); } static void -octeon_uart_identify (driver_t *drv, device_t parent) +octeon_uart_identify(driver_t * drv, device_t parent) { BUS_ADD_CHILD(parent, 0, "uart", 0); } @@ -113,4 +120,3 @@ octeon_uart_identify (driver_t *drv, device_t parent) DRIVER_MODULE(uart, obio, uart_octeon_driver, uart_devclass, 0, 0); - diff --git a/sys/mips/octeon1/uart_cpu_octeonusart.c b/sys/mips/octeon1/uart_cpu_octeonusart.c index 4e9ffb269d7..016d71c0b87 100644 --- a/sys/mips/octeon1/uart_cpu_octeonusart.c +++ b/sys/mips/octeon1/uart_cpu_octeonusart.c @@ -50,9 +50,7 @@ __FBSDID("$FreeBSD$"); #include -bus_space_tag_t uart_bus_space_io; -bus_space_tag_t uart_bus_space_mem; - +extern struct uart_class uart_oct16550_class; extern struct uart_ops octeon_usart_ops; extern struct bus_space octeon_bs_tag; @@ -66,18 +64,21 @@ uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) int uart_cpu_getdev(int devtype, struct uart_devinfo *di) { - di->ops = uart_getops(&uart_oct16550_class); - di->bas.chan = 0; + struct uart_class *class; + + class = &uart_oct16550_class; + di->ops = uart_getops(class); di->bas.bst = 0; - di->bas.regshft = 3; /* Each UART reg is 8 byte addresss apart. 1 << 3 */ + di->bas.chan = 0; + di->bas.regshft = 3; /* Each UART reg is 8 byte addresss apart. 1 + * << 3 */ di->bas.rclk = 0; di->baudrate = 115200; di->databits = 8; di->stopbits = 1; di->parity = UART_PARITY_NONE; - uart_bus_space_io = MIPS_PHYS_TO_KSEG1(OCTEON_UART0ADR); - uart_bus_space_mem = MIPS_PHYS_TO_KSEG1(OCTEON_UART0ADR); - di->bas.bsh = OCTEON_UART0ADR; + di->bas.bsh = OCTEON_UART0ADR; + uart_getenv(devtype, di, class); return (0); } From e3652db0ce1858a0ce697af1f334c0ded5c04d1c Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sun, 14 Jun 2009 20:54:46 +0000 Subject: [PATCH 126/380] - Fix prototypes to make compiler happy --- sys/mips/malta/gt_pci.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sys/mips/malta/gt_pci.c b/sys/mips/malta/gt_pci.c index 152730370cf..2f0eadaba4e 100644 --- a/sys/mips/malta/gt_pci.c +++ b/sys/mips/malta/gt_pci.c @@ -135,8 +135,9 @@ static int gt_pci_teardown_intr(device_t, device_t, struct resource *, void*); static int gt_pci_maxslots(device_t ); static int gt_pci_conf_setup(struct gt_pci_softc *, int, int, int, int, uint32_t *); -static uint32_t gt_pci_read_config(device_t, int, int, int, int, int); -static void gt_pci_write_config(device_t, int, int, int, int, uint32_t, int); +static uint32_t gt_pci_read_config(device_t, u_int, u_int, u_int, u_int, int); +static void gt_pci_write_config(device_t, u_int, u_int, u_int, u_int, + uint32_t, int); static int gt_pci_route_interrupt(device_t pcib, device_t dev, int pin); static struct resource * gt_pci_alloc_resource(device_t, device_t, int, int *, u_long, u_long, u_long, u_int); @@ -420,7 +421,7 @@ gt_pci_conf_setup(struct gt_pci_softc *sc, int bus, int slot, int func, } static uint32_t -gt_pci_read_config(device_t dev, int bus, int slot, int func, int reg, +gt_pci_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, int bytes) { struct gt_pci_softc *sc = device_get_softc(dev); @@ -490,7 +491,7 @@ gt_pci_read_config(device_t dev, int bus, int slot, int func, int reg, } static void -gt_pci_write_config(device_t dev, int bus, int slot, int func, int reg, +gt_pci_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, uint32_t data, int bytes) { struct gt_pci_softc *sc = device_get_softc(dev); From 1ee48ffda934da6536e9734f90d2fdee449bc59a Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sun, 14 Jun 2009 21:04:54 +0000 Subject: [PATCH 127/380] - Fix prototype and implementation of admsw_shutdown --- sys/mips/adm5120/if_admsw.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sys/mips/adm5120/if_admsw.c b/sys/mips/adm5120/if_admsw.c index 1f6a4b313d3..f8f0b36e8b2 100644 --- a/sys/mips/adm5120/if_admsw.c +++ b/sys/mips/adm5120/if_admsw.c @@ -133,7 +133,7 @@ static int admsw_ioctl(struct ifnet *, u_long, caddr_t); static void admsw_init(void *); static void admsw_stop(struct ifnet *, int); -static void admsw_shutdown(void *); +static int admsw_shutdown(device_t); static void admsw_reset(struct admsw_softc *); static void admsw_set_filter(struct admsw_softc *); @@ -571,14 +571,16 @@ admsw_detach(device_t dev) * * Make sure the interface is stopped at reboot time. */ -static void -admsw_shutdown(void *arg) +static int +admsw_shutdown(device_t dev) { - struct admsw_softc *sc = arg; + struct admsw_softc *sc = (struct admsw_softc *) device_get_softc(dev); int i; for (i = 0; i < SW_DEVS; i++) admsw_stop(sc->sc_ifnet[i], 1); + + return (0); } /* From d7913bf5ab1f7ea83e1f09d24c116e8a1e0736de Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sun, 14 Jun 2009 21:16:04 +0000 Subject: [PATCH 128/380] - Get rid of mask_fn and fix pre_filter/post_filter functions' prototypes --- sys/mips/idt/obio.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sys/mips/idt/obio.c b/sys/mips/idt/obio.c index 893e88321bd..44e9bfa6ea4 100644 --- a/sys/mips/idt/obio.c +++ b/sys/mips/idt/obio.c @@ -76,8 +76,10 @@ static int obio_setup_intr(device_t, device_t, struct resource *, int, static int obio_teardown_intr(device_t, device_t, struct resource *, void *); -static void obio_mask_irq(unsigned int irq) +static void +obio_mask_irq(void *arg) { + unsigned int irq = (unsigned int)arg; int ip_bit, mask, mask_register; /* mask IRQ */ @@ -88,8 +90,10 @@ static void obio_mask_irq(unsigned int irq) ICU_REG_WRITE(mask_register, mask | ip_bit); } -static void obio_unmask_irq(unsigned int irq) +static void +obio_unmask_irq(void *arg) { + unsigned int irq = (unsigned int)arg; int ip_bit, mask, mask_register; /* unmask IRQ */ @@ -274,7 +278,7 @@ obio_setup_intr(device_t dev, device_t child, struct resource *ires, event = sc->sc_eventstab[irq]; if (event == NULL) { error = intr_event_create(&event, (void *)irq, 0, irq, - (mask_fn)obio_mask_irq, (mask_fn)obio_unmask_irq, + obio_mask_irq, obio_unmask_irq, NULL, NULL, "obio intr%d:", irq); From ee58bf31535c5227be8a35919aba894e9cd3abff Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sun, 14 Jun 2009 21:16:23 +0000 Subject: [PATCH 129/380] - Fix prototypes to make compiler happy --- sys/mips/idt/idtpci.c | 4 ++-- sys/mips/idt/if_kr.c | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/sys/mips/idt/idtpci.c b/sys/mips/idt/idtpci.c index 32033d40ff6..2fce32dc58a 100644 --- a/sys/mips/idt/idtpci.c +++ b/sys/mips/idt/idtpci.c @@ -287,7 +287,7 @@ idtpci_maxslots(device_t dev) } static uint32_t -idtpci_read_config(device_t dev, int bus, int slot, int func, int reg, +idtpci_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, int bytes) { uint32_t data; @@ -343,7 +343,7 @@ idtpci_read_config(device_t dev, int bus, int slot, int func, int reg, } static void -idtpci_write_config(device_t dev, int bus, int slot, int func, int reg, +idtpci_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, uint32_t data, int bytes) { bus_addr_t addr; diff --git a/sys/mips/idt/if_kr.c b/sys/mips/idt/if_kr.c index 45378b00c8d..bbc800fd3e1 100644 --- a/sys/mips/idt/if_kr.c +++ b/sys/mips/idt/if_kr.c @@ -89,7 +89,7 @@ static void kr_reset(struct kr_softc *); static int kr_resume(device_t); static int kr_rx_ring_init(struct kr_softc *); static int kr_tx_ring_init(struct kr_softc *); -static void kr_shutdown(device_t); +static int kr_shutdown(device_t); static void kr_start(struct ifnet *); static void kr_start_locked(struct ifnet *); static void kr_stop(struct kr_softc *); @@ -392,7 +392,7 @@ kr_resume(device_t dev) return 0; } -static void +static int kr_shutdown(device_t dev) { struct kr_softc *sc; @@ -402,6 +402,8 @@ kr_shutdown(device_t dev) KR_LOCK(sc); kr_stop(sc); KR_UNLOCK(sc); + + return (0); } static int From 8766ab738d4621b118e391b159634c11ebd66ca3 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 16 Jun 2009 00:02:02 +0000 Subject: [PATCH 130/380] - Take into account only unmasked bits in interrupt status register --- sys/mips/atheros/ar71xx_pci.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/sys/mips/atheros/ar71xx_pci.c b/sys/mips/atheros/ar71xx_pci.c index 6d3430b1821..de786e4a8d5 100644 --- a/sys/mips/atheros/ar71xx_pci.c +++ b/sys/mips/atheros/ar71xx_pci.c @@ -86,9 +86,10 @@ ar71xx_pci_mask_irq(void *source) uint32_t reg; unsigned int irq = (unsigned int)source; + reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK); + /* flush */ reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK); ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, reg & ~(1 << irq)); - } static void @@ -99,6 +100,8 @@ ar71xx_pci_unmask_irq(void *source) reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK); ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, reg | (1 << irq)); + /* flush */ + reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK); } /* @@ -294,10 +297,12 @@ ar71xx_pci_attach(device_t dev) reset |= (RST_RESET_PCI_CORE | RST_RESET_PCI_BUS); ATH_WRITE_REG(AR71XX_RST_RESET, reset); DELAY(1000); + ATH_READ_REG(AR71XX_RST_RESET); reset &= ~(RST_RESET_PCI_CORE | RST_RESET_PCI_BUS); ATH_WRITE_REG(AR71XX_RST_RESET, reset); DELAY(1000); + ATH_READ_REG(AR71XX_RST_RESET); /* Init PCI windows */ ATH_WRITE_REG(AR71XX_PCI_WINDOW0, PCI_WINDOW0_ADDR); @@ -472,9 +477,14 @@ ar71xx_pci_intr(void *arg) { struct ar71xx_pci_softc *sc = arg; struct intr_event *event; - uint32_t reg, irq; + uint32_t reg, irq, mask; reg = ATH_READ_REG(AR71XX_PCI_INTR_STATUS); + mask = ATH_READ_REG(AR71XX_PCI_INTR_MASK); + /* + * Handle only unmasked interrupts + */ + reg &= mask; for (irq = AR71XX_PCI_IRQ_START; irq <= AR71XX_PCI_IRQ_END; irq++) { if (reg & (1 << irq)) { event = sc->sc_eventstab[irq]; From 04af8c86f589d901fac2a4da565eeea1e3f197b6 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 16 Jun 2009 01:43:33 +0000 Subject: [PATCH 131/380] - Handle KSEG0/KSEG1 addresses for /dev/mem as well. netstat requires it --- sys/mips/mips/mem.c | 47 ++++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/sys/mips/mips/mem.c b/sys/mips/mips/mem.c index 53fe634418e..db0d1231712 100644 --- a/sys/mips/mips/mem.c +++ b/sys/mips/mips/mem.c @@ -124,8 +124,10 @@ memrw(dev, uio, flags) pmap_unmap_fpage(pa, fp); sched_unpin(); mtx_unlock(&sysmaps->lock); - } else + } else { + printf("NOT OK\n"); return (EFAULT); + } continue; } @@ -133,6 +135,7 @@ memrw(dev, uio, flags) else if (dev2unit(dev) == CDEV_MINOR_KMEM) { v = uio->uio_offset; c = min(iov->iov_len, MAXPHYS); + vm_offset_t addr, eaddr; vm_offset_t wired_tlb_virtmem_end; @@ -143,25 +146,37 @@ memrw(dev, uio, flags) addr = trunc_page(uio->uio_offset); eaddr = round_page(uio->uio_offset + c); - if (addr < (vm_offset_t) VM_MIN_KERNEL_ADDRESS) - return EFAULT; + if (addr > (vm_offset_t) VM_MIN_KERNEL_ADDRESS) { + wired_tlb_virtmem_end = VM_MIN_KERNEL_ADDRESS + + VM_KERNEL_ALLOC_OFFSET; + if ((addr < wired_tlb_virtmem_end) && + (eaddr >= wired_tlb_virtmem_end)) + addr = wired_tlb_virtmem_end; - wired_tlb_virtmem_end = VM_MIN_KERNEL_ADDRESS + - VM_KERNEL_ALLOC_OFFSET; - if ((addr < wired_tlb_virtmem_end) && - (eaddr >= wired_tlb_virtmem_end)) - addr = wired_tlb_virtmem_end; + if (addr >= wired_tlb_virtmem_end) { + for (; addr < eaddr; addr += PAGE_SIZE) + if (pmap_extract(kernel_pmap, + addr) == 0) + return EFAULT; - if (addr >= wired_tlb_virtmem_end) { - for (; addr < eaddr; addr += PAGE_SIZE) - if (pmap_extract(kernel_pmap,addr) == 0) - return EFAULT; - - if (!kernacc((caddr_t)(int)uio->uio_offset, c, - uio->uio_rw == UIO_READ ? - VM_PROT_READ : VM_PROT_WRITE)) + if (!kernacc( + (caddr_t)(int)uio->uio_offset, c, + uio->uio_rw == UIO_READ ? + VM_PROT_READ : VM_PROT_WRITE)) + return (EFAULT); + } + } + else if (MIPS_IS_KSEG0_ADDR(v)) { + if (MIPS_KSEG0_TO_PHYS(v + c) >= ctob(physmem)) return (EFAULT); } + else if (MIPS_IS_KSEG1_ADDR(v)) { + if (MIPS_KSEG1_TO_PHYS(v + c) >= ctob(physmem)) + return (EFAULT); + } + else + return (EFAULT); + error = uiomove((caddr_t)v, c, uio); continue; From 1a28ce2dcb49a1f52db79ae1abd3a85ef3a19af5 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 16 Jun 2009 02:36:21 +0000 Subject: [PATCH 132/380] - Remove debug printfs --- sys/mips/mips/mem.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sys/mips/mips/mem.c b/sys/mips/mips/mem.c index db0d1231712..be7a9f5ed35 100644 --- a/sys/mips/mips/mem.c +++ b/sys/mips/mips/mem.c @@ -124,10 +124,8 @@ memrw(dev, uio, flags) pmap_unmap_fpage(pa, fp); sched_unpin(); mtx_unlock(&sysmaps->lock); - } else { - printf("NOT OK\n"); + } else return (EFAULT); - } continue; } From 6846a68073317407ecb5da51574ff49998c0afda Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 19 Jun 2009 04:43:49 +0000 Subject: [PATCH 133/380] - Mark temp variable as "earlyclobber" in assembler inline in atomic_fetchadd_32. Without it gcc would use it as input register for v and sometimes generate following code for function call like atomic_fetchadd_32(&(fp)->f_count, -1): 801238b4: 2402ffff li v0,-1 801238b8: c2230018 ll v1,24(s1) 801238bc: 00431021 addu v0,v0,v1 801238c0: e2220018 sc v0,24(s1) 801238c4: 1040fffc beqz v0,801238b8 801238c8: 00000000 nop Which is definitly wrong because if sc fails v0 is set to 0 and previous value of -1 is overriden hence whole operation turns to bogus --- sys/mips/include/atomic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/include/atomic.h b/sys/mips/include/atomic.h index 9b2d18a698e..06de6242df1 100644 --- a/sys/mips/include/atomic.h +++ b/sys/mips/include/atomic.h @@ -294,7 +294,7 @@ atomic_fetchadd_32(__volatile uint32_t *p, uint32_t v) "addu %2, %3, %0\n\t" /* calculate new value */ "sc %2, %1\n\t" /* attempt to store */ "beqz %2, 1b\n\t" /* spin if failed */ - : "=&r" (value), "=m" (*p), "=r" (temp) + : "=&r" (value), "=m" (*p), "=&r" (temp) : "r" (v), "m" (*p)); return (value); } From d7766b45867aa1acc7b615a45503734a7c007eed Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 19 Jun 2009 05:00:17 +0000 Subject: [PATCH 134/380] - Flush PCI register write before delay Spotted by: Pyun YongHyeon --- sys/mips/atheros/ar71xx_pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/mips/atheros/ar71xx_pci.c b/sys/mips/atheros/ar71xx_pci.c index de786e4a8d5..345091a188a 100644 --- a/sys/mips/atheros/ar71xx_pci.c +++ b/sys/mips/atheros/ar71xx_pci.c @@ -296,13 +296,13 @@ ar71xx_pci_attach(device_t dev) reset = ATH_READ_REG(AR71XX_RST_RESET); reset |= (RST_RESET_PCI_CORE | RST_RESET_PCI_BUS); ATH_WRITE_REG(AR71XX_RST_RESET, reset); - DELAY(1000); ATH_READ_REG(AR71XX_RST_RESET); + DELAY(1000); reset &= ~(RST_RESET_PCI_CORE | RST_RESET_PCI_BUS); ATH_WRITE_REG(AR71XX_RST_RESET, reset); - DELAY(1000); ATH_READ_REG(AR71XX_RST_RESET); + DELAY(1000); /* Init PCI windows */ ATH_WRITE_REG(AR71XX_PCI_WINDOW0, PCI_WINDOW0_ADDR); From e3ebc7a32e2a0624191c8c00c7bbfc4ae36d6f90 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 19 Jun 2009 19:02:40 +0000 Subject: [PATCH 135/380] - Keep interrupts mask intact by RESTORE_CPU in MipsKernGenException trap() function re-enables interrupts if exception happened with interrupts enabled and therefor status register might be modified by interrupt filters --- sys/mips/mips/exception.S | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sys/mips/mips/exception.S b/sys/mips/mips/exception.S index b14c1479e9c..29e263928ce 100644 --- a/sys/mips/mips/exception.S +++ b/sys/mips/mips/exception.S @@ -389,6 +389,19 @@ NNON_LEAF(MipsKernGenException, KERN_EXC_FRAME_SIZE, ra) jalr k0 sw a3, STAND_RA_OFFSET + KERN_REG_SIZE(sp) # for debugging + /* + * Update interrupt mask in saved status register + * Some of interrupts could be disabled by + * intr filters if interrupts are enabled later + * in trap handler + */ + mfc0 a0, COP_0_STATUS_REG + mtc0 zero, COP_0_STATUS_REG + and a0, a0, SR_INT_MASK + RESTORE_REG(a1, SR, sp) + and a1, a1, ~SR_INT_MASK + or a1, a1, a0 + SAVE_REG(a1, SR, sp) RESTORE_CPU # v0 contains the return address. sync eret From 21d845c5158710c0fe8ee84b5ce2e8c1d9197652 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 19 Jun 2009 23:28:26 +0000 Subject: [PATCH 136/380] - set -mabicalls and -msoft-float as a default in order to simplify building ports --- contrib/gcc/config/mips/freebsd.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contrib/gcc/config/mips/freebsd.h b/contrib/gcc/config/mips/freebsd.h index f4b1cf572e3..b53dae66a38 100644 --- a/contrib/gcc/config/mips/freebsd.h +++ b/contrib/gcc/config/mips/freebsd.h @@ -97,6 +97,9 @@ Boston, MA 02110-1301, USA. */ Needs to agree with . GCC defaults come from c-decl.c, c-common.c, and config//.h. */ +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (MASK_ABICALLS | MASK_SOFT_FLOAT) + #if TARGET_ENDIAN_DEFAULT != 0 #define TARGET_VERSION fprintf (stderr, " (FreeBSD/mips)"); #else From 790b0677259ccb23d9ebb6999a4c10815dc15ba3 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 24 Jun 2009 22:42:52 +0000 Subject: [PATCH 137/380] - Do not use hardcoded uart speed - Call mips_timer_early_init before initializing uart in order to make DELAY usable for ns8250 driver Submitted by: Neelkanth Natu --- sys/mips/malta/malta_machdep.c | 88 ++++++++++++++++------------ sys/mips/malta/uart_cpu_maltausart.c | 2 +- 2 files changed, 50 insertions(+), 40 deletions(-) diff --git a/sys/mips/malta/malta_machdep.c b/sys/mips/malta/malta_machdep.c index c5c28af8b63..0f53f13fb47 100644 --- a/sys/mips/malta/malta_machdep.c +++ b/sys/mips/malta/malta_machdep.c @@ -226,6 +226,52 @@ platform_trap_exit(void) } +static uint64_t +malta_cpu_freq(void) +{ + uint64_t platform_counter_freq = 0; + +#if defined(TICK_USE_YAMON_FREQ) + /* + * If we are running on a board which uses YAMON firmware, + * then query CPU pipeline clock from the syscon object. + * If unsuccessful, use hard-coded default. + */ + platform_counter_freq = yamon_getcpufreq(); + +#elif defined(TICK_USE_MALTA_RTC) + /* + * If we are running on a board with the MC146818 RTC, + * use it to determine CPU pipeline clock frequency. + */ + u_int64_t counterval[2]; + + /* Set RTC to binary mode. */ + writertc(RTC_STATUSB, (rtcin(RTC_STATUSB) | RTCSB_BCD)); + + /* Busy-wait for falling edge of RTC update. */ + while (((rtcin(RTC_STATUSA) & RTCSA_TUP) == 0)) + ; + while (((rtcin(RTC_STATUSA)& RTCSA_TUP) != 0)) + ; + counterval[0] = mips_rd_count(); + + /* Busy-wait for falling edge of RTC update. */ + while (((rtcin(RTC_STATUSA) & RTCSA_TUP) == 0)) + ; + while (((rtcin(RTC_STATUSA)& RTCSA_TUP) != 0)) + ; + counterval[1] = mips_rd_count(); + + platform_counter_freq = counterval[1] - counterval[0]; +#endif + + if (platform_counter_freq == 0) + platform_counter_freq = MIPS_DEFAULT_HZ; + + return (platform_counter_freq); +} + void platform_start(__register_t a0, __register_t a1, __register_t a2, __register_t a3) @@ -242,6 +288,9 @@ platform_start(__register_t a0, __register_t a1, __register_t a2, kernend = round_page((vm_offset_t)&end); memset(&edata, 0, kernend - (vm_offset_t)(&edata)); + platform_counter_freq = malta_cpu_freq(); + mips_timer_early_init(platform_counter_freq); + cninit(); printf("entry: platform_start()\n"); @@ -262,44 +311,5 @@ platform_start(__register_t a0, __register_t a1, __register_t a2, realmem = btoc(memsize); mips_init(); - do { -#if defined(TICK_USE_YAMON_FREQ) - /* - * If we are running on a board which uses YAMON firmware, - * then query CPU pipeline clock from the syscon object. - * If unsuccessful, use hard-coded default. - */ - platform_counter_freq = yamon_getcpufreq(); - if (platform_counter_freq == 0) - platform_counter_freq = MIPS_DEFAULT_HZ; - -#elif defined(TICK_USE_MALTA_RTC) - /* - * If we are running on a board with the MC146818 RTC, - * use it to determine CPU pipeline clock frequency. - */ - u_int64_t counterval[2]; - - /* Set RTC to binary mode. */ - writertc(RTC_STATUSB, (rtcin(RTC_STATUSB) | RTCSB_BCD)); - - /* Busy-wait for falling edge of RTC update. */ - while (((rtcin(RTC_STATUSA) & RTCSA_TUP) == 0)) - ; - while (((rtcin(RTC_STATUSA)& RTCSA_TUP) != 0)) - ; - counterval[0] = mips_rd_count(); - - /* Busy-wait for falling edge of RTC update. */ - while (((rtcin(RTC_STATUSA) & RTCSA_TUP) == 0)) - ; - while (((rtcin(RTC_STATUSA)& RTCSA_TUP) != 0)) - ; - counterval[1] = mips_rd_count(); - - platform_counter_freq = counterval[1] - counterval[0]; -#endif - } while(0); - mips_timer_init_params(platform_counter_freq, 0); } diff --git a/sys/mips/malta/uart_cpu_maltausart.c b/sys/mips/malta/uart_cpu_maltausart.c index 01ef8db332d..d65ddfaffa1 100644 --- a/sys/mips/malta/uart_cpu_maltausart.c +++ b/sys/mips/malta/uart_cpu_maltausart.c @@ -71,7 +71,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) di->bas.bsh = MIPS_PHYS_TO_KSEG1(MALTA_UART0ADR); di->bas.regshft = 0; di->bas.rclk = 0; - di->baudrate = 115200; + di->baudrate = 0; /* retain the baudrate configured by YAMON */ di->databits = 8; di->stopbits = 1; di->parity = UART_PARITY_NONE; From 77edcd641ca57fa7e0d9ce6627f3b0a67dcd734f Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 25 Jun 2009 02:15:04 +0000 Subject: [PATCH 138/380] - Invalidate cache in pmap_qenter. Fixes corruption of data that comes through pipe (may be other bugs) --- sys/mips/mips/pmap.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index 4a9e4b23cd6..2ee7550f30a 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -744,11 +744,14 @@ void pmap_qenter(vm_offset_t va, vm_page_t *m, int count) { int i; + vm_offset_t origva = va; for (i = 0; i < count; i++) { pmap_kenter(va, VM_PAGE_TO_PHYS(m[i])); va += PAGE_SIZE; } + + mips_dcache_wbinv_range_index(origva, PAGE_SIZE*count); } /* @@ -758,6 +761,11 @@ pmap_qenter(vm_offset_t va, vm_page_t *m, int count) void pmap_qremove(vm_offset_t va, int count) { + /* + * No need to wb/inv caches here, + * pmap_kremove will do it for us + */ + while (count-- > 0) { pmap_kremove(va); va += PAGE_SIZE; From ba6db3cc31f81d65b4a44f34e246fda8d1d70baf Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 26 Jun 2009 00:44:23 +0000 Subject: [PATCH 139/380] - Add MIPS to the list of 32-bit architectures --- gnu/usr.bin/binutils/Makefile.inc0 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gnu/usr.bin/binutils/Makefile.inc0 b/gnu/usr.bin/binutils/Makefile.inc0 index 859a3a8cff3..945c9339b4e 100644 --- a/gnu/usr.bin/binutils/Makefile.inc0 +++ b/gnu/usr.bin/binutils/Makefile.inc0 @@ -22,7 +22,8 @@ RELTOP:= .. RELSRC= ${RELTOP}/../../../contrib/binutils SRCDIR= ${.CURDIR}/${RELSRC} -.if ${TARGET_ARCH} == "arm" || ${TARGET_ARCH} == "i386" || ${TARGET_ARCH} == "powerpc" +.if ${TARGET_ARCH} == "arm" || ${TARGET_ARCH} == "i386" || \ + ${TARGET_ARCH} == "powerpc" || ${TARGET_ARCH} == "mips" CFLAGS+= -DBFD_DEFAULT_TARGET_SIZE=32 .else CFLAGS+= -DBFD_DEFAULT_TARGET_SIZE=64 From 9f67da7c266d7570bfa5d2fd73f4fc781646d8e3 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 26 Jun 2009 01:01:50 +0000 Subject: [PATCH 140/380] - Move fpgetXXX.c/fpsetXXX.c sources to hardfloat subdir/ to prevenmt them from being mixed up with lib/libc/softfloat files with the same names --- lib/libc/mips/gen/{ => hardfloat}/fpgetmask.c | 0 lib/libc/mips/gen/{ => hardfloat}/fpgetround.c | 0 lib/libc/mips/gen/{ => hardfloat}/fpgetsticky.c | 0 lib/libc/mips/gen/{ => hardfloat}/fpsetmask.c | 0 lib/libc/mips/gen/{ => hardfloat}/fpsetround.c | 0 lib/libc/mips/gen/{ => hardfloat}/fpsetsticky.c | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename lib/libc/mips/gen/{ => hardfloat}/fpgetmask.c (100%) rename lib/libc/mips/gen/{ => hardfloat}/fpgetround.c (100%) rename lib/libc/mips/gen/{ => hardfloat}/fpgetsticky.c (100%) rename lib/libc/mips/gen/{ => hardfloat}/fpsetmask.c (100%) rename lib/libc/mips/gen/{ => hardfloat}/fpsetround.c (100%) rename lib/libc/mips/gen/{ => hardfloat}/fpsetsticky.c (100%) diff --git a/lib/libc/mips/gen/fpgetmask.c b/lib/libc/mips/gen/hardfloat/fpgetmask.c similarity index 100% rename from lib/libc/mips/gen/fpgetmask.c rename to lib/libc/mips/gen/hardfloat/fpgetmask.c diff --git a/lib/libc/mips/gen/fpgetround.c b/lib/libc/mips/gen/hardfloat/fpgetround.c similarity index 100% rename from lib/libc/mips/gen/fpgetround.c rename to lib/libc/mips/gen/hardfloat/fpgetround.c diff --git a/lib/libc/mips/gen/fpgetsticky.c b/lib/libc/mips/gen/hardfloat/fpgetsticky.c similarity index 100% rename from lib/libc/mips/gen/fpgetsticky.c rename to lib/libc/mips/gen/hardfloat/fpgetsticky.c diff --git a/lib/libc/mips/gen/fpsetmask.c b/lib/libc/mips/gen/hardfloat/fpsetmask.c similarity index 100% rename from lib/libc/mips/gen/fpsetmask.c rename to lib/libc/mips/gen/hardfloat/fpsetmask.c diff --git a/lib/libc/mips/gen/fpsetround.c b/lib/libc/mips/gen/hardfloat/fpsetround.c similarity index 100% rename from lib/libc/mips/gen/fpsetround.c rename to lib/libc/mips/gen/hardfloat/fpsetround.c diff --git a/lib/libc/mips/gen/fpsetsticky.c b/lib/libc/mips/gen/hardfloat/fpsetsticky.c similarity index 100% rename from lib/libc/mips/gen/fpsetsticky.c rename to lib/libc/mips/gen/hardfloat/fpsetsticky.c From 860c31caa102a41bf49129b5db9c3e7bf558895d Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 26 Jun 2009 01:27:31 +0000 Subject: [PATCH 141/380] - Switch to libc softfloat from libgcc implementation. The problem with latter is that it is not complete, fpsetXXX/fpgetXXX functions are missing. --- gnu/lib/libgcc/Makefile | 6 +++++- lib/libc/Makefile | 2 +- lib/libc/mips/Symbol.map | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/gnu/lib/libgcc/Makefile b/gnu/lib/libgcc/Makefile index 49b96e6e3a0..4d1caf5dd21 100644 --- a/gnu/lib/libgcc/Makefile +++ b/gnu/lib/libgcc/Makefile @@ -109,6 +109,10 @@ LIB2FUNCS_EXTRA = floatunsidf.c floatunsisf.c # _fixsfsi _fixunssfsi _floatdidf _floatdisf .endif +.if ${TARGET_ARCH} == "mips" +LIB2FUNCS_EXTRA = floatunsidf.c floatunsisf.c +.endif + .if ${TARGET_ARCH} == "ia64" # from config/ia64/t-ia64 LIB1ASMSRC = lib1funcs.asm @@ -173,7 +177,7 @@ OBJ_GRPS = STD DIV # # Floating point emulation functions # -.if ${TARGET_ARCH} == "armNOT_YET" || ${TARGET_ARCH} == "mips" || \ +.if ${TARGET_ARCH} == "armNOT_YET" || \ ${TARGET_ARCH} == "powerpc" || ${TARGET_ARCH} == "sparc64" FPBIT_CFLAGS = -DFINE_GRAINED_LIBRARIES -DFLOAT diff --git a/lib/libc/Makefile b/lib/libc/Makefile index cf9ef3aa77e..6b2b2576458 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -64,7 +64,7 @@ NOASM= .include "${.CURDIR}/rpc/Makefile.inc" .include "${.CURDIR}/uuid/Makefile.inc" .include "${.CURDIR}/xdr/Makefile.inc" -.if ${MACHINE_ARCH} == "arm" +.if ${MACHINE_ARCH} == "arm" || ${MACHINE_ARCH} == "mips" .include "${.CURDIR}/softfloat/Makefile.inc" .endif .if ${MK_NIS} != "no" diff --git a/lib/libc/mips/Symbol.map b/lib/libc/mips/Symbol.map index 2bbdd6dd344..589c8c1c183 100644 --- a/lib/libc/mips/Symbol.map +++ b/lib/libc/mips/Symbol.map @@ -61,4 +61,22 @@ FBSDprivate_1.0 { minbrk; _brk; _sbrk; + + /* softfloat */ + __addsf3; + __adddf3; + __subsf3; + __subdf3; + __mulsf3; + __muldf3; + __divsf3; + __divdf3; + __floatsisf; + __floatsidf; + __fixsfsi; + __fixdfsi; + __fixunssfsi; + __fixunsdfsi; + __extendsfdf2; + __truncdfsf2; }; From 5576af82b57d72c0705fc9e7afb83b9ac921e1ce Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 26 Jun 2009 19:54:06 +0000 Subject: [PATCH 142/380] - Add guards to ensure that these files are included only once --- sys/mips/include/cache.h | 4 ++++ sys/mips/include/cache_mipsNN.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/sys/mips/include/cache.h b/sys/mips/include/cache.h index 8f22cdb381a..8c8cf34d9dd 100644 --- a/sys/mips/include/cache.h +++ b/sys/mips/include/cache.h @@ -37,6 +37,9 @@ * $FreeBSD$ */ +#ifndef _MACHINE_CACHE_H_ +#define _MACHINE_CACHE_H_ + /* * Cache operations. * @@ -259,3 +262,4 @@ void mips_config_cache(struct mips_cpuinfo *); void mips_dcache_compute_align(void); #include +#endif /* _MACHINE_CACHE_H_ */ diff --git a/sys/mips/include/cache_mipsNN.h b/sys/mips/include/cache_mipsNN.h index e44746a2523..9933e74b452 100644 --- a/sys/mips/include/cache_mipsNN.h +++ b/sys/mips/include/cache_mipsNN.h @@ -36,6 +36,8 @@ * * $FreeBSD$ */ +#ifndef _MACHINE_CACHE_MIPSNN_H_ +#define _MACHINE_CACHE_MIPSNN_H_ void mipsNN_cache_init(struct mips_cpuinfo *); @@ -65,3 +67,5 @@ void mipsNN_pdcache_wbinv_range_index_128(vm_offset_t, vm_size_t); void mipsNN_pdcache_inv_range_128(vm_offset_t, vm_size_t); void mipsNN_pdcache_wb_range_128(vm_offset_t, vm_size_t); #endif + +#endif /* _MACHINE_CACHE_MIPSNN_H_ */ From a79d8960b174a3a877b3ca24441b6d2aa5810625 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sat, 27 Jun 2009 23:01:35 +0000 Subject: [PATCH 143/380] - Make cpu_set_upcall_kse conform MIPS ABI. T9 should be the same as PC in subroutine entry point - Preserve interrupt mask --- sys/mips/mips/vm_machdep.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c index 143d6ddb927..08bb365d876 100644 --- a/sys/mips/mips/vm_machdep.c +++ b/sys/mips/mips/vm_machdep.c @@ -351,9 +351,18 @@ cpu_set_upcall_kse(struct thread *td, void (*entry)(void *), void *arg, bzero(tf, sizeof(struct trapframe)); tf->sp = (register_t)sp; tf->pc = (register_t)entry; + /* + * MIPS ABI requires T9 to be the same as PC + * in subroutine entry point + */ + tf->t9 = (register_t)entry; tf->a0 = (register_t)arg; - tf->sr = SR_KSU_USER | SR_EXL; + /* + * Keep interrupt mask + */ + tf->sr = SR_KSU_USER | SR_EXL | (SR_INT_MASK & mips_rd_status()) | + MIPS_SR_INT_IE; #ifdef TARGET_OCTEON tf->sr |= MIPS_SR_INT_IE | MIPS_SR_COP_0_BIT | MIPS_SR_UX | MIPS_SR_KX; From 00741bfc80160b2cfe6552a6a821fe6a08e8dc60 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sat, 27 Jun 2009 23:27:41 +0000 Subject: [PATCH 144/380] - Add support for handling TLS area address in kernel space. From the userland point of view get/set operations are performed using sysarch(2) call. --- sys/mips/include/proc.h | 1 + sys/mips/include/sysarch.h | 10 ++--- sys/mips/include/ucontext.h | 1 + sys/mips/mips/genassym.c | 1 + sys/mips/mips/machdep.c | 6 --- sys/mips/mips/pm_machdep.c | 8 ++++ sys/mips/mips/sys_machdep.c | 77 +++++++++++++++++++++++++++++++++++++ sys/mips/mips/vm_machdep.c | 3 +- 8 files changed, 93 insertions(+), 14 deletions(-) create mode 100644 sys/mips/mips/sys_machdep.c diff --git a/sys/mips/include/proc.h b/sys/mips/include/proc.h index 6a0ce7dc077..d09620a2d11 100644 --- a/sys/mips/include/proc.h +++ b/sys/mips/include/proc.h @@ -54,6 +54,7 @@ struct mdthread { int md_pc_count; /* performance counter */ int md_pc_spill; /* performance counter spill */ vm_offset_t md_realstack; + void *md_tls; }; /* md_flags */ diff --git a/sys/mips/include/sysarch.h b/sys/mips/include/sysarch.h index acb30713a46..350ad9583ee 100644 --- a/sys/mips/include/sysarch.h +++ b/sys/mips/include/sysarch.h @@ -35,16 +35,12 @@ #ifndef _MACHINE_SYSARCH_H_ #define _MACHINE_SYSARCH_H_ +#define MIPS_SET_TLS 1 +#define MIPS_GET_TLS 2 + #ifndef _KERNEL #include -#if 0 -/* Something useful for each MIPS platform. */ -#else -#define mips_tcb_set(tcb) do {} while (0) -#define mips_tcb_get() NULL -#endif /* _MIPS_ARCH_XLR */ - __BEGIN_DECLS int sysarch(int, void *); __END_DECLS diff --git a/sys/mips/include/ucontext.h b/sys/mips/include/ucontext.h index d9dfe4ea09f..c28f08371c7 100644 --- a/sys/mips/include/ucontext.h +++ b/sys/mips/include/ucontext.h @@ -53,6 +53,7 @@ typedef struct __mcontext { int mc_fpused; /* fp has been used */ f_register_t mc_fpregs[33]; /* fp regs 0 to 31 and csr */ register_t mc_fpc_eir; /* fp exception instruction reg */ + void *mc_tls; /* pointer to TLS area */ int __spare__[8]; /* XXX reserved */ } mcontext_t; #endif diff --git a/sys/mips/mips/genassym.c b/sys/mips/mips/genassym.c index 90974c7bcff..2912ab10c62 100644 --- a/sys/mips/mips/genassym.c +++ b/sys/mips/mips/genassym.c @@ -69,6 +69,7 @@ ASSYM(TD_REALKSTACK, offsetof(struct thread, td_md.md_realstack)); ASSYM(TD_FLAGS, offsetof(struct thread, td_flags)); ASSYM(TD_LOCK, offsetof(struct thread, td_lock)); ASSYM(TD_FRAME, offsetof(struct thread, td_frame)); +ASSYM(TD_TLS, offsetof(struct thread, td_md.md_tls)); ASSYM(TF_REG_SR, offsetof(struct trapframe, sr)); diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c index 6bd518018e7..7b2825714aa 100644 --- a/sys/mips/mips/machdep.c +++ b/sys/mips/mips/machdep.c @@ -349,12 +349,6 @@ cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size) pcpu->pc_asid_generation = 1; } -int -sysarch(struct thread *td, register struct sysarch_args *uap) -{ - return (ENOSYS); -} - int fill_dbregs(struct thread *td, struct dbreg *dbregs) { diff --git a/sys/mips/mips/pm_machdep.c b/sys/mips/mips/pm_machdep.c index 3c927521e0a..097334756f4 100644 --- a/sys/mips/mips/pm_machdep.c +++ b/sys/mips/mips/pm_machdep.c @@ -413,9 +413,16 @@ get_mcontext(struct thread *td, mcontext_t *mcp, int flags) bcopy((void *)&td->td_frame->f0, (void *)&mcp->mc_fpregs, sizeof(mcp->mc_fpregs)); } + if (flags & GET_MC_CLEAR_RET) { + mcp->mc_regs[V0] = 0; + mcp->mc_regs[V1] = 0; + mcp->mc_regs[A3] = 0; + } + mcp->mc_pc = td->td_frame->pc; mcp->mullo = td->td_frame->mullo; mcp->mulhi = td->td_frame->mulhi; + mcp->mc_tls = td->td_md.md_tls; return (0); } @@ -436,6 +443,7 @@ set_mcontext(struct thread *td, const mcontext_t *mcp) td->td_frame->pc = mcp->mc_pc; td->td_frame->mullo = mcp->mullo; td->td_frame->mulhi = mcp->mulhi; + td->td_md.md_tls = mcp->mc_tls; /* Dont let user to set any bits in Status and casue registers */ return (0); diff --git a/sys/mips/mips/sys_machdep.c b/sys/mips/mips/sys_machdep.c new file mode 100644 index 00000000000..c316db33a72 --- /dev/null +++ b/sys/mips/mips/sys_machdep.c @@ -0,0 +1,77 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)sys_machdep.c 5.5 (Berkeley) 1/19/91 + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include + +#ifndef _SYS_SYSPROTO_H_ +struct sysarch_args { + int op; + char *parms; +}; +#endif + +int +sysarch(td, uap) + struct thread *td; + register struct sysarch_args *uap; +{ + int error; + void *tlsbase; + + switch (uap->op) { + case MIPS_SET_TLS : + td->td_md.md_tls = (void*)uap->parms; + error = 0; + break; + + case MIPS_GET_TLS : + tlsbase = td->td_md.md_tls; + error = copyout(&tlsbase, uap->parms, sizeof(tlsbase)); + break; + default: + error = EINVAL; + } + return (error); +} diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c index 08bb365d876..9d39401119c 100644 --- a/sys/mips/mips/vm_machdep.c +++ b/sys/mips/mips/vm_machdep.c @@ -156,6 +156,7 @@ cpu_fork(register struct thread *td1,register struct proc *p2, * that are needed. */ + td2->td_md.md_tls = td1->td_md.md_tls; td2->td_md.md_saved_intr = MIPS_SR_INT_IE; td2->td_md.md_spinlock_count = 1; #ifdef TARGET_OCTEON @@ -535,7 +536,7 @@ int cpu_set_user_tls(struct thread *td, void *tls_base) { - /* TBD */ + td->td_md.md_tls = tls_base; return (0); } From 28399804b48947a9a44ebd91863800d43068bf3a Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sat, 27 Jun 2009 23:28:56 +0000 Subject: [PATCH 145/380] - Use sysarch(2) in MIPS version of _tcb_set/_tcb_get --- lib/libthr/arch/mips/include/pthread_md.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/libthr/arch/mips/include/pthread_md.h b/lib/libthr/arch/mips/include/pthread_md.h index 34e58c676c4..24139a3a71f 100644 --- a/lib/libthr/arch/mips/include/pthread_md.h +++ b/lib/libthr/arch/mips/include/pthread_md.h @@ -60,7 +60,8 @@ void _tcb_dtor(struct tcb *); static __inline void _tcb_set(struct tcb *tcb) { - mips_tcb_set(tcb); + + sysarch(MIPS_SET_TLS, tcb); } /* @@ -69,7 +70,10 @@ _tcb_set(struct tcb *tcb) static __inline struct tcb * _tcb_get(void) { - return (mips_tcb_get()); + void *tcb; + + sysarch(MIPS_GET_TLS, &tcb); + return tcb; } extern struct pthread *_thr_initial; From fa596cbd835636d94e674c8ab36985901270781b Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sun, 28 Jun 2009 21:01:00 +0000 Subject: [PATCH 146/380] - Replace casuword and casuword32 stubs with proper implementation --- sys/mips/mips/support.S | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/sys/mips/mips/support.S b/sys/mips/mips/support.S index d8213618108..a5c46d851cc 100644 --- a/sys/mips/mips/support.S +++ b/sys/mips/mips/support.S @@ -474,12 +474,31 @@ XLEAF(suword32) END(suword) /* + * XXXMIPS: ATM it's the same as casuword32, but MIPS64 will require + * own implementation * casuword(9) * u_long casuword(u_long *p, u_long oldval, u_long newval) */ ENTRY(casuword) - break + blt a0, zero, fswberr # make sure address is in user space + li v0, FSWBERR + GET_CPU_PCPU(v1) + lw v1, PC_CURPCB(v1) + sw v0, U_PCB_ONFAULT(v1) +1: + move t0, a2 + ll v0, 0(a0) + bne a1, v0, 2f + nop + sc t0, 0(a0) # store word + beqz t0, 1b + nop + j 3f + nop +2: li v0, -1 +3: + sw zero, U_PCB_ONFAULT(v1) jr ra nop END(casuword) @@ -490,8 +509,25 @@ END(casuword) * uint32_t newval) */ ENTRY(casuword32) - break + blt a0, zero, fswberr # make sure address is in user space + li v0, FSWBERR + GET_CPU_PCPU(v1) + lw v1, PC_CURPCB(v1) + sw v0, U_PCB_ONFAULT(v1) +1: + move t0, a2 + ll v0, 0(a0) + bne a1, v0, 2f + nop + sc t0, 0(a0) # store word + beqz t0, 1b + nop + j 3f + nop +2: li v0, -1 +3: + sw zero, U_PCB_ONFAULT(v1) jr ra nop END(casuword32) From f2d4ea406013aa438509d988ad6aa36d79124630 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 29 Jun 2009 17:36:47 +0000 Subject: [PATCH 147/380] - add sys_machdep.c to build --- sys/conf/files.mips | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/conf/files.mips b/sys/conf/files.mips index aa8fef37d03..868d6c8fc94 100644 --- a/sys/conf/files.mips +++ b/sys/conf/files.mips @@ -70,6 +70,7 @@ mips/mips/mem.c optional mem mips/mips/nexus.c standard mips/mips/stack_machdep.c optional ddb | stack mips/mips/support.S standard +mips/mips/sys_machdep.c standard mips/mips/swtch.S standard mips/mips/uio_machdep.c standard geom/geom_bsd.c optional geom_bsd From 579c0614d5b0cbcda8d43463df30a1b209410b1f Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 4 Jul 2009 02:49:17 +0000 Subject: [PATCH 148/380] Merge in new cfe environment passing of kenv for swarm/sibyte boards. Submitted by: Neelkanth Natu --- sys/conf/files.mips | 1 + sys/conf/options.mips | 2 ++ sys/dev/cfe/cfe_env.c | 74 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 sys/dev/cfe/cfe_env.c diff --git a/sys/conf/files.mips b/sys/conf/files.mips index 868d6c8fc94..22cba83050a 100644 --- a/sys/conf/files.mips +++ b/sys/conf/files.mips @@ -96,6 +96,7 @@ libkern/umoddi3.c standard dev/cfe/cfe_api.c optional cfe dev/cfe/cfe_console.c optional cfe_console +dev/cfe/cfe_env.c optional cfe_env #dev/cfe/cfe_resource.c optional cfe # not yet needed dev/siba/siba.c optional siba diff --git a/sys/conf/options.mips b/sys/conf/options.mips index 1b218a466cf..cc6e33340ea 100644 --- a/sys/conf/options.mips +++ b/sys/conf/options.mips @@ -44,6 +44,8 @@ ISA_MIPS64v2 opt_cputype.h YAMON opt_global.h CFE opt_global.h CFE_CONSOLE opt_global.h +CFE_ENV opt_global.h +CFE_ENV_SIZE opt_global.h KERNPHYSADDR opt_global.h KERNVIRTADDR opt_global.h diff --git a/sys/dev/cfe/cfe_env.c b/sys/dev/cfe/cfe_env.c new file mode 100644 index 00000000000..a72e46e141a --- /dev/null +++ b/sys/dev/cfe/cfe_env.c @@ -0,0 +1,74 @@ +/*- + * Copyright (c) 2009 Neelkanth Natu + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +#include + +__FBSDID("$FreeBSD$"); + +#ifndef CFE_ENV_SIZE +#define CFE_ENV_SIZE PAGE_SIZE /* default is one page */ +#endif + +extern void cfe_env_init(void); + +static char cfe_env_buf[CFE_ENV_SIZE]; + +void +cfe_env_init(void) +{ + int idx, len; + char name[64], val[128], *cp, *cplim; + + cp = cfe_env_buf; + cplim = cp + CFE_ENV_SIZE; + + idx = 0; + while (1) { + if (cfe_enumenv(idx, name, sizeof(name), val, sizeof(val)) != 0) + break; + + if (bootverbose) + printf("Importing CFE env: \"%s=%s\"\n", name, val); + + /* + * name=val\0\0 + */ + len = strlen(name) + 1 + strlen(val) + 1 + 1; + if (cplim - cp < len) + printf("No space to store CFE env: \"%s=%s\"\n", + name, val); + else + cp += sprintf(cp, "%s=%s", name, val) + 1; + ++idx; + } + *cp++ = '\0'; + + kern_envp = cfe_env_buf; +} From c72a141e817e604e2e616f5f4c3eed38194b61d1 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 4 Jul 2009 02:50:33 +0000 Subject: [PATCH 149/380] Fix various conolse issues with cfe after MPSAFE tty. Fix a bug with getting env on cfe... --- sys/dev/cfe/cfe_api.c | 2 +- sys/dev/cfe/cfe_console.c | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sys/dev/cfe/cfe_api.c b/sys/dev/cfe/cfe_api.c index 15f6ae7ab2c..bf3fa66e895 100644 --- a/sys/dev/cfe/cfe_api.c +++ b/sys/dev/cfe/cfe_api.c @@ -160,7 +160,7 @@ cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_ENV_SET; + xiocb.xiocb_fcode = CFE_CMD_ENV_ENUM; xiocb.xiocb_status = 0; xiocb.xiocb_handle = 0; xiocb.xiocb_flags = 0; diff --git a/sys/dev/cfe/cfe_console.c b/sys/dev/cfe/cfe_console.c index 2c38096859f..1461ef21119 100644 --- a/sys/dev/cfe/cfe_console.c +++ b/sys/dev/cfe/cfe_console.c @@ -84,14 +84,12 @@ CONSOLE_DRIVER(cfe); static void cn_drvinit(void *unused) { - char output[32]; struct tty *tp; if (cfe_consdev.cn_pri != CN_DEAD && cfe_consdev.cn_name[0] != '\0') { tp = tty_alloc(&cfe_ttydevsw, NULL); - tty_makedev(tp, NULL, "%s", output); - tty_makealias(tp, "cfecons"); + tty_makedev(tp, NULL, "cfecons"); } } @@ -117,15 +115,21 @@ cfe_tty_close(struct tty *tp) static void cfe_tty_outwakeup(struct tty *tp) { - int len; + int len, written, rc; u_char buf[CFEBURSTLEN]; for (;;) { len = ttydisc_getc(tp, buf, sizeof buf); if (len == 0) break; - while (cfe_write(conhandle, buf, len) == 0) - continue; + + written = 0; + while (written < len) { + rc = cfe_write(conhandle, &buf[written], len - written); + if (rc < 0) + break; + written += rc; + } } } @@ -184,13 +188,9 @@ cfe_cnterm(struct consdev *cp) static int cfe_cngetc(struct consdev *cp) { - int result; unsigned char ch; - while ((result = cfe_read(conhandle, &ch, 1)) == 0) - continue; - - if (result > 0) { + if (cfe_read(conhandle, &ch, 1) == 1) { #if defined(KDB) && defined(ALT_BREAK_TO_DEBUGGER) int kdb_brk; From f94784e8182eea2a175f8a183eb69578e8a44392 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 4 Jul 2009 03:05:48 +0000 Subject: [PATCH 150/380] Add sibyte device support. Submitted by: Neelkanth Natu --- sys/mips/sibyte/ata_zbbus.c | 170 ++++++++++++ sys/mips/sibyte/files.sibyte | 9 + sys/mips/sibyte/sb_asm.S | 155 +++++++++++ sys/mips/sibyte/sb_machdep.c | 259 ++++++++++++++++++ sys/mips/sibyte/sb_scd.c | 152 +++++++++++ sys/mips/sibyte/sb_scd.h | 46 ++++ sys/mips/sibyte/sb_zbbus.c | 501 +++++++++++++++++++++++++++++++++++ sys/mips/sibyte/sb_zbpci.c | 283 ++++++++++++++++++++ 8 files changed, 1575 insertions(+) create mode 100644 sys/mips/sibyte/ata_zbbus.c create mode 100644 sys/mips/sibyte/files.sibyte create mode 100644 sys/mips/sibyte/sb_asm.S create mode 100644 sys/mips/sibyte/sb_machdep.c create mode 100644 sys/mips/sibyte/sb_scd.c create mode 100644 sys/mips/sibyte/sb_scd.h create mode 100644 sys/mips/sibyte/sb_zbbus.c create mode 100644 sys/mips/sibyte/sb_zbpci.c diff --git a/sys/mips/sibyte/ata_zbbus.c b/sys/mips/sibyte/ata_zbbus.c new file mode 100644 index 00000000000..87a2a42943e --- /dev/null +++ b/sys/mips/sibyte/ata_zbbus.c @@ -0,0 +1,170 @@ +/*- + * Copyright (c) 2009 Neelkanth Natu + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include + +__FBSDID("$FreeBSD$"); + +static int +ata_zbbus_probe(device_t dev) +{ + + return (ata_probe(dev)); +} + +static int +ata_zbbus_attach(device_t dev) +{ + int i, rid, regshift, regoffset; + struct ata_channel *ch; + struct resource *io; + + ch = device_get_softc(dev); + + if (ch->attached) + return (0); + ch->attached = 1; + + rid = 0; + io = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, 1, RF_ACTIVE); + if (io == NULL) + return (ENXIO); + + /* + * SWARM needs an address shift of 5 when accessing ATA registers. + * + * For e.g. an access to register 4 actually needs an address + * of (4 << 5) to be output on the generic bus. + */ + regshift = 5; + resource_int_value(device_get_name(dev), device_get_unit(dev), + "regshift", ®shift); + if (regshift && bootverbose) + device_printf(dev, "using a register shift of %d\n", regshift); + + regoffset = 0x1F0; + resource_int_value(device_get_name(dev), device_get_unit(dev), + "regoffset", ®offset); + if (regoffset && bootverbose) { + device_printf(dev, "using a register offset of 0x%0x\n", + regoffset); + } + + /* setup the ata register addresses */ + for (i = ATA_DATA; i <= ATA_COMMAND; ++i) { + ch->r_io[i].res = io; + ch->r_io[i].offset = (regoffset + i) << regshift; + } + + ch->r_io[ATA_CONTROL].res = io; + ch->r_io[ATA_CONTROL].offset = (regoffset + ATA_CTLOFFSET) << regshift; + ch->r_io[ATA_IDX_ADDR].res = io; /* XXX what is this used for */ + ata_default_registers(dev); + + /* initialize softc for this channel */ + ch->unit = 0; + ch->flags |= ATA_USE_16BIT; + ata_generic_hw(dev); + + return (ata_attach(dev)); +} + +static int +ata_zbbus_detach(device_t dev) +{ + int error; + struct ata_channel *ch = device_get_softc(dev); + + if (!ch->attached) + return (0); + ch->attached = 0; + + error = ata_detach(dev); + + bus_release_resource(dev, SYS_RES_MEMORY, 0, + ch->r_io[ATA_IDX_ADDR].res); + + return (error); +} + +static int +ata_zbbus_suspend(device_t dev) +{ + struct ata_channel *ch = device_get_softc(dev); + + if (!ch->attached) + return (0); + + return (ata_suspend(dev)); +} + +static int +ata_zbbus_resume(device_t dev) +{ + struct ata_channel *ch = device_get_softc(dev); + + if (!ch->attached) + return (0); + + return (ata_resume(dev)); +} + +static device_method_t ata_zbbus_methods[] = { + /* device interface */ + DEVMETHOD(device_probe, ata_zbbus_probe), + DEVMETHOD(device_attach, ata_zbbus_attach), + DEVMETHOD(device_detach, ata_zbbus_detach), + DEVMETHOD(device_suspend, ata_zbbus_suspend), + DEVMETHOD(device_resume, ata_zbbus_resume), + + { 0, 0 } +}; + +static driver_t ata_zbbus_driver = { + "ata", + ata_zbbus_methods, + sizeof(struct ata_channel) +}; + +DRIVER_MODULE(ata, zbbus, ata_zbbus_driver, ata_devclass, 0, 0); diff --git a/sys/mips/sibyte/files.sibyte b/sys/mips/sibyte/files.sibyte new file mode 100644 index 00000000000..56f317d31e3 --- /dev/null +++ b/sys/mips/sibyte/files.sibyte @@ -0,0 +1,9 @@ +# $FreeBSD$ + +mips/sibyte/sb_machdep.c standard +mips/sibyte/sb_zbbus.c standard +mips/sibyte/sb_zbpci.c standard +mips/sibyte/sb_scd.c standard +mips/sibyte/ata_zbbus.c standard + +mips/sibyte/sb_asm.S standard diff --git a/sys/mips/sibyte/sb_asm.S b/sys/mips/sibyte/sb_asm.S new file mode 100644 index 00000000000..d878113c022 --- /dev/null +++ b/sys/mips/sibyte/sb_asm.S @@ -0,0 +1,155 @@ +/*- + * Copyright (c) 2009 Neelkanth Natu + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +/* + * We compile a 32-bit kernel to run on the SB-1 processor which is a 64-bit + * processor. It has some registers that must be accessed using 64-bit load + * and store instructions. + * + * So we have to resort to assembly because the compiler does not emit the + * 'ld' and 'sd' instructions since it thinks that it is compiling for a + * 32-bit mips processor. + */ + +.set mips64 +.set noat +.set noreorder + +/* + * return (MIPS_PHYS_TO_KSEG1(0x10020008)) + * Parameters: none + */ +LEAF(sb_read_syscfg) + lui v0, 0xb002 + ori v0, v0, 0x8 + ld v1, 0(v0) /* syscfg = MIPS_PHYS_TO_KSEG1(0x10020008) */ + move v0, v1 + dsll32 v0, v0, 0 + dsrl32 v0, v0, 0 /* v0 = lower_uint32(mask) */ + jr ra + dsrl32 v1, v1, 0 /* v1 = upper_uint32(mask) */ +END(sb_read_syscfg) + +/* + * MIPS_PHYS_TO_KSEG1(0x10020008) = (uint64_t)val + * Parameters: + * - lower_uint32(val): a0 + * - upper_uint32(val): a1 + */ +LEAF(sb_write_syscfg) + lui v0, 0xb002 + ori v0, v0, 0x8 + dsll32 a1, a1, 0 /* clear lower 32 bits of a1 */ + dsll32 a0, a0, 0 + dsrl32 a0, a0, 0 /* clear upper 32 bits of a0 */ + or a1, a1, a0 + sd a1, 0(v0) /* MIPS_PHYS_TO_KSEG1(0x10020008) = val */ + jr ra + nop + nop +END(sb_write_syscfg) + +/* + * MIPS_PHYS_TO_KSEG1(0x10020028) |= (1 << intsrc) + * + * Parameters: + * - intsrc (a0) + */ +LEAF(sb_disable_intsrc) + lui v0, 0xb002 + ori v0, v0, 0x28 + ld v1, 0(v0) /* mask = MIPS_PHYS_TO_KSEG1(0x10020028) */ + li a1, 1 + dsllv a1, a1, a0 + or a1, a1, v1 /* mask |= (1 << intsrc) */ + jr ra + sd a1, 0(v0) /* MIPS_PHYS_TO_KSEG1(0x10020028) = mask */ +END(sb_disable_intsrc) + +/* + * MIPS_PHYS_TO_KSEG1(0x10020028) &= ~(1 << intsrc) + * + * Parameters: + * - intsrc (a0) + */ +LEAF(sb_enable_intsrc) + lui v0, 0xb002 + ori v0, v0, 0x28 + ld v1, 0(v0) /* mask = MIPS_PHYS_TO_KSEG1(0x10020028) */ + li a2, 1 + dsllv a2, a2, a0 + nor a2, zero, a2 + and a2, a2, v1 /* mask &= ~(1 << intsrc) */ + sd a2, 0(v0) /* MIPS_PHYS_TO_KSEG1(0x10020028) = mask */ + jr ra + nop +END(sb_enable_intsrc) + +/* + * return ((uint64_t)MIPS_PHYS_TO_KSEG1(0x10020028)) + * Parameters: none + */ +LEAF(sb_read_intsrc_mask) + lui v0, 0xb002 + ori v0, v0, 0x28 + ld v1, 0(v0) /* mask = MIPS_PHYS_TO_KSEG1(0x10020028) */ + move v0, v1 + dsll32 v0, v0, 0 + dsrl32 v0, v0, 0 /* v0 = lower_uint32(mask) */ + jr ra + dsrl32 v1, v1, 0 /* v1 = upper_uint32(mask) */ +END(sb_read_intsrc_mask) + +/* + * return ((uint64_t *)MIPS_PHYS_TO_KSEG1(0x10020200) + intsrc) + * Parameters: + * - intsrc (a0) + */ +LEAF(sb_read_intmap) + sll a0, a0, 3 /* compute the offset of the intmap register */ + lui v0, 0xb002 + addu a0, a0, v0 + ld v0, 512(a0) /* v0 = MIPS_PHYS_TO_KSEG1(0x10020200) + off */ + jr ra + nop +END(sb_read_intmap) + +/* + * (uint64_t *)MIPS_PHYS_TO_KSEG1(0x10020200) + intsrc = irq + * Parameters: + * - intsrc (a0) + * - irq (a1) + */ +LEAF(sb_write_intmap) + sll a0, a0, 0x3 /* compute the offset of the intmap register */ + lui v0, 0xb002 + addu a0, a0, v0 + sd a1, 512(a0) /* MIPS_PHYS_TO_KSEG1(0x10020200) + off = irq */ + jr ra + nop +END(sb_write_intmap) diff --git a/sys/mips/sibyte/sb_machdep.c b/sys/mips/sibyte/sb_machdep.c new file mode 100644 index 00000000000..79a1b8975cc --- /dev/null +++ b/sys/mips/sibyte/sb_machdep.c @@ -0,0 +1,259 @@ +/*- + * Copyright (c) 2007 Bruce M. Simpson. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include "opt_ddb.h" +#include "opt_kdb.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CFE +#include +#endif + +#include "sb_scd.h" + +#ifdef DDB +#ifndef KDB +#error KDB must be enabled in order for DDB to work! +#endif +#endif + +#ifdef CFE +extern uint32_t cfe_handle; +extern uint32_t cfe_vector; +#endif + +#ifdef CFE_ENV +extern void cfe_env_init(void); +#endif + +extern int *edata; +extern int *end; + +static void +mips_init(void) +{ + int i, cfe_mem_idx, tmp; + uint64_t maxmem; + +#ifdef CFE_ENV + cfe_env_init(); +#endif + + TUNABLE_INT_FETCH("boothowto", &boothowto); + + if (boothowto & RB_VERBOSE) + bootverbose++; + +#ifdef MAXMEM + tmp = MAXMEM; +#else + tmp = 0; +#endif + TUNABLE_INT_FETCH("hw.physmem", &tmp); + maxmem = (uint64_t)tmp * 1024; + +#ifdef CFE + /* + * Query DRAM memory map from CFE. + */ + physmem = 0; + cfe_mem_idx = 0; + for (i = 0; i < 10; i += 2) { + int result; + uint64_t addr, len, type; + + result = cfe_enummem(cfe_mem_idx++, 0, &addr, &len, &type); + if (result < 0) { + phys_avail[i] = phys_avail[i + 1] = 0; + break; + } + + KASSERT(type == CFE_MI_AVAILABLE, + ("CFE DRAM region is not available?")); + + if (bootverbose) + printf("cfe_enummem: 0x%016jx/%llu.\n", addr, len); + + if (maxmem != 0) { + if (addr >= maxmem) { + printf("Ignoring %llu bytes of memory at 0x%jx " + "that is above maxmem %dMB\n", + len, addr, + (int)(maxmem / (1024 * 1024))); + continue; + } + + if (addr + len > maxmem) { + printf("Ignoring %llu bytes of memory " + "that is above maxmem %dMB\n", + (addr + len) - maxmem, + (int)(maxmem / (1024 * 1024))); + len = maxmem - addr; + } + } + + phys_avail[i] = addr; + if (i == 0 && addr == 0) { + /* + * If this is the first physical memory segment probed + * from CFE, omit the region at the start of physical + * memory where the kernel has been loaded. + */ + phys_avail[i] += MIPS_KSEG0_TO_PHYS((vm_offset_t)&end); + } + phys_avail[i + 1] = addr + len; + physmem += len; + } + + realmem = btoc(physmem); +#endif + + physmem = realmem; + + init_param1(); + init_param2(physmem); + mips_cpu_init(); + pmap_bootstrap(); + mips_proc0_init(); + mutex_init(); + + kdb_init(); +#ifdef KDB + if (boothowto & RB_KDB) + kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); +#endif +} + +void +platform_halt(void) +{ + +} + + +void +platform_identify(void) +{ + +} + +void +platform_reset(void) +{ + + /* + * XXX SMP + * XXX flush data caches + */ + sb_system_reset(); +} + +void +platform_trap_enter(void) +{ + +} + +void +platform_trap_exit(void) +{ + +} + +void +platform_start(__register_t a0 __unused, __register_t a1 __unused, + __register_t a2 __unused, __register_t a3 __unused) +{ + vm_offset_t kernend; + + /* clear the BSS and SBSS segments */ + memset(&edata, 0, (vm_offset_t)&end - (vm_offset_t)&edata); + kernend = round_page((vm_offset_t)&end); + +#ifdef CFE + /* + * Initialize CFE firmware trampolines before + * we initialize the low-level console. + */ + if (cfe_handle != 0) + cfe_init(cfe_handle, cfe_vector); +#endif + cninit(); + +#ifdef CFE + if (cfe_handle == 0) + panic("CFE was not detected by locore.\n"); +#endif + mips_init(); + + mips_timer_init_params(sb_cpu_speed(), 0); +} diff --git a/sys/mips/sibyte/sb_scd.c b/sys/mips/sibyte/sb_scd.c new file mode 100644 index 00000000000..d6a80e1be1b --- /dev/null +++ b/sys/mips/sibyte/sb_scd.c @@ -0,0 +1,152 @@ +/*- + * Copyright (c) 2009 Neelkanth Natu + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include +#include +#include +#include +#include + +#include + +#include "sb_scd.h" + +__FBSDID("$FreeBSD$"); + +/* + * System Control and Debug (SCD) unit on the Sibyte ZBbus. + */ + +/* + * Extract the value starting at bit position 'b' for 'n' bits from 'x'. + */ +#define GET_VAL_64(x, b, n) (((x) >> (b)) & ((1ULL << (n)) - 1)) + +#define SYSCFG_PLLDIV(x) GET_VAL_64((x), 7, 5) + +uint64_t +sb_cpu_speed(void) +{ + int plldiv; + const uint64_t MHZ = 1000000; + + plldiv = SYSCFG_PLLDIV(sb_read_syscfg()); + if (plldiv == 0) { + printf("PLL_DIV is 0 - assuming 6 (300MHz).\n"); + plldiv = 6; + } + + return (plldiv * 50 * MHZ); +} + +void +sb_system_reset(void) +{ + uint64_t syscfg; + + const uint64_t SYSTEM_RESET = 1ULL << 60; + const uint64_t EXT_RESET = 1ULL << 59; + const uint64_t SOFT_RESET = 1ULL << 58; + + syscfg = sb_read_syscfg(); + syscfg &= ~SOFT_RESET; + syscfg |= SYSTEM_RESET | EXT_RESET; + sb_write_syscfg(syscfg); +} + +int +sb_route_intsrc(int intsrc) +{ + int intrnum; + + KASSERT(intsrc >= 0 && intsrc < NUM_INTSRC, + ("Invalid interrupt source number (%d)", intsrc)); + + /* + * Interrupt 5 is used by sources internal to the CPU (e.g. timer). + * Use a deterministic mapping for the remaining sources to map to + * interrupt numbers 0 through 4. + */ + intrnum = intsrc % 5; + + /* + * Program the interrupt mapper while we are here. + */ + sb_write_intmap(intsrc, intrnum); + + return (intrnum); +} + +#define SCD_PHYSADDR 0x10000000 +#define SCD_SIZE 0x00060000 + +static int +scd_probe(device_t dev) +{ + + device_set_desc(dev, "Broadcom/Sibyte System Control and Debug"); + return (0); +} + +static int +scd_attach(device_t dev) +{ + int rid; + struct resource *res; + + if (bootverbose) { + device_printf(dev, "attached.\n"); + } + + rid = 0; + res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, SCD_PHYSADDR, + SCD_PHYSADDR + SCD_SIZE - 1, SCD_SIZE, 0); + if (res == NULL) { + panic("Cannot allocate resource for system control and debug."); + } + + return (0); +} + +static device_method_t scd_methods[] ={ + /* Device interface */ + DEVMETHOD(device_probe, scd_probe), + DEVMETHOD(device_attach, scd_attach), + DEVMETHOD(device_detach, bus_generic_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(device_suspend, bus_generic_suspend), + DEVMETHOD(device_resume, bus_generic_resume), + + { 0, 0 } +}; + +static driver_t scd_driver = { + "scd", + scd_methods +}; + +static devclass_t scd_devclass; + +DRIVER_MODULE(scd, zbbus, scd_driver, scd_devclass, 0, 0); diff --git a/sys/mips/sibyte/sb_scd.h b/sys/mips/sibyte/sb_scd.h new file mode 100644 index 00000000000..8de3aae7dd7 --- /dev/null +++ b/sys/mips/sibyte/sb_scd.h @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2009 Neelkanth Natu + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SB_SCD_H_ +#define _SB_SCD_H_ + +#define NUM_INTSRC 64 /* total number of interrupt sources */ + +uint64_t sb_cpu_speed(void); +void sb_system_reset(void); + +int sb_route_intsrc(int src); +void sb_enable_intsrc(int src); +void sb_disable_intsrc(int src); +uint64_t sb_read_intsrc_mask(void); + +int sb_read_intmap(int intsrc); +void sb_write_intmap(int intsrc, int intrnum); + +uint64_t sb_read_syscfg(void); +void sb_write_syscfg(uint64_t val); + +#endif /* _SB_SCD_H_ */ diff --git a/sys/mips/sibyte/sb_zbbus.c b/sys/mips/sibyte/sb_zbbus.c new file mode 100644 index 00000000000..e67ae359297 --- /dev/null +++ b/sys/mips/sibyte/sb_zbbus.c @@ -0,0 +1,501 @@ +/*- + * Copyright (c) 2009 Neelkanth Natu + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "sb_scd.h" + +__FBSDID("$FreeBSD$"); + +static MALLOC_DEFINE(M_INTMAP, "sb1250 intmap", "Sibyte 1250 Interrupt Mapper"); + +#define NUM_HARD_IRQS 6 + +struct sb_intmap { + int intsrc; /* interrupt mapper register number (0 - 63) */ + int active; /* Does this source generate interrupts? */ + + /* + * The device that the interrupt belongs to. Note that multiple + * devices may share an interrupt. For e.g. PCI_INT_x lines. + * + * The device 'dev' in combination with the 'rid' uniquely + * identify this interrupt source. + */ + device_t dev; + int rid; + + SLIST_ENTRY(sb_intmap) next; +}; + +/* + * We register 'sb_intsrc.isrc' using cpu_register_hard_intsrc() for each + * hard interrupt source [0-5]. + * + * The mask/unmask callbacks use the information in 'sb_intmap' to figure + * out the corresponding interrupt sources to mask/unmask. + */ +struct sb_intsrc { + struct intsrc isrc; + SLIST_HEAD(, sb_intmap) sb_intmap_head; +}; + +static struct sb_intsrc sb_intsrc[NUM_HARD_IRQS]; + +static struct sb_intmap * +sb_intmap_lookup(int intrnum, device_t dev, int rid) +{ + struct sb_intsrc *isrc; + struct sb_intmap *map; + + isrc = &sb_intsrc[intrnum]; + SLIST_FOREACH(map, &isrc->sb_intmap_head, next) { + if (dev == map->dev && rid == map->rid) + break; + } + return (map); +} + +/* + * Keep track of which (dev,rid) tuple is using the interrupt source. + * + * We don't actually unmask the interrupt source until the device calls + * a bus_setup_intr() on the resource. + */ +static void +sb_intmap_add(int intrnum, device_t dev, int rid, int intsrc) +{ + struct sb_intsrc *isrc; + struct sb_intmap *map; + register_t sr; + + KASSERT(intrnum >= 0 && intrnum < NUM_HARD_IRQS, + ("intrnum is out of range: %d", intrnum)); + + isrc = &sb_intsrc[intrnum]; + map = sb_intmap_lookup(intrnum, dev, rid); + if (map) { + KASSERT(intsrc == map->intsrc, + ("%s%d allocating SYS_RES_IRQ resource with rid %d " + "with a different intsrc (%d versus %d)", + device_get_name(dev), device_get_unit(dev), rid, + intsrc, map->intsrc)); + return; + } + + map = malloc(sizeof(*map), M_INTMAP, M_WAITOK | M_ZERO); + map->intsrc = intsrc; + map->dev = dev; + map->rid = rid; + + sr = intr_disable(); + SLIST_INSERT_HEAD(&isrc->sb_intmap_head, map, next); + intr_restore(sr); +} + +static void +sb_intmap_activate(int intrnum, device_t dev, int rid) +{ + struct sb_intmap *map; + register_t sr; + + KASSERT(intrnum >= 0 && intrnum < NUM_HARD_IRQS, + ("intrnum is out of range: %d", intrnum)); + + map = sb_intmap_lookup(intrnum, dev, rid); + if (map) { + /* + * See comments in sb_unmask_func() about disabling cpu intr + */ + sr = intr_disable(); + map->active = 1; + sb_enable_intsrc(map->intsrc); + intr_restore(sr); + } else { + /* + * In zbbus_setup_intr() we blindly call sb_intmap_activate() + * for every interrupt activation that comes our way. + * + * We might end up here if we did not "hijack" the SYS_RES_IRQ + * resource in zbbus_alloc_resource(). + */ + printf("sb_intmap_activate: unable to activate interrupt %d " + "for device %s%d rid %d.\n", intrnum, + device_get_name(dev), device_get_unit(dev), rid); + } +} + +static void +sb_mask_func(struct intsrc *arg) +{ + struct sb_intmap *map; + struct sb_intsrc *isrc; + uint64_t isrc_bitmap; + + isrc_bitmap = 0; + isrc = (struct sb_intsrc *)arg; + SLIST_FOREACH(map, &isrc->sb_intmap_head, next) { + if (map->active == 0) + continue; + /* + * If we have already disabled this interrupt source then don't + * do it again. This can happen when multiple devices share + * an interrupt source (e.g. PCI_INT_x). + */ + if (isrc_bitmap & (1ULL << map->intsrc)) + continue; + sb_disable_intsrc(map->intsrc); + isrc_bitmap |= 1ULL << map->intsrc; + } +} + +static void +sb_unmask_func(struct intsrc *arg) +{ + struct sb_intmap *map; + struct sb_intsrc *sb_isrc; + uint64_t isrc_bitmap; + register_t sr; + + isrc_bitmap = 0; + sb_isrc = (struct sb_intsrc *)arg; + + /* + * Make sure we disable the cpu interrupts when enabling the + * interrupt sources. + * + * This is to prevent a condition where some interrupt sources have + * been enabled (but not all) and one of those interrupt sources + * triggers an interrupt. + * + * If any of the interrupt handlers executes in an ithread then + * cpu_intr() will return with all interrupt sources feeding into + * that cpu irq masked. But when the loop below picks up where it + * left off it will enable the remaining interrupt sources!!! + * + * If the disable the cpu interrupts then this race does not happen. + */ + sr = intr_disable(); + + SLIST_FOREACH(map, &sb_isrc->sb_intmap_head, next) { + if (map->active == 0) + continue; + /* + * If we have already enabled this interrupt source then don't + * do it again. This can happen when multiple devices share + * an interrupt source (e.g. PCI_INT_x). + */ + if (isrc_bitmap & (1ULL << map->intsrc)) + continue; + sb_enable_intsrc(map->intsrc); + isrc_bitmap |= 1ULL << map->intsrc; + } + + intr_restore(sr); +} + +struct zbbus_devinfo { + struct resource_list resources; +}; + +static MALLOC_DEFINE(M_ZBBUSDEV, "zbbusdev", "zbbusdev"); + +static int +zbbus_probe(device_t dev) +{ + + device_set_desc(dev, "Broadcom/Sibyte ZBbus"); + return (0); +} + +static int +zbbus_attach(device_t dev) +{ + int i, error; + struct intsrc *isrc; + + if (bootverbose) { + device_printf(dev, "attached.\n"); + } + + for (i = 0; i < NUM_HARD_IRQS; ++i) { + isrc = &sb_intsrc[i].isrc; + isrc->intrnum = i; + isrc->mask_func = sb_mask_func; + isrc->unmask_func = sb_unmask_func; + error = cpu_register_hard_intsrc(isrc); + if (error) + panic("Error %d registering intsrc %d", error, i); + } + + bus_generic_probe(dev); + bus_enumerate_hinted_children(dev); + bus_generic_attach(dev); + + return (0); +} + +static void +zbbus_hinted_child(device_t bus, const char *dname, int dunit) +{ + device_t child; + long maddr, msize; + int err, irq; + + if (resource_disabled(dname, dunit)) + return; + + child = BUS_ADD_CHILD(bus, 0, dname, dunit); + if (child == NULL) { + panic("zbbus: could not add child %s unit %d\n", dname, dunit); + } + + if (bootverbose) + device_printf(bus, "Adding hinted child %s%d\n", dname, dunit); + + /* + * Assign any pre-defined resources to the child. + */ + if (resource_long_value(dname, dunit, "msize", &msize) == 0 && + resource_long_value(dname, dunit, "maddr", &maddr) == 0) { + if (bootverbose) { + device_printf(bus, "Assigning memory resource " + "0x%0lx/%ld to child %s%d\n", + maddr, msize, dname, dunit); + } + err = bus_set_resource(child, SYS_RES_MEMORY, 0, maddr, msize); + if (err) { + device_printf(bus, "Unable to set memory resource " + "0x%0lx/%ld for child %s%d: %d\n", + maddr, msize, dname, dunit, err); + } + } + + if (resource_int_value(dname, dunit, "irq", &irq) == 0) { + if (bootverbose) { + device_printf(bus, "Assigning irq resource %d to " + "child %s%d\n", irq, dname, dunit); + } + err = bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1); + if (err) { + device_printf(bus, "Unable to set irq resource %d" + "for child %s%d: %d\n", + irq, dname, dunit, err); + } + } +} + +static struct resource * +zbbus_alloc_resource(device_t bus, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + struct resource *res; + int intrnum, intsrc, isdefault; + struct resource_list *rl; + struct resource_list_entry *rle; + struct zbbus_devinfo *dinfo; + + isdefault = (start == 0UL && end == ~0UL && count == 1); + + /* + * Our direct child is asking for a default resource allocation. + */ + if (device_get_parent(child) == bus) { + dinfo = device_get_ivars(child); + rl = &dinfo->resources; + rle = resource_list_find(rl, type, *rid); + if (rle) { + if (rle->res) + panic("zbbus_alloc_resource: resource is busy"); + if (isdefault) { + start = rle->start; + count = ulmax(count, rle->count); + end = ulmax(rle->end, start + count - 1); + } + } else { + if (isdefault) { + /* + * Our child is requesting a default + * resource allocation but we don't have the + * 'type/rid' tuple in the resource list. + * + * We have to fail the resource allocation. + */ + return (NULL); + } else { + /* + * The child is requesting a non-default + * resource. We just pass the request up + * to our parent. If the resource allocation + * succeeds we will create a resource list + * entry corresponding to that resource. + */ + } + } + } else { + rl = NULL; + rle = NULL; + } + + /* + * nexus doesn't know about the interrupt mapper and only wants to + * see the hard irq numbers [0-6]. We translate from the interrupt + * source presented to the mapper to the interrupt number presented + * to the cpu. + */ + if ((count == 1) && (type == SYS_RES_IRQ)) { + intsrc = start; + intrnum = sb_route_intsrc(intsrc); + start = end = intrnum; + } else { + intsrc = -1; /* satisfy gcc */ + intrnum = -1; + } + + res = bus_generic_alloc_resource(bus, child, type, rid, + start, end, count, flags); + + /* + * Keep track of the input into the interrupt mapper that maps + * to the resource allocated by 'child' with resource id 'rid'. + * + * If we don't record the mapping here then we won't be able to + * locate the interrupt source when bus_setup_intr(child,rid) is + * called. + */ + if (res != NULL && intrnum != -1) + sb_intmap_add(intrnum, child, rman_get_rid(res), intsrc); + + /* + * If a non-default resource allocation by our child was successful + * then keep track of the resource in the resource list associated + * with the child. + */ + if (res != NULL && rle == NULL && device_get_parent(child) == bus) { + resource_list_add(rl, type, *rid, start, end, count); + rle = resource_list_find(rl, type, *rid); + if (rle == NULL) + panic("zbbus_alloc_resource: cannot find resource"); + } + + if (rle != NULL) { + KASSERT(device_get_parent(child) == bus, + ("rle should be NULL for passthru device")); + rle->res = res; + if (rle->res) { + rle->start = rman_get_start(rle->res); + rle->end = rman_get_end(rle->res); + rle->count = count; + } + } + + return (res); +} + +static int +zbbus_setup_intr(device_t dev, device_t child, struct resource *irq, int flags, + driver_filter_t *filter, driver_intr_t *intr, void *arg, + void **cookiep) +{ + int error; + + error = bus_generic_setup_intr(dev, child, irq, flags, + filter, intr, arg, cookiep); + if (error == 0) + sb_intmap_activate(rman_get_start(irq), child, + rman_get_rid(irq)); + + return (error); +} + +static device_t +zbbus_add_child(device_t bus, int order, const char *name, int unit) +{ + device_t child; + struct zbbus_devinfo *dinfo; + + child = device_add_child_ordered(bus, order, name, unit); + if (child != NULL) { + dinfo = malloc(sizeof(struct zbbus_devinfo), M_ZBBUSDEV, + M_WAITOK | M_ZERO); + resource_list_init(&dinfo->resources); + device_set_ivars(child, dinfo); + } + + return (child); +} + +static struct resource_list * +zbbus_get_resource_list(device_t dev, device_t child) +{ + struct zbbus_devinfo *dinfo = device_get_ivars(child); + + return (&dinfo->resources); +} + +static device_method_t zbbus_methods[] ={ + /* Device interface */ + DEVMETHOD(device_probe, zbbus_probe), + DEVMETHOD(device_attach, zbbus_attach), + DEVMETHOD(device_detach, bus_generic_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(device_suspend, bus_generic_suspend), + DEVMETHOD(device_resume, bus_generic_resume), + + /* Bus interface */ + DEVMETHOD(bus_alloc_resource, zbbus_alloc_resource), + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_release_resource, bus_generic_release_resource), + DEVMETHOD(bus_get_resource_list,zbbus_get_resource_list), + DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), + DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), + DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource), + DEVMETHOD(bus_setup_intr, zbbus_setup_intr), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + DEVMETHOD(bus_add_child, zbbus_add_child), + DEVMETHOD(bus_hinted_child, zbbus_hinted_child), + + { 0, 0 } +}; + +static driver_t zbbus_driver = { + "zbbus", + zbbus_methods +}; + +static devclass_t zbbus_devclass; + +DRIVER_MODULE(zbbus, nexus, zbbus_driver, zbbus_devclass, 0, 0); diff --git a/sys/mips/sibyte/sb_zbpci.c b/sys/mips/sibyte/sb_zbpci.c new file mode 100644 index 00000000000..6017aa5ff8c --- /dev/null +++ b/sys/mips/sibyte/sb_zbpci.c @@ -0,0 +1,283 @@ +/*- + * Copyright (c) 2009 Neelkanth Natu + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "pcib_if.h" + +#include "sb_scd.h" + +__FBSDID("$FreeBSD$"); + +static struct { + vm_offset_t vaddr; + vm_paddr_t paddr; +} zbpci_config_space[MAXCPU]; + +static const vm_paddr_t CFG_PADDR_BASE = 0xFE000000; + +static int +zbpci_probe(device_t dev) +{ + + device_set_desc(dev, "Broadcom/Sibyte PCI I/O Bridge"); + return (0); +} + +static int +zbpci_attach(device_t dev) +{ + int n, rid, size; + vm_offset_t va; + struct resource *res; + + /* + * Reserve the the physical memory that is used to read/write to the + * pci config space but don't activate it. We are using a page worth + * of KVA as a window over this region. + */ + rid = 0; + size = (PCI_BUSMAX + 1) * (PCI_SLOTMAX + 1) * (PCI_FUNCMAX + 1) * 256; + res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, CFG_PADDR_BASE, + CFG_PADDR_BASE + size - 1, size, 0); + if (res == NULL) { + panic("Cannot allocate resource for config space accesses."); + } + + /* + * Allocate KVA for accessing PCI config space. + */ + va = kmem_alloc_nofault(kernel_map, PAGE_SIZE * mp_ncpus); + if (va == 0) { + device_printf(dev, "Cannot allocate virtual addresses for " + "config space access.\n"); + return (ENOMEM); + } + + for (n = 0; n < mp_ncpus; ++n) { + zbpci_config_space[n].vaddr = va + n * PAGE_SIZE; + } + + /* + * Sibyte has the PCI bus hierarchy rooted at bus 0 and HT-PCI + * hierarchy rooted at bus 1. + */ + if (device_add_child(dev, "pci", 0) == NULL) { + panic("zbpci_attach: could not add pci bus 0.\n"); + } + + if (device_add_child(dev, "pci", 1) == NULL) { + panic("zbpci_attach: could not add pci bus 1.\n"); + } + + if (bootverbose) { + device_printf(dev, "attached.\n"); + } + + return (bus_generic_attach(dev)); +} + +static int +zbpci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) +{ + + switch (which) { + case PCIB_IVAR_DOMAIN: + *result = 0; /* single PCI domain */ + return (0); + case PCIB_IVAR_BUS: + *result = device_get_unit(child); /* PCI bus 0 or 1 */ + return (0); + default: + return (ENOENT); + } +} + +/* + * We rely on the CFE to have configured the intline correctly to point to + * one of PCI-A/PCI-B/PCI-C/PCI-D in the interupt mapper. + */ +static int +zbpci_route_interrupt(device_t pcib, device_t dev, int pin) +{ + + return (PCI_INVALID_IRQ); +} + +/* + * This function is expected to be called in a critical section since it + * changes the per-cpu pci config space va-to-pa mappings. + */ +static vm_offset_t +zbpci_config_space_va(int bus, int slot, int func, int reg, int bytes) +{ + int cpu; + vm_offset_t va_page; + vm_paddr_t pa, pa_page; + + if (bus <= PCI_BUSMAX && slot <= PCI_SLOTMAX && func <= PCI_FUNCMAX && + reg <= PCI_REGMAX && (bytes == 1 || bytes == 2 || bytes == 4) && + ((reg & (bytes - 1)) == 0)) { + cpu = PCPU_GET(cpuid); + va_page = zbpci_config_space[cpu].vaddr; + pa = CFG_PADDR_BASE | + (bus << 16) | (slot << 11) | (func << 8) | reg; + pa_page = pa & ~(PAGE_SIZE - 1); + if (zbpci_config_space[cpu].paddr != pa_page) { + pmap_kremove(va_page); + pmap_kenter(va_page, pa_page); + zbpci_config_space[cpu].paddr = pa_page; + } + return (va_page + (pa - pa_page)); + } else { + return (0); + } +} + +static uint32_t +zbpci_read_config(device_t dev, u_int b, u_int s, u_int f, u_int r, int w) +{ + uint32_t data; + vm_offset_t va; + + critical_enter(); + + va = zbpci_config_space_va(b, s, f, r, w); + if (va == 0) { + panic("zbpci_read_config: invalid %d/%d/%d[%d] %d\n", + b, s, f, r, w); + } + + switch (w) { + case 4: + data = *(uint32_t *)va; + break; + case 2: + data = *(uint16_t *)va; + break; + case 1: + data = *(uint8_t *)va; + break; + default: + panic("zbpci_read_config: invalid width %d\n", w); + } + + critical_exit(); + + return (data); +} + +static void +zbpci_write_config(device_t d, u_int b, u_int s, u_int f, u_int r, + uint32_t data, int w) +{ + vm_offset_t va; + + critical_enter(); + + va = zbpci_config_space_va(b, s, f, r, w); + if (va == 0) { + panic("zbpci_write_config: invalid %d/%d/%d[%d] %d/%d\n", + b, s, f, r, data, w); + } + + switch (w) { + case 4: + *(uint32_t *)va = data; + break; + case 2: + *(uint16_t *)va = data; + break; + case 1: + *(uint8_t *)va = data; + break; + default: + panic("zbpci_write_config: invalid width %d\n", w); + } + + critical_exit(); +} + +static device_method_t zbpci_methods[] ={ + /* Device interface */ + DEVMETHOD(device_probe, zbpci_probe), + DEVMETHOD(device_attach, zbpci_attach), + DEVMETHOD(device_detach, bus_generic_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(device_suspend, bus_generic_suspend), + DEVMETHOD(device_resume, bus_generic_resume), + + /* Bus interface */ + DEVMETHOD(bus_read_ivar, zbpci_read_ivar), + DEVMETHOD(bus_write_ivar, bus_generic_write_ivar), + DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_release_resource, bus_generic_release_resource), + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + DEVMETHOD(bus_add_child, bus_generic_add_child), + + /* pcib interface */ + DEVMETHOD(pcib_maxslots, pcib_maxslots), + DEVMETHOD(pcib_read_config, zbpci_read_config), + DEVMETHOD(pcib_write_config, zbpci_write_config), + DEVMETHOD(pcib_route_interrupt, zbpci_route_interrupt), + + { 0, 0 } +}; + +/* + * The "zbpci" class inherits from the "pcib" base class. Therefore in + * addition to drivers that belong to the "zbpci" class we will also + * consider drivers belonging to the "pcib" when probing children of + * "zbpci". + */ +DECLARE_CLASS(pcib_driver); +DEFINE_CLASS_1(zbpci, zbpci_driver, zbpci_methods, 0, pcib_driver); + +static devclass_t zbpci_devclass; + +DRIVER_MODULE(zbpci, zbbus, zbpci_driver, zbpci_devclass, 0, 0); From 561a3cc1a12582449133e92826c9409b23559bec Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 4 Jul 2009 03:22:34 +0000 Subject: [PATCH 151/380] Move from using the lame invalid address I chose when trying to get Octeon going... Turns out that you get tlb shutdowns with this... Use PGSHIFT instead of PAGE_SHIFT. Submitted by: Neelkanth Natu --- sys/mips/mips/swtch.S | 4 +--- sys/mips/mips/tlb.S | 42 ++++++++++++++++++++++++++++++------------ 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/sys/mips/mips/swtch.S b/sys/mips/mips/swtch.S index 7a016fa4e99..7b79ab0b178 100644 --- a/sys/mips/mips/swtch.S +++ b/sys/mips/mips/swtch.S @@ -81,14 +81,12 @@ #define _MFC0 dmfc0 #define _MTC0 dmtc0 #define WIRED_SHIFT 34 -#define PAGE_SHIFT 34 #else #define _SLL sll #define _SRL srl #define _MFC0 mfc0 #define _MTC0 mtc0 #define WIRED_SHIFT 2 -#define PAGE_SHIFT 2 #endif .set noreorder # Noreorder is default style! #if defined(ISA_MIPS32) @@ -366,7 +364,7 @@ entry0: nop pgm: bltz s0, entry0set - li t1, MIPS_KSEG0_START + 0x0fff0000 # invalidate tlb entry + li t1, MIPS_KSEG0_START # invalidate tlb entry sll s0, PAGE_SHIFT + 1 addu t1, s0 mtc0 t1, COP_0_TLB_HI diff --git a/sys/mips/mips/tlb.S b/sys/mips/mips/tlb.S index 28636b125e7..33f21266450 100644 --- a/sys/mips/mips/tlb.S +++ b/sys/mips/mips/tlb.S @@ -81,14 +81,12 @@ #define _MFC0 dmfc0 #define _MTC0 dmtc0 #define WIRED_SHIFT 34 -#define PAGE_SHIFT 34 #else #define _SLL sll #define _SRL srl #define _MFC0 mfc0 #define _MTC0 mtc0 #define WIRED_SHIFT 2 -#define PAGE_SHIFT 2 #endif .set noreorder # Noreorder is default style! #if defined(ISA_MIPS32) @@ -232,28 +230,38 @@ LEAF(Mips_TLBFlush) mtc0 zero, COP_0_STATUS_REG # Disable interrupts ITLBNOPFIX mfc0 t1, COP_0_TLB_WIRED - li v0, MIPS_KSEG3_START + 0x0fff0000 # invalid address _MFC0 t0, COP_0_TLB_HI # Save the PID - _MTC0 v0, COP_0_TLB_HI # Mark entry high as invalid _MTC0 zero, COP_0_TLB_LO0 # Zero out low entry0. _MTC0 zero, COP_0_TLB_LO1 # Zero out low entry1. mtc0 zero, COP_0_TLB_PG_MASK # Zero out mask entry. + # + # Load invalid entry, each TLB entry should have it's own bogus + # address calculated by following expression: + # MIPS_KSEG0_START + 2 * i * PAGE_SIZE; + # One bogus value for every TLB entry might cause MCHECK exception + # + sll t3, t1, PGSHIFT + 1 + li v0, MIPS_KSEG0_START # invalid address + addu v0, t3 /* * Align the starting value (t1) and the upper bound (a0). */ 1: mtc0 t1, COP_0_TLB_INDEX # Set the index register. ITLBNOPFIX - _MTC0 t0, COP_0_TLB_HI # Restore the PID +#xxx imp +# _MTC0 t0, COP_0_TLB_HI # Restore the PID + _MTC0 v0, COP_0_TLB_HI # Mark entry high as invalid addu t1, t1, 1 # Increment index. - addu t0, t0, 8 * 1024 +#xxx imp +# addu t0, t0, 8 * 1024 + addu v0, v0, 8 * 1024 MIPS_CPU_NOP_DELAY tlbwi # Write the TLB entry. MIPS_CPU_NOP_DELAY bne t1, a0, 1b nop - _MTC0 t0, COP_0_TLB_HI # Restore the PID mtc0 v1, COP_0_STATUS_REG # Restore the status register ITLBNOPFIX @@ -289,14 +297,14 @@ LEAF(Mips_TLBFlushAddr) tlbp # Probe for the entry. MIPS_CPU_NOP_DELAY mfc0 v0, COP_0_TLB_INDEX # See what we got - li t1, MIPS_KSEG0_START + 0x0fff0000 + li t1, MIPS_KSEG0_START bltz v0, 1f # index < 0 => !found nop # Load invalid entry, each TLB entry should have it's own bogus # address calculated by following expression: - # MIPS_KSEG0_START + 0x0fff0000 + 2 * i * PAGE_SIZE; + # MIPS_KSEG0_START + 2 * i * PAGE_SIZE; # One bogus value for every TLB entry might cause MCHECK exception - sll v0, PAGE_SHIFT + 1 + sll v0, PGSHIFT + 1 addu t1, v0 _MTC0 t1, COP_0_TLB_HI # Mark entry high as invalid @@ -473,7 +481,17 @@ LEAF(mips_TBIAP) _MFC0 t4, COP_0_TLB_HI # Get current PID move t2, a0 mfc0 t1, COP_0_TLB_WIRED - li v0, MIPS_KSEG0_START + 0x0fff0000 # invalid address + li v0, MIPS_KSEG0_START # invalid address + # + # Load invalid entry, each TLB entry should have it's own bogus + # address calculated by following expression: + # MIPS_KSEG0_START + 2 * i * PAGE_SIZE; + # One bogus value for every TLB entry might cause MCHECK exception + # + sll t3, t1, PGSHIFT + 1 + li v0, MIPS_KSEG0_START # invalid address + addu v0, t3 + mfc0 t3, COP_0_TLB_PG_MASK # save current pgMask # do {} while (t1 < t2) @@ -495,7 +513,7 @@ LEAF(mips_TBIAP) tlbwi # invalidate the TLB entry 2: addu t1, t1, 1 - addu v0, 1 << (PAGE_SHIFT + 1) + addu v0, 1 << (PGSHIFT + 1) bne t1, t2, 1b nop From 2c1c8bb345744df6d4c9e2a1b4a3f4f41787ac4d Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 06:39:37 +0000 Subject: [PATCH 152/380] Switch to ABI agnostic ta0-ta3. Provide defs for this in the right places. Provide n32/n64 register name defintions. This should have no effect for the O32 builds that everybody else uses, but should help make N64 builds possible (lots of other changes are needed for that). Obtained from: NetBSD (for the regdef.h changes) --- sys/mips/include/regdef.h | 33 +++++++++++++++++++++++++ sys/mips/include/regnum.h | 8 +++--- sys/mips/mips/exception.S | 52 +++++++++++++++++++-------------------- sys/mips/mips/swtch.S | 8 +++--- 4 files changed, 67 insertions(+), 34 deletions(-) diff --git a/sys/mips/include/regdef.h b/sys/mips/include/regdef.h index bb9eb3d9f81..7efdd95f7ac 100644 --- a/sys/mips/include/regdef.h +++ b/sys/mips/include/regdef.h @@ -12,6 +12,8 @@ #ifndef _MACHINE_REGDEF_H_ #define _MACHINE_REGDEF_H_ +#include /* For API selection */ + #if defined(__ASSEMBLER__) /* General purpose CPU register names */ #define zero $0 /* wired zero */ @@ -22,6 +24,16 @@ #define a1 $5 #define a2 $6 #define a3 $7 +#if defined(__mips_n32) || defined(__mips_n64) +#define a4 $8 +#define a5 $9 +#define a6 $10 +#define a7 $11 +#define t0 $12 /* Temp regs, not saved accross subroutine calls */ +#define t1 $13 +#define t2 $14 +#define t3 $15 +#else #define t0 $8 /* caller saved */ #define t1 $9 #define t2 $10 @@ -30,6 +42,7 @@ #define t5 $13 #define t6 $14 #define t7 $15 +#endif #define s0 $16 /* callee saved */ #define s1 $17 #define s2 $18 @@ -48,6 +61,26 @@ #define s8 $30 /* callee saved */ #define ra $31 /* return address */ +/* + * These are temp registers whose names can be used in either the old + * or new ABI, although they map to different physical registers. In + * the old ABI, they map to t4-t7, and in the new ABI, they map to a4-a7. + * + * Because they overlap with the last 4 arg regs in the new ABI, ta0-ta3 + * should be used only when we need more than t0-t3. + */ +#if defined(__mips_n32) || defined(__mips_n64) +#define ta0 $8 +#define ta1 $9 +#define ta2 $10 +#define ta3 $11 +#else +#define ta0 $12 +#define ta1 $13 +#define ta2 $14 +#define ta3 $15 +#endif /* __mips_n32 || __mips_n64 */ + #endif /* __ASSEMBLER__ */ #endif /* !_MACHINE_REGDEF_H_ */ diff --git a/sys/mips/include/regnum.h b/sys/mips/include/regnum.h index 1e3f2c875b9..6293e790730 100644 --- a/sys/mips/include/regnum.h +++ b/sys/mips/include/regnum.h @@ -82,10 +82,10 @@ #define T1 9 #define T2 10 #define T3 11 -#define T4 12 -#define T5 13 -#define T6 14 -#define T7 15 +#define TA0 12 +#define TA1 13 +#define TA2 14 +#define TA3 15 #define S0 16 #define S1 17 #define S2 18 diff --git a/sys/mips/mips/exception.S b/sys/mips/mips/exception.S index 29e263928ce..6223e80e129 100644 --- a/sys/mips/mips/exception.S +++ b/sys/mips/mips/exception.S @@ -272,7 +272,7 @@ SlowFault: and a0, a0, a2 ; \ mtc0 a0, COP_0_STATUS_REG #endif - + #define SAVE_CPU \ SAVE_REG(AT, AST, sp) ;\ .set at ; \ @@ -286,10 +286,10 @@ SlowFault: SAVE_REG(t1, T1, sp) ;\ SAVE_REG(t2, T2, sp) ;\ SAVE_REG(t3, T3, sp) ;\ - SAVE_REG(t4, T4, sp) ;\ - SAVE_REG(t5, T5, sp) ;\ - SAVE_REG(t6, T6, sp) ;\ - SAVE_REG(t7, T7, sp) ;\ + SAVE_REG(ta0, TA0, sp) ;\ + SAVE_REG(ta1, TA1, sp) ;\ + SAVE_REG(ta2, TA2, sp) ;\ + SAVE_REG(ta3, TA3, sp) ;\ SAVE_REG(t8, T8, sp) ;\ SAVE_REG(t9, T9, sp) ;\ SAVE_REG(gp, GP, sp) ;\ @@ -332,7 +332,7 @@ SlowFault: mtlo t0 ;\ mthi t1 ;\ _MTC0 v0, COP_0_EXC_PC ;\ - .set noat ; \ + .set noat ;\ RESTORE_REG(AT, AST, sp) ;\ RESTORE_REG(v0, V0, sp) ;\ RESTORE_REG(v1, V1, sp) ;\ @@ -344,10 +344,10 @@ SlowFault: RESTORE_REG(t1, T1, sp) ;\ RESTORE_REG(t2, T2, sp) ;\ RESTORE_REG(t3, T3, sp) ;\ - RESTORE_REG(t4, T4, sp) ;\ - RESTORE_REG(t5, T5, sp) ;\ - RESTORE_REG(t6, T6, sp) ;\ - RESTORE_REG(t7, T7, sp) ;\ + RESTORE_REG(ta0, TA0, sp) ;\ + RESTORE_REG(ta1, TA1, sp) ;\ + RESTORE_REG(ta2, TA2, sp) ;\ + RESTORE_REG(ta3, TA3, sp) ;\ RESTORE_REG(t8, T8, sp) ;\ RESTORE_REG(t9, T9, sp) ;\ RESTORE_REG(s0, S0, sp) ;\ @@ -451,11 +451,11 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra) SAVE_U_PCB_REG(t1, T1, k1) SAVE_U_PCB_REG(t2, T2, k1) SAVE_U_PCB_REG(t3, T3, k1) - SAVE_U_PCB_REG(t4, T4, k1) + SAVE_U_PCB_REG(ta0, TA0, k1) mfc0 a0, COP_0_STATUS_REG # First arg is the status reg. - SAVE_U_PCB_REG(t5, T5, k1) - SAVE_U_PCB_REG(t6, T6, k1) - SAVE_U_PCB_REG(t7, T7, k1) + SAVE_U_PCB_REG(ta1, TA1, k1) + SAVE_U_PCB_REG(ta2, TA2, k1) + SAVE_U_PCB_REG(ta3, TA3, k1) SAVE_U_PCB_REG(s0, S0, k1) mfc0 a1, COP_0_CAUSE_REG # Second arg is the cause reg. SAVE_U_PCB_REG(s1, S1, k1) @@ -548,10 +548,10 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra) RESTORE_U_PCB_REG(t1, T1, k1) RESTORE_U_PCB_REG(t2, T2, k1) RESTORE_U_PCB_REG(t3, T3, k1) - RESTORE_U_PCB_REG(t4, T4, k1) - RESTORE_U_PCB_REG(t5, T5, k1) - RESTORE_U_PCB_REG(t6, T6, k1) - RESTORE_U_PCB_REG(t7, T7, k1) + RESTORE_U_PCB_REG(ta0, TA0, k1) + RESTORE_U_PCB_REG(ta1, TA1, k1) + RESTORE_U_PCB_REG(ta2, TA2, k1) + RESTORE_U_PCB_REG(ta3, TA3, k1) RESTORE_U_PCB_REG(s0, S0, k1) RESTORE_U_PCB_REG(s1, S1, k1) RESTORE_U_PCB_REG(s2, S2, k1) @@ -684,10 +684,10 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra) SAVE_U_PCB_REG(t1, T1, k1) SAVE_U_PCB_REG(t2, T2, k1) SAVE_U_PCB_REG(t3, T3, k1) - SAVE_U_PCB_REG(t4, T4, k1) - SAVE_U_PCB_REG(t5, T5, k1) - SAVE_U_PCB_REG(t6, T6, k1) - SAVE_U_PCB_REG(t7, T7, k1) + SAVE_U_PCB_REG(ta0, TA0, k1) + SAVE_U_PCB_REG(ta1, TA1, k1) + SAVE_U_PCB_REG(ta2, TA2, k1) + SAVE_U_PCB_REG(ta3, TA3, k1) SAVE_U_PCB_REG(t8, T8, k1) SAVE_U_PCB_REG(t9, T9, k1) SAVE_U_PCB_REG(gp, GP, k1) @@ -790,10 +790,10 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra) RESTORE_U_PCB_REG(t1, T1, k1) RESTORE_U_PCB_REG(t2, T2, k1) RESTORE_U_PCB_REG(t3, T3, k1) - RESTORE_U_PCB_REG(t4, T4, k1) - RESTORE_U_PCB_REG(t5, T5, k1) - RESTORE_U_PCB_REG(t6, T6, k1) - RESTORE_U_PCB_REG(t7, T7, k1) + RESTORE_U_PCB_REG(ta0, TA0, k1) + RESTORE_U_PCB_REG(ta1, TA1, k1) + RESTORE_U_PCB_REG(ta2, TA2, k1) + RESTORE_U_PCB_REG(ta3, TA3, k1) RESTORE_U_PCB_REG(t8, T8, k1) RESTORE_U_PCB_REG(t9, T9, k1) RESTORE_U_PCB_REG(gp, GP, k1) diff --git a/sys/mips/mips/swtch.S b/sys/mips/mips/swtch.S index 7b79ab0b178..d07ab2c1249 100644 --- a/sys/mips/mips/swtch.S +++ b/sys/mips/mips/swtch.S @@ -203,10 +203,10 @@ LEAF(fork_trampoline) RESTORE_U_PCB_REG(t1, T1, k1) RESTORE_U_PCB_REG(t2, T2, k1) RESTORE_U_PCB_REG(t3, T3, k1) - RESTORE_U_PCB_REG(t4, T4, k1) - RESTORE_U_PCB_REG(t5, T5, k1) - RESTORE_U_PCB_REG(t6, T6, k1) - RESTORE_U_PCB_REG(t7, T7, k1) + RESTORE_U_PCB_REG(ta0, TA0, k1) + RESTORE_U_PCB_REG(ta1, TA1, k1) + RESTORE_U_PCB_REG(ta2, TA2, k1) + RESTORE_U_PCB_REG(ta3, TA3, k1) RESTORE_U_PCB_REG(s0, S0, k1) RESTORE_U_PCB_REG(s1, S1, k1) RESTORE_U_PCB_REG(s2, S2, k1) From 6855d90580229dcf01d9258558fed15065826533 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 06:43:01 +0000 Subject: [PATCH 153/380] Define COP0_SYNC for SB1 CPU. Submitted by: Neelkanth Natu --- sys/mips/include/cpuregs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/mips/include/cpuregs.h b/sys/mips/include/cpuregs.h index e590c9de4fe..036ee896ac9 100644 --- a/sys/mips/include/cpuregs.h +++ b/sys/mips/include/cpuregs.h @@ -103,6 +103,8 @@ /* CPU dependent mtc0 hazard hook */ #ifdef TARGET_OCTEON #define COP0_SYNC nop; nop; nop; nop; nop; +#elif defined(CPU_SB1) +#define COP0_SYNC ssnop; ssnop; ssnop; ssnop; ssnop; ssnop; ssnop; ssnop; ssnop #else #define COP0_SYNC /* nothing */ #endif From 4ecfc54d9d519abd73168ccf687face27575ea22 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 06:44:37 +0000 Subject: [PATCH 154/380] db_expr_t should be a intptr_t, not an int. These expressions can be addresses or numbers, and that's a intptr_t if I ever saw one. --- sys/mips/include/db_machdep.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/include/db_machdep.h b/sys/mips/include/db_machdep.h index 989f05c61af..77700c15af6 100644 --- a/sys/mips/include/db_machdep.h +++ b/sys/mips/include/db_machdep.h @@ -46,7 +46,7 @@ typedef struct trapframe db_regs_t; extern db_regs_t ddb_regs; /* register state */ typedef vm_offset_t db_addr_t; /* address - unsigned */ -typedef int db_expr_t; /* expression - signed */ +typedef intptr_t db_expr_t; /* expression - signed */ #if BYTE_ORDER == _BIG_ENDIAN #define BYTE_MSF (1) From bca296cba8b4b87093960ba9c80fccdaf52365ac Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 06:46:54 +0000 Subject: [PATCH 155/380] Publish PAGE_SHIFT to assembler # we should likely phase out PGSHIFT Submitted by: Neelkanth Natu --- sys/mips/mips/genassym.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/mips/mips/genassym.c b/sys/mips/mips/genassym.c index 2912ab10c62..ce95cc6b60e 100644 --- a/sys/mips/mips/genassym.c +++ b/sys/mips/mips/genassym.c @@ -91,6 +91,7 @@ ASSYM(VM_MAXUSER_ADDRESS, VM_MAXUSER_ADDRESS); ASSYM(VM_KERNEL_ALLOC_OFFSET, VM_KERNEL_ALLOC_OFFSET); ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc)); ASSYM(SIGFPE, SIGFPE); +ASSYM(PAGE_SHIFT, PAGE_SHIFT); ASSYM(PGSHIFT, PGSHIFT); ASSYM(NBPG, NBPG); ASSYM(SEGSHIFT, SEGSHIFT); From 220d1e7fb0590fa929740758b3d581af0dd2d965 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 06:49:56 +0000 Subject: [PATCH 156/380] Go for broke: configure this to build mips64 N64 binary. --- sys/mips/conf/OCTEON1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/mips/conf/OCTEON1 b/sys/mips/conf/OCTEON1 index 4d96e5b28b2..40536642c7c 100644 --- a/sys/mips/conf/OCTEON1 +++ b/sys/mips/conf/OCTEON1 @@ -21,7 +21,7 @@ machine mips cpu CPU_MIPS4KC ident OCTEON1 -#makeoptions ARCH_FLAGS=-march=mips32 +makeoptions ARCH_FLAGS="-march=mips64 -mabi=64" # Don't build any modules yet. makeoptions MODULES_OVERRIDE="" @@ -35,7 +35,7 @@ hints "OCTEON1.hints" #Default places to look for devices. makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols #XXXimp: Need to make work with 64-bit too -options ISA_MIPS32 +options ISA_MIPS64 options DDB options KDB From 64003afe2e8a3d32acf778c9ab9efa2ee7a701b5 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 06:56:51 +0000 Subject: [PATCH 157/380] (1) Use uintptr_t in preference to unsigned. The latter isn't right for 64-bit case, while the former is. (2) include a SB1 specific coherency mapping Submitted by: Neelkanth Nath (2) --- sys/mips/include/cpu.h | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/sys/mips/include/cpu.h b/sys/mips/include/cpu.h index 11b81df381b..3e939a04d7c 100644 --- a/sys/mips/include/cpu.h +++ b/sys/mips/include/cpu.h @@ -56,21 +56,21 @@ #define MIPS_RESERVED_ADDR 0xbfc80000 #define MIPS_KSEG0_LARGEST_PHYS 0x20000000 -#define MIPS_CACHED_TO_PHYS(x) ((unsigned)(x) & 0x1fffffff) -#define MIPS_PHYS_TO_CACHED(x) ((unsigned)(x) | MIPS_CACHED_MEMORY_ADDR) -#define MIPS_UNCACHED_TO_PHYS(x) ((unsigned)(x) & 0x1fffffff) -#define MIPS_PHYS_TO_UNCACHED(x) ((unsigned)(x) | MIPS_UNCACHED_MEMORY_ADDR) +#define MIPS_CACHED_TO_PHYS(x) ((uintptr_t)(x) & 0x1fffffff) +#define MIPS_PHYS_TO_CACHED(x) ((uintptr_t)(x) | MIPS_CACHED_MEMORY_ADDR) +#define MIPS_UNCACHED_TO_PHYS(x) ((uintptr_t)(x) & 0x1fffffff) +#define MIPS_PHYS_TO_UNCACHED(x) ((uintptr_t)(x) | MIPS_UNCACHED_MEMORY_ADDR) #define MIPS_PHYS_MASK (0x1fffffff) #define MIPS_PA_2_K1VA(x) (MIPS_KSEG1_START | ((x) & MIPS_PHYS_MASK)) -#define MIPS_VA_TO_CINDEX(x) ((unsigned)(x) & 0xffffff | MIPS_CACHED_MEMORY_ADDR) +#define MIPS_VA_TO_CINDEX(x) ((uintptr_t)(x) & 0xffffff | MIPS_CACHED_MEMORY_ADDR) #define MIPS_CACHED_TO_UNCACHED(x) (MIPS_PHYS_TO_UNCACHED(MIPS_CACHED_TO_PHYS(x))) -#define MIPS_PHYS_TO_KSEG0(x) ((unsigned)(x) | MIPS_KSEG0_START) -#define MIPS_PHYS_TO_KSEG1(x) ((unsigned)(x) | MIPS_KSEG1_START) -#define MIPS_KSEG0_TO_PHYS(x) ((unsigned)(x) & MIPS_PHYS_MASK) -#define MIPS_KSEG1_TO_PHYS(x) ((unsigned)(x) & MIPS_PHYS_MASK) +#define MIPS_PHYS_TO_KSEG0(x) ((uintptr_t)(x) | MIPS_KSEG0_START) +#define MIPS_PHYS_TO_KSEG1(x) ((uintptr_t)(x) | MIPS_KSEG1_START) +#define MIPS_KSEG0_TO_PHYS(x) ((uintptr_t)(x) & MIPS_PHYS_MASK) +#define MIPS_KSEG1_TO_PHYS(x) ((uintptr_t)(x) & MIPS_PHYS_MASK) #define MIPS_IS_KSEG0_ADDR(x) \ (((vm_offset_t)(x) >= MIPS_KSEG0_START) && \ @@ -163,7 +163,11 @@ * The bits in the CONFIG register */ #define CFG_K0_UNCACHED 2 +#if defined(CPU_SB1) +#define CFG_K0_COHERENT 5 /* cacheable coherent */ +#else #define CFG_K0_CACHED 3 +#endif /* * The bits in the context register. From da96ff5daee95d2a2a25ea13c97dc5b95983b41a Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 07:00:51 +0000 Subject: [PATCH 158/380] Define __ELF_WORD_SIZE appropriately for n64. Note for N32 I believe this is correct. While registers are 64-bit, n32 is a 32-bit ABI and lives in a 32-bit world (with explicit 64-bit registers, however). Change an 8, which was 4 + 4 or sizeof(int) + SZREG to be a simple '4 + SZREG' to reflect the actual offset of the structure in question. --- sys/mips/include/elf.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/mips/include/elf.h b/sys/mips/include/elf.h index 3a31daa0bd1..90662e1d97d 100644 --- a/sys/mips/include/elf.h +++ b/sys/mips/include/elf.h @@ -41,8 +41,12 @@ /* Information taken from MIPS ABI supplemental */ #ifndef __ELF_WORD_SIZE +#if defined(__mips_n64) +#define __ELF_WORD_SIZE 64 /* Used by */ +#else #define __ELF_WORD_SIZE 32 /* Used by */ #endif +#endif #include /* Definitions common to all 32 bit architectures. */ #include /* Definitions common to all 64 bit architectures. */ #include From f5470730889a6f73db5ee5911e843f6e7ccf1cc9 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 07:01:34 +0000 Subject: [PATCH 159/380] Use uintptr_t rather than unsigned here for 64-bit correctness. --- sys/mips/include/param.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sys/mips/include/param.h b/sys/mips/include/param.h index ea599d11f5e..49a74f58af9 100644 --- a/sys/mips/include/param.h +++ b/sys/mips/include/param.h @@ -146,12 +146,13 @@ /* * Conversion macros */ -#define mips_round_page(x) ((((unsigned)(x)) + NBPG - 1) & ~(NBPG-1)) -#define mips_trunc_page(x) ((unsigned)(x) & ~(NBPG-1)) -#define mips_btop(x) ((unsigned)(x) >> PGSHIFT) -#define mips_ptob(x) ((unsigned)(x) << PGSHIFT) +#define mips_round_page(x) ((((uintptr_t)(x)) + NBPG - 1) & ~(NBPG-1)) +#define mips_trunc_page(x) ((uintptr_t)(x) & ~(NBPG-1)) +#define mips_btop(x) ((uintptr_t)(x) >> PGSHIFT) +#define mips_ptob(x) ((uintptr_t)(x) << PGSHIFT) #define round_page mips_round_page #define trunc_page mips_trunc_page +/* XXXimp: Is unsigned long the right cast type here? PA can be > 32bits */ #define atop(x) ((unsigned long)(x) >> PAGE_SHIFT) #define ptoa(x) ((unsigned long)(x) << PAGE_SHIFT) From 0d978536b2964361d51a053287b98df38a6835ff Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 08:13:19 +0000 Subject: [PATCH 160/380] Pull in machine/cdefs.h for the ABI definitions. Provide a PTR_LA, ala sgi, and use it in preference to a bare 'la' so that it gets translated to a 'dla' for the 64-bit pointer ABIs. --- sys/mips/include/asm.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/sys/mips/include/asm.h b/sys/mips/include/asm.h index 56ea37b0ec8..6b8e515a80e 100644 --- a/sys/mips/include/asm.h +++ b/sys/mips/include/asm.h @@ -60,6 +60,7 @@ #include #endif #include +#include #undef __FBSDID #if !defined(lint) && !defined(STRIP_FBSDID) @@ -281,7 +282,7 @@ _C_LABEL(x): * Macros to panic and printf from assembly language. */ #define PANIC(msg) \ - la a0, 9f; \ + PTR_LA a0, 9f; \ jal _C_LABEL(panic); \ nop; \ MSG(msg) @@ -289,7 +290,7 @@ _C_LABEL(x): #define PANIC_KSEG0(msg, reg) PANIC(msg) #define PRINTF(msg) \ - la a0, 9f; \ + PTR_LA a0, 9f; \ jal _C_LABEL(printf); \ nop; \ MSG(msg) @@ -308,7 +309,7 @@ _C_LABEL(x): */ #define DO_AST \ 44: \ - la s0, _C_LABEL(disableintr) ;\ + PTR_LA s0, _C_LABEL(disableintr) ;\ jalr s0 ;\ nop ;\ move a0, v0 ;\ @@ -318,12 +319,12 @@ _C_LABEL(x): lw s2, TD_FLAGS(s1) ;\ li s0, TDF_ASTPENDING | TDF_NEEDRESCHED;\ and s2, s0 ;\ - la s0, _C_LABEL(restoreintr) ;\ + PTR_LA s0, _C_LABEL(restoreintr) ;\ jalr s0 ;\ nop ;\ beq s2, zero, 4f ;\ nop ;\ - la s0, _C_LABEL(ast) ;\ + PTR_LA s0, _C_LABEL(ast) ;\ jalr s0 ;\ addu a0, s3, U_PCB_REGS ;\ j 44b ;\ @@ -362,12 +363,14 @@ _C_LABEL(x): */ #if !defined(_MIPS_BSD_API) || _MIPS_BSD_API == _MIPS_BSD_API_LP32 +/* #if !defined(__mips_n64) */ #define REG_L lw #define REG_S sw #define REG_LI li #define REG_PROLOGUE .set push #define REG_EPILOGUE .set pop #define SZREG 4 +#define PTR_LA la #else #define REG_L ld #define REG_S sd @@ -375,6 +378,7 @@ _C_LABEL(x): #define REG_PROLOGUE .set push ; .set mips3 #define REG_EPILOGUE .set pop #define SZREG 8 +#define PTR_LA dla #endif /* _MIPS_BSD_API */ #define mfc0_macro(data, spr) \ From 24646e120ce04183af62ec7b947979e105b8d926 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 08:14:00 +0000 Subject: [PATCH 161/380] Bring in cdefs.h from NetBSD to define ABI goo. Obtained from: NetBSD --- sys/mips/include/cdefs.h | 54 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 sys/mips/include/cdefs.h diff --git a/sys/mips/include/cdefs.h b/sys/mips/include/cdefs.h new file mode 100644 index 00000000000..c45cefd54cb --- /dev/null +++ b/sys/mips/include/cdefs.h @@ -0,0 +1,54 @@ +/* $NetBSD: cdefs.h,v 1.12 2006/08/27 19:04:30 matt Exp $ */ + +/* + * Copyright (c) 1995 Carnegie-Mellon University. + * All rights reserved. + * + * Author: Chris G. Demetriou + * + * Permission to use, copy, modify and distribute this software and + * its documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND + * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ + +#ifndef _MIPS_CDEFS_H_ +#define _MIPS_CDEFS_H_ + +/* MIPS Subprogram Interface Model */ +#define _MIPS_SIM_ABIX32 4 /* 64 bit safe, ILP32 o32 model */ +#define _MIPS_SIM_ABI64 3 +#define _MIPS_SIM_NABI32 2 /* 64bit safe, ILP32 n32 model */ +#define _MIPS_SIM_ABI32 1 + +#define _MIPS_BSD_API_LP32 _MIPS_SIM_ABI32 +#define _MIPS_BSD_API_LP32_64CLEAN _MIPS_SIM_ABIX32 +#define _MIPS_BSD_API_N32 _MIPS_SIM_NABI32 +#define _MIPS_BSD_API_LP64 _MIPS_SIM_ABI64 + +#if defined(__mips_n64) +#define _MIPS_BSD_API _MIPS_BSD_API_LP64 +#elif defined(__mips_n32) +#define _MIPS_BSD_API _MIPS_BSD_API_N32 +#elif defined(__mips_o64) +#define _MIPS_BSD_API _MIPS_BSD_API_LP32_64CLEAN +#else +#define _MIPS_BSD_API _MIPS_BSD_API_LP32 +#endif + +#endif /* !_MIPS_CDEFS_H_ */ From 2d3c40cf498bd4330d286ca70886d3538ed24326 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 08:40:26 +0000 Subject: [PATCH 162/380] Add config file for SWARM board, a sybyte SB-1-based board by Broadcom. BCM-91250. Submitted by: Neelkanth Natu --- sys/mips/conf/SWARM | 82 +++++++++++++++++++++++++++++++++++++++ sys/mips/conf/SWARM.hints | 17 ++++++++ 2 files changed, 99 insertions(+) create mode 100644 sys/mips/conf/SWARM create mode 100644 sys/mips/conf/SWARM.hints diff --git a/sys/mips/conf/SWARM b/sys/mips/conf/SWARM new file mode 100644 index 00000000000..bd395d8fe2f --- /dev/null +++ b/sys/mips/conf/SWARM @@ -0,0 +1,82 @@ +# +# $Id: //depot/user/neelnatu/freebsd_sibyte/src/sys/mips/conf/SWARM#7 $ +# + +ident SWARM +options CPU_NOFPU +options CPU_SB1 + +files "../sibyte/files.sibyte" +hints "SWARM.hints" + +options PCI_IOSPACE_ADDR=0xFC000000 +options PCI_IOSPACE_SIZE=0x02000000 + +# +# 32-bit kernel cannot deal with physical memory beyond 4GB +# +options MAXMEM=4096*1024 + +options CFE +options CFE_CONSOLE +options CFE_ENV +options ALT_BREAK_TO_DEBUGGER + +# cfe loader expects kernel at 0x80001000 for mips32 w/o backwards +# offsets in the linked elf image (see ldscript hack) +# XXX can we conditionalize the linker stuff on options CFE? +options KERNVIRTADDR=0x80001000 + +makeoptions LDSCRIPT_NAME= ldscript.mips.cfe + +#cpu CPU_MIPS64 +#options ISA_MIPS64 +#makeoptions ARCH_FLAGS="-march=mips64 -mgp64 -mabi=o64" +cpu CPU_MIPS32 +options ISA_MIPS32 +makeoptions ARCH_FLAGS="-march=mips32" + +makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols +makeoptions MODULES_OVERRIDE="" + +options DDB +options KDB + +options SCHED_4BSD #4BSD scheduler +options INET #InterNETworking +options NFSCLIENT #Network Filesystem Client +options NFS_ROOT #NFS usable as /, requires NFSCLIENT +options PSEUDOFS #Pseudo-filesystem framework +options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions + +# Debugging for use in -current +options INVARIANTS +options INVARIANT_SUPPORT +options WITNESS + +options MD_ROOT +options MD_ROOT_SIZE=4096 +options FFS #Fast filesystem + +device pci +device miibus +device bge +device loop +device ether +device md + +options USB_DEBUG +device usb +device ohci +device uhci +device ehci + +device umass + +device scbus +device da + +device ata +device atadisk +device atapicd +options ATA_STATIC_ID diff --git a/sys/mips/conf/SWARM.hints b/sys/mips/conf/SWARM.hints new file mode 100644 index 00000000000..00465ad41be --- /dev/null +++ b/sys/mips/conf/SWARM.hints @@ -0,0 +1,17 @@ +# $FreeBSD$ +hint.zbbus.0.at="nexus0" +hint.zbpci.0.at="zbbus0" +hint.scd.0.at="zbbus0" + +# +# SWARM IDE interface is on the generic bus at chip select 4. +# The CS4 region is 64KB in size and starts at 0x100B0000. +# The IDE interrupt is wired to GPIO4 (intsrc 36 to the interrupt mapper) +# +hint.ata.0.at="zbbus0" +hint.ata.0.maddr=0x100B0000 +hint.ata.0.msize=0x10000 +hint.ata.0.irq=36 +#hint.ata.0.disabled=0 +#hint.ata.0.regoffset=0x1F0 +#hint.ata.0.regshift=5 From 753b803f71fa6e9376fa6882a800e63774deeccc Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 15:10:07 +0000 Subject: [PATCH 163/380] use %p in preference to 0x%08x for printing register_t values. Cast them to void * first. This neatly solves the "how do I print a register_t" problem because sizeof(void *) is always the same as sizeof(register_t), afaik. --- sys/mips/mips/trap.c | 113 ++++++++++++++++++++++--------------------- 1 file changed, 57 insertions(+), 56 deletions(-) diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c index 0e0fa35a336..76a1371ac08 100644 --- a/sys/mips/mips/trap.c +++ b/sys/mips/mips/trap.c @@ -364,7 +364,7 @@ trap(trapframe) printf("cpuid = %d\n", PCPU_GET(cpuid)); #endif MachTLBGetPID(pid); - printf("badaddr = %p, pc = %p, ra = %p, sp = %p, sr = 0x%x, pid = %d, ASID = 0x%x\n", + printf("badaddr = 0x%0x, pc = 0x%0x, ra = 0x%0x, sp = 0x%0x, sr = 0x%x, pid = %d, ASID = 0x%x\n", trapframe->badvaddr, trapframe->pc, trapframe->ra, trapframe->sp, trapframe->sr, (curproc ? curproc->p_pid : -1), pid); @@ -388,7 +388,7 @@ trap(trapframe) ((type & ~T_USER) != T_SYSCALL)) { if (++count == 3) { trap_frame_dump(trapframe); - panic("too many faults at %p\n", last_badvaddr); + panic("too many faults at %x\n", last_badvaddr); } } else { last_badvaddr = this_badvaddr; @@ -569,7 +569,7 @@ dofault: --p->p_lock; PROC_UNLOCK(p); #ifdef VMFAULT_TRACE - printf("vm_fault(%x (pmap %x), %x (%x), %x, %d) -> %x at pc %x\n", + printf("vm_fault(%p (pmap %p), %x (%x), %x, %d) -> %x at pc %x\n", map, &vm->vm_pmap, va, trapframe->badvaddr, ftype, flag, rv, trapframe->pc); #endif @@ -1538,39 +1538,39 @@ static void log_frame_dump(struct trapframe *frame) { log(LOG_ERR, "Trapframe Register Dump:\n"); - log(LOG_ERR, "\tzero: %08x\tat: %08x\tv0: %08x\tv1: %08x\n", - 0, frame->ast, frame->v0, frame->v1); + log(LOG_ERR, "\tzero: %p\tat: %p\tv0: %p\tv1: %p\n", + (void *)0, (void *)frame->ast, (void *)frame->v0, (void *)frame->v1); - log(LOG_ERR, "\ta0: %08x\ta1: %08x\ta2: %08x\ta3: %08x\n", - frame->a0, frame->a1, frame->a2, frame->a3); + log(LOG_ERR, "\ta0: %p\ta1: %p\ta2: %p\ta3: %p\n", + (void *)frame->a0, (void *)frame->a1, (void *)frame->a2, (void *)frame->a3); - log(LOG_ERR, "\tt0: %08x\tt1: %08x\tt2: %08x\tt3: %08x\n", - frame->t0, frame->t1, frame->t2, frame->t3); + log(LOG_ERR, "\tt0: %p\tt1: %p\tt2: %p\tt3: %p\n", + (void *)frame->t0, (void *)frame->t1, (void *)frame->t2, (void *)frame->t3); - log(LOG_ERR, "\tt4: %08x\tt5: %08x\tt6: %08x\tt7: %08x\n", - frame->t4, frame->t5, frame->t6, frame->t7); + log(LOG_ERR, "\tt4: %p\tt5: %p\tt6: %p\tt7: %p\n", + (void *)frame->t4, (void *)frame->t5, (void *)frame->t6, (void *)frame->t7); - log(LOG_ERR, "\tt8: %08x\tt9: %08x\ts0: %08x\ts1: %08x\n", - frame->t8, frame->t9, frame->s0, frame->s1); + log(LOG_ERR, "\tt8: %p\tt9: %p\ts0: %p\ts1: %p\n", + (void *)frame->t8, (void *)frame->t9, (void *)frame->s0, (void *)frame->s1); - log(LOG_ERR, "\ts2: %08x\ts3: %08x\ts4: %08x\ts5: %08x\n", - frame->s2, frame->s3, frame->s4, frame->s5); + log(LOG_ERR, "\ts2: %p\ts3: %p\ts4: %p\ts5: %p\n", + (void *)frame->s2, (void *)frame->s3, (void *)frame->s4, (void *)frame->s5); - log(LOG_ERR, "\ts6: %08x\ts7: %08x\tk0: %08x\tk1: %08x\n", - frame->s6, frame->s7, frame->k0, frame->k1); + log(LOG_ERR, "\ts6: %p\ts7: %p\tk0: %p\tk1: %p\n", + (void *)frame->s6, (void *)frame->s7, (void *)frame->k0, (void *)frame->k1); - log(LOG_ERR, "\tgp: %08x\tsp: %08x\ts8: %08x\tra: %08x\n", - frame->gp, frame->sp, frame->s8, frame->ra); + log(LOG_ERR, "\tgp: %p\tsp: %p\ts8: %p\tra: %p\n", + (void *)frame->gp, (void *)frame->sp, (void *)frame->s8, (void *)frame->ra); - log(LOG_ERR, "\tsr: %08x\tmullo: %08x\tmulhi: %08x\tbadvaddr: %08x\n", - frame->sr, frame->mullo, frame->mulhi, frame->badvaddr); + log(LOG_ERR, "\tsr: %p\tmullo: %p\tmulhi: %p\tbadvaddr: %p\n", + (void *)frame->sr, (void *)frame->mullo, (void *)frame->mulhi, (void *)frame->badvaddr); #ifdef IC_REG - log(LOG_ERR, "\tcause: %08x\tpc: %08x\tic: %08x\n", - frame->cause, frame->pc, frame->ic); + log(LOG_ERR, "\tcause: %p\tpc: %p\tic: %p\n", + (void *)frame->cause, (void *)frame->pc, (void *)frame->ic); #else - log(LOG_ERR, "\tcause: %08x\tpc: %08x\n", - frame->cause, frame->pc); + log(LOG_ERR, "\tcause: %p\tpc: %p\n", + (void *)frame->cause, (void *)frame->pc); #endif } @@ -1579,39 +1579,39 @@ static void trap_frame_dump(struct trapframe *frame) { printf("Trapframe Register Dump:\n"); - printf("\tzero: %08x\tat: %08x\tv0: %08x\tv1: %08x\n", - 0, frame->ast, frame->v0, frame->v1); + printf("\tzero: %p\tat: %p\tv0: %p\tv1: %p\n", + (void *)0, (void *)frame->ast, (void *)frame->v0, (void *)frame->v1); - printf("\ta0: %08x\ta1: %08x\ta2: %08x\ta3: %08x\n", - frame->a0, frame->a1, frame->a2, frame->a3); + printf("\ta0: %p\ta1: %p\ta2: %p\ta3: %p\n", + (void *)frame->a0, (void *)frame->a1, (void *)frame->a2, (void *)frame->a3); - printf("\tt0: %08x\tt1: %08x\tt2: %08x\tt3: %08x\n", - frame->t0, frame->t1, frame->t2, frame->t3); + printf("\tt0: %p\tt1: %p\tt2: %p\tt3: %p\n", + (void *)frame->t0, (void *)frame->t1, (void *)frame->t2, (void *)frame->t3); - printf("\tt4: %08x\tt5: %08x\tt6: %08x\tt7: %08x\n", - frame->t4, frame->t5, frame->t6, frame->t7); + printf("\tt4: %p\tt5: %p\tt6: %p\tt7: %p\n", + (void *)frame->t4, (void *)frame->t5, (void *)frame->t6, (void *)frame->t7); - printf("\tt8: %08x\tt9: %08x\ts0: %08x\ts1: %08x\n", - frame->t8, frame->t9, frame->s0, frame->s1); + printf("\tt8: %p\tt9: %p\ts0: %p\ts1: %p\n", + (void *)frame->t8, (void *)frame->t9, (void *)frame->s0, (void *)frame->s1); - printf("\ts2: %08x\ts3: %08x\ts4: %08x\ts5: %08x\n", - frame->s2, frame->s3, frame->s4, frame->s5); + printf("\ts2: %p\ts3: %p\ts4: %p\ts5: %p\n", + (void *)frame->s2, (void *)frame->s3, (void *)frame->s4, (void *)frame->s5); - printf("\ts6: %08x\ts7: %08x\tk0: %08x\tk1: %08x\n", - frame->s6, frame->s7, frame->k0, frame->k1); + printf("\ts6: %p\ts7: %p\tk0: %p\tk1: %p\n", + (void *)frame->s6, (void *)frame->s7, (void *)frame->k0, (void *)frame->k1); - printf("\tgp: %08x\tsp: %08x\ts8: %08x\tra: %08x\n", - frame->gp, frame->sp, frame->s8, frame->ra); + printf("\tgp: %p\tsp: %p\ts8: %p\tra: %p\n", + (void *)frame->gp, (void *)frame->sp, (void *)frame->s8, (void *)frame->ra); - printf("\tsr: %08x\tmullo: %08x\tmulhi: %08x\tbadvaddr: %08x\n", - frame->sr, frame->mullo, frame->mulhi, frame->badvaddr); + printf("\tsr: %p\tmullo: %p\tmulhi: %p\tbadvaddr: %p\n", + (void *)frame->sr, (void *)frame->mullo, (void *)frame->mulhi, (void *)frame->badvaddr); #ifdef IC_REG - printf("\tcause: %08x\tpc: %08x\tic: %08x\n", - frame->cause, frame->pc, frame->ic); + printf("\tcause: %p\tpc: %p\tic: %p\n", + (void *)frame->cause, (void *)frame->pc, (void *)frame->ic); #else - printf("\tcause: %08x\tpc: %08x\n", - frame->cause, frame->pc); + printf("\tcause: %p\tpc: %p\n", + (void *)frame->cause, (void *)frame->pc); #endif } @@ -1666,12 +1666,12 @@ log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type) } pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0); - log(LOG_ERR, "%s: pid %d (%s), uid %d: pc 0x%x got a %s fault at 0x%x\n", + log(LOG_ERR, "%s: pid %d (%s), uid %d: pc %p got a %s fault at %p\n", msg, p->p_pid, p->p_comm, p->p_ucred ? p->p_ucred->cr_uid : -1, - pc, + (void *)pc, read_or_write, - frame->badvaddr); + (void *)frame->badvaddr); /* log registers in trap frame */ log_frame_dump(frame); @@ -1686,8 +1686,8 @@ log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type) (trap_type != T_BUS_ERR_IFETCH) && useracc((caddr_t)pc, sizeof(int) * 4, VM_PROT_READ)) { /* dump page table entry for faulting instruction */ - log(LOG_ERR, "Page table info for pc address 0x%x: pde = %p, pte = 0x%lx\n", - pc, *pdep, ptep ? *ptep : 0); + log(LOG_ERR, "Page table info for pc address %p: pde = %p, pte = 0x%lx\n", + (void *)pc, *pdep, ptep ? *ptep : 0); addr = (unsigned int *)pc; log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n", @@ -1695,8 +1695,8 @@ log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type) log(LOG_ERR, "%08x %08x %08x %08x\n", addr[0], addr[1], addr[2], addr[3]); } else { - log(LOG_ERR, "pc address 0x%x is inaccessible, pde = 0x%p, pte = 0x%lx\n", - pc, *pdep, ptep ? *ptep : 0); + log(LOG_ERR, "pc address %p is inaccessible, pde = 0x%p, pte = 0x%lx\n", + (void *)pc, *pdep, ptep ? *ptep : 0); } /* panic("Bad trap");*/ } @@ -1805,8 +1805,9 @@ emulate_unaligned_access(struct trapframe *frame) else frame->pc += 4; - log(LOG_INFO, "Unaligned %s: pc=0x%x, badvaddr=0x%x\n", - access_name[access_type - 1], pc, frame->badvaddr); + log(LOG_INFO, "Unaligned %s: pc=%p, badvaddr=%p\n", + access_name[access_type - 1], (void *)pc, + (void *)frame->badvaddr); } } return access_type; From 61a1eed0b47117b332cd4d409473d8534b4c9fbd Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 15:13:24 +0000 Subject: [PATCH 164/380] First cut at atomics for 64-bit machines and SMP machines. # Note: Cavium provided a port that has atomics similar to these, but # that does a syncw; sync; atomic; sync; syncw where we just do the classic # mips 'atomic' operation (eg ll; frob; sc). It is unclear to me why # the extra is needed. Since my initial target is one core, I'll defer # investigation until I bring up multiple cores. syncw is an octeon specific # instruction. --- sys/mips/include/atomic.h | 279 +++++++++++++++++++++++++++++++------- 1 file changed, 233 insertions(+), 46 deletions(-) diff --git a/sys/mips/include/atomic.h b/sys/mips/include/atomic.h index 06de6242df1..6b99863ebd5 100644 --- a/sys/mips/include/atomic.h +++ b/sys/mips/include/atomic.h @@ -34,6 +34,17 @@ #error this file needs sys/cdefs.h as a prerequisite #endif +/* + * Note: All the 64-bit atomic operations are only atomic when running + * in 64-bit mode. It is assumed that code compiled for n32 and n64 + * fits into this definition and no further safeties are needed. + * + * It is also assumed that the add, subtract and other arithmetic is + * done on numbers not pointers. The special rules for n32 pointers + * do not have atomic operations defined for them, but generally shouldn't + * need atomic operations. + */ + static __inline void mips_sync(void) { @@ -166,6 +177,110 @@ atomic_readandset_32(__volatile uint32_t *addr, uint32_t value) return result; } +#if defined(__mips_n64) || defined(__mips_n32) +static __inline void +atomic_set_64(__volatile uint64_t *p, uint64_t v) +{ + uint64_t temp; + + __asm __volatile ( + "1:\n\t" + "lld %0, %3\n\t" /* load old value */ + "or %0, %2, %0\n\t" /* calculate new value */ + "scd %0, %1\n\t" /* attempt to store */ + "beqz %0, 1b\n\t" /* spin if failed */ + : "=&r" (temp), "=m" (*p) + : "r" (v), "m" (*p) + : "memory"); + +} + +static __inline void +atomic_clear_64(__volatile uint64_t *p, uint64_t v) +{ + uint64_t temp; + v = ~v; + + __asm __volatile ( + "1:\n\t" + "lld %0, %3\n\t" /* load old value */ + "and %0, %2, %0\n\t" /* calculate new value */ + "scd %0, %1\n\t" /* attempt to store */ + "beqz %0, 1b\n\t" /* spin if failed */ + : "=&r" (temp), "=m" (*p) + : "r" (v), "m" (*p) + : "memory"); +} + +static __inline void +atomic_add_64(__volatile uint64_t *p, uint64_t v) +{ + uint64_t temp; + + __asm __volatile ( + "1:\n\t" + "lld %0, %3\n\t" /* load old value */ + "addu %0, %2, %0\n\t" /* calculate new value */ + "scd %0, %1\n\t" /* attempt to store */ + "beqz %0, 1b\n\t" /* spin if failed */ + : "=&r" (temp), "=m" (*p) + : "r" (v), "m" (*p) + : "memory"); +} + +static __inline void +atomic_subtract_64(__volatile uint64_t *p, uint64_t v) +{ + uint64_t temp; + + __asm __volatile ( + "1:\n\t" + "lld %0, %3\n\t" /* load old value */ + "subu %0, %2\n\t" /* calculate new value */ + "scd %0, %1\n\t" /* attempt to store */ + "beqz %0, 1b\n\t" /* spin if failed */ + : "=&r" (temp), "=m" (*p) + : "r" (v), "m" (*p) + : "memory"); +} + +static __inline uint64_t +atomic_readandclear_64(__volatile uint64_t *addr) +{ + uint64_t result,temp; + + __asm __volatile ( + "1:\n\t" + "lld %0, %3\n\t" /* load old value */ + "li %1, 0\n\t" /* value to store */ + "scd %1, %2\n\t" /* attempt to store */ + "beqz %1, 1b\n\t" /* if the store failed, spin */ + : "=&r"(result), "=&r"(temp), "=m" (*addr) + : "m" (*addr) + : "memory"); + + return result; +} + +static __inline uint64_t +atomic_readandset_64(__volatile uint64_t *addr, uint64_t value) +{ + uint64_t result,temp; + + __asm __volatile ( + "1:\n\t" + "lld %0,%3\n\t" /* Load old value*/ + "or %1,$0,%4\n\t" + "scd %1,%2\n\t" /* attempt to store */ + "beqz %1, 1b\n\t" /* if the store failed, spin */ + : "=&r"(result), "=&r"(temp), "=m" (*addr) + : "m" (*addr), "r" (value) + : "memory"); + + return result; +} +#endif + #define ATOMIC_ACQ_REL(NAME, WIDTH) \ static __inline void \ atomic_##NAME##_acq_##WIDTH(__volatile uint##WIDTH##_t *p, uint##WIDTH##_t v)\ @@ -194,7 +309,7 @@ ATOMIC_ACQ_REL(set, 32) ATOMIC_ACQ_REL(clear, 32) ATOMIC_ACQ_REL(add, 32) ATOMIC_ACQ_REL(subtract, 32) -#if 0 +#if defined(__mips_n64) || defined(__mips_n32) ATOMIC_ACQ_REL(set, 64) ATOMIC_ACQ_REL(clear, 64) ATOMIC_ACQ_REL(add, 64) @@ -226,8 +341,23 @@ atomic_store_rel_##WIDTH(__volatile uint##WIDTH##_t *p, uint##WIDTH##_t v)\ ATOMIC_STORE_LOAD(32) ATOMIC_STORE_LOAD(64) -void atomic_store_64 (__volatile uint64_t *, uint64_t *); -void atomic_load_64 (__volatile uint64_t *, uint64_t *); +#if !defined(__mips_n64) && !defined(__mips_n32) +void atomic_store_64(__volatile uint64_t *, uint64_t *); +void atomic_load_64(__volatile uint64_t *, uint64_t *); +#else +static __inline void +atomic_store_64(__volatile uint64_t *p, uint64_t v) +{ + + *p = v; +} + +static __inline void +atomic_load_64(__volatile uint64_t *p, uint64_t *v) +{ + *v = *p; +} +#endif #undef ATOMIC_STORE_LOAD @@ -299,6 +429,78 @@ atomic_fetchadd_32(__volatile uint32_t *p, uint32_t v) return (value); } +#if defined(__mips_n64) || defined(__mips_n32) +/* + * Atomically compare the value stored at *p with cmpval and if the + * two values are equal, update the value of *p with newval. Returns + * zero if the compare failed, nonzero otherwise. + */ +static __inline uint64_t +atomic_cmpset_64(__volatile uint64_t* p, uint64_t cmpval, uint64_t newval) +{ + uint64_t ret; + + __asm __volatile ( + "1:\n\t" + "lld %0, %4\n\t" /* load old value */ + "bne %0, %2, 2f\n\t" /* compare */ + "move %0, %3\n\t" /* value to store */ + "scd %0, %1\n\t" /* attempt to store */ + "beqz %0, 1b\n\t" /* if it failed, spin */ + "j 3f\n\t" + "2:\n\t" + "li %0, 0\n\t" + "3:\n" + : "=&r" (ret), "=m" (*p) + : "r" (cmpval), "r" (newval), "m" (*p) + : "memory"); + + return ret; +} + +/* + * Atomically compare the value stored at *p with cmpval and if the + * two values are equal, update the value of *p with newval. Returns + * zero if the compare failed, nonzero otherwise. + */ +static __inline uint64_t +atomic_cmpset_acq_64(__volatile uint64_t *p, uint64_t cmpval, uint64_t newval) +{ + int retval; + + retval = atomic_cmpset_64(p, cmpval, newval); + mips_sync(); + return (retval); +} + +static __inline uint64_t +atomic_cmpset_rel_64(__volatile uint64_t *p, uint64_t cmpval, uint64_t newval) +{ + mips_sync(); + return (atomic_cmpset_64(p, cmpval, newval)); +} + +/* + * Atomically add the value of v to the integer pointed to by p and return + * the previous value of *p. + */ +static __inline uint64_t +atomic_fetchadd_64(__volatile uint64_t *p, uint64_t v) +{ + uint64_t value, temp; + + __asm __volatile ( + "1:\n\t" + "lld %0, %1\n\t" /* load old value */ + "addu %2, %3, %0\n\t" /* calculate new value */ + "scd %2, %1\n\t" /* attempt to store */ + "beqz %2, 1b\n\t" /* spin if failed */ + : "=&r" (value), "=m" (*p), "=&r" (temp) + : "r" (v), "m" (*p)); + return (value); +} +#endif + /* Operations on chars. */ #define atomic_set_char atomic_set_8 #define atomic_set_acq_char atomic_set_acq_8 @@ -349,7 +551,13 @@ atomic_fetchadd_32(__volatile uint32_t *p, uint32_t v) #define atomic_readandset_int atomic_readandset_32 #define atomic_fetchadd_int atomic_fetchadd_32 -#ifdef __mips64 +/* + * I think the following is right, even for n32. For n32 the pointers + * are still 32-bits, so we need to operate on them as 32-bit quantities, + * even though they are sign extended in operation. For longs, there's + * no question because they are always 32-bits. + */ +#ifdef __mips_n64 /* Operations on longs. */ #define atomic_set_long atomic_set_64 #define atomic_set_acq_long atomic_set_acq_64 @@ -371,27 +579,7 @@ atomic_fetchadd_32(__volatile uint32_t *p, uint32_t v) #define atomic_fetchadd_long atomic_fetchadd_64 #define atomic_readandclear_long atomic_readandclear_64 -/* Operations on pointers. */ -#define atomic_set_ptr atomic_set_64 -#define atomic_set_acq_ptr atomic_set_acq_64 -#define atomic_set_rel_ptr atomic_set_rel_64 -#define atomic_clear_ptr atomic_clear_64 -#define atomic_clear_acq_ptr atomic_clear_acq_64 -#define atomic_clear_rel_ptr atomic_clear_rel_64 -#define atomic_add_ptr atomic_add_64 -#define atomic_add_acq_ptr atomic_add_acq_64 -#define atomic_add_rel_ptr atomic_add_rel_64 -#define atomic_subtract_ptr atomic_subtract_64 -#define atomic_subtract_acq_ptr atomic_subtract_acq_64 -#define atomic_subtract_rel_ptr atomic_subtract_rel_64 -#define atomic_cmpset_ptr atomic_cmpset_64 -#define atomic_cmpset_acq_ptr atomic_cmpset_acq_64 -#define atomic_cmpset_rel_ptr atomic_cmpset_rel_64 -#define atomic_load_acq_ptr atomic_load_acq_64 -#define atomic_store_rel_ptr atomic_store_rel_64 -#define atomic_readandclear_ptr atomic_readandclear_64 - -#else /* __mips64 */ +#else /* !__mips_n64 */ /* Operations on longs. */ #define atomic_set_long atomic_set_32 @@ -421,27 +609,26 @@ atomic_fetchadd_32(__volatile uint32_t *p, uint32_t v) atomic_fetchadd_32((volatile u_int *)(p), (u_int)(v)) #define atomic_readandclear_long atomic_readandclear_32 +#endif /* __mips_n64 */ + /* Operations on pointers. */ -#define atomic_set_ptr atomic_set_32 -#define atomic_set_acq_ptr atomic_set_acq_32 -#define atomic_set_rel_ptr atomic_set_rel_32 -#define atomic_clear_ptr atomic_clear_32 -#define atomic_clear_acq_ptr atomic_clear_acq_32 -#define atomic_clear_rel_ptr atomic_clear_rel_32 -#define atomic_add_ptr atomic_add_32 -#define atomic_add_acq_ptr atomic_add_acq_32 -#define atomic_add_rel_ptr atomic_add_rel_32 -#define atomic_subtract_ptr atomic_subtract_32 -#define atomic_subtract_acq_ptr atomic_subtract_acq_32 -#define atomic_subtract_rel_ptr atomic_subtract_rel_32 -#define atomic_cmpset_ptr atomic_cmpset_32 -#define atomic_cmpset_acq_ptr(dst, old, new) \ - atomic_cmpset_acq_32((volatile u_int *)(dst), \ - (u_int)(old), (u_int)(new)) -#define atomic_cmpset_rel_ptr atomic_cmpset_rel_32 -#define atomic_load_acq_ptr atomic_load_acq_32 -#define atomic_store_rel_ptr atomic_store_rel_32 -#define atomic_readandclear_ptr atomic_readandclear_32 -#endif /* __mips64 */ +#define atomic_set_ptr atomic_set_long +#define atomic_set_acq_ptr atomic_set_acq_long +#define atomic_set_rel_ptr atomic_set_rel_long +#define atomic_clear_ptr atomic_clear_long +#define atomic_clear_acq_ptr atomic_clear_acq_long +#define atomic_clear_rel_ptr atomic_clear_rel_long +#define atomic_add_ptr atomic_add_long +#define atomic_add_acq_ptr atomic_add_acq_long +#define atomic_add_rel_ptr atomic_add_rel_long +#define atomic_subtract_ptr atomic_subtract_long +#define atomic_subtract_acq_ptr atomic_subtract_acq_long +#define atomic_subtract_rel_ptr atomic_subtract_rel_long +#define atomic_cmpset_ptr atomic_cmpset_long +#define atomic_cmpset_acq_ptr atomic_cmpset_acq_long +#define atomic_cmpset_rel_ptr atomic_cmpset_rel_long +#define atomic_load_acq_ptr atomic_load_acq_long +#define atomic_store_rel_ptr atomic_store_rel_long +#define atomic_readandclear_ptr atomic_readandclear_long #endif /* ! _MACHINE_ATOMIC_H_ */ From 8de20ddba825013e7f97cfe033e789bd078685e2 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 15:16:27 +0000 Subject: [PATCH 165/380] Trim unreferenced goo. SDRAM likely should be next, but it is still referenced. --- sys/mips/include/pltfm.h | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/sys/mips/include/pltfm.h b/sys/mips/include/pltfm.h index e3f118b8101..86d50d964c4 100644 --- a/sys/mips/include/pltfm.h +++ b/sys/mips/include/pltfm.h @@ -13,17 +13,4 @@ #define SDRAM_ADDR_END (SDRAM_ADDR_START + (1024*0x100000)) #define SDRAM_MEM_SIZE (SDRAM_ADDR_END - SDRAM_ADDR_START) -#define UART_ADDR_START 0x1ef14000 /* UART */ -#define UART_ADDR_END 0x1ef14fff -#define UART_MEM_SIZE (UART_ADDR_END-UART_ADDR_START) - -/* - * NS16550 UART address - */ -#ifdef ADDR_NS16550_UART1 -#undef ADDR_NS16550_UART1 -#endif -#define ADDR_NS16550_UART1 0x1ef14000 /* UART */ -#define VADDR_NS16550_UART1 0xbef14000 /* UART */ - #endif /* !_MACHINE_PLTFM_H_ */ From f8b89abb9de59b14e2a64fe094435321e49993fa Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 15:17:11 +0000 Subject: [PATCH 166/380] First cut at 64-bit types. not 100% sure these are all correct for N32 ABI. --- sys/mips/include/_types.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/mips/include/_types.h b/sys/mips/include/_types.h index ec94439f40c..694b02a32d0 100644 --- a/sys/mips/include/_types.h +++ b/sys/mips/include/_types.h @@ -54,7 +54,7 @@ typedef unsigned short __uint16_t; typedef int __int32_t; typedef unsigned int __uint32_t; -#ifdef __mips64 +#ifdef __mips_n64 typedef long __int64_t; typedef unsigned long __uint64_t; #else @@ -79,14 +79,14 @@ typedef unsigned long long __uint64_t; */ typedef __int32_t __clock_t; /* clock()... */ typedef unsigned int __cpumask_t; -#ifdef __mips64 +#ifdef __mips_n64 typedef __int64_t __critical_t; #else typedef __int32_t __critical_t; #endif typedef double __double_t; typedef double __float_t; -#ifdef __mips64 +#ifdef __mips_n64 typedef __int64_t __intfptr_t; typedef __int64_t __intptr_t; #else @@ -102,14 +102,14 @@ typedef __int8_t __int_least8_t; typedef __int16_t __int_least16_t; typedef __int32_t __int_least32_t; typedef __int64_t __int_least64_t; -#if defined(__mips64) || defined(ISA_MIPS64) +#if defined(__mips_n64) || defined(ISA_MIPS64) typedef __int64_t __register_t; typedef __int64_t f_register_t; #else typedef __int32_t __register_t; typedef __int32_t f_register_t; #endif -#ifdef __mips64 +#ifdef __mips_n64 typedef __int64_t __ptrdiff_t; typedef __int64_t __segsz_t; typedef __uint64_t __size_t; @@ -134,7 +134,7 @@ typedef __uint8_t __uint_least8_t; typedef __uint16_t __uint_least16_t; typedef __uint32_t __uint_least32_t; typedef __uint64_t __uint_least64_t; -#if defined(__mips64) || defined(ISA_MIPS64) +#if defined(__mips_n64) || defined(ISA_MIPS64) typedef __uint64_t __u_register_t; typedef __uint64_t __vm_offset_t; typedef __uint64_t __vm_paddr_t; From 72322b23183175c87aba29c4a681bb8668fc0df9 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 15:18:06 +0000 Subject: [PATCH 167/380] compute the areas to save registers in for 64-bit access correctly. --- sys/mips/include/ucontext.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/mips/include/ucontext.h b/sys/mips/include/ucontext.h index c28f08371c7..c360a65b870 100644 --- a/sys/mips/include/ucontext.h +++ b/sys/mips/include/ucontext.h @@ -58,10 +58,14 @@ typedef struct __mcontext { } mcontext_t; #endif +#if defined(__mips_n64) || defined(__mips_n32) +#define SZREG 8 +#else #define SZREG 4 +#endif /* offsets into mcontext_t */ -#define UCTX_REG(x) (8 + (x)*SZREG) +#define UCTX_REG(x) (4 + SZREG + (x)*SZREG) #define UCR_ZERO UCTX_REG(0) #define UCR_AT UCTX_REG(1) From 46d854bbdb2c3705d7e0ccf5a837719c14b28df7 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 15:19:28 +0000 Subject: [PATCH 168/380] The SB1 needs a special value for the cache field of the pte. Submitted by: Neelkanth Natu --- sys/mips/include/pte.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/mips/include/pte.h b/sys/mips/include/pte.h index aa7e839c439..db26cbb0929 100644 --- a/sys/mips/include/pte.h +++ b/sys/mips/include/pte.h @@ -105,7 +105,11 @@ typedef pt_entry_t *pd_entry_t; #define PTE_ODDPG 0x00001000 /*#define PG_ATTR 0x0000003f Not Used */ #define PTE_UNCACHED 0x00000010 +#ifdef CPU_SB1 +#define PTE_CACHE 0x00000028 /* cacheable coherent */ +#else #define PTE_CACHE 0x00000018 +#endif /*#define PG_CACHEMODE 0x00000038 Not Used*/ #define PTE_ROPAGE (PTE_V | PTE_RO | PTE_CACHE) /* Write protected */ #define PTE_RWPAGE (PTE_V | PTE_M | PTE_CACHE) /* Not wr-prot not clean */ From bd34d4821026d288703642f425030929320b338b Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 15:20:16 +0000 Subject: [PATCH 169/380] The SB1 has cohernet memory, so add it. Also, Maxmem is better as a long. Submitted by: Neelkanth Natu --- sys/mips/include/md_var.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/mips/include/md_var.h b/sys/mips/include/md_var.h index 3b8d0a7e82c..6aa557977f6 100644 --- a/sys/mips/include/md_var.h +++ b/sys/mips/include/md_var.h @@ -39,7 +39,7 @@ /* * Miscellaneous machine-dependent declarations. */ -extern int Maxmem; +extern long Maxmem; extern char sigcode[]; extern int szsigcode, szosigcode; @@ -52,6 +52,7 @@ u_int MipsEmulateBranch(struct trapframe *, int, int, u_int); u_long kvtop(void *addr); int is_physical_memory(vm_offset_t addr); int is_cacheable_mem(vm_offset_t pa); +int is_coherent_mem(vm_offset_t pa); #define MIPS_DEBUG 0 From add6da074c9de6439eb33f6cb43722876a2843b4 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 15:21:35 +0000 Subject: [PATCH 170/380] Now that we define atomic_{load,store}_64 inline in atomic.h, we don't need to define them here for the !N64 case. We now define atomic_readandclear_64 in atomic.h, so no need to repeat it here. --- sys/mips/mips/support.S | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/sys/mips/mips/support.S b/sys/mips/mips/support.S index a5c46d851cc..19a2b4569d4 100644 --- a/sys/mips/mips/support.S +++ b/sys/mips/mips/support.S @@ -1316,17 +1316,11 @@ END(atomic_subtract_8) .set mips3 #endif -LEAF(atomic_readandclear_64) -1: - lld v0, 0(a0) - li t0, 0 - scd t0, 0(a0) - beqz t0, 1b - nop - j ra - nop -END(atomic_readandclear_64) - +#if !defined(__mips_n64) && !defined(__mips_n32) + /* + * I don't know if these routines have the right number of + * NOPs in it for all processors. XXX + */ LEAF(atomic_store_64) mfc0 t1, COP_0_STATUS_REG and t2, t1, ~SR_INT_ENAB @@ -1372,6 +1366,7 @@ LEAF(atomic_load_64) j ra nop END(atomic_load_64) +#endif #if defined(DDB) || defined(DEBUG) From 4f4793e60526013cc6d64fdc723df93d1bf21dfe Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 15:22:22 +0000 Subject: [PATCH 171/380] use "PTR_LA" in preference to a bare la so it translates to dla on 64-bit ABIs. --- sys/mips/mips/swtch.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/mips/mips/swtch.S b/sys/mips/mips/swtch.S index d07ab2c1249..2d93ef29e7c 100644 --- a/sys/mips/mips/swtch.S +++ b/sys/mips/mips/swtch.S @@ -323,7 +323,7 @@ NON_LEAF(cpu_switch, STAND_FRAME_SIZE, ra) mips_sw1: #if defined(SMP) && defined(SCHED_ULE) - la t0, _C_LABEL(blocked_lock) + PTR_LA t0, _C_LABEL(blocked_lock) blocked_loop: lw t1, TD_LOCK(a1) beq t0, t1, blocked_loop @@ -388,7 +388,7 @@ entry0set: * Now running on new u struct. */ sw2: - la t1, _C_LABEL(pmap_activate) # s7 = new proc pointer + PTR_LA t1, _C_LABEL(pmap_activate) # s7 = new proc pointer jalr t1 # s7 = new proc pointer move a0, s7 # BDSLOT /* From ece5503dbe34a987e92ec2bb50e6fa9f474696da Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 15:23:54 +0000 Subject: [PATCH 172/380] (1) Use PTR_LA rather than bare la for N64 goodness (it is dla there) (2) SB1 needs COHERENT policy, not cached for the config register Submitted by: (2) Neelkanth Natu --- sys/mips/mips/locore.S | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/sys/mips/mips/locore.S b/sys/mips/mips/locore.S index 6655eb6cb2f..b742bb96091 100644 --- a/sys/mips/mips/locore.S +++ b/sys/mips/mips/locore.S @@ -138,7 +138,11 @@ VECTOR(_locore, unknown) mtc0 t2, COP_0_STATUS_REG COP0_SYNC /* Make sure KSEG0 is cached */ +#ifdef CPU_SB1 + li t0, CFG_K0_COHERENT +#else li t0, CFG_K0_CACHED +#endif mtc0 t0, MIPS_COP_0_CONFIG COP0_SYNC @@ -164,8 +168,8 @@ VECTOR(_locore, unknown) /* * Initialize stack and call machine startup. */ - la sp, _C_LABEL(topstack) - START_FRAME - la gp, _C_LABEL(_gp) + PTR_LA sp, _C_LABEL(topstack) - START_FRAME + PTR_LA gp, _C_LABEL(_gp) sw zero, START_FRAME - 4(sp) # Zero out old ra for debugger /*xxximp @@ -187,7 +191,7 @@ VECTOR(_locore, unknown) no_cfe: #endif #if defined(TARGET_OCTEON) - la a0, app_descriptor_addr + PTR_LA a0, app_descriptor_addr sw a3, 0(a0) /* Store app descriptor ptr */ #endif @@ -232,7 +236,7 @@ no_cfe: nop #ifdef SMP - la t0, _C_LABEL(__pcpu) + PTR_LA t0, _C_LABEL(__pcpu) SET_CPU_PCPU(t0) /* If not master cpu, jump... */ /*XXX this assumes the above #if 0'd code runs */ @@ -244,7 +248,7 @@ no_cfe: jal _C_LABEL(platform_start) sw zero, START_FRAME - 8(sp) # Zero out old fp for debugger - la sp, _C_LABEL(thread0) + PTR_LA sp, _C_LABEL(thread0) lw a0, TD_PCB(sp) li t0, ~7 and a0, a0, t0 From 3eecc82e894802c34614baad6ca735b9ffcc8884 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 5 Jul 2009 21:16:26 +0000 Subject: [PATCH 173/380] addu and subu are special. We need to use daddu and dsubu here to get proper behavior. Submitted by: jmallet@ --- sys/mips/include/atomic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/mips/include/atomic.h b/sys/mips/include/atomic.h index 6b99863ebd5..9305a7bb60f 100644 --- a/sys/mips/include/atomic.h +++ b/sys/mips/include/atomic.h @@ -220,7 +220,7 @@ atomic_add_64(__volatile uint64_t *p, uint64_t v) __asm __volatile ( "1:\n\t" "lld %0, %3\n\t" /* load old value */ - "addu %0, %2, %0\n\t" /* calculate new value */ + "daddu %0, %2, %0\n\t" /* calculate new value */ "scd %0, %1\n\t" /* attempt to store */ "beqz %0, 1b\n\t" /* spin if failed */ : "=&r" (temp), "=m" (*p) @@ -236,7 +236,7 @@ atomic_subtract_64(__volatile uint64_t *p, uint64_t v) __asm __volatile ( "1:\n\t" "lld %0, %3\n\t" /* load old value */ - "subu %0, %2\n\t" /* calculate new value */ + "dsubu %0, %2\n\t" /* calculate new value */ "scd %0, %1\n\t" /* attempt to store */ "beqz %0, 1b\n\t" /* spin if failed */ : "=&r" (temp), "=m" (*p) From 54d05c03e5e3405da61a09c4d231847d4c18a980 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 6 Jul 2009 02:22:06 +0000 Subject: [PATCH 174/380] Change the addu here to daddu. addu paranoina prodded by: jmallet@ --- sys/mips/include/atomic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/mips/include/atomic.h b/sys/mips/include/atomic.h index 9305a7bb60f..ab99a6e5c51 100644 --- a/sys/mips/include/atomic.h +++ b/sys/mips/include/atomic.h @@ -137,7 +137,7 @@ atomic_subtract_32(__volatile uint32_t *p, uint32_t v) "1:\tll %0, %3\n\t" /* load old value */ "subu %0, %2\n\t" /* calculate new value */ "sc %0, %1\n\t" /* attempt to store */ - "beqz %0, 1b\n\t" /* spin if failed */ + "beqz %0, 1b\n\t" /* spin if failed */ : "=&r" (temp), "=m" (*p) : "r" (v), "m" (*p) : "memory"); @@ -492,7 +492,7 @@ atomic_fetchadd_64(__volatile uint64_t *p, uint64_t v) __asm __volatile ( "1:\n\t" "lld %0, %1\n\t" /* load old value */ - "addu %2, %3, %0\n\t" /* calculate new value */ + "daddu %2, %3, %0\n\t" /* calculate new value */ "scd %2, %1\n\t" /* attempt to store */ "beqz %2, 1b\n\t" /* spin if failed */ : "=&r" (value), "=m" (*p), "=&r" (temp) From 2967976763fff83d0146ab09a907e95c56484ebc Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 6 Jul 2009 02:22:51 +0000 Subject: [PATCH 175/380] Provide a macro for PTR_ADDU as well. We may need to implement this differently for N32... Use PTR_ADDU in DO_AST macro. --- sys/mips/include/asm.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/mips/include/asm.h b/sys/mips/include/asm.h index 6b8e515a80e..db6929d0d9b 100644 --- a/sys/mips/include/asm.h +++ b/sys/mips/include/asm.h @@ -326,7 +326,7 @@ _C_LABEL(x): nop ;\ PTR_LA s0, _C_LABEL(ast) ;\ jalr s0 ;\ - addu a0, s3, U_PCB_REGS ;\ + PTR_ADDU a0, s3, U_PCB_REGS ;\ j 44b ;\ nop ;\ 4: @@ -371,6 +371,7 @@ _C_LABEL(x): #define REG_EPILOGUE .set pop #define SZREG 4 #define PTR_LA la +#define PTR_ADDU addu #else #define REG_L ld #define REG_S sd @@ -379,6 +380,7 @@ _C_LABEL(x): #define REG_EPILOGUE .set pop #define SZREG 8 #define PTR_LA dla +#define PTR_ADDU daddu #endif /* _MIPS_BSD_API */ #define mfc0_macro(data, spr) \ From b04ad5dd490c6b566aa9e63416bb1ea1480b64e0 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 6 Jul 2009 02:27:03 +0000 Subject: [PATCH 176/380] The MCOUNT macro isn't going to work in 64-bit mode. Add a note to this effect. --- sys/mips/include/profile.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/mips/include/profile.h b/sys/mips/include/profile.h index 9659d1fa87d..728a468dbf4 100644 --- a/sys/mips/include/profile.h +++ b/sys/mips/include/profile.h @@ -41,6 +41,8 @@ /*XXX The cprestore instruction is a "dummy" to shut up as(1). */ +/*XXX This is not MIPS64 safe. */ + #define MCOUNT \ __asm(".globl _mcount;" \ ".type _mcount,@function;" \ From 243ab23fcf3498e387efae20a96a1313ee1b6a37 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 6 Jul 2009 07:42:54 +0000 Subject: [PATCH 177/380] (1) Improvements for SB1. only allow real memory to be accessed. (2) make compile n64 by using more-proper casts. Submitted by: Neelkanth Natu (1) --- sys/mips/mips/mem.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sys/mips/mips/mem.c b/sys/mips/mips/mem.c index be7a9f5ed35..1a03d5b79a7 100644 --- a/sys/mips/mips/mem.c +++ b/sys/mips/mips/mem.c @@ -101,8 +101,15 @@ memrw(dev, uio, flags) vm_paddr_t pa; register int o; +#ifdef CPU_SB1 + if (!is_physical_memory(v) || + !is_physical_memory(roundup2(v, PAGE_SIZE) - 1)) { + return (EFAULT); + } +#else if (v + c > (SDRAM_ADDR_START + ctob(physmem))) return (EFAULT); +#endif if (is_cacheable_mem(v) && is_cacheable_mem(v + c)) { struct fpage *fp; @@ -117,7 +124,7 @@ memrw(dev, uio, flags) va = pmap_map_fpage(pa, fp, FALSE); o = (int)uio->uio_offset & PAGE_MASK; c = (u_int)(PAGE_SIZE - - ((int)iov->iov_base & PAGE_MASK)); + ((uintptr_t)iov->iov_base & PAGE_MASK)); c = min(c, (u_int)(PAGE_SIZE - o)); c = min(c, (u_int)iov->iov_len); error = uiomove((caddr_t)(va + o), (int)c, uio); @@ -158,7 +165,7 @@ memrw(dev, uio, flags) return EFAULT; if (!kernacc( - (caddr_t)(int)uio->uio_offset, c, + (caddr_t)(uintptr_t)uio->uio_offset, c, uio->uio_rw == UIO_READ ? VM_PROT_READ : VM_PROT_WRITE)) return (EFAULT); From 10c8cc2b9fa4f1676bb10323854fcc9c1af30fdb Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 6 Jul 2009 07:43:50 +0000 Subject: [PATCH 178/380] Use better casts for passing the small integer as a pointer here. Basically, replace int with uintptr_t. --- sys/mips/mips/intr_machdep.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sys/mips/mips/intr_machdep.c b/sys/mips/mips/intr_machdep.c index 21d668f2681..c42b5fb729d 100644 --- a/sys/mips/mips/intr_machdep.c +++ b/sys/mips/mips/intr_machdep.c @@ -56,7 +56,7 @@ static int last_printed = 0; static void mips_mask_hard_irq(void *source) { - int irq = (int)source; + uintptr_t irq = (uintptr_t)source; mips_wr_status(mips_rd_status() & ~(((1 << irq) << 8) << 2)); } @@ -64,7 +64,7 @@ mips_mask_hard_irq(void *source) static void mips_unmask_hard_irq(void *source) { - int irq = (int)source; + uintptr_t irq = (uintptr_t)source; mips_wr_status(mips_rd_status() | (((1 << irq) << 8) << 2)); } @@ -72,7 +72,7 @@ mips_unmask_hard_irq(void *source) static void mips_mask_soft_irq(void *source) { - int irq = (int)source; + uintptr_t irq = (uintptr_t)source; mips_wr_status(mips_rd_status() & ~((1 << irq) << 8)); } @@ -80,7 +80,7 @@ mips_mask_soft_irq(void *source) static void mips_unmask_soft_irq(void *source) { - int irq = (int)source; + uintptr_t irq = (uintptr_t)source; mips_wr_status(mips_rd_status() | ((1 << irq) << 8)); } @@ -105,8 +105,8 @@ cpu_establish_hardintr(const char *name, driver_filter_t *filt, event = hardintr_events[irq]; if (event == NULL) { - error = intr_event_create(&event, (void *)irq, 0, irq, - mips_mask_hard_irq, mips_unmask_hard_irq, + error = intr_event_create(&event, (void *)(uintptr_t)irq, 0, + irq, mips_mask_hard_irq, mips_unmask_hard_irq, NULL, NULL, "hard intr%d:", irq); if (error) return; @@ -124,7 +124,7 @@ cpu_establish_hardintr(const char *name, driver_filter_t *filt, intr_event_add_handler(event, name, filt, handler, arg, intr_priority(flags), flags, cookiep); - mips_unmask_hard_irq((void*)irq); + mips_unmask_hard_irq((void*)(uintptr_t)irq); } void @@ -144,8 +144,8 @@ cpu_establish_softintr(const char *name, driver_filter_t *filt, event = softintr_events[irq]; if (event == NULL) { - error = intr_event_create(&event, (void *)irq, 0, irq, - mips_mask_soft_irq, mips_unmask_soft_irq, + error = intr_event_create(&event, (void *)(uintptr_t)irq, 0, + irq, mips_mask_soft_irq, mips_unmask_soft_irq, NULL, NULL, "intr%d:", irq); if (error) return; @@ -155,7 +155,7 @@ cpu_establish_softintr(const char *name, driver_filter_t *filt, intr_event_add_handler(event, name, filt, handler, arg, intr_priority(flags), flags, cookiep); - mips_unmask_soft_irq((void*)irq); + mips_unmask_soft_irq((void*)(uintptr_t)irq); } void From e3c2111d5cfabd81425fe067ce8d8e50f514cca5 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 6 Jul 2009 07:45:02 +0000 Subject: [PATCH 179/380] Use ta0 instead of t4 and ta1 instead of t5. These map to the same registers on O32 builds, but t4 and t5 don't exist on N32 or N64. --- sys/mips/mips/tlb.S | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/mips/mips/tlb.S b/sys/mips/mips/tlb.S index 33f21266450..7829bd879ac 100644 --- a/sys/mips/mips/tlb.S +++ b/sys/mips/mips/tlb.S @@ -432,17 +432,17 @@ LEAF(Mips_TLBRead) MIPS_CPU_NOP_DELAY mfc0 t2, COP_0_TLB_PG_MASK # fetch the hi entry _MFC0 t3, COP_0_TLB_HI # fetch the hi entry - _MFC0 t4, COP_0_TLB_LO0 # See what we got - _MFC0 t5, COP_0_TLB_LO1 # See what we got + _MFC0 ta0, COP_0_TLB_LO0 # See what we got + _MFC0 ta1, COP_0_TLB_LO1 # See what we got _MTC0 t0, COP_0_TLB_HI # restore PID MIPS_CPU_NOP_DELAY mtc0 v1, COP_0_STATUS_REG # Restore the status register ITLBNOPFIX sw t2, 0(a1) sw t3, 4(a1) - sw t4, 8(a1) + sw ta0, 8(a1) j ra - sw t5, 12(a1) + sw ta1, 12(a1) END(Mips_TLBRead) /*-------------------------------------------------------------------------- @@ -478,7 +478,7 @@ LEAF(mips_TBIAP) mfc0 v1, COP_0_STATUS_REG # save status register mtc0 zero, COP_0_STATUS_REG # disable interrupts - _MFC0 t4, COP_0_TLB_HI # Get current PID + _MFC0 ta0, COP_0_TLB_HI # Get current PID move t2, a0 mfc0 t1, COP_0_TLB_WIRED li v0, MIPS_KSEG0_START # invalid address @@ -517,7 +517,7 @@ LEAF(mips_TBIAP) bne t1, t2, 1b nop - _MTC0 t4, COP_0_TLB_HI # restore PID + _MTC0 ta0, COP_0_TLB_HI # restore PID mtc0 t3, COP_0_TLB_PG_MASK # restore pgMask MIPS_CPU_NOP_DELAY mtc0 v1, COP_0_STATUS_REG # restore status register From 025e48c64cd97250f9cdb56af77e172bf3e2ff24 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 6 Jul 2009 07:46:13 +0000 Subject: [PATCH 180/380] Pass in the uint64 value, rather than a pointer to it. that's what the function expects... --- sys/mips/mips/db_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/mips/db_interface.c b/sys/mips/mips/db_interface.c index 455c03e4dc5..80f65f23f64 100644 --- a/sys/mips/mips/db_interface.c +++ b/sys/mips/mips/db_interface.c @@ -197,7 +197,7 @@ db_write_bytes(vm_offset_t addr, size_t size, char *data) break; case 8: atomic_store_64((volatile u_int64_t *)addr, - (u_int64_t *)data); + *(u_int64_t *)data); break; } } else { From f5481090870bec878f8e65d047f4c2d494b37ca8 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 6 Jul 2009 07:47:39 +0000 Subject: [PATCH 181/380] No need to force mips32 here. --- sys/mips/mips/cache_mipsNN.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/mips/mips/cache_mipsNN.c b/sys/mips/mips/cache_mipsNN.c index 1b27776a0dc..93556aa0a8f 100644 --- a/sys/mips/mips/cache_mipsNN.c +++ b/sys/mips/mips/cache_mipsNN.c @@ -66,8 +66,6 @@ __FBSDID("$FreeBSD$"); #endif -__asm(".set mips32"); - static int picache_size; static int picache_stride; static int picache_loopcount; From 26b14c6dde9ef3b149290aa8fe8a07e788a5d594 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 6 Jul 2009 07:48:31 +0000 Subject: [PATCH 182/380] Better types for 64-bit compatibility. Use %p and cast to void * and prefer uintptr_t to other int-type casts. --- sys/mips/mips/pm_machdep.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sys/mips/mips/pm_machdep.c b/sys/mips/mips/pm_machdep.c index 097334756f4..43cbdae589b 100644 --- a/sys/mips/mips/pm_machdep.c +++ b/sys/mips/mips/pm_machdep.c @@ -230,13 +230,13 @@ sigreturn(struct thread *td, struct sigreturn_args *uap) /* #ifdef DEBUG */ if (ucp->uc_mcontext.mc_regs[ZERO] != UCONTEXT_MAGIC) { printf("sigreturn: pid %d, ucp %p\n", p->p_pid, ucp); - printf(" old sp %x ra %x pc %x\n", - regs->sp, regs->ra, regs->pc); - printf(" new sp %x ra %x pc %x z %x\n", - ucp->uc_mcontext.mc_regs[SP], - ucp->uc_mcontext.mc_regs[RA], - ucp->uc_mcontext.mc_regs[PC], - ucp->uc_mcontext.mc_regs[ZERO]); + printf(" old sp %p ra %p pc %p\n", + (void *)regs->sp, (void *)regs->ra, (void *)regs->pc); + printf(" new sp %p ra %p pc %p z %p\n", + (void *)ucp->uc_mcontext.mc_regs[SP], + (void *)ucp->uc_mcontext.mc_regs[RA], + (void *)ucp->uc_mcontext.mc_regs[PC], + (void *)ucp->uc_mcontext.mc_regs[ZERO]); return EINVAL; } /* #endif */ @@ -327,7 +327,7 @@ ptrace_single_step(struct thread *td) /* compute next address after current location */ if(curinstr != 0) { va = MipsEmulateBranch(locr0, locr0->pc, locr0->fsr, - (u_int)&curinstr); + (uintptr_t)&curinstr); } else { va = locr0->pc + 4; } From 4b9aa0a9737edebc7a234fcadcfe63701ffcc6e8 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 6 Jul 2009 07:49:24 +0000 Subject: [PATCH 183/380] Prefer uintptr_t to int cast here. --- sys/mips/mips/in_cksum.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/mips/in_cksum.c b/sys/mips/mips/in_cksum.c index f0c95d9064b..31bcd3ebdd0 100644 --- a/sys/mips/mips/in_cksum.c +++ b/sys/mips/mips/in_cksum.c @@ -226,7 +226,7 @@ skip_start: if (len < mlen) mlen = len; - if ((clen ^ (int) addr) & 1) + if ((clen ^ (uintptr_t) addr) & 1) sum += in_cksumdata(addr, mlen) << 8; else sum += in_cksumdata(addr, mlen); From e0dab9bcb84ef6506c1e54bc9e7b51a9c7be9d3b Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 6 Jul 2009 08:00:26 +0000 Subject: [PATCH 184/380] Be more pedantic here. If we're going to shift something sizeof(long)*8 / 2 bits, then we better make sure we're shifting a long that much, not an int. # I'm surprised this is code would have a bug this basic. --- sys/libkern/qdivrem.c | 2 +- sys/libkern/quad.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/libkern/qdivrem.c b/sys/libkern/qdivrem.c index fbfd715ef0a..635f53c88b2 100644 --- a/sys/libkern/qdivrem.c +++ b/sys/libkern/qdivrem.c @@ -41,7 +41,7 @@ __FBSDID("$FreeBSD$"); #include -#define B (1 << HALF_BITS) /* digit base */ +#define B (1UL << HALF_BITS) /* digit base */ /* Combine two `digits' to make a single two-digit number. */ #define COMBINE(a, b) (((u_long)(a) << HALF_BITS) | (b)) diff --git a/sys/libkern/quad.h b/sys/libkern/quad.h index 5d4f844ce67..4d09afa3b05 100644 --- a/sys/libkern/quad.h +++ b/sys/libkern/quad.h @@ -94,7 +94,7 @@ union uu { * (sizeof(long)*CHAR_BIT/2). */ #define HHALF(x) ((x) >> HALF_BITS) -#define LHALF(x) ((x) & ((1 << HALF_BITS) - 1)) +#define LHALF(x) ((x) & ((1UL << HALF_BITS) - 1)) #define LHUP(x) ((x) << HALF_BITS) typedef unsigned int qshift_t; From a01f85e046c8b08c978cc7f44c301cb4d32e7650 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 6 Jul 2009 08:16:25 +0000 Subject: [PATCH 185/380] Only build qdivrem on 32-bit ISA... # not sure this is the right selector... --- sys/conf/files.mips | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/conf/files.mips b/sys/conf/files.mips index 22cba83050a..c8c6b8cd267 100644 --- a/sys/conf/files.mips +++ b/sys/conf/files.mips @@ -49,7 +49,7 @@ mips/mips/tick.c standard # ---------------------------------------------------------------------- # Phase 5 # ---------------------------------------------------------------------- -mips/mips/fp.S standard +mips/mips/fp.S optional hardfp mips/mips/pm_machdep.c standard mips/mips/swtch.S standard mips/mips/tlb.S standard @@ -86,7 +86,7 @@ libkern/flsl.c standard libkern/lshrdi3.c standard libkern/memmove.c standard libkern/moddi3.c standard -libkern/qdivrem.c standard +libkern/qdivrem.c optional isa_mips32 libkern/udivdi3.c standard libkern/umoddi3.c standard From 9d7dcb83db8275f796766b50ad041a026462ba7b Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 6 Jul 2009 18:12:49 +0000 Subject: [PATCH 186/380] Minor fixes to printf formats. --- sys/mips/octeon1/dev/rgmii/octeon_fpa.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/mips/octeon1/dev/rgmii/octeon_fpa.c b/sys/mips/octeon1/dev/rgmii/octeon_fpa.c index 0f456984b3a..b5d8f7c39cf 100644 --- a/sys/mips/octeon1/dev/rgmii/octeon_fpa.c +++ b/sys/mips/octeon1/dev/rgmii/octeon_fpa.c @@ -36,7 +36,7 @@ void octeon_dump_fpa (void) return; } printf(" FPA Ctrl-Status-reg 0x%llX := 0x%llX EN %X M1_E %X M0_E %X\n", - OCTEON_FPA_CTL_STATUS, status.word64, + OCTEON_FPA_CTL_STATUS, (unsigned long long)status.word64, status.bits.enb, status.bits.mem1_err, status.bits.mem0_err); for (i = 0; i < OCTEON_FPA_QUEUES; i++) { printf(" Pool: %d\n", i); @@ -61,7 +61,7 @@ void octeon_dump_fpa_pool (u_int pool) return; } printf(" FPA Ctrl-Status-reg 0x%llX := 0x%llX EN %X M1_E %X M0_E %X\n", - OCTEON_FPA_CTL_STATUS, status.word64, + OCTEON_FPA_CTL_STATUS, (unsigned long long)status.word64, status.bits.enb, status.bits.mem1_err, status.bits.mem0_err); q_avail.word64 = oct_read64((OCTEON_FPA_QUEUE_AVAILABLE + (pool)*8ull)); printf(" FPA Pool: %u Avail-reg 0x%llX := Size: 0x%X\n", pool, @@ -168,8 +168,8 @@ void octeon_fpa_fill_pool_mem (u_int pool, u_int elem_size_words, u_int elem_num memory = (void *) OCTEON_ALIGN(memory); #ifdef FPA_DEBUG_TERSE - printf("FPA fill: %u Count: %u SizeBytes: %u SizeBytesAligned: %u 1st: 0x%X = 0x%X\n", - pool, elem_num, elem_size_bytes, block_size, memory, OCTEON_PTR2PHYS(memory)); + printf("FPA fill: %u Count: %u SizeBytes: %u SizeBytesAligned: %u 1st: 0x%X = %p\n", + pool, elem_num, elem_size_bytes, block_size, memory, (void *)OCTEON_PTR2PHYS(memory)); #endif // memory = (void *) ((((u_int) memory / OCTEON_FPA_POOL_ALIGNMENT) + 1) * OCTEON_FPA_POOL_ALIGNMENT); From 4df29a25aaad81ad75a8dfcc4446042fe903fb88 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 6 Jul 2009 18:15:57 +0000 Subject: [PATCH 187/380] 64-bit fixes: (1) fix printf formats. (2) Prefer FreeBSD's MIPS_PHYS_TO_KSEG0 to hand-rolled one from Cavium. (3) Mark a few 64-bit cleanliness issues (possible). (4) Minor formatting fixes. --- sys/mips/octeon1/dev/rgmii/octeon_fpa.h | 33 +++--------------------- sys/mips/octeon1/dev/rgmii/octeon_pko.c | 8 +++--- sys/mips/octeon1/dev/rgmii/octeon_rgmx.c | 4 +-- sys/mips/octeon1/dev/rgmii/octeon_rgmx.h | 19 ++++++-------- 4 files changed, 17 insertions(+), 47 deletions(-) diff --git a/sys/mips/octeon1/dev/rgmii/octeon_fpa.h b/sys/mips/octeon1/dev/rgmii/octeon_fpa.h index 04cd98bbd26..174ff73952c 100644 --- a/sys/mips/octeon1/dev/rgmii/octeon_fpa.h +++ b/sys/mips/octeon1/dev/rgmii/octeon_fpa.h @@ -168,7 +168,7 @@ static inline void octeon_fpa_free (void *ptr, u_int pool, { octeon_addr_t free_ptr; - free_ptr.word64 = (uint64_t) OCTEON_PTR2PHYS(ptr); + free_ptr.word64 = (uint64_t)OCTEON_PTR2PHYS(ptr); free_ptr.sfilldidspace.didspace = OCTEON_ADDR_DIDSPACE( OCTEON_ADDR_FULL_DID(OCTEON_DID_FPA, pool)); @@ -200,16 +200,15 @@ static inline void *octeon_fpa_alloc (u_int pool) /* * 32 bit FPA pointers only */ - /* * We only use 32 bit pointers at this time */ - return ((void *) OCTEON_PHYS2PTR(address & 0xffffffff)); +/*XXX mips64 issue */ + return ((void *) MIPS_PHYS_TO_KSEG0(address & 0xffffffff)); } return (NULL); } - static inline uint64_t octeon_fpa_alloc_phys (u_int pool) { @@ -217,30 +216,4 @@ static inline uint64_t octeon_fpa_alloc_phys (u_int pool) pool)))); } - -#if 0 - -/* - * octeon_fpa_alloc - * - * Allocate a new block from the FPA - * - * Buffer passes away from FPA management to SW control - */ -static inline void *octeon_fpa_alloc (u_int pool) -{ - uint64_t address; - - address = oct_read64(OCTEON_ADDR_DID(OCTEON_ADDR_FULL_DID(OCTEON_DID_FPA, - pool))); - if (address) { - return ((void *) (oct_ptr_size) OCTEON_PHYS2PTR(address)); - } - return (NULL); -} - -#endif - - - #endif /* ___OCTEON_FPA__H___ */ diff --git a/sys/mips/octeon1/dev/rgmii/octeon_pko.c b/sys/mips/octeon1/dev/rgmii/octeon_pko.c index 2b2cb5ea3ee..cfd8cd4b992 100644 --- a/sys/mips/octeon1/dev/rgmii/octeon_pko.c +++ b/sys/mips/octeon1/dev/rgmii/octeon_pko.c @@ -174,7 +174,9 @@ static void octeon_pko_doorbell_data_dump (uint64_t port) octeon_pko_get_port_status(port, 0, &status); printf("\n Port #%lld Pkts %ld Bytes %lld DoorBell %lld", - port, status.packets, status.octets, status.doorbell); + (unsigned long long)port, status.packets, + (unsigned long long)status.octets, + (unsigned long long)status.doorbell); } /* @@ -229,7 +231,7 @@ void octeon_pko_show (u_int start_port, u_int end_port) printf("\n Port # %d Queue %3d [%d] BufPtr: 0x%llX Mask: %X%s", octeon_pko_queue_cfg.bits.port, octeon_pko_queue_cfg.bits.queue, octeon_pko_queue_cfg.bits.index, - (uint64_t)octeon_pko_queue_cfg.bits.buf_ptr, + (unsigned long long)octeon_pko_queue_cfg.bits.buf_ptr, octeon_pko_queue_cfg.bits.qos_mask, (octeon_pko_queue_cfg.bits.tail)? " Last":""); } @@ -238,8 +240,6 @@ void octeon_pko_show (u_int start_port, u_int end_port) for (port = start_port; port < (end_port + 1); port++) { octeon_pko_get_port_status(port, 0, &status); - printf("\n Port #%d Packets %ld Bytes %lld DoorBell %lld", - port, status.packets, status.octets, status.doorbell); octeon_pko_doorbell_data_dump(port); } diff --git a/sys/mips/octeon1/dev/rgmii/octeon_rgmx.c b/sys/mips/octeon1/dev/rgmii/octeon_rgmx.c index aca755da65a..af4aba31511 100644 --- a/sys/mips/octeon1/dev/rgmii/octeon_rgmx.c +++ b/sys/mips/octeon1/dev/rgmii/octeon_rgmx.c @@ -696,7 +696,7 @@ static struct mbuf *octeon_rgmx_build_new_rx_mbuf (struct ifnet *ifp, void *data } if (m == m0) { - newdata = (caddr_t) ALIGN(m->m_data + ETHER_HDR_LEN) - ETHER_HDR_LEN; + newdata = (caddr_t)ALIGN(m->m_data + ETHER_HDR_LEN) - ETHER_HDR_LEN; len -= newdata - m->m_data; m->m_data = newdata; } @@ -969,7 +969,7 @@ static u_int octeon_rgmx_pko_xmit_packet (struct rgmx_softc_dev *sc, void *out_b #ifdef DEBUG_TX printf(" temp: 0x%X ", temp); #endif - xmit_cmd_ptr = (uint64_t *) OCTEON_PHYS2PTR(temp); + xmit_cmd_ptr = (uint64_t *) MIPS_PHYS_TO_KSEG0(temp); xmit_cmd_index = xmit_cmd_state & OCTEON_PKO_INDEX_MASK; xmit_cmd_ptr += xmit_cmd_index; diff --git a/sys/mips/octeon1/dev/rgmii/octeon_rgmx.h b/sys/mips/octeon1/dev/rgmii/octeon_rgmx.h index d1eb8b9171a..e6d8e767aea 100644 --- a/sys/mips/octeon1/dev/rgmii/octeon_rgmx.h +++ b/sys/mips/octeon1/dev/rgmii/octeon_rgmx.h @@ -423,7 +423,7 @@ static inline octeon_wqe_t *octeon_pow_work_request_sync_nocheck (octeon_pow_wai if (result.s_work.no_work || !result.s_work.addr) { return NULL; } - return (octeon_wqe_t *) OCTEON_PHYS2PTR(result.s_work.addr); + return (octeon_wqe_t *) MIPS_PHYS_TO_KSEG0(result.s_work.addr); } static inline octeon_wqe_t *octeon_pow_work_request_sync_nocheck_debug (octeon_pow_wait_t wait) @@ -440,13 +440,14 @@ static inline octeon_wqe_t *octeon_pow_work_request_sync_nocheck_debug (octeon_p result.word64 = oct_read64(ptr.word64); printf("WQE Result: 0x%llX No-work %X Addr %llX Ptr: %p\n", - result.word64, result.s_work.no_work, (uint64_t)result.s_work.addr, - OCTEON_PHYS2PTR(result.s_work.addr)); + (unsigned long long)result.word64, result.s_work.no_work, + (unsigned long long)result.s_work.addr, + (void *)MIPS_PHYS_TO_KSEG0(result.s_work.addr)); if (result.s_work.no_work || !result.s_work.addr) { return NULL; } - return (octeon_wqe_t *) OCTEON_PHYS2PTR(result.s_work.addr); + return (octeon_wqe_t *) MIPS_PHYS_TO_KSEG0(result.s_work.addr); } static inline octeon_wqe_t *octeon_pow_work_request_sync (octeon_pow_wait_t wait) @@ -482,7 +483,7 @@ static inline octeon_wqe_t *octeon_pow_work_response_async(int scratch_addr) if (result.s_work.no_work) { return NULL; } - return (octeon_wqe_t*) OCTEON_PHYS2PTR(result.s_work.addr); + return (octeon_wqe_t*) MIPS_PHYS_TO_KSEG0(result.s_work.addr); } @@ -493,18 +494,14 @@ static inline octeon_wqe_t *octeon_pow_work_response_async(int scratch_addr) */ static inline void *octeon_pow_pktptr_to_kbuffer (octeon_buf_ptr_t pkt_ptr) { - return (OCTEON_PHYS2PTR(((pkt_ptr.bits.addr >> 7) - pkt_ptr.bits.back) << 7)); + return ((void *)MIPS_PHYS_TO_KSEG0( + ((pkt_ptr.bits.addr >> 7) - pkt_ptr.bits.back) << 7)); } - - - #define INTERFACE(port) (port >> 4) /* Ports 0-15 are interface 0, 16-31 are interface 1 */ #define INDEX(port) (port & 0xf) - - #define OCTEON_RGMX_PRTX_CFG(index,interface) (0x8001180008000010ull+((index)*2048)+((interface)*0x8000000ull)) #define OCTEON_RGMX_SMACX(offset,block_id) (0x8001180008000230ull+((offset)*2048)+((block_id)*0x8000000ull)) #define OCTEON_RGMX_RXX_ADR_CAM0(offset,block_id) (0x8001180008000180ull+((offset)*2048)+((block_id)*0x8000000ull)) From a371f04d6697e432c39b2f4e537abcc8325038bf Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 6 Jul 2009 18:17:48 +0000 Subject: [PATCH 188/380] GC some now-unused items. Fix for 64-bit build. Note: this breaks the 32-bit build (which we're not computing correctly anyway). --- sys/mips/octeon1/octeon_pcmap_regs.h | 39 +++------------------------- 1 file changed, 3 insertions(+), 36 deletions(-) diff --git a/sys/mips/octeon1/octeon_pcmap_regs.h b/sys/mips/octeon1/octeon_pcmap_regs.h index 282e15e6f7e..8834a9b55e3 100644 --- a/sys/mips/octeon1/octeon_pcmap_regs.h +++ b/sys/mips/octeon1/octeon_pcmap_regs.h @@ -538,17 +538,6 @@ typedef enum { * We limit the allocated device physical blocks to low mem. So use Kseg0 */ -#ifndef AVOID_CODE_NOT_64_BIT /* #ifdef PTR_SIZE == sizeof(u_int32) */ -//#define OCTEON_PHYS2PTR(addr) ((void *) (((uint32_t) addr) | 0x80000000)) -#define OCTEON_PHYS2PTR(addr) ((void *) (((vm_offset_t) addr) | MIPS_KSEG0_START)) -#endif - -#ifdef IN_FUTURE_64_BIT -#ifdef PTR_SIZE == sizeof(u_int64) -#define OCTEON_PHYS2PTR(addr) ((void *) (((uint64_t) addr) | (1ul << 63)) -#endif -#endif - /* * Need to go back to kernel to find v->p mappings & vice-versa * We are getting non 1-1 mappings. @@ -560,17 +549,14 @@ typedef enum { /* PTR_SIZE == sizeof(uint32_t) */ +#if 0 #define mipsx_addr_size uint32_t // u_int64 #define MIPSX_ADDR_SIZE_KSEGX_BIT_SHIFT 30 // 62 #define MIPSX_ADDR_SIZE_KSEGX_MASK_REMOVED 0x1fffffff // 0x1fffffff - - -#ifdef CODE_FOR_64_BIT_NEEDED -#ifdef PTR_SIZE == sizeof(uint64_t) +#else #define mipsx_addr_size uint64_t #define MIPSX_ADDR_SIZE_KSEGX_BIT_SHIFT 62 -#define MIPSX_ADDR_SIZE_KSEGX_MASK_REMOVED 0x1fffffff ffff ffff -#endif +#define MIPSX_ADDR_SIZE_KSEGX_MASK_REMOVED 0x1fffffffffffffff #endif @@ -1071,11 +1057,6 @@ typedef union { #define OCTEON_GENTIMER_LEN_1MS (0x7a120ull) /* Back of envelope. 500Mhz Octeon */ // FIXME IF WRONG #define OCTEON_GENTIMER_LEN_1SEC ((OCTEON_GENTIMER_LEN_1MS) * 1000) - - - - - /* * Physical Memory Banks */ @@ -1095,18 +1076,4 @@ typedef union { #define OCTEON_DRAM_ABOVE_512_END (0x0000000300000000ull - 1ull) /* To be calculated as remaining */ #define OCTEON_DRAM_THIRD_BANK_SIZE (OCTEON_DRAM_ABOVE_512_END - OCTEON_DRAM_ABOVE_512_START + 1ull) - -/* - * Mips Address Range conversions - */ -#define PHY_TO_KSEG1(x) ((x)+0xA0000000) -#define PHY_TO_KSEG0(x) ((x)+0x80000000) -#define PHY_ADDR(x) ((x)&0x1FFFFFFF) -#define ROM_OFFSET(x) ((x)&0x000FFFFF) -#define KSEG1_TO_KSEG0(x) ((x)-0x20000000) - - - - #endif /* !OCTEON_PCMAP_REGS_H__ */ - From 4d33e6554c02f62c0105a948fcbe6fffc3cf123b Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 6 Jul 2009 18:18:27 +0000 Subject: [PATCH 189/380] 64-bit fixes: fix printf formats and prefer MIPS_PHYS_TO_KSEG0. --- sys/mips/octeon1/octeon_ebt3000_cf.c | 2 +- sys/mips/octeon1/octeon_machdep.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/sys/mips/octeon1/octeon_ebt3000_cf.c b/sys/mips/octeon1/octeon_ebt3000_cf.c index a776a4046f7..babeece040c 100644 --- a/sys/mips/octeon1/octeon_ebt3000_cf.c +++ b/sys/mips/octeon1/octeon_ebt3000_cf.c @@ -509,7 +509,7 @@ static void cf_identify (driver_t *drv, device_t parent) if (!octeon_board_real()) return; - base_addr = (void *) OCTEON_PHYS2PTR(OCTEON_CF_COMMON_BASE_ADDR); + base_addr = (void *) MIPS_PHYS_TO_KSEG0(OCTEON_CF_COMMON_BASE_ADDR); for (bus_region = 0; bus_region < 8; bus_region++) { diff --git a/sys/mips/octeon1/octeon_machdep.c b/sys/mips/octeon1/octeon_machdep.c index a8d05a8bd34..907f7a4e4ff 100644 --- a/sys/mips/octeon1/octeon_machdep.c +++ b/sys/mips/octeon1/octeon_machdep.c @@ -563,8 +563,9 @@ void ciu_dump_interrutps_enabled (int core_num, int intx, int enx, int ciu_ip) } ciu_intr_bits = oct_read64(ciu_intr_reg_addr); - printf(" CIU core %d int: %d en: %d ip: %d Add: 0x%llX enabled: 0x%llX SR: %X\n", - core_num, intx, enx, ciu_ip, ciu_intr_reg_addr, ciu_intr_bits, mips_rd_status()); + printf(" CIU core %d int: %d en: %d ip: %d Add: %p enabled: 0x%llX SR: %x\n", + core_num, intx, enx, ciu_ip, (void *)ciu_intr_reg_addr, + (unsigned long long)ciu_intr_bits, mips_rd_status()); } From b661054728dea5b58ab729e0682bbd13150be603 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 7 Jul 2009 19:55:09 +0000 Subject: [PATCH 190/380] - Move dpcpu initialization to mips_proc0_init. It's more appropriate place for it. Besides dpcpu_init requires pmap module to be initialized and calling it int pmap.c hangs the system --- sys/mips/mips/machdep.c | 3 +++ sys/mips/mips/pmap.c | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c index 7b2825714aa..37a25b14e2f 100644 --- a/sys/mips/mips/machdep.c +++ b/sys/mips/mips/machdep.c @@ -274,6 +274,9 @@ mips_proc0_init(void) (thread0.td_kstack_pages - 1) * PAGE_SIZE) - 1; thread0.td_frame = &thread0.td_pcb->pcb_regs; + /* Steal memory for the dynamic per-cpu area. */ + dpcpu_init((void *)pmap_steal_memory(DPCPU_SIZE), 0); + /* * There is no need to initialize md_upte array for thread0 as it's * located in .bss section and should be explicitly zeroed during diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index 32879280085..2ee7550f30a 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -332,9 +332,6 @@ again: msgbufp = (struct msgbuf *)pmap_steal_memory(MSGBUF_SIZE); msgbufinit(msgbufp, MSGBUF_SIZE); - /* Steal memory for the dynamic per-cpu area. */ - dpcpu_init((void *)pmap_steal_memory(DPCPU_SIZE), 0); - /* * Steal thread0 kstack. */ From 41d99511cbdf4d4f2a1650aed77d2f080108b7a9 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 8 Jul 2009 02:21:08 +0000 Subject: [PATCH 191/380] - Fix off-by-one bug in arge_fixup_rx. If mbuf is located by the end of the page and even number of bytes long, that may cause TLBMiss exception for unallocated address. - Fix mess with DMA sync opeartions --- sys/mips/atheros/if_arge.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index 5a6244efe83..88d4384e47d 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -162,7 +162,6 @@ DRIVER_MODULE(miibus, arge, miibus_driver, miibus_devclass, 0, 0); */ extern uint32_t ar711_base_mac[ETHER_ADDR_LEN]; - /* * Flushes all */ @@ -1323,7 +1322,7 @@ arge_rx_ring_init(struct arge_softc *sc) bus_dmamap_sync(sc->arge_cdata.arge_rx_ring_tag, sc->arge_cdata.arge_rx_ring_map, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + BUS_DMASYNC_PREWRITE); return (0); } @@ -1356,8 +1355,6 @@ arge_newbuf(struct arge_softc *sc, int idx) rxd = &sc->arge_cdata.arge_rxdesc[idx]; if (rxd->rx_m != NULL) { - bus_dmamap_sync(sc->arge_cdata.arge_rx_tag, rxd->rx_dmamap, - BUS_DMASYNC_POSTREAD); bus_dmamap_unload(sc->arge_cdata.arge_rx_tag, rxd->rx_dmamap); } map = rxd->rx_dmamap; @@ -1370,6 +1367,10 @@ arge_newbuf(struct arge_softc *sc, int idx) desc->packet_addr = segs[0].ds_addr; desc->packet_ctrl = ARGE_DESC_EMPTY | ARGE_DMASIZE(segs[0].ds_len); + bus_dmamap_sync(sc->arge_cdata.arge_rx_ring_tag, + sc->arge_cdata.arge_rx_ring_map, + BUS_DMASYNC_PREWRITE); + return (0); } @@ -1382,8 +1383,12 @@ arge_fixup_rx(struct mbuf *m) src = mtod(m, uint16_t *); dst = src - 1; - for (i = 0; i < (m->m_len / sizeof(uint16_t) + 1); i++) + for (i = 0; i < m->m_len / sizeof(uint16_t); i++) { *dst++ = *src++; + } + + if (m->m_len % sizeof(uint16_t)) + *(uint8_t *)dst = *(uint8_t *)src; m->m_data -= ETHER_ALIGN; } @@ -1497,7 +1502,7 @@ arge_rx_locked(struct arge_softc *sc) packet_len = ARGE_DMASIZE(cur_rx->packet_ctrl); bus_dmamap_sync(sc->arge_cdata.arge_rx_tag, rxd->rx_dmamap, - BUS_DMASYNC_PREREAD); + BUS_DMASYNC_POSTREAD); m = rxd->rx_m; arge_fixup_rx(m); @@ -1526,14 +1531,9 @@ arge_rx_locked(struct arge_softc *sc) bus_dmamap_sync(sc->arge_cdata.arge_rx_ring_tag, sc->arge_cdata.arge_rx_ring_map, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - + BUS_DMASYNC_PREWRITE); sc->arge_cdata.arge_rx_cons = cons; - - bus_dmamap_sync(sc->arge_cdata.arge_rx_ring_tag, - sc->arge_cdata.arge_rx_ring_map, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); } } From 59e5dff794b2e804890405750ee04a5765bf533b Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 8 Jul 2009 05:57:58 +0000 Subject: [PATCH 192/380] The kernel isn't quite ready for this to be optional... --- sys/conf/files.mips | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/conf/files.mips b/sys/conf/files.mips index c8c6b8cd267..2828d441aff 100644 --- a/sys/conf/files.mips +++ b/sys/conf/files.mips @@ -49,7 +49,7 @@ mips/mips/tick.c standard # ---------------------------------------------------------------------- # Phase 5 # ---------------------------------------------------------------------- -mips/mips/fp.S optional hardfp +mips/mips/fp.S standard mips/mips/pm_machdep.c standard mips/mips/swtch.S standard mips/mips/tlb.S standard From 902598a268af9334f718a1586aabf4a1cd5e14e6 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 8 Jul 2009 06:00:18 +0000 Subject: [PATCH 193/380] Turns out this code was right, revert last change. --- sys/mips/mips/db_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/mips/db_interface.c b/sys/mips/mips/db_interface.c index 80f65f23f64..455c03e4dc5 100644 --- a/sys/mips/mips/db_interface.c +++ b/sys/mips/mips/db_interface.c @@ -197,7 +197,7 @@ db_write_bytes(vm_offset_t addr, size_t size, char *data) break; case 8: atomic_store_64((volatile u_int64_t *)addr, - *(u_int64_t *)data); + (u_int64_t *)data); break; } } else { From 5ac0137013d34299ce45c751599f91b686c6f515 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 8 Jul 2009 06:01:37 +0000 Subject: [PATCH 194/380] Fix atomic_store_64 prototype for 64-bit systems. --- sys/mips/include/atomic.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sys/mips/include/atomic.h b/sys/mips/include/atomic.h index ab99a6e5c51..4b87738cf90 100644 --- a/sys/mips/include/atomic.h +++ b/sys/mips/include/atomic.h @@ -346,10 +346,9 @@ void atomic_store_64(__volatile uint64_t *, uint64_t *); void atomic_load_64(__volatile uint64_t *, uint64_t *); #else static __inline void -atomic_store_64(__volatile uint64_t *p, uint64_t v) +atomic_store_64(__volatile uint64_t *p, uint64_t *v) { - - *p = v; + *p = *v; } static __inline void From 63080dcd946e1cb656e473d54f00903ac9a5c7f8 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 8 Jul 2009 17:20:53 +0000 Subject: [PATCH 195/380] - Fix PCI routing code --- sys/mips/atheros/ar71xx_pci.c | 5 ++++- sys/mips/atheros/ar71xxreg.h | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/sys/mips/atheros/ar71xx_pci.c b/sys/mips/atheros/ar71xx_pci.c index 345091a188a..000860d904c 100644 --- a/sys/mips/atheros/ar71xx_pci.c +++ b/sys/mips/atheros/ar71xx_pci.c @@ -513,8 +513,11 @@ ar71xx_pci_maxslots(device_t dev) static int ar71xx_pci_route_interrupt(device_t pcib, device_t device, int pin) { + if (pci_get_slot(device) < AR71XX_PCI_BASE_SLOT) + panic("%s: PCI slot %d is less then AR71XX_PCI_BASE_SLOT", + __func__, pci_get_slot(device)); - return (pin); + return (pci_get_slot(device) - AR71XX_PCI_BASE_SLOT); } static device_method_t ar71xx_pci_methods[] = { diff --git a/sys/mips/atheros/ar71xxreg.h b/sys/mips/atheros/ar71xxreg.h index c5765320749..33ae55ce51a 100644 --- a/sys/mips/atheros/ar71xxreg.h +++ b/sys/mips/atheros/ar71xxreg.h @@ -42,6 +42,10 @@ #define AR71XX_PCI_IRQ_START 0 #define AR71XX_PCI_IRQ_END 2 #define AR71XX_PCI_NIRQS 3 +/* + * PCI devices slots are starting from this number + */ +#define AR71XX_PCI_BASE_SLOT 17 /* PCI config registers */ #define AR71XX_PCI_LCONF_CMD 0x17010000 From 258430ffd11c71ac650924a9b17d3e22a8e4f707 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 8 Jul 2009 22:28:36 +0000 Subject: [PATCH 196/380] - Port busdma code from FreeBSD/arm. This is more mature version that takes into account all limitation to DMA memory (boundaries, alignment) and implements bounce pages. - Add BUS_DMASYNC_POSTREAD case to bus_dmamap_sync_buf --- sys/mips/include/md_var.h | 3 + sys/mips/mips/busdma_machdep.c | 900 +++++++++++++++++++++++++++------ 2 files changed, 742 insertions(+), 161 deletions(-) diff --git a/sys/mips/include/md_var.h b/sys/mips/include/md_var.h index 6aa557977f6..4101ee6a8dd 100644 --- a/sys/mips/include/md_var.h +++ b/sys/mips/include/md_var.h @@ -70,4 +70,7 @@ void mips_proc0_init(void); /* Platform call-downs. */ void platform_identify(void); +extern int busdma_swi_pending; +void busdma_swi(void); + #endif /* !_MACHINE_MD_VAR_H_ */ diff --git a/sys/mips/mips/busdma_machdep.c b/sys/mips/mips/busdma_machdep.c index 13c45b84b00..1c5229ea31b 100644 --- a/sys/mips/mips/busdma_machdep.c +++ b/sys/mips/mips/busdma_machdep.c @@ -23,50 +23,16 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * + * From i386/busdma_machdep.c,v 1.26 2002/04/19 22:58:09 alfred */ -/*- - * Copyright (c) 1997, 1998, 2001 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, - * NASA Ames Research Center. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* $NetBSD: bus_dma.c,v 1.17 2006/03/01 12:38:11 yamt Exp $ */ - #include __FBSDID("$FreeBSD$"); +/* + * MIPS bus dma support routines + */ + #include #include #include @@ -79,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -88,6 +55,13 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include + +#define MAX_BPAGES 64 +#define BUS_DMA_COULD_BOUNCE BUS_DMA_BUS3 +#define BUS_DMA_MIN_ALLOC_COMP BUS_DMA_BUS4 + +struct bounce_zone; struct bus_dma_tag { bus_dma_tag_t parent; @@ -105,12 +79,47 @@ struct bus_dma_tag { int map_count; bus_dma_lock_t *lockfunc; void *lockfuncarg; - /* XXX: machine-dependent fields */ - vm_offset_t _physbase; - vm_offset_t _wbase; - vm_offset_t _wsize; + struct bounce_zone *bounce_zone; }; +struct bounce_page { + vm_offset_t vaddr; /* kva of bounce buffer */ + vm_offset_t vaddr_nocache; /* kva of bounce buffer uncached */ + bus_addr_t busaddr; /* Physical address */ + vm_offset_t datavaddr; /* kva of client data */ + bus_size_t datacount; /* client data count */ + STAILQ_ENTRY(bounce_page) links; +}; + +int busdma_swi_pending; + +struct bounce_zone { + STAILQ_ENTRY(bounce_zone) links; + STAILQ_HEAD(bp_list, bounce_page) bounce_page_list; + int total_bpages; + int free_bpages; + int reserved_bpages; + int active_bpages; + int total_bounced; + int total_deferred; + int map_count; + bus_size_t alignment; + bus_addr_t lowaddr; + char zoneid[8]; + char lowaddrid[20]; + struct sysctl_ctx_list sysctl_tree; + struct sysctl_oid *sysctl_tree_top; +}; + +static struct mtx bounce_lock; +static int total_bpages; +static int busdma_zonecount; +static STAILQ_HEAD(, bounce_zone) bounce_zone_list; + +SYSCTL_NODE(_hw, OID_AUTO, busdma, CTLFLAG_RD, 0, "Busdma parameters"); +SYSCTL_INT(_hw_busdma, OID_AUTO, total_bpages, CTLFLAG_RD, &total_bpages, 0, + "Total bounce pages"); + #define DMAMAP_LINEAR 0x1 #define DMAMAP_MBUF 0x2 #define DMAMAP_UIO 0x4 @@ -118,6 +127,9 @@ struct bus_dma_tag { #define DMAMAP_TYPE_MASK (DMAMAP_LINEAR|DMAMAP_MBUF|DMAMAP_UIO) #define DMAMAP_COHERENT 0x8 struct bus_dmamap { + struct bp_list bpages; + int pagesneeded; + int pagesreserved; bus_dma_tag_t dmat; int flags; void *buffer; @@ -125,8 +137,15 @@ struct bus_dmamap { void *allocbuffer; TAILQ_ENTRY(bus_dmamap) freelist; int len; + STAILQ_ENTRY(bus_dmamap) links; + bus_dmamap_callback_t *callback; + void *callback_arg; + }; +static STAILQ_HEAD(, bus_dmamap) bounce_map_waitinglist; +static STAILQ_HEAD(, bus_dmamap) bounce_map_callbacklist; + static TAILQ_HEAD(,bus_dmamap) dmamap_freelist = TAILQ_HEAD_INITIALIZER(dmamap_freelist); @@ -137,6 +156,45 @@ static struct mtx busdma_mtx; MTX_SYSINIT(busdma_mtx, &busdma_mtx, "busdma lock", MTX_DEF); +static void init_bounce_pages(void *dummy); +static int alloc_bounce_zone(bus_dma_tag_t dmat); +static int alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages); +static int reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map, + int commit); +static bus_addr_t add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, + vm_offset_t vaddr, bus_size_t size); +static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage); + +/* Default tag, as most drivers provide no parent tag. */ +bus_dma_tag_t mips_root_dma_tag; + +/* + * Return true if a match is made. + * + * To find a match walk the chain of bus_dma_tag_t's looking for 'paddr'. + * + * If paddr is within the bounds of the dma tag then call the filter callback + * to check for a match, if there is no filter callback then assume a match. + */ +static int +run_filter(bus_dma_tag_t dmat, bus_addr_t paddr) +{ + int retval; + + retval = 0; + + do { + if (((paddr > dmat->lowaddr && paddr <= dmat->highaddr) + || ((paddr & (dmat->alignment - 1)) != 0)) + && (dmat->filter == NULL + || (*dmat->filter)(dmat->filterarg, paddr) != 0)) + retval = 1; + + dmat = dmat->parent; + } while (retval == 0 && dmat != NULL); + return (retval); +} + static void mips_dmamap_freelist_init(void *dummy) { @@ -157,6 +215,19 @@ bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dma_segment_t *segs, bus_dmamap_t map, void *buf, bus_size_t buflen, struct pmap *pmap, int flags, vm_offset_t *lastaddrp, int *segp); +static __inline int +_bus_dma_can_bounce(vm_offset_t lowaddr, vm_offset_t highaddr) +{ + int i; + for (i = 0; phys_avail[i] && phys_avail[i + 1]; i += 2) { + if ((lowaddr >= phys_avail[i] && lowaddr <= phys_avail[i + 1]) + || (lowaddr < phys_avail[i] && + highaddr > phys_avail[i])) + return (1); + } + return (0); +} + /* * Convenience function for manipulating driver locks from busdma (during * busdma_swi, for example). Drivers that don't provide their own locks @@ -213,6 +284,7 @@ _busdma_alloc_dmamap(void) map->flags = DMAMAP_ALLOCATED; } else map->flags = 0; + STAILQ_INIT(&map->bpages); return (map); } @@ -228,6 +300,11 @@ _busdma_free_dmamap(bus_dmamap_t map) } } +/* + * Allocate a device specific dma_tag. + */ +#define SEG_NB 1024 + int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, bus_size_t boundary, bus_addr_t lowaddr, @@ -238,16 +315,12 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, { bus_dma_tag_t newtag; int error = 0; - - /* Basic sanity checking */ - if (boundary != 0 && boundary < maxsegsz) - maxsegsz = boundary; - /* Return a NULL tag on failure */ *dmat = NULL; + if (!parent) + parent = mips_root_dma_tag; - newtag = (bus_dma_tag_t)malloc(sizeof(*newtag), M_DEVBUF, - M_ZERO | M_NOWAIT); + newtag = (bus_dma_tag_t)malloc(sizeof(*newtag), M_DEVBUF, M_NOWAIT); if (newtag == NULL) { CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d", __func__, newtag, 0, error); @@ -257,21 +330,16 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, newtag->parent = parent; newtag->alignment = alignment; newtag->boundary = boundary; - newtag->lowaddr = trunc_page((vm_paddr_t)lowaddr) + (PAGE_SIZE - 1); - newtag->highaddr = trunc_page((vm_paddr_t)highaddr) + - (PAGE_SIZE - 1); + newtag->lowaddr = trunc_page((vm_offset_t)lowaddr) + (PAGE_SIZE - 1); + newtag->highaddr = trunc_page((vm_offset_t)highaddr) + (PAGE_SIZE - 1); newtag->filter = filter; newtag->filterarg = filterarg; - newtag->maxsize = maxsize; - newtag->nsegments = nsegments; + newtag->maxsize = maxsize; + newtag->nsegments = nsegments; newtag->maxsegsz = maxsegsz; newtag->flags = flags; newtag->ref_count = 1; /* Count ourself */ newtag->map_count = 0; - newtag->_wbase = 0; - newtag->_physbase = 0; - /* XXXMIPS: Should we limit window size to amount of physical memory */ - newtag->_wsize = MIPS_KSEG1_START - MIPS_KSEG0_START; if (lockfunc != NULL) { newtag->lockfunc = lockfunc; newtag->lockfuncarg = lockfuncarg; @@ -279,36 +347,68 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, newtag->lockfunc = dflt_lock; newtag->lockfuncarg = NULL; } - - /* Take into account any restrictions imposed by our parent tag */ - if (parent != NULL) { - newtag->lowaddr = MIN(parent->lowaddr, newtag->lowaddr); - newtag->highaddr = MAX(parent->highaddr, newtag->highaddr); + /* + * Take into account any restrictions imposed by our parent tag + */ + if (parent != NULL) { + newtag->lowaddr = min(parent->lowaddr, newtag->lowaddr); + newtag->highaddr = max(parent->highaddr, newtag->highaddr); if (newtag->boundary == 0) newtag->boundary = parent->boundary; else if (parent->boundary != 0) - newtag->boundary = MIN(parent->boundary, + newtag->boundary = min(parent->boundary, newtag->boundary); - if (newtag->filter == NULL) { - /* - * Short circuit looking at our parent directly - * since we have encapsulated all of its information - */ - newtag->filter = parent->filter; - newtag->filterarg = parent->filterarg; - newtag->parent = parent->parent; + if ((newtag->filter != NULL) || + ((parent->flags & BUS_DMA_COULD_BOUNCE) != 0)) + newtag->flags |= BUS_DMA_COULD_BOUNCE; + if (newtag->filter == NULL) { + /* + * Short circuit looking at our parent directly + * since we have encapsulated all of its information + */ + newtag->filter = parent->filter; + newtag->filterarg = parent->filterarg; + newtag->parent = parent->parent; } if (newtag->parent != NULL) atomic_add_int(&parent->ref_count, 1); } + if (_bus_dma_can_bounce(newtag->lowaddr, newtag->highaddr) + || newtag->alignment > 1) + newtag->flags |= BUS_DMA_COULD_BOUNCE; - if (error != 0) { + if (((newtag->flags & BUS_DMA_COULD_BOUNCE) != 0) && + (flags & BUS_DMA_ALLOCNOW) != 0) { + struct bounce_zone *bz; + + /* Must bounce */ + + if ((error = alloc_bounce_zone(newtag)) != 0) { + free(newtag, M_DEVBUF); + return (error); + } + bz = newtag->bounce_zone; + + if (ptoa(bz->total_bpages) < maxsize) { + int pages; + + pages = atop(maxsize) - bz->total_bpages; + + /* Add pages to our bounce pool */ + if (alloc_bounce_pages(newtag, pages) < pages) + error = ENOMEM; + } + /* Performed initial allocation */ + newtag->flags |= BUS_DMA_MIN_ALLOC_COMP; + } else + newtag->bounce_zone = NULL; + if (error != 0) free(newtag, M_DEVBUF); - } else { + else *dmat = newtag; - } CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d", __func__, newtag, (newtag != NULL ? newtag->flags : 0), error); + return (error); } @@ -346,6 +446,7 @@ bus_dma_tag_destroy(bus_dma_tag_t dmat) return (0); } +#include /* * Allocate a handle for mapping from kva/uva/physical * address space into bus device space. @@ -354,9 +455,7 @@ int bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) { bus_dmamap_t newmap; -#ifdef KTR int error = 0; -#endif newmap = _busdma_alloc_dmamap(); if (newmap == NULL) { @@ -365,13 +464,60 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) } *mapp = newmap; newmap->dmat = dmat; + newmap->allocbuffer = NULL; dmat->map_count++; + /* + * Bouncing might be required if the driver asks for an active + * exclusion region, a data alignment that is stricter than 1, and/or + * an active address boundary. + */ + if (dmat->flags & BUS_DMA_COULD_BOUNCE) { + + /* Must bounce */ + struct bounce_zone *bz; + int maxpages; + + if (dmat->bounce_zone == NULL) { + if ((error = alloc_bounce_zone(dmat)) != 0) { + _busdma_free_dmamap(newmap); + *mapp = NULL; + return (error); + } + } + bz = dmat->bounce_zone; + + /* Initialize the new map */ + STAILQ_INIT(&((*mapp)->bpages)); + + /* + * Attempt to add pages to our pool on a per-instance + * basis up to a sane limit. + */ + maxpages = MAX_BPAGES; + if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0 + || (bz->map_count > 0 && bz->total_bpages < maxpages)) { + int pages; + + pages = MAX(atop(dmat->maxsize), 1); + pages = MIN(maxpages - bz->total_bpages, pages); + pages = MAX(pages, 1); + if (alloc_bounce_pages(dmat, pages) < pages) + error = ENOMEM; + + if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0) { + if (error == 0) + dmat->flags |= BUS_DMA_MIN_ALLOC_COMP; + } else { + error = 0; + } + } + bz->map_count++; + } CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", __func__, dmat, dmat->flags, error); return (0); - } /* @@ -381,7 +527,15 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) int bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map) { + _busdma_free_dmamap(map); + if (STAILQ_FIRST(&map->bpages) != NULL) { + CTR3(KTR_BUSDMA, "%s: tag %p error %d", + __func__, dmat, EBUSY); + return (EBUSY); + } + if (dmat->bounce_zone) + dmat->bounce_zone->map_count--; dmat->map_count--; CTR2(KTR_BUSDMA, "%s: tag %p error 0", __func__, dmat); return (0); @@ -417,7 +571,10 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, *mapp = newmap; newmap->dmat = dmat; - if (dmat->maxsize <= PAGE_SIZE) { + if (dmat->maxsize <= PAGE_SIZE && + (dmat->alignment < dmat->maxsize) && + !_bus_dma_can_bounce(dmat->lowaddr, dmat->highaddr) && + !(flags & BUS_DMA_COHERENT)) { *vaddr = malloc(dmat->maxsize, M_DEVBUF, mflags); } else { /* @@ -440,7 +597,7 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, maxphys = dmat->lowaddr; } *vaddr = contigmalloc(dmat->maxsize, M_DEVBUF, mflags, - 0ul, maxphys, dmat->alignment? dmat->alignment : 1ul, + 0ul, dmat->lowaddr, dmat->alignment? dmat->alignment : 1ul, dmat->boundary); } if (*vaddr == NULL) { @@ -451,22 +608,37 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, *mapp = NULL; return (ENOMEM); } + if (flags & BUS_DMA_COHERENT) { void *tmpaddr = (void *)*vaddr; + unsigned char *buf1 = (void *)*vaddr; if (tmpaddr) { + int gi; tmpaddr = (void *)MIPS_PHYS_TO_KSEG1(vtophys(tmpaddr)); + unsigned char *buf2 = tmpaddr; + unsigned char *buf3 = (void + *)MIPS_PHYS_TO_KSEG0(vtophys(tmpaddr)); newmap->origbuffer = *vaddr; newmap->allocbuffer = tmpaddr; mips_dcache_wbinv_range((vm_offset_t)*vaddr, dmat->maxsize); *vaddr = tmpaddr; + for (gi = 0; gi < dmat->maxsize; gi++) { + if (buf1[gi] != buf2[gi]) + panic("cache fucked up\n"); + + if (buf1[gi] != buf3[gi]) + panic("cache fucked up2\n"); + } } else newmap->origbuffer = newmap->allocbuffer = NULL; - } else + } else { + unsigned char *buf1 = (void *)*vaddr; newmap->origbuffer = newmap->allocbuffer = NULL; - return (0); + } + return (0); } /* @@ -481,7 +653,9 @@ bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map) ("Trying to freeing the wrong DMA buffer")); vaddr = map->origbuffer; } - if (dmat->maxsize <= PAGE_SIZE) + if (dmat->maxsize <= PAGE_SIZE && + dmat->alignment < dmat->maxsize && + !_bus_dma_can_bounce(dmat->lowaddr, dmat->highaddr)) free(vaddr, M_DEVBUF); else { contigfree(vaddr, dmat->maxsize, M_DEVBUF); @@ -489,7 +663,60 @@ bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map) dmat->map_count--; _busdma_free_dmamap(map); CTR3(KTR_BUSDMA, "%s: tag %p flags 0x%x", __func__, dmat, dmat->flags); +} +static int +_bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map, pmap_t pmap, + void *buf, bus_size_t buflen, int flags) +{ + vm_offset_t vaddr; + vm_offset_t vendaddr; + bus_addr_t paddr; + + if ((map->pagesneeded == 0)) { + CTR3(KTR_BUSDMA, "lowaddr= %d, boundary= %d, alignment= %d", + dmat->lowaddr, dmat->boundary, dmat->alignment); + CTR2(KTR_BUSDMA, "map= %p, pagesneeded= %d", + map, map->pagesneeded); + /* + * Count the number of bounce pages + * needed in order to complete this transfer + */ + vaddr = trunc_page((vm_offset_t)buf); + vendaddr = (vm_offset_t)buf + buflen; + + while (vaddr < vendaddr) { + KASSERT(kernel_pmap == pmap, ("pmap is not kernel pmap")); + paddr = pmap_kextract(vaddr); + if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) && + run_filter(dmat, paddr) != 0) + map->pagesneeded++; + vaddr += PAGE_SIZE; + } + CTR1(KTR_BUSDMA, "pagesneeded= %d\n", map->pagesneeded); + } + + /* Reserve Necessary Bounce Pages */ + if (map->pagesneeded != 0) { + mtx_lock(&bounce_lock); + if (flags & BUS_DMA_NOWAIT) { + if (reserve_bounce_pages(dmat, map, 0) != 0) { + mtx_unlock(&bounce_lock); + return (ENOMEM); + } + } else { + if (reserve_bounce_pages(dmat, map, 1) != 0) { + /* Queue us for resources */ + STAILQ_INSERT_TAIL(&bounce_map_waitinglist, + map, links); + mtx_unlock(&bounce_lock); + return (EINPROGRESS); + } + } + mtx_unlock(&bounce_lock); + } + + return (0); } /* @@ -504,8 +731,7 @@ bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dma_segment_t *segs, int flags, vm_offset_t *lastaddrp, int *segp) { bus_size_t sgsize; - bus_size_t bmask; - vm_offset_t curaddr, lastaddr; + bus_addr_t curaddr, lastaddr, baddr, bmask; vm_offset_t vaddr = (vm_offset_t)buf; int seg; int error = 0; @@ -513,35 +739,47 @@ bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dma_segment_t *segs, lastaddr = *lastaddrp; bmask = ~(dmat->boundary - 1); + if ((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) { + error = _bus_dmamap_count_pages(dmat, map, pmap, buf, buflen, + flags); + if (error) + return (error); + } + CTR3(KTR_BUSDMA, "lowaddr= %d boundary= %d, " + "alignment= %d", dmat->lowaddr, dmat->boundary, dmat->alignment); + for (seg = *segp; buflen > 0 ; ) { /* * Get the physical address for this segment. + * + * XXX Don't support checking for coherent mappings + * XXX in user address space. */ KASSERT(kernel_pmap == pmap, ("pmap is not kernel pmap")); curaddr = pmap_kextract(vaddr); - /* - * If we're beyond the current DMA window, indicate - * that and try to fall back onto something else. - */ - if (curaddr < dmat->_physbase || - curaddr >= (dmat->_physbase + dmat->_wsize)) - return (EINVAL); - - /* - * In a valid DMA range. Translate the physical - * memory address to an address in the DMA window. - */ - curaddr = (curaddr - dmat->_physbase) + dmat->_wbase; - - /* * Compute the segment size, and adjust counts. */ sgsize = PAGE_SIZE - ((u_long)curaddr & PAGE_MASK); + if (sgsize > dmat->maxsegsz) + sgsize = dmat->maxsegsz; if (buflen < sgsize) sgsize = buflen; + /* + * Make sure we don't cross any boundaries. + */ + if (dmat->boundary > 0) { + baddr = (curaddr + dmat->boundary) & bmask; + if (sgsize > (baddr - curaddr)) + sgsize = (baddr - curaddr); + } + if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) && + map->pagesneeded != 0 && run_filter(dmat, curaddr)) { + curaddr = add_bounce_page(dmat, map, vaddr, sgsize); + } + /* * Insert chunk into a segment, coalescing with * the previous segment if possible. @@ -569,14 +807,15 @@ segdone: *segp = seg; *lastaddrp = lastaddr; + if (map->flags & DMAMAP_COHERENT) + panic("not coherent\n"); /* * Did we fit? */ if (buflen != 0) - error = EFBIG; - - return error; + error = EFBIG; /* XXX better return value here? */ + return (error); } /* @@ -597,14 +836,17 @@ bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, KASSERT(dmat != NULL, ("dmatag is NULL")); KASSERT(map != NULL, ("dmamap is NULL")); + map->callback = callback; + map->callback_arg = callback_arg; map->flags &= ~DMAMAP_TYPE_MASK; - map->flags |= DMAMAP_LINEAR|DMAMAP_COHERENT; + map->flags |= DMAMAP_LINEAR; map->buffer = buf; map->len = buflen; error = bus_dmamap_load_buffer(dmat, dm_segments, map, buf, buflen, kernel_pmap, flags, &lastaddr, &nsegs); - + if (error == EINPROGRESS) + return (error); if (error) (*callback)(callback_arg, NULL, 0, error); else @@ -613,8 +855,7 @@ bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", __func__, dmat, dmat->flags, nsegs + 1, error); - return (0); - + return (error); } /* @@ -635,10 +876,9 @@ bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0, M_ASSERTPKTHDR(m0); map->flags &= ~DMAMAP_TYPE_MASK; - map->flags |= DMAMAP_MBUF | DMAMAP_COHERENT; + map->flags |= DMAMAP_MBUF; map->buffer = m0; map->len = 0; - if (m0->m_pkthdr.len <= dmat->maxsize) { vm_offset_t lastaddr = 0; struct mbuf *m; @@ -676,16 +916,14 @@ bus_dmamap_load_mbuf_sg(bus_dma_tag_t dmat, bus_dmamap_t map, int flags) { int error = 0; - M_ASSERTPKTHDR(m0); flags |= BUS_DMA_NOWAIT; *nsegs = -1; map->flags &= ~DMAMAP_TYPE_MASK; - map->flags |= DMAMAP_MBUF | DMAMAP_COHERENT; - map->buffer = m0; + map->flags |= DMAMAP_MBUF; + map->buffer = m0; map->len = 0; - if (m0->m_pkthdr.len <= dmat->maxsize) { vm_offset_t lastaddr = 0; struct mbuf *m; @@ -693,8 +931,9 @@ bus_dmamap_load_mbuf_sg(bus_dma_tag_t dmat, bus_dmamap_t map, for (m = m0; m != NULL && error == 0; m = m->m_next) { if (m->m_len > 0) { error = bus_dmamap_load_buffer(dmat, segs, map, - m->m_data, m->m_len, - kernel_pmap, flags, &lastaddr, nsegs); + m->m_data, m->m_len, + kernel_pmap, flags, &lastaddr, + nsegs); map->len += m->m_len; } } @@ -702,12 +941,11 @@ bus_dmamap_load_mbuf_sg(bus_dma_tag_t dmat, bus_dmamap_t map, error = EINVAL; } + /* XXX FIXME: Having to increment nsegs is really annoying */ ++*nsegs; CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", __func__, dmat, dmat->flags, error, *nsegs); - return (error); - } /* @@ -718,9 +956,65 @@ bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map, struct uio *uio, bus_dmamap_callback2_t *callback, void *callback_arg, int flags) { + vm_offset_t lastaddr = 0; +#ifdef __CC_SUPPORTS_DYNAMIC_ARRAY_INIT + bus_dma_segment_t dm_segments[dmat->nsegments]; +#else + bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; +#endif + int nsegs, i, error; + bus_size_t resid; + struct iovec *iov; + struct pmap *pmap; - panic("Unimplemented %s at %s:%d\n", __func__, __FILE__, __LINE__); - return (0); + resid = uio->uio_resid; + iov = uio->uio_iov; + map->flags &= ~DMAMAP_TYPE_MASK; + map->flags |= DMAMAP_UIO; + map->buffer = uio; + map->len = 0; + + if (uio->uio_segflg == UIO_USERSPACE) { + KASSERT(uio->uio_td != NULL, + ("bus_dmamap_load_uio: USERSPACE but no proc")); + /* XXX: pmap = vmspace_pmap(uio->uio_td->td_proc->p_vmspace); */ + panic("can't do it yet"); + } else + pmap = kernel_pmap; + + error = 0; + nsegs = -1; + for (i = 0; i < uio->uio_iovcnt && resid != 0 && !error; i++) { + /* + * Now at the first iovec to load. Load each iovec + * until we have exhausted the residual count. + */ + bus_size_t minlen = + resid < iov[i].iov_len ? resid : iov[i].iov_len; + caddr_t addr = (caddr_t) iov[i].iov_base; + + if (minlen > 0) { + error = bus_dmamap_load_buffer(dmat, dm_segments, map, + addr, minlen, pmap, flags, &lastaddr, &nsegs); + + map->len += minlen; + resid -= minlen; + } + } + + if (error) { + /* + * force "no valid mappings" on error in callback. + */ + (*callback)(callback_arg, dm_segments, 0, 0, error); + } else { + (*callback)(callback_arg, dm_segments, nsegs+1, + uio->uio_resid, error); + } + + CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d", + __func__, dmat, dmat->flags, error, nsegs + 1); + return (error); } /* @@ -729,21 +1023,31 @@ bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map, struct uio *uio, void _bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map) { + struct bounce_page *bpage; + map->flags &= ~DMAMAP_TYPE_MASK; + while ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) { + STAILQ_REMOVE_HEAD(&map->bpages, links); + free_bounce_page(dmat, bpage); + } return; } -static __inline void +static void bus_dmamap_sync_buf(void *buf, int len, bus_dmasync_op_t op) { - switch (op) { + case BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE: + case BUS_DMASYNC_POSTREAD: + mips_dcache_inv_range((vm_offset_t)buf, len); + break; + case BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE: mips_dcache_wbinv_range((vm_offset_t)buf, len); break; case BUS_DMASYNC_PREREAD: -#if 1 +#if 0 mips_dcache_wbinv_range((vm_offset_t)buf, len); #else mips_dcache_inv_range((vm_offset_t)buf, len); @@ -756,6 +1060,52 @@ bus_dmamap_sync_buf(void *buf, int len, bus_dmasync_op_t op) } } +static void +_bus_dmamap_sync_bp(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) +{ + struct bounce_page *bpage; + + panic("sync bp"); + STAILQ_FOREACH(bpage, &map->bpages, links) { + if (op & BUS_DMASYNC_PREWRITE) { + bcopy((void *)bpage->datavaddr, + (void *)(bpage->vaddr_nocache != 0 ? + bpage->vaddr_nocache : bpage->vaddr), + bpage->datacount); + if (bpage->vaddr_nocache == 0) { + mips_dcache_wb_range(bpage->vaddr, + bpage->datacount); + } + dmat->bounce_zone->total_bounced++; + } + if (op & BUS_DMASYNC_POSTREAD) { + if (bpage->vaddr_nocache == 0) { + mips_dcache_inv_range(bpage->vaddr, + bpage->datacount); + } + bcopy((void *)(bpage->vaddr_nocache != 0 ? + bpage->vaddr_nocache : bpage->vaddr), + (void *)bpage->datavaddr, bpage->datacount); + dmat->bounce_zone->total_bounced++; + } + } +} + +static __inline int +_bus_dma_buf_is_in_bp(bus_dmamap_t map, void *buf, int len) +{ + struct bounce_page *bpage; + + STAILQ_FOREACH(bpage, &map->bpages, links) { + if ((vm_offset_t)buf >= bpage->datavaddr && + (vm_offset_t)buf + len <= bpage->datavaddr + + bpage->datacount) + return (1); + } + return (0); + +} + void _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) { @@ -764,51 +1114,23 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) int resid; struct iovec *iov; - - /* - * Mixing PRE and POST operations is not allowed. - */ - if ((op & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)) != 0 && - (op & (BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)) != 0) - panic("_bus_dmamap_sync: mix PRE and POST"); - - /* - * Since we're dealing with a virtually-indexed, write-back - * cache, we need to do the following things: - * - * PREREAD -- Invalidate D-cache. Note we might have - * to also write-back here if we have to use an Index - * op, or if the buffer start/end is not cache-line aligned. - * - * PREWRITE -- Write-back the D-cache. If we have to use - * an Index op, we also have to invalidate. Note that if - * we are doing PREREAD|PREWRITE, we can collapse everything - * into a single op. - * - * POSTREAD -- Nothing. - * - * POSTWRITE -- Nothing. - */ - - /* - * Flush the write buffer. - * XXX Is this always necessary? - */ - mips_wbflush(); - - op &= (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); - if (op == 0) + if (op == BUS_DMASYNC_POSTWRITE) + return; + if (STAILQ_FIRST(&map->bpages)) + _bus_dmamap_sync_bp(dmat, map, op); + if (map->flags & DMAMAP_COHERENT) return; - CTR3(KTR_BUSDMA, "%s: op %x flags %x", __func__, op, map->flags); switch(map->flags & DMAMAP_TYPE_MASK) { case DMAMAP_LINEAR: - bus_dmamap_sync_buf(map->buffer, map->len, op); + if (!(_bus_dma_buf_is_in_bp(map, map->buffer, map->len))) + bus_dmamap_sync_buf(map->buffer, map->len, op); break; case DMAMAP_MBUF: m = map->buffer; while (m) { - if (m->m_len > 0) + if (m->m_len > 0 && + !(_bus_dma_buf_is_in_bp(map, m->m_data, m->m_len))) bus_dmamap_sync_buf(m->m_data, m->m_len, op); m = m->m_next; } @@ -821,7 +1143,10 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) bus_size_t minlen = resid < iov[i].iov_len ? resid : iov[i].iov_len; if (minlen > 0) { - bus_dmamap_sync_buf(iov[i].iov_base, minlen, op); + if (!_bus_dma_buf_is_in_bp(map, iov[i].iov_base, + minlen)) + bus_dmamap_sync_buf(iov[i].iov_base, + minlen, op); resid -= minlen; } } @@ -830,3 +1155,256 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) break; } } + +static void +init_bounce_pages(void *dummy __unused) +{ + + total_bpages = 0; + STAILQ_INIT(&bounce_zone_list); + STAILQ_INIT(&bounce_map_waitinglist); + STAILQ_INIT(&bounce_map_callbacklist); + mtx_init(&bounce_lock, "bounce pages lock", NULL, MTX_DEF); +} +SYSINIT(bpages, SI_SUB_LOCK, SI_ORDER_ANY, init_bounce_pages, NULL); + +static struct sysctl_ctx_list * +busdma_sysctl_tree(struct bounce_zone *bz) +{ + return (&bz->sysctl_tree); +} + +static struct sysctl_oid * +busdma_sysctl_tree_top(struct bounce_zone *bz) +{ + return (bz->sysctl_tree_top); +} + +static int +alloc_bounce_zone(bus_dma_tag_t dmat) +{ + struct bounce_zone *bz; + + /* Check to see if we already have a suitable zone */ + STAILQ_FOREACH(bz, &bounce_zone_list, links) { + if ((dmat->alignment <= bz->alignment) + && (dmat->lowaddr >= bz->lowaddr)) { + dmat->bounce_zone = bz; + return (0); + } + } + + if ((bz = (struct bounce_zone *)malloc(sizeof(*bz), M_DEVBUF, + M_NOWAIT | M_ZERO)) == NULL) + return (ENOMEM); + + STAILQ_INIT(&bz->bounce_page_list); + bz->free_bpages = 0; + bz->reserved_bpages = 0; + bz->active_bpages = 0; + bz->lowaddr = dmat->lowaddr; + bz->alignment = MAX(dmat->alignment, PAGE_SIZE); + bz->map_count = 0; + snprintf(bz->zoneid, 8, "zone%d", busdma_zonecount); + busdma_zonecount++; + snprintf(bz->lowaddrid, 18, "%#jx", (uintmax_t)bz->lowaddr); + STAILQ_INSERT_TAIL(&bounce_zone_list, bz, links); + dmat->bounce_zone = bz; + + sysctl_ctx_init(&bz->sysctl_tree); + bz->sysctl_tree_top = SYSCTL_ADD_NODE(&bz->sysctl_tree, + SYSCTL_STATIC_CHILDREN(_hw_busdma), OID_AUTO, bz->zoneid, + CTLFLAG_RD, 0, ""); + if (bz->sysctl_tree_top == NULL) { + sysctl_ctx_free(&bz->sysctl_tree); + return (0); /* XXX error code? */ + } + + SYSCTL_ADD_INT(busdma_sysctl_tree(bz), + SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, + "total_bpages", CTLFLAG_RD, &bz->total_bpages, 0, + "Total bounce pages"); + SYSCTL_ADD_INT(busdma_sysctl_tree(bz), + SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, + "free_bpages", CTLFLAG_RD, &bz->free_bpages, 0, + "Free bounce pages"); + SYSCTL_ADD_INT(busdma_sysctl_tree(bz), + SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, + "reserved_bpages", CTLFLAG_RD, &bz->reserved_bpages, 0, + "Reserved bounce pages"); + SYSCTL_ADD_INT(busdma_sysctl_tree(bz), + SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, + "active_bpages", CTLFLAG_RD, &bz->active_bpages, 0, + "Active bounce pages"); + SYSCTL_ADD_INT(busdma_sysctl_tree(bz), + SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, + "total_bounced", CTLFLAG_RD, &bz->total_bounced, 0, + "Total bounce requests"); + SYSCTL_ADD_INT(busdma_sysctl_tree(bz), + SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, + "total_deferred", CTLFLAG_RD, &bz->total_deferred, 0, + "Total bounce requests that were deferred"); + SYSCTL_ADD_STRING(busdma_sysctl_tree(bz), + SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, + "lowaddr", CTLFLAG_RD, bz->lowaddrid, 0, ""); + SYSCTL_ADD_INT(busdma_sysctl_tree(bz), + SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, + "alignment", CTLFLAG_RD, &bz->alignment, 0, ""); + + return (0); +} + +static int +alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages) +{ + struct bounce_zone *bz; + int count; + + bz = dmat->bounce_zone; + count = 0; + while (numpages > 0) { + struct bounce_page *bpage; + + bpage = (struct bounce_page *)malloc(sizeof(*bpage), M_DEVBUF, + M_NOWAIT | M_ZERO); + + if (bpage == NULL) + break; + bpage->vaddr = (vm_offset_t)contigmalloc(PAGE_SIZE, M_DEVBUF, + M_NOWAIT, 0ul, + bz->lowaddr, + PAGE_SIZE, + 0); + if (bpage->vaddr == 0) { + free(bpage, M_DEVBUF); + break; + } + bpage->busaddr = pmap_kextract(bpage->vaddr); + bpage->vaddr_nocache = + (vm_offset_t)MIPS_PHYS_TO_KSEG1(bpage->busaddr); + mtx_lock(&bounce_lock); + STAILQ_INSERT_TAIL(&bz->bounce_page_list, bpage, links); + total_bpages++; + bz->total_bpages++; + bz->free_bpages++; + mtx_unlock(&bounce_lock); + count++; + numpages--; + } + return (count); +} + +static int +reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map, int commit) +{ + struct bounce_zone *bz; + int pages; + + mtx_assert(&bounce_lock, MA_OWNED); + bz = dmat->bounce_zone; + pages = MIN(bz->free_bpages, map->pagesneeded - map->pagesreserved); + if (commit == 0 && map->pagesneeded > (map->pagesreserved + pages)) + return (map->pagesneeded - (map->pagesreserved + pages)); + bz->free_bpages -= pages; + bz->reserved_bpages += pages; + map->pagesreserved += pages; + pages = map->pagesneeded - map->pagesreserved; + + return (pages); +} + +static bus_addr_t +add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr, + bus_size_t size) +{ + struct bounce_zone *bz; + struct bounce_page *bpage; + + KASSERT(dmat->bounce_zone != NULL, ("no bounce zone in dma tag")); + KASSERT(map != NULL, ("add_bounce_page: bad map %p", map)); + + bz = dmat->bounce_zone; + if (map->pagesneeded == 0) + panic("add_bounce_page: map doesn't need any pages"); + map->pagesneeded--; + + if (map->pagesreserved == 0) + panic("add_bounce_page: map doesn't need any pages"); + map->pagesreserved--; + + mtx_lock(&bounce_lock); + bpage = STAILQ_FIRST(&bz->bounce_page_list); + if (bpage == NULL) + panic("add_bounce_page: free page list is empty"); + + STAILQ_REMOVE_HEAD(&bz->bounce_page_list, links); + bz->reserved_bpages--; + bz->active_bpages++; + mtx_unlock(&bounce_lock); + + if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) { + /* Page offset needs to be preserved. */ + bpage->vaddr |= vaddr & PAGE_MASK; + bpage->busaddr |= vaddr & PAGE_MASK; + } + bpage->datavaddr = vaddr; + bpage->datacount = size; + STAILQ_INSERT_TAIL(&(map->bpages), bpage, links); + return (bpage->busaddr); +} + +static void +free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage) +{ + struct bus_dmamap *map; + struct bounce_zone *bz; + + bz = dmat->bounce_zone; + bpage->datavaddr = 0; + bpage->datacount = 0; + if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) { + /* + * Reset the bounce page to start at offset 0. Other uses + * of this bounce page may need to store a full page of + * data and/or assume it starts on a page boundary. + */ + bpage->vaddr &= ~PAGE_MASK; + bpage->busaddr &= ~PAGE_MASK; + } + + mtx_lock(&bounce_lock); + STAILQ_INSERT_HEAD(&bz->bounce_page_list, bpage, links); + bz->free_bpages++; + bz->active_bpages--; + if ((map = STAILQ_FIRST(&bounce_map_waitinglist)) != NULL) { + if (reserve_bounce_pages(map->dmat, map, 1) == 0) { + STAILQ_REMOVE_HEAD(&bounce_map_waitinglist, links); + STAILQ_INSERT_TAIL(&bounce_map_callbacklist, + map, links); + busdma_swi_pending = 1; + bz->total_deferred++; + swi_sched(vm_ih, 0); + } + } + mtx_unlock(&bounce_lock); +} + +void +busdma_swi(void) +{ + bus_dma_tag_t dmat; + struct bus_dmamap *map; + + mtx_lock(&bounce_lock); + while ((map = STAILQ_FIRST(&bounce_map_callbacklist)) != NULL) { + STAILQ_REMOVE_HEAD(&bounce_map_callbacklist, links); + mtx_unlock(&bounce_lock); + dmat = map->dmat; + (dmat->lockfunc)(dmat->lockfuncarg, BUS_DMA_LOCK); + bus_dmamap_load(map->dmat, map, map->buffer, map->len, + map->callback, map->callback_arg, /*flags*/0); + (dmat->lockfunc)(dmat->lockfuncarg, BUS_DMA_UNLOCK); + mtx_lock(&bounce_lock); + } + mtx_unlock(&bounce_lock); +} From 93b7e5564749e370ecc3a3f959c1f44d3281120a Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 9 Jul 2009 14:54:09 +0000 Subject: [PATCH 197/380] Addresses should be unsigned long. Make the address constants unsigned long. --- sys/mips/malta/maltareg.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/sys/mips/malta/maltareg.h b/sys/mips/malta/maltareg.h index f2a7d083bbb..c311d30885b 100644 --- a/sys/mips/malta/maltareg.h +++ b/sys/mips/malta/maltareg.h @@ -94,37 +94,37 @@ 15 Secondary IDE Secondary IDE slot/Compact flash connector */ -#define MALTA_SYSTEMRAM_BASE 0x00000000 /* System RAM: */ +#define MALTA_SYSTEMRAM_BASE 0x00000000ul /* System RAM: */ #define MALTA_SYSTEMRAM_SIZE 0x08000000 /* 128 MByte */ -#define MALTA_PCIMEM1_BASE 0x08000000 /* PCI 1 memory: */ +#define MALTA_PCIMEM1_BASE 0x08000000ul /* PCI 1 memory: */ #define MALTA_PCIMEM1_SIZE 0x08000000 /* 128 MByte */ -#define MALTA_PCIMEM2_BASE 0x10000000 /* PCI 2 memory: */ +#define MALTA_PCIMEM2_BASE 0x10000000ul /* PCI 2 memory: */ #define MALTA_PCIMEM2_SIZE 0x08000000 /* 128 MByte */ -#define MALTA_PCIMEM3_BASE 0x18000000 /* PCI 3 memory */ +#define MALTA_PCIMEM3_BASE 0x18000000ul /* PCI 3 memory */ #define MALTA_PCIMEM3_SIZE 0x03e00000 /* 62 MByte */ -#define MALTA_CORECTRL_BASE 0x1be00000 /* Core control: */ +#define MALTA_CORECTRL_BASE 0x1be00000ul /* Core control: */ #define MALTA_CORECTRL_SIZE 0x00200000 /* 2 MByte */ -#define MALTA_RESERVED_BASE1 0x1c000000 /* Reserved: */ +#define MALTA_RESERVED_BASE1 0x1c000000ul /* Reserved: */ #define MALTA_RESERVED_SIZE1 0x02000000 /* 32 MByte */ -#define MALTA_MONITORFLASH_BASE 0x1e000000 /* Monitor Flash: */ +#define MALTA_MONITORFLASH_BASE 0x1e000000ul /* Monitor Flash: */ #define MALTA_MONITORFLASH_SIZE 0x003e0000 /* 4 MByte */ #define MALTA_MONITORFLASH_SECTORSIZE 0x00010000 /* Sect. = 64 KB */ -#define MALTA_FILEFLASH_BASE 0x1e3e0000 /* File Flash (for monitor): */ +#define MALTA_FILEFLASH_BASE 0x1e3e0000ul /* File Flash (for monitor): */ #define MALTA_FILEFLASH_SIZE 0x00020000 /* 128 KByte */ #define MALTA_FILEFLASH_SECTORSIZE 0x00010000 /* Sect. = 64 KB */ -#define MALTA_RESERVED_BASE2 0x1e400000 /* Reserved: */ +#define MALTA_RESERVED_BASE2 0x1e400000ul /* Reserved: */ #define MALTA_RESERVED_SIZE2 0x00c00000 /* 12 MByte */ -#define MALTA_FPGA_BASE 0x1f000000 /* FPGA: */ +#define MALTA_FPGA_BASE 0x1f000000ul /* FPGA: */ #define MALTA_FPGA_SIZE 0x00c00000 /* 12 MByte */ #define MALTA_NMISTATUS (MALTA_FPGA_BASE + 0x24) @@ -191,10 +191,10 @@ #define MALTA_I2COUT 0x10 #define MALTA_I2CSEL 0x18 -#define MALTA_BOOTROM_BASE 0x1fc00000 /* Boot ROM: */ +#define MALTA_BOOTROM_BASE 0x1fc00000ul /* Boot ROM: */ #define MALTA_BOOTROM_SIZE 0x00400000 /* 4 MByte */ -#define MALTA_REVISION 0x1fc00010 +#define MALTA_REVISION 0x1fc00010ul #define MALTA_REV_FPGRV 0xff0000 /* CBUS FPGA revision */ #define MALTA_REV_CORID 0x00fc00 /* Core Board ID */ #define MALTA_REV_CORRV 0x000300 /* Core Board Revision */ From aacc46585b2f21e12f7bec69fce530ff25f24814 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 9 Jul 2009 15:04:24 +0000 Subject: [PATCH 198/380] Make the yamon function pointer stuff 64-bit safe. Make the base unsigned long, and sign extend the address of the function we're calling through. --- sys/mips/malta/yamon.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/mips/malta/yamon.h b/sys/mips/malta/yamon.h index 69705103a40..f039ae8342d 100644 --- a/sys/mips/malta/yamon.h +++ b/sys/mips/malta/yamon.h @@ -38,7 +38,7 @@ #ifndef _MALTA_YAMON_H_ #define _MALTA_YAMON_H_ -#define YAMON_FUNCTION_BASE 0x1fc00500 +#define YAMON_FUNCTION_BASE 0x1fc00500ul #define YAMON_PRINT_COUNT_OFS (YAMON_FUNCTION_BASE + 0x04) #define YAMON_EXIT_OFS (YAMON_FUNCTION_BASE + 0x20) @@ -53,7 +53,7 @@ #define YAMON_GETCHAR_OFS (YAMON_FUNCTION_BASE + 0x50) #define YAMON_SYSCON_READ_OFS (YAMON_FUNCTION_BASE + 0x54) -#define YAMON_FUNC(ofs) (*(uint32_t *)(MIPS_PHYS_TO_KSEG0(ofs))) +#define YAMON_FUNC(ofs) ((long)(*(int32_t *)(MIPS_PHYS_TO_KSEG0(ofs)))) typedef void (*t_yamon_print_count)(uint32_t port, char *s, uint32_t count); #define YAMON_PRINT_COUNT(s, count) \ From f33235245347e17f4461d23a139ee44d8f59f99d Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 9 Jul 2009 15:04:52 +0000 Subject: [PATCH 199/380] Don't force ISA_MIPS32. --- sys/mips/malta/std.malta | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/malta/std.malta b/sys/mips/malta/std.malta index 8a796fea6bd..6035c3294d8 100644 --- a/sys/mips/malta/std.malta +++ b/sys/mips/malta/std.malta @@ -2,7 +2,7 @@ files "../malta/files.malta" cpu CPU_MIPS4KC -options ISA_MIPS32 +#options ISA_MIPS32 device pci device ata device atadisk From e4bd1497e02bb67525b30f66f3cb91c1402935c8 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 9 Jul 2009 15:05:50 +0000 Subject: [PATCH 200/380] Add support for compiling MALTA as mips64. # MALTA64 builds, but doesn't link yet. --- sys/mips/conf/MALTA | 2 ++ sys/mips/conf/MALTA64 | 70 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 sys/mips/conf/MALTA64 diff --git a/sys/mips/conf/MALTA b/sys/mips/conf/MALTA index d4ce4461651..ac6bd6d59f2 100644 --- a/sys/mips/conf/MALTA +++ b/sys/mips/conf/MALTA @@ -33,6 +33,8 @@ options TICK_USE_YAMON_FREQ=defined include "../malta/std.malta" +options ISA_MIPS32 + hints "MALTA.hints" #Default places to look for devices. makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols diff --git a/sys/mips/conf/MALTA64 b/sys/mips/conf/MALTA64 new file mode 100644 index 00000000000..1e3626f6501 --- /dev/null +++ b/sys/mips/conf/MALTA64 @@ -0,0 +1,70 @@ +# MALTA -- Kernel config for MALTA boards +# +# For more information on this file, please read the handbook section on +# Kernel Configuration Files: +# +# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# +# The handbook is also available locally in /usr/share/doc/handbook +# if you've installed the doc distribution, otherwise always see the +# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# latest information. +# +# An exhaustive list of options and more detailed explanations of the +# device lines is also present in the ../../conf/NOTES and NOTES files. +# If you are in doubt as to the purpose or necessity of a line, check first +# in NOTES. +# +# $FreeBSD: projects/mips/sys/mips/conf/MALTA 192819 2009-05-26 17:01:12Z gonzo $ + +ident MALTA + +makeoptions ARCH_FLAGS="-march=mips64 -mabi=64" +makeoptions MIPS_LITTLE_ENDIAN=defined + +options YAMON + +# Don't build any modules yet. +makeoptions MODULES_OVERRIDE="" + +options KERNVIRTADDR=0x80100000 +options TICK_USE_YAMON_FREQ=defined +#options TICK_USE_MALTA_RTC=defined + +include "../malta/std.malta" + +options ISA_MIPS64 + +hints "MALTA.hints" #Default places to look for devices. + +makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols + +options DDB +options KDB + +options SCHED_4BSD #4BSD scheduler +options INET #InterNETworking +options NFSCLIENT #Network Filesystem Client +options NFS_ROOT #NFS usable as /, requires NFSCLIENT +options PSEUDOFS #Pseudo-filesystem framework +options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions + +options FFS #Berkeley Fast Filesystem +options SOFTUPDATES #Enable FFS soft updates support +options UFS_ACL #Support for access control lists +options UFS_DIRHASH #Improve performance on big directories +options ROOTDEVNAME=\"ufs:ad0s1a\" + + +# Debugging for use in -current +options INVARIANTS #Enable calls of extra sanity checking +options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS +#options WITNESS #Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed + +device loop +device ether +device le +device miibus +device md +device uart From 6adaa2749fd17d638cda308b3980d878741a2353 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 9 Jul 2009 19:02:17 +0000 Subject: [PATCH 201/380] - Ooops, this debug code wasn't supposed to get into final commit. My appologises. --- sys/mips/mips/busdma_machdep.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/sys/mips/mips/busdma_machdep.c b/sys/mips/mips/busdma_machdep.c index 1c5229ea31b..350a85139a5 100644 --- a/sys/mips/mips/busdma_machdep.c +++ b/sys/mips/mips/busdma_machdep.c @@ -611,32 +611,18 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, if (flags & BUS_DMA_COHERENT) { void *tmpaddr = (void *)*vaddr; - unsigned char *buf1 = (void *)*vaddr; if (tmpaddr) { - int gi; tmpaddr = (void *)MIPS_PHYS_TO_KSEG1(vtophys(tmpaddr)); - unsigned char *buf2 = tmpaddr; - unsigned char *buf3 = (void - *)MIPS_PHYS_TO_KSEG0(vtophys(tmpaddr)); newmap->origbuffer = *vaddr; newmap->allocbuffer = tmpaddr; mips_dcache_wbinv_range((vm_offset_t)*vaddr, dmat->maxsize); *vaddr = tmpaddr; - for (gi = 0; gi < dmat->maxsize; gi++) { - if (buf1[gi] != buf2[gi]) - panic("cache fucked up\n"); - - if (buf1[gi] != buf3[gi]) - panic("cache fucked up2\n"); - } } else newmap->origbuffer = newmap->allocbuffer = NULL; - } else { - unsigned char *buf1 = (void *)*vaddr; + } else newmap->origbuffer = newmap->allocbuffer = NULL; - } return (0); } @@ -807,8 +793,6 @@ segdone: *segp = seg; *lastaddrp = lastaddr; - if (map->flags & DMAMAP_COHERENT) - panic("not coherent\n"); /* * Did we fit? @@ -1065,7 +1049,6 @@ _bus_dmamap_sync_bp(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) { struct bounce_page *bpage; - panic("sync bp"); STAILQ_FOREACH(bpage, &map->bpages, links) { if (op & BUS_DMASYNC_PREWRITE) { bcopy((void *)bpage->datavaddr, From 61bfa4ba5dfba7810260b70bd3f9d64471ac7297 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 9 Jul 2009 20:11:26 +0000 Subject: [PATCH 202/380] - Move CPU/AHB frequency calculations to functions to prevent code duplication --- sys/mips/atheros/ar71xx_machdep.c | 11 ++---- sys/mips/atheros/ar71xxreg.h | 54 ++++++++++++++++++++++++++---- sys/mips/atheros/uart_bus_ar71xx.c | 13 +------ sys/mips/atheros/uart_cpu_ar71xx.c | 13 +------ 4 files changed, 53 insertions(+), 38 deletions(-) diff --git a/sys/mips/atheros/ar71xx_machdep.c b/sys/mips/atheros/ar71xx_machdep.c index a12095980a6..6ca395a3a71 100644 --- a/sys/mips/atheros/ar71xx_machdep.c +++ b/sys/mips/atheros/ar71xx_machdep.c @@ -100,8 +100,8 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, __register_t a2 __unused, __register_t a3 __unused) { vm_offset_t kernend; - uint64_t platform_counter_freq, freq; - uint32_t reg, div, pll_config; + uint64_t platform_counter_freq; + uint32_t reg; int argc, i, count = 0; char **argv, **envp; @@ -151,12 +151,7 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, * should be called first. */ init_param1(); - pll_config = ATH_READ_REG(AR71XX_PLL_CPU_CONFIG); - div = ((pll_config >> PLL_FB_SHIFT) & PLL_FB_MASK) + 1; - freq = div * AR71XX_BASE_FREQ; - div = ((pll_config >> PLL_CPU_DIV_SEL_SHIFT) & PLL_CPU_DIV_SEL_MASK) - + 1; - platform_counter_freq = freq / div; + platform_counter_freq = ar71xx_cpu_freq(); mips_timer_init_params(platform_counter_freq, 1); cninit(); diff --git a/sys/mips/atheros/ar71xxreg.h b/sys/mips/atheros/ar71xxreg.h index 33ae55ce51a..cc331d4c59d 100644 --- a/sys/mips/atheros/ar71xxreg.h +++ b/sys/mips/atheros/ar71xxreg.h @@ -26,12 +26,6 @@ #ifndef _AR71XX_REG_H_ #define _AR71XX_REG_H_ -#define ATH_READ_REG(reg) \ - *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((reg))) - -#define ATH_WRITE_REG(reg, val) \ - *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((reg))) = (val) - /* PCI region */ #define AR71XX_PCI_MEM_BASE 0x10000000 /* @@ -174,6 +168,15 @@ #define AR71XX_PLL_ETH_EXT_CLK 0x18050018 #define AR71XX_PLL_PCI_CLK 0x1805001C +#define AR71XX_RST_WDOG_CONTROL 0x18060008 +#define RST_WDOG_LAST (1 << 31) +#define RST_WDOG_ACTION_MASK 3 +#define RST_WDOG_ACTION_RESET 3 +#define RST_WDOG_ACTION_NMI 2 +#define RST_WDOG_ACTION_GP_INTR 1 +#define RST_WDOG_ACTION_NOACTION 0 + +#define AR71XX_RST_WDOG_TIMER 0x1806000C /* * APB interrupt status and mask register and interrupt bit numbers for */ @@ -419,4 +422,43 @@ #define SPI_IO_CTRL_DO 1 #define AR71XX_SPI_RDS 0x0C +#define ATH_READ_REG(reg) \ + *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((reg))) + +#define ATH_WRITE_REG(reg, val) \ + *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((reg))) = (val) + +static inline uint64_t +ar71xx_cpu_freq(void) +{ + uint32_t pll_config, div; + uint64_t freq; + + /* PLL freq */ + pll_config = ATH_READ_REG(AR71XX_PLL_CPU_CONFIG); + div = ((pll_config >> PLL_FB_SHIFT) & PLL_FB_MASK) + 1; + freq = div * AR71XX_BASE_FREQ; + /* CPU freq */ + div = ((pll_config >> PLL_CPU_DIV_SEL_SHIFT) & PLL_CPU_DIV_SEL_MASK) + + 1; + freq = freq / div; + + return (freq); +} + +static inline uint64_t +ar71xx_ahb_freq(void) +{ + uint32_t pll_config, div; + uint64_t freq; + + /* PLL freq */ + pll_config = ATH_READ_REG(AR71XX_PLL_CPU_CONFIG); + /* AHB freq */ + div = (((pll_config >> PLL_AHB_DIV_SHIFT) & PLL_AHB_DIV_MASK) + 1) * 2; + freq = ar71xx_cpu_freq() / div; + return (freq); +} + + #endif /* _AR71XX_REG_H_ */ diff --git a/sys/mips/atheros/uart_bus_ar71xx.c b/sys/mips/atheros/uart_bus_ar71xx.c index 380c3daba6b..8d83291c271 100644 --- a/sys/mips/atheros/uart_bus_ar71xx.c +++ b/sys/mips/atheros/uart_bus_ar71xx.c @@ -67,20 +67,9 @@ static int uart_ar71xx_probe(device_t dev) { struct uart_softc *sc; - uint32_t pll_config, div; uint64_t freq; - /* PLL freq */ - pll_config = ATH_READ_REG(AR71XX_PLL_CPU_CONFIG); - div = ((pll_config >> PLL_FB_SHIFT) & PLL_FB_MASK) + 1; - freq = div * AR71XX_BASE_FREQ; - /* CPU freq */ - div = ((pll_config >> PLL_CPU_DIV_SEL_SHIFT) & PLL_CPU_DIV_SEL_MASK) - + 1; - freq = freq / div; - /* AHB freq */ - div = (((pll_config >> PLL_AHB_DIV_SHIFT) & PLL_AHB_DIV_MASK) + 1) * 2; - freq = freq / div; + freq = ar71xx_ahb_freq(); sc = device_get_softc(dev); sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); diff --git a/sys/mips/atheros/uart_cpu_ar71xx.c b/sys/mips/atheros/uart_cpu_ar71xx.c index 67b5d98c1d2..4528ac68142 100644 --- a/sys/mips/atheros/uart_cpu_ar71xx.c +++ b/sys/mips/atheros/uart_cpu_ar71xx.c @@ -53,20 +53,9 @@ uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) int uart_cpu_getdev(int devtype, struct uart_devinfo *di) { - uint32_t pll_config, div; uint64_t freq; - /* PLL freq */ - pll_config = ATH_READ_REG(AR71XX_PLL_CPU_CONFIG); - div = ((pll_config >> PLL_FB_SHIFT) & PLL_FB_MASK) + 1; - freq = div * AR71XX_BASE_FREQ; - /* CPU freq */ - div = ((pll_config >> PLL_CPU_DIV_SEL_SHIFT) & PLL_CPU_DIV_SEL_MASK) - + 1; - freq = freq / div; - /* AHB freq */ - div = (((pll_config >> PLL_AHB_DIV_SHIFT) & PLL_AHB_DIV_MASK) + 1) * 2; - freq = freq / div; + freq = ar71xx_ahb_freq(); di->ops = uart_getops(&uart_ns8250_class); di->bas.chan = 0; From 4bdb59f3423432e49b968cf5284000e2d7247199 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 9 Jul 2009 20:16:01 +0000 Subject: [PATCH 203/380] - Add AR71XX watchdog timer driver --- sys/mips/atheros/ar71xx_wdog.c | 118 +++++++++++++++++++++++++++++++++ sys/mips/atheros/files.ar71xx | 1 + sys/mips/conf/AR71XX | 2 + sys/mips/conf/AR71XX.hints | 3 + 4 files changed, 124 insertions(+) create mode 100644 sys/mips/atheros/ar71xx_wdog.c diff --git a/sys/mips/atheros/ar71xx_wdog.c b/sys/mips/atheros/ar71xx_wdog.c new file mode 100644 index 00000000000..90caaa84f8a --- /dev/null +++ b/sys/mips/atheros/ar71xx_wdog.c @@ -0,0 +1,118 @@ +/*- + * Copyright (c) 2009, Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Watchdog driver for AR71xx + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include + +struct ar71xx_wdog_softc { + device_t dev; + int armed; +}; + +static void +ar71xx_wdog_watchdog_fn(void *private, u_int cmd, int *error) +{ + struct ar71xx_wdog_softc *sc = private; + uint64_t timer_val; + + cmd &= WD_INTERVAL; + if (cmd > 0) { + timer_val = (uint64_t)(1ULL << cmd) * ar71xx_ahb_freq() / + 1000000000; + /* + * Load timer with large enough value to prevent spurious + * reset + */ + ATH_WRITE_REG(AR71XX_RST_WDOG_TIMER, + ar71xx_ahb_freq() * 10); + ATH_WRITE_REG(AR71XX_RST_WDOG_CONTROL, + RST_WDOG_ACTION_RESET); + ATH_WRITE_REG(AR71XX_RST_WDOG_TIMER, + (timer_val & 0xffffffff)); + sc->armed = 1; + *error = 0; + } else { + if (sc->armed) { + ATH_WRITE_REG(AR71XX_RST_WDOG_CONTROL, + RST_WDOG_ACTION_NOACTION); + sc->armed = 0; + } + } +} + +static int +ar71xx_wdog_probe(device_t dev) +{ + + device_set_desc(dev, "Atheros AR71XX watchdog timer"); + return (0); +} + +static int +ar71xx_wdog_attach(device_t dev) +{ + struct ar71xx_wdog_softc *sc = device_get_softc(dev); + + if (ATH_READ_REG(AR71XX_RST_WDOG_CONTROL) & RST_WDOG_LAST) + device_printf (dev, + "Previous reset was due to watchdog timeout\n"); + + ATH_WRITE_REG(AR71XX_RST_WDOG_CONTROL, RST_WDOG_ACTION_NOACTION); + + sc->dev = dev; + EVENTHANDLER_REGISTER(watchdog_list, ar71xx_wdog_watchdog_fn, sc, 0); + + return (0); +} + +static device_method_t ar71xx_wdog_methods[] = { + DEVMETHOD(device_probe, ar71xx_wdog_probe), + DEVMETHOD(device_attach, ar71xx_wdog_attach), + {0, 0}, +}; + +static driver_t ar71xx_wdog_driver = { + "ar71xx_wdog", + ar71xx_wdog_methods, + sizeof(struct ar71xx_wdog_softc), +}; +static devclass_t ar71xx_wdog_devclass; + +DRIVER_MODULE(ar71xx_wdog, nexus, ar71xx_wdog_driver, ar71xx_wdog_devclass, 0, 0); diff --git a/sys/mips/atheros/files.ar71xx b/sys/mips/atheros/files.ar71xx index cb2e00bc05a..b3db957512e 100644 --- a/sys/mips/atheros/files.ar71xx +++ b/sys/mips/atheros/files.ar71xx @@ -7,6 +7,7 @@ mips/atheros/ar71xx_ohci.c optional ohci mips/atheros/ar71xx_pci.c optional pci mips/atheros/ar71xx_pci_bus_space.c optional pci mips/atheros/ar71xx_spi.c optional ar71xx_spi +mips/atheros/ar71xx_wdog.c optional ar71xx_wdog mips/atheros/if_arge.c optional arge mips/atheros/uart_bus_ar71xx.c optional uart mips/atheros/uart_cpu_ar71xx.c optional uart diff --git a/sys/mips/conf/AR71XX b/sys/mips/conf/AR71XX index e06ea43dd02..8e8fff4ae78 100644 --- a/sys/mips/conf/AR71XX +++ b/sys/mips/conf/AR71XX @@ -74,6 +74,8 @@ device ar71xx_spi device mx25l # device geom_redboot +device ar71xx_wdog + device uart device loop diff --git a/sys/mips/conf/AR71XX.hints b/sys/mips/conf/AR71XX.hints index 17026c10a80..2b97880c60c 100644 --- a/sys/mips/conf/AR71XX.hints +++ b/sys/mips/conf/AR71XX.hints @@ -41,3 +41,6 @@ hint.spi.0.msize=0x10 hint.mx25l.0.at="spibus0" hint.mx25l.0.cs=0 + +# Watchdog +hint.ar71xx_wdog.0.at="nexus0" From fc6d784068e8be891c3650e0be4e4176c381927d Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 10 Jul 2009 07:18:30 +0000 Subject: [PATCH 204/380] Always build all 4 emulators into the mips toolchain. # I think we have a gcc spec file issue with abi=64 since I have to do other # hacks to get it mostly kinda right. --- gnu/usr.bin/binutils/ld/Makefile.mips | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/gnu/usr.bin/binutils/ld/Makefile.mips b/gnu/usr.bin/binutils/ld/Makefile.mips index cf58c706818..765f2d263d2 100644 --- a/gnu/usr.bin/binutils/ld/Makefile.mips +++ b/gnu/usr.bin/binutils/ld/Makefile.mips @@ -10,15 +10,22 @@ NATIVE_EMULATION=elf${_sz}btsmip_fbsd NATIVE_EMULATION=elf${_sz}ltsmip_fbsd .endif -SRCS+= e${NATIVE_EMULATION}.c -CLEANFILES+= e${NATIVE_EMULATION}.c - +MIPS_ABIS=elf32btsmip_fbsd elf32ltsmip_fbsd elf64btsmip_fbsd elf64ltsmip_fbsd +.for abi in ${MIPS_ABIS} +.if (${abi} != ${NATIVE_EMULATION}) +EMS+= ${abi} +.endif +.for ext in ${ELF_SCR_EXT} +LDSCRIPTS+= ${abi}.${ext} +.endfor +SRCS+= e${abi}.c +CLEANFILES+= e${abi}.c # nb: elf32 handles both elf32 and elf64 targets -e${NATIVE_EMULATION}.c: ${.CURDIR}/${NATIVE_EMULATION}.sh emultempl/elf32.em \ +e${abi}.c: ${.CURDIR}/${abi}.sh emultempl/elf32.em \ scripttempl/elf.sc genscripts.sh stringify.sed sh ${.CURDIR}/genscripts.sh ${SRCDIR}/ld ${LIBSERACHPATH} \ ${TOOLS_PREFIX}/usr \ ${HOST} ${TARGET_TUPLE} ${TARGET_TUPLE} \ - ${NATIVE_EMULATION} "" no ${NATIVE_EMULATION} ${TARGET_TUPLE} \ - ${.CURDIR}/${NATIVE_EMULATION}.sh - + ${abi} "" no ${abi} ${TARGET_TUPLE} \ + ${.CURDIR}/${abi}.sh +.endfor From f0bb71694bd372bfb0967e626f0dc0c286d24a78 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 10 Jul 2009 07:19:30 +0000 Subject: [PATCH 205/380] Flag this as a 64-bit build. # Too many flagas needed to build 64-bit, plus different endian, etc. The # makefile is getting kinda gross with ifdefs. --- sys/mips/conf/MALTA64 | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/mips/conf/MALTA64 b/sys/mips/conf/MALTA64 index 1e3626f6501..70be8fef7ad 100644 --- a/sys/mips/conf/MALTA64 +++ b/sys/mips/conf/MALTA64 @@ -21,6 +21,7 @@ ident MALTA makeoptions ARCH_FLAGS="-march=mips64 -mabi=64" makeoptions MIPS_LITTLE_ENDIAN=defined +makeoptions TARGET_64BIT=t options YAMON From 9690fcee638a948e762a657ec18aa40c463797a4 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 10 Jul 2009 07:20:07 +0000 Subject: [PATCH 206/380] Properly size things for n64 builds. --- sys/sys/user.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/sys/user.h b/sys/sys/user.h index a9dfcebd5ba..782bf66af8c 100644 --- a/sys/sys/user.h +++ b/sys/sys/user.h @@ -100,8 +100,12 @@ #define KINFO_PROC_SIZE 768 #endif #ifdef __mips__ +#if defined(__mips_n64) +#define KINFO_PROC_SIZE 1088 +#else #define KINFO_PROC_SIZE 816 #endif +#endif #ifdef __powerpc__ #define KINFO_PROC_SIZE 768 #endif From 6fb8bbf5c162c0b0dec6bcd1da5c855e2b5ed316 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 10 Jul 2009 07:21:26 +0000 Subject: [PATCH 207/380] Add in the emulation selection when linking... We're still not 100% of the way there, but we're better with it. hack.so build now, but we die when we try to link it in. --- sys/conf/Makefile.mips | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sys/conf/Makefile.mips b/sys/conf/Makefile.mips index e03432c9edf..89a2bd50ada 100644 --- a/sys/conf/Makefile.mips +++ b/sys/conf/Makefile.mips @@ -53,13 +53,22 @@ SYSTEM_LD+=-EB EXTRA_FLAGS+=-EB TRAMP_LDFLAGS+=-Wl,-EB HACK_EXTRA_FLAGS+=-EB -Wl,-EB +.if defined(TARGET_64BIT) +SYSTEM_LD+=-m elf64btsmip_fbsd +HACK_EXTRA_FLAGS+=-Wl,-m,elf64btsmip_fbsd +.endif .else CFLAGS+=-EL SYSTEM_LD+=-EL EXTRA_FLAGS+=-EL TRAMP_LDFLAGS+=-Wl,-EL HACK_EXTRA_FLAGS+=-EL -Wl,-EL +.if defined(TARGET_64BIT) +SYSTEM_LD+=-m elf64ltsmip_fbsd +HACK_EXTRA_FLAGS+=-Wl,-m,elf64ltsmip_fbsd .endif +.endif + # We add the -fno-pic flag to kernels because otherwise performance # is extremely poor, as well as -mno-abicalls to force no ABI usage. From 2b455bd196501cae7904297ffa5c874dfd195c07 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 10 Jul 2009 18:24:02 +0000 Subject: [PATCH 208/380] quick hack for the problem gonzo is seeing. --- gnu/usr.bin/binutils/ld/Makefile.mips | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gnu/usr.bin/binutils/ld/Makefile.mips b/gnu/usr.bin/binutils/ld/Makefile.mips index 765f2d263d2..785d7336467 100644 --- a/gnu/usr.bin/binutils/ld/Makefile.mips +++ b/gnu/usr.bin/binutils/ld/Makefile.mips @@ -12,9 +12,9 @@ NATIVE_EMULATION=elf${_sz}ltsmip_fbsd MIPS_ABIS=elf32btsmip_fbsd elf32ltsmip_fbsd elf64btsmip_fbsd elf64ltsmip_fbsd .for abi in ${MIPS_ABIS} -.if (${abi} != ${NATIVE_EMULATION}) +#.if (${abi} != ${NATIVE_EMULATION}) EMS+= ${abi} -.endif +#.endif .for ext in ${ELF_SCR_EXT} LDSCRIPTS+= ${abi}.${ext} .endfor From ec55ba21ce1f8021fcb6f4c9c66148f466440245 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 10 Jul 2009 19:04:32 +0000 Subject: [PATCH 209/380] use ta0-ta3 rather than t4-t7 for n32/n64 goodness. --- sys/mips/mips/fp.S | 734 ++++++++++++++++++++++----------------------- 1 file changed, 367 insertions(+), 367 deletions(-) diff --git a/sys/mips/mips/fp.S b/sys/mips/mips/fp.S index b211c12fb15..afe9f03d1e0 100644 --- a/sys/mips/mips/fp.S +++ b/sys/mips/mips/fp.S @@ -634,7 +634,7 @@ func_fmt_tbl: */ sub_s: jal get_ft_fs_s - xor t4, t4, 1 # negate FT sign bit + xor ta0, ta0, 1 # negate FT sign bit b add_sub_s /* * Single precision add. @@ -643,38 +643,38 @@ add_s: jal get_ft_fs_s add_sub_s: bne t1, SEXP_INF, 1f # is FS an infinity? - bne t5, SEXP_INF, result_fs_s # if FT is not inf, result=FS + bne ta1, SEXP_INF, result_fs_s # if FT is not inf, result=FS bne t2, zero, result_fs_s # if FS is NAN, result is FS - bne t6, zero, result_ft_s # if FT is NAN, result is FT - bne t0, t4, invalid_s # both infinities same sign? + bne ta2, zero, result_ft_s # if FT is NAN, result is FT + bne t0, ta0, invalid_s # both infinities same sign? b result_fs_s # result is in FS 1: - beq t5, SEXP_INF, result_ft_s # if FT is inf, result=FT + beq ta1, SEXP_INF, result_ft_s # if FT is inf, result=FT bne t1, zero, 4f # is FS a denormalized num? beq t2, zero, 3f # is FS zero? - bne t5, zero, 2f # is FT a denormalized num? - beq t6, zero, result_fs_s # FT is zero, result=FS + bne ta1, zero, 2f # is FT a denormalized num? + beq ta2, zero, result_fs_s # FT is zero, result=FS jal renorm_fs_s jal renorm_ft_s b 5f 2: jal renorm_fs_s - subu t5, t5, SEXP_BIAS # unbias FT exponent - or t6, t6, SIMPL_ONE # set implied one bit + subu ta1, ta1, SEXP_BIAS # unbias FT exponent + or ta2, ta2, SIMPL_ONE # set implied one bit b 5f 3: - bne t5, zero, result_ft_s # if FT != 0, result=FT - bne t6, zero, result_ft_s + bne ta1, zero, result_ft_s # if FT != 0, result=FT + bne ta2, zero, result_ft_s and v0, a1, FPC_ROUNDING_BITS # get rounding mode bne v0, FPC_ROUND_RM, 1f # round to -infinity? - or t0, t0, t4 # compute result sign + or t0, t0, ta0 # compute result sign b result_fs_s 1: - and t0, t0, t4 # compute result sign + and t0, t0, ta0 # compute result sign b result_fs_s 4: - bne t5, zero, 2f # is FT a denormalized num? - beq t6, zero, result_fs_s # FT is zero, result=FS + bne ta1, zero, 2f # is FT a denormalized num? + beq ta2, zero, result_fs_s # FT is zero, result=FS subu t1, t1, SEXP_BIAS # unbias FS exponent or t2, t2, SIMPL_ONE # set implied one bit jal renorm_ft_s @@ -682,15 +682,15 @@ add_sub_s: 2: subu t1, t1, SEXP_BIAS # unbias FS exponent or t2, t2, SIMPL_ONE # set implied one bit - subu t5, t5, SEXP_BIAS # unbias FT exponent - or t6, t6, SIMPL_ONE # set implied one bit + subu ta1, ta1, SEXP_BIAS # unbias FT exponent + or ta2, ta2, SIMPL_ONE # set implied one bit /* * Perform the addition. */ 5: move t8, zero # no shifted bits (sticky reg) - beq t1, t5, 4f # no shift needed - subu v0, t1, t5 # v0 = difference of exponents + beq t1, ta1, 4f # no shift needed + subu v0, t1, ta1 # v0 = difference of exponents move v1, v0 # v1 = abs(difference) bge v0, zero, 1f negu v1 @@ -698,50 +698,50 @@ add_sub_s: ble v1, SFRAC_BITS+2, 2f # is difference too great? li t8, STICKYBIT # set the sticky bit bge v0, zero, 1f # check which exp is larger - move t1, t5 # result exp is FTs + move t1, ta1 # result exp is FTs move t2, zero # FSs fraction shifted is zero b 4f 1: - move t6, zero # FTs fraction shifted is zero + move ta2, zero # FTs fraction shifted is zero b 4f 2: li t9, 32 # compute 32 - abs(exp diff) subu t9, t9, v1 bgt v0, zero, 3f # if FS > FT, shift FTs frac - move t1, t5 # FT > FS, result exp is FTs + move t1, ta1 # FT > FS, result exp is FTs sll t8, t2, t9 # save bits shifted out srl t2, t2, v1 # shift FSs fraction b 4f 3: - sll t8, t6, t9 # save bits shifted out - srl t6, t6, v1 # shift FTs fraction + sll t8, ta2, t9 # save bits shifted out + srl ta2, ta2, v1 # shift FTs fraction 4: - bne t0, t4, 1f # if signs differ, subtract - addu t2, t2, t6 # add fractions + bne t0, ta0, 1f # if signs differ, subtract + addu t2, t2, ta2 # add fractions b norm_s 1: - blt t2, t6, 3f # subtract larger from smaller - bne t2, t6, 2f # if same, result=0 + blt t2, ta2, 3f # subtract larger from smaller + bne t2, ta2, 2f # if same, result=0 move t1, zero # result=0 move t2, zero and v0, a1, FPC_ROUNDING_BITS # get rounding mode - bne v0, FPC_ROUND_RM, 1f # round to -infinity? - or t0, t0, t4 # compute result sign + bne v0, FPC_ROUND_RM, 1f # round to -infinity? + or t0, t0, ta0 # compute result sign b result_fs_s 1: - and t0, t0, t4 # compute result sign + and t0, t0, ta0 # compute result sign b result_fs_s 2: - sltu t9, zero, t8 # compute t2:zero - t6:t8 + sltu t9, zero, t8 # compute t2:zero - ta2:t8 subu t8, zero, t8 - subu t2, t2, t6 # subtract fractions + subu t2, t2, ta2 # subtract fractions subu t2, t2, t9 # subtract barrow b norm_s 3: - move t0, t4 # sign of result = FTs - sltu t9, zero, t8 # compute t6:zero - t2:t8 + move t0, ta0 # sign of result = FTs + sltu t9, zero, t8 # compute ta2:zero - t2:t8 subu t8, zero, t8 - subu t2, t6, t2 # subtract fractions + subu t2, ta2, t2 # subtract fractions subu t2, t2, t9 # subtract barrow b norm_s @@ -750,7 +750,7 @@ add_sub_s: */ sub_d: jal get_ft_fs_d - xor t4, t4, 1 # negate sign bit + xor ta0, ta0, 1 # negate sign bit b add_sub_d /* * Double precision add. @@ -759,46 +759,46 @@ add_d: jal get_ft_fs_d add_sub_d: bne t1, DEXP_INF, 1f # is FS an infinity? - bne t5, DEXP_INF, result_fs_d # if FT is not inf, result=FS + bne ta1, DEXP_INF, result_fs_d # if FT is not inf, result=FS bne t2, zero, result_fs_d # if FS is NAN, result is FS bne t3, zero, result_fs_d - bne t6, zero, result_ft_d # if FT is NAN, result is FT - bne t7, zero, result_ft_d - bne t0, t4, invalid_d # both infinities same sign? + bne ta2, zero, result_ft_d # if FT is NAN, result is FT + bne ta3, zero, result_ft_d + bne t0, ta0, invalid_d # both infinities same sign? b result_fs_d # result is in FS 1: - beq t5, DEXP_INF, result_ft_d # if FT is inf, result=FT + beq ta1, DEXP_INF, result_ft_d # if FT is inf, result=FT bne t1, zero, 4f # is FS a denormalized num? bne t2, zero, 1f # is FS zero? beq t3, zero, 3f 1: - bne t5, zero, 2f # is FT a denormalized num? - bne t6, zero, 1f - beq t7, zero, result_fs_d # FT is zero, result=FS + bne ta1, zero, 2f # is FT a denormalized num? + bne ta2, zero, 1f + beq ta3, zero, result_fs_d # FT is zero, result=FS 1: jal renorm_fs_d jal renorm_ft_d b 5f 2: jal renorm_fs_d - subu t5, t5, DEXP_BIAS # unbias FT exponent - or t6, t6, DIMPL_ONE # set implied one bit + subu ta1, ta1, DEXP_BIAS # unbias FT exponent + or ta2, ta2, DIMPL_ONE # set implied one bit b 5f 3: - bne t5, zero, result_ft_d # if FT != 0, result=FT - bne t6, zero, result_ft_d - bne t7, zero, result_ft_d + bne ta1, zero, result_ft_d # if FT != 0, result=FT + bne ta2, zero, result_ft_d + bne ta3, zero, result_ft_d and v0, a1, FPC_ROUNDING_BITS # get rounding mode - bne v0, FPC_ROUND_RM, 1f # round to -infinity? - or t0, t0, t4 # compute result sign + bne v0, FPC_ROUND_RM, 1f # round to -infinity? + or t0, t0, ta0 # compute result sign b result_fs_d 1: - and t0, t0, t4 # compute result sign + and t0, t0, ta0 # compute result sign b result_fs_d 4: - bne t5, zero, 2f # is FT a denormalized num? - bne t6, zero, 1f - beq t7, zero, result_fs_d # FT is zero, result=FS + bne ta1, zero, 2f # is FT a denormalized num? + bne ta2, zero, 1f + beq ta3, zero, result_fs_d # FT is zero, result=FS 1: subu t1, t1, DEXP_BIAS # unbias FS exponent or t2, t2, DIMPL_ONE # set implied one bit @@ -807,15 +807,15 @@ add_sub_d: 2: subu t1, t1, DEXP_BIAS # unbias FS exponent or t2, t2, DIMPL_ONE # set implied one bit - subu t5, t5, DEXP_BIAS # unbias FT exponent - or t6, t6, DIMPL_ONE # set implied one bit + subu ta1, ta1, DEXP_BIAS # unbias FT exponent + or ta2, ta2, DIMPL_ONE # set implied one bit /* * Perform the addition. */ 5: move t8, zero # no shifted bits (sticky reg) - beq t1, t5, 4f # no shift needed - subu v0, t1, t5 # v0 = difference of exponents + beq t1, ta1, 4f # no shift needed + subu v0, t1, ta1 # v0 = difference of exponents move v1, v0 # v1 = abs(difference) bge v0, zero, 1f negu v1 @@ -823,18 +823,18 @@ add_sub_d: ble v1, DFRAC_BITS+2, 2f # is difference too great? li t8, STICKYBIT # set the sticky bit bge v0, zero, 1f # check which exp is larger - move t1, t5 # result exp is FTs + move t1, ta1 # result exp is FTs move t2, zero # FSs fraction shifted is zero move t3, zero b 4f 1: - move t6, zero # FTs fraction shifted is zero - move t7, zero + move ta2, zero # FTs fraction shifted is zero + move ta3, zero b 4f 2: li t9, 32 bge v0, zero, 3f # if FS > FT, shift FTs frac - move t1, t5 # FT > FS, result exp is FTs + move t1, ta1 # FT > FS, result exp is FTs blt v1, t9, 1f # shift right by < 32? subu v1, v1, t9 subu t9, t9, v1 @@ -856,62 +856,62 @@ add_sub_d: blt v1, t9, 1f # shift right by < 32? subu v1, v1, t9 subu t9, t9, v1 - sll t8, t6, t9 # save bits shifted out - srl t7, t6, v1 # shift FTs fraction - move t6, zero + sll t8, ta2, t9 # save bits shifted out + srl ta3, ta2, v1 # shift FTs fraction + move ta2, zero b 4f 1: subu t9, t9, v1 - sll t8, t7, t9 # save bits shifted out - srl t7, t7, v1 # shift FTs fraction - sll t9, t6, t9 # save bits shifted out of t2 - or t7, t7, t9 # and put into t3 - srl t6, t6, v1 + sll t8, ta3, t9 # save bits shifted out + srl ta3, ta3, v1 # shift FTs fraction + sll t9, ta2, t9 # save bits shifted out of t2 + or ta3, ta3, t9 # and put into t3 + srl ta2, ta2, v1 4: - bne t0, t4, 1f # if signs differ, subtract - addu t3, t3, t7 # add fractions - sltu t9, t3, t7 # compute carry - addu t2, t2, t6 # add fractions + bne t0, ta0, 1f # if signs differ, subtract + addu t3, t3, ta3 # add fractions + sltu t9, t3, ta3 # compute carry + addu t2, t2, ta2 # add fractions addu t2, t2, t9 # add carry b norm_d 1: - blt t2, t6, 3f # subtract larger from smaller - bne t2, t6, 2f - bltu t3, t7, 3f - bne t3, t7, 2f # if same, result=0 + blt t2, ta2, 3f # subtract larger from smaller + bne t2, ta2, 2f + bltu t3, ta3, 3f + bne t3, ta3, 2f # if same, result=0 move t1, zero # result=0 move t2, zero move t3, zero and v0, a1, FPC_ROUNDING_BITS # get rounding mode bne v0, FPC_ROUND_RM, 1f # round to -infinity? - or t0, t0, t4 # compute result sign + or t0, t0, ta0 # compute result sign b result_fs_d 1: - and t0, t0, t4 # compute result sign + and t0, t0, ta0 # compute result sign b result_fs_d 2: - beq t8, zero, 1f # compute t2:t3:zero - t6:t7:t8 + beq t8, zero, 1f # compute t2:t3:zero - ta2:ta3:t8 subu t8, zero, t8 sltu v0, t3, 1 # compute barrow out subu t3, t3, 1 # subtract barrow subu t2, t2, v0 1: - sltu v0, t3, t7 - subu t3, t3, t7 # subtract fractions - subu t2, t2, t6 # subtract fractions + sltu v0, t3, ta3 + subu t3, t3, ta3 # subtract fractions + subu t2, t2, ta2 # subtract fractions subu t2, t2, v0 # subtract barrow b norm_d 3: - move t0, t4 # sign of result = FTs - beq t8, zero, 1f # compute t6:t7:zero - t2:t3:t8 + move t0, ta0 # sign of result = FTs + beq t8, zero, 1f # compute ta2:ta3:zero - t2:t3:t8 subu t8, zero, t8 - sltu v0, t7, 1 # compute barrow out - subu t7, t7, 1 # subtract barrow - subu t6, t6, v0 + sltu v0, ta3, 1 # compute barrow out + subu ta3, ta3, 1 # subtract barrow + subu ta2, ta2, v0 1: - sltu v0, t7, t3 - subu t3, t7, t3 # subtract fractions - subu t2, t6, t2 # subtract fractions + sltu v0, ta3, t3 + subu t3, ta3, t3 # subtract fractions + subu t2, ta2, t2 # subtract fractions subu t2, t2, v0 # subtract barrow b norm_d @@ -920,22 +920,22 @@ add_sub_d: */ mul_s: jal get_ft_fs_s - xor t0, t0, t4 # compute sign of result - move t4, t0 + xor t0, t0, ta0 # compute sign of result + move ta0, t0 bne t1, SEXP_INF, 2f # is FS an infinity? bne t2, zero, result_fs_s # if FS is a NAN, result=FS - bne t5, SEXP_INF, 1f # FS is inf, is FT an infinity? - bne t6, zero, result_ft_s # if FT is a NAN, result=FT + bne ta1, SEXP_INF, 1f # FS is inf, is FT an infinity? + bne ta2, zero, result_ft_s # if FT is a NAN, result=FT b result_fs_s # result is infinity 1: - bne t5, zero, result_fs_s # inf * zero? if no, result=FS - bne t6, zero, result_fs_s + bne ta1, zero, result_fs_s # inf * zero? if no, result=FS + bne ta2, zero, result_fs_s b invalid_s # infinity * zero is invalid 2: - bne t5, SEXP_INF, 1f # FS != inf, is FT an infinity? + bne ta1, SEXP_INF, 1f # FS != inf, is FT an infinity? bne t1, zero, result_ft_s # zero * inf? if no, result=FT bne t2, zero, result_ft_s - bne t6, zero, result_ft_s # if FT is a NAN, result=FT + bne ta2, zero, result_ft_s # if FT is a NAN, result=FT b invalid_s # zero * infinity is invalid 1: bne t1, zero, 1f # is FS zero? @@ -946,17 +946,17 @@ mul_s: subu t1, t1, SEXP_BIAS # unbias FS exponent or t2, t2, SIMPL_ONE # set implied one bit 2: - bne t5, zero, 1f # is FT zero? - beq t6, zero, result_ft_s # result is zero + bne ta1, zero, 1f # is FT zero? + beq ta2, zero, result_ft_s # result is zero jal renorm_ft_s b 2f 1: - subu t5, t5, SEXP_BIAS # unbias FT exponent - or t6, t6, SIMPL_ONE # set implied one bit + subu ta1, ta1, SEXP_BIAS # unbias FT exponent + or ta2, ta2, SIMPL_ONE # set implied one bit 2: - addu t1, t1, t5 # compute result exponent + addu t1, t1, ta1 # compute result exponent addu t1, t1, 9 # account for binary point - multu t2, t6 # multiply fractions + multu t2, ta2 # multiply fractions mflo t8 mfhi t2 b norm_s @@ -966,27 +966,27 @@ mul_s: */ mul_d: jal get_ft_fs_d - xor t0, t0, t4 # compute sign of result - move t4, t0 + xor t0, t0, ta0 # compute sign of result + move ta0, t0 bne t1, DEXP_INF, 2f # is FS an infinity? bne t2, zero, result_fs_d # if FS is a NAN, result=FS bne t3, zero, result_fs_d - bne t5, DEXP_INF, 1f # FS is inf, is FT an infinity? - bne t6, zero, result_ft_d # if FT is a NAN, result=FT - bne t7, zero, result_ft_d + bne ta1, DEXP_INF, 1f # FS is inf, is FT an infinity? + bne ta2, zero, result_ft_d # if FT is a NAN, result=FT + bne ta3, zero, result_ft_d b result_fs_d # result is infinity 1: - bne t5, zero, result_fs_d # inf * zero? if no, result=FS - bne t6, zero, result_fs_d - bne t7, zero, result_fs_d + bne ta1, zero, result_fs_d # inf * zero? if no, result=FS + bne ta2, zero, result_fs_d + bne ta3, zero, result_fs_d b invalid_d # infinity * zero is invalid 2: - bne t5, DEXP_INF, 1f # FS != inf, is FT an infinity? + bne ta1, DEXP_INF, 1f # FS != inf, is FT an infinity? bne t1, zero, result_ft_d # zero * inf? if no, result=FT bne t2, zero, result_ft_d # if FS is a NAN, result=FS bne t3, zero, result_ft_d - bne t6, zero, result_ft_d # if FT is a NAN, result=FT - bne t7, zero, result_ft_d + bne ta2, zero, result_ft_d # if FT is a NAN, result=FT + bne ta3, zero, result_ft_d b invalid_d # zero * infinity is invalid 1: bne t1, zero, 2f # is FS zero? @@ -999,37 +999,37 @@ mul_d: subu t1, t1, DEXP_BIAS # unbias FS exponent or t2, t2, DIMPL_ONE # set implied one bit 3: - bne t5, zero, 2f # is FT zero? - bne t6, zero, 1f - beq t7, zero, result_ft_d # result is zero + bne ta1, zero, 2f # is FT zero? + bne ta2, zero, 1f + beq ta3, zero, result_ft_d # result is zero 1: jal renorm_ft_d b 3f 2: - subu t5, t5, DEXP_BIAS # unbias FT exponent - or t6, t6, DIMPL_ONE # set implied one bit + subu ta1, ta1, DEXP_BIAS # unbias FT exponent + or ta2, ta2, DIMPL_ONE # set implied one bit 3: - addu t1, t1, t5 # compute result exponent + addu t1, t1, ta1 # compute result exponent addu t1, t1, 12 # ??? - multu t3, t7 # multiply fractions (low * low) - move t4, t2 # free up t2,t3 for result - move t5, t3 + multu t3, ta3 # multiply fractions (low * low) + move ta0, t2 # free up t2,t3 for result + move ta1, t3 mflo a3 # save low order bits mfhi t8 not v0, t8 - multu t4, t7 # multiply FS(high) * FT(low) + multu ta0, ta3 # multiply FS(high) * FT(low) mflo v1 mfhi t3 # init low result sltu v0, v0, v1 # compute carry addu t8, v1 - multu t5, t6 # multiply FS(low) * FT(high) + multu ta1, ta2 # multiply FS(low) * FT(high) addu t3, t3, v0 # add carry not v0, t8 mflo v1 mfhi t2 sltu v0, v0, v1 addu t8, v1 - multu t4, t6 # multiply FS(high) * FT(high) + multu ta0, ta2 # multiply FS(high) * FT(high) addu t3, v0 not v1, t3 sltu v1, v1, t2 @@ -1050,24 +1050,24 @@ mul_d: */ div_s: jal get_ft_fs_s - xor t0, t0, t4 # compute sign of result - move t4, t0 + xor t0, t0, ta0 # compute sign of result + move ta0, t0 bne t1, SEXP_INF, 1f # is FS an infinity? bne t2, zero, result_fs_s # if FS is NAN, result is FS - bne t5, SEXP_INF, result_fs_s # is FT an infinity? - bne t6, zero, result_ft_s # if FT is NAN, result is FT + bne ta1, SEXP_INF, result_fs_s # is FT an infinity? + bne ta2, zero, result_ft_s # if FT is NAN, result is FT b invalid_s # infinity/infinity is invalid 1: - bne t5, SEXP_INF, 1f # is FT an infinity? - bne t6, zero, result_ft_s # if FT is NAN, result is FT + bne ta1, SEXP_INF, 1f # is FT an infinity? + bne ta2, zero, result_ft_s # if FT is NAN, result is FT move t1, zero # x / infinity is zero move t2, zero b result_fs_s 1: bne t1, zero, 2f # is FS zero? bne t2, zero, 1f - bne t5, zero, result_fs_s # FS=zero, is FT zero? - beq t6, zero, invalid_s # 0 / 0 + bne ta1, zero, result_fs_s # FS=zero, is FT zero? + beq ta2, zero, invalid_s # 0 / 0 b result_fs_s # result = zero 1: jal renorm_fs_s @@ -1076,8 +1076,8 @@ div_s: subu t1, t1, SEXP_BIAS # unbias FS exponent or t2, t2, SIMPL_ONE # set implied one bit 3: - bne t5, zero, 2f # is FT zero? - bne t6, zero, 1f + bne ta1, zero, 2f # is FT zero? + bne ta2, zero, 1f or a1, a1, FPC_EXCEPTION_DIV0 | FPC_STICKY_DIV0 and v0, a1, FPC_ENABLE_DIV0 # trap enabled? bne v0, zero, fpe_trap @@ -1089,18 +1089,18 @@ div_s: jal renorm_ft_s b 3f 2: - subu t5, t5, SEXP_BIAS # unbias FT exponent - or t6, t6, SIMPL_ONE # set implied one bit + subu ta1, ta1, SEXP_BIAS # unbias FT exponent + or ta2, ta2, SIMPL_ONE # set implied one bit 3: - subu t1, t1, t5 # compute exponent + subu t1, t1, ta1 # compute exponent subu t1, t1, 3 # compensate for result position li v0, SFRAC_BITS+3 # number of bits to divide move t8, t2 # init dividend move t2, zero # init result 1: - bltu t8, t6, 3f # is dividend >= divisor? + bltu t8, ta2, 3f # is dividend >= divisor? 2: - subu t8, t8, t6 # subtract divisor from dividend + subu t8, t8, ta2 # subtract divisor from dividend or t2, t2, 1 # remember that we did bne t8, zero, 3f # if not done, continue sll t2, t2, v0 # shift result to final position @@ -1117,19 +1117,19 @@ div_s: */ div_d: jal get_ft_fs_d - xor t0, t0, t4 # compute sign of result - move t4, t0 + xor t0, t0, ta0 # compute sign of result + move ta0, t0 bne t1, DEXP_INF, 1f # is FS an infinity? bne t2, zero, result_fs_d # if FS is NAN, result is FS bne t3, zero, result_fs_d - bne t5, DEXP_INF, result_fs_d # is FT an infinity? - bne t6, zero, result_ft_d # if FT is NAN, result is FT - bne t7, zero, result_ft_d + bne ta1, DEXP_INF, result_fs_d # is FT an infinity? + bne ta2, zero, result_ft_d # if FT is NAN, result is FT + bne ta3, zero, result_ft_d b invalid_d # infinity/infinity is invalid 1: - bne t5, DEXP_INF, 1f # is FT an infinity? - bne t6, zero, result_ft_d # if FT is NAN, result is FT - bne t7, zero, result_ft_d + bne ta1, DEXP_INF, 1f # is FT an infinity? + bne ta2, zero, result_ft_d # if FT is NAN, result is FT + bne ta3, zero, result_ft_d move t1, zero # x / infinity is zero move t2, zero move t3, zero @@ -1138,9 +1138,9 @@ div_d: bne t1, zero, 2f # is FS zero? bne t2, zero, 1f bne t3, zero, 1f - bne t5, zero, result_fs_d # FS=zero, is FT zero? - bne t6, zero, result_fs_d - beq t7, zero, invalid_d # 0 / 0 + bne ta1, zero, result_fs_d # FS=zero, is FT zero? + bne ta2, zero, result_fs_d + beq ta3, zero, invalid_d # 0 / 0 b result_fs_d # result = zero 1: jal renorm_fs_d @@ -1149,9 +1149,9 @@ div_d: subu t1, t1, DEXP_BIAS # unbias FS exponent or t2, t2, DIMPL_ONE # set implied one bit 3: - bne t5, zero, 2f # is FT zero? - bne t6, zero, 1f - bne t7, zero, 1f + bne ta1, zero, 2f # is FT zero? + bne ta2, zero, 1f + bne ta3, zero, 1f or a1, a1, FPC_EXCEPTION_DIV0 | FPC_STICKY_DIV0 and v0, a1, FPC_ENABLE_DIV0 # trap enabled? bne v0, zero, fpe_trap @@ -1164,10 +1164,10 @@ div_d: jal renorm_ft_d b 3f 2: - subu t5, t5, DEXP_BIAS # unbias FT exponent - or t6, t6, DIMPL_ONE # set implied one bit + subu ta1, ta1, DEXP_BIAS # unbias FT exponent + or ta2, ta2, DIMPL_ONE # set implied one bit 3: - subu t1, t1, t5 # compute exponent + subu t1, t1, ta1 # compute exponent subu t1, t1, 3 # compensate for result position li v0, DFRAC_BITS+3 # number of bits to divide move t8, t2 # init dividend @@ -1175,13 +1175,13 @@ div_d: move t2, zero # init result move t3, zero 1: - bltu t8, t6, 3f # is dividend >= divisor? - bne t8, t6, 2f - bltu t9, t7, 3f + bltu t8, ta2, 3f # is dividend >= divisor? + bne t8, ta2, 2f + bltu t9, ta3, 3f 2: - sltu v1, t9, t7 # subtract divisor from dividend - subu t9, t9, t7 - subu t8, t8, t6 + sltu v1, t9, ta3 # subtract divisor from dividend + subu t9, t9, ta3 + subu t8, t8, ta2 subu t8, t8, v1 or t3, t3, 1 # remember that we did bne t8, zero, 3f # if not done, continue @@ -1576,23 +1576,23 @@ cmp_s: bne t1, SEXP_INF, 1f # is FS an infinity? bne t2, zero, unordered # FS is a NAN 1: - bne t5, SEXP_INF, 2f # is FT an infinity? - bne t6, zero, unordered # FT is a NAN + bne ta1, SEXP_INF, 2f # is FT an infinity? + bne ta2, zero, unordered # FT is a NAN 2: sll t1, t1, 23 # reassemble exp & frac or t1, t1, t2 - sll t5, t5, 23 # reassemble exp & frac - or t5, t5, t6 + sll ta1, ta1, 23 # reassemble exp & frac + or ta1, ta1, ta2 beq t0, zero, 1f # is FS positive? negu t1 1: - beq t4, zero, 1f # is FT positive? - negu t5 + beq ta0, zero, 1f # is FT positive? + negu ta1 1: li v0, COND_LESS - blt t1, t5, test_cond # is FS < FT? + blt t1, ta1, test_cond # is FS < FT? li v0, COND_EQUAL - beq t1, t5, test_cond # is FS == FT? + beq t1, ta1, test_cond # is FS == FT? move v0, zero # FS > FT b test_cond @@ -1605,14 +1605,14 @@ cmp_d: bne t2, zero, unordered bne t3, zero, unordered # FS is a NAN 1: - bne t5, DEXP_INF, 2f # is FT an infinity? - bne t6, zero, unordered - bne t7, zero, unordered # FT is a NAN + bne ta1, DEXP_INF, 2f # is FT an infinity? + bne ta2, zero, unordered + bne ta3, zero, unordered # FT is a NAN 2: sll t1, t1, 20 # reassemble exp & frac or t1, t1, t2 - sll t5, t5, 20 # reassemble exp & frac - or t5, t5, t6 + sll ta1, ta1, 20 # reassemble exp & frac + or ta1, ta1, ta2 beq t0, zero, 1f # is FS positive? not t3 # negate t1,t3 not t1 @@ -1620,21 +1620,21 @@ cmp_d: seq v0, t3, zero # compute carry addu t1, t1, v0 1: - beq t4, zero, 1f # is FT positive? - not t7 # negate t5,t7 - not t5 - addu t7, t7, 1 - seq v0, t7, zero # compute carry - addu t5, t5, v0 + beq ta0, zero, 1f # is FT positive? + not ta3 # negate ta1,ta3 + not ta1 + addu ta3, ta3, 1 + seq v0, ta3, zero # compute carry + addu ta1, ta1, v0 1: li v0, COND_LESS - blt t1, t5, test_cond # is FS(MSW) < FT(MSW)? + blt t1, ta1, test_cond # is FS(MSW) < FT(MSW)? move v0, zero - bne t1, t5, test_cond # is FS(MSW) > FT(MSW)? + bne t1, ta1, test_cond # is FS(MSW) > FT(MSW)? li v0, COND_LESS - bltu t3, t7, test_cond # is FS(LSW) < FT(LSW)? + bltu t3, ta3, test_cond # is FS(LSW) < FT(LSW)? li v0, COND_EQUAL - beq t3, t7, test_cond # is FS(LSW) == FT(LSW)? + beq t3, ta3, test_cond # is FS(LSW) == FT(LSW)? move v0, zero # FS > FT test_cond: and v0, v0, a0 # condition match instruction? @@ -1725,8 +1725,8 @@ norm_s: or t8, t8, v0 srl t2, t2, t9 norm_noshift_s: - move t5, t1 # save unrounded exponent - move t6, t2 # save unrounded fraction + move ta1, t1 # save unrounded exponent + move ta2, t2 # save unrounded fraction and v0, a1, FPC_ROUNDING_BITS # get rounding mode beq v0, FPC_ROUND_RN, 3f # round to nearest beq v0, FPC_ROUND_RZ, 5f # round to zero (truncate) @@ -1826,8 +1826,8 @@ underflow_s: * signal inexact result (if it is) and trap (if enabled). */ 1: - move t1, t5 # get unrounded exponent - move t2, t6 # get unrounded fraction + move t1, ta1 # get unrounded exponent + move t2, ta2 # get unrounded fraction li t9, SEXP_MIN # compute shift amount subu t9, t9, t1 # shift t2,t8 right by t9 blt t9, SFRAC_BITS+2, 3f # shift all the bits out? @@ -1841,7 +1841,7 @@ underflow_s: and v0, a1, FPC_ROUNDING_BITS # get rounding mode beq v0, FPC_ROUND_RN, inexact_nobias_s # round to nearest beq v0, FPC_ROUND_RZ, inexact_nobias_s # round to zero - beq v0, FPC_ROUND_RP, 1f # round to +infinity + beq v0, FPC_ROUND_RP, 1f # round to +infinity beq t0, zero, inexact_nobias_s # if sign is positive, truncate b 2f 1: @@ -1970,9 +1970,9 @@ norm_d: or t3, t3, v0 srl t2, t2, t9 norm_noshift_d: - move t5, t1 # save unrounded exponent - move t6, t2 # save unrounded fraction (MS) - move t7, t3 # save unrounded fraction (LS) + move ta1, t1 # save unrounded exponent + move ta2, t2 # save unrounded fraction (MS) + move ta3, t3 # save unrounded fraction (LS) and v0, a1, FPC_ROUNDING_BITS # get rounding mode beq v0, FPC_ROUND_RN, 3f # round to nearest beq v0, FPC_ROUND_RZ, 5f # round to zero (truncate) @@ -2078,9 +2078,9 @@ underflow_d: * signal inexact result (if it is) and trap (if enabled). */ 1: - move t1, t5 # get unrounded exponent - move t2, t6 # get unrounded fraction (MS) - move t3, t7 # get unrounded fraction (LS) + move t1, ta1 # get unrounded exponent + move t2, ta2 # get unrounded fraction (MS) + move t3, ta3 # get unrounded fraction (LS) li t9, DEXP_MIN # compute shift amount subu t9, t9, t1 # shift t2,t8 right by t9 blt t9, DFRAC_BITS+2, 3f # shift all the bits out? @@ -2095,7 +2095,7 @@ underflow_d: and v0, a1, FPC_ROUNDING_BITS # get rounding mode beq v0, FPC_ROUND_RN, inexact_nobias_d # round to nearest beq v0, FPC_ROUND_RZ, inexact_nobias_d # round to zero - beq v0, FPC_ROUND_RP, 1f # round to +infinity + beq v0, FPC_ROUND_RP, 1f # round to +infinity beq t0, zero, inexact_nobias_d # if sign is positive, truncate b 2f 1: @@ -2128,9 +2128,9 @@ underflow_d: */ 2: and v0, a1, FPC_ROUNDING_BITS # get rounding mode - beq v0, FPC_ROUND_RN, 3f # round to nearest - beq v0, FPC_ROUND_RZ, 5f # round to zero (truncate) - beq v0, FPC_ROUND_RP, 1f # round to +infinity + beq v0, FPC_ROUND_RN, 3f # round to nearest + beq v0, FPC_ROUND_RZ, 5f # round to zero (truncate) + beq v0, FPC_ROUND_RP, 1f # round to +infinity beq t0, zero, 5f # if sign is positive, truncate b 2f 1: @@ -2227,9 +2227,9 @@ ill: break 0 result_ft_s: - move t0, t4 # result is FT - move t1, t5 - move t2, t6 + move t0, ta0 # result is FT + move t1, ta1 + move t2, ta2 result_fs_s: # result is FS jal set_fd_s # save result (in t0,t1,t2) b done @@ -2239,10 +2239,10 @@ result_fs_w: b done result_ft_d: - move t0, t4 # result is FT - move t1, t5 - move t2, t6 - move t3, t7 + move t0, ta0 # result is FT + move t1, ta1 + move t2, ta2 + move t3, ta3 result_fs_d: # result is FS jal set_fd_d # save result (in t0,t1,t2,t3) @@ -2356,9 +2356,9 @@ END(get_fs_int) * t0 contains the FS sign * t1 contains the FS (biased) exponent * t2 contains the FS fraction - * t4 contains the FT sign - * t5 contains the FT (biased) exponent - * t6 contains the FT fraction + * ta0 contains the FT sign + * ta1 contains the FT (biased) exponent + * ta2 contains the FT fraction * *---------------------------------------------------------------------------- */ @@ -2389,59 +2389,59 @@ get_ft_s_tbl: .text get_ft_s_f0: - mfc1 t4, $f0 + mfc1 ta0, $f0 b get_ft_s_done get_ft_s_f2: - mfc1 t4, $f2 + mfc1 ta0, $f2 b get_ft_s_done get_ft_s_f4: - mfc1 t4, $f4 + mfc1 ta0, $f4 b get_ft_s_done get_ft_s_f6: - mfc1 t4, $f6 + mfc1 ta0, $f6 b get_ft_s_done get_ft_s_f8: - mfc1 t4, $f8 + mfc1 ta0, $f8 b get_ft_s_done get_ft_s_f10: - mfc1 t4, $f10 + mfc1 ta0, $f10 b get_ft_s_done get_ft_s_f12: - mfc1 t4, $f12 + mfc1 ta0, $f12 b get_ft_s_done get_ft_s_f14: - mfc1 t4, $f14 + mfc1 ta0, $f14 b get_ft_s_done get_ft_s_f16: - mfc1 t4, $f16 + mfc1 ta0, $f16 b get_ft_s_done get_ft_s_f18: - mfc1 t4, $f18 + mfc1 ta0, $f18 b get_ft_s_done get_ft_s_f20: - mfc1 t4, $f20 + mfc1 ta0, $f20 b get_ft_s_done get_ft_s_f22: - mfc1 t4, $f22 + mfc1 ta0, $f22 b get_ft_s_done get_ft_s_f24: - mfc1 t4, $f24 + mfc1 ta0, $f24 b get_ft_s_done get_ft_s_f26: - mfc1 t4, $f26 + mfc1 ta0, $f26 b get_ft_s_done get_ft_s_f28: - mfc1 t4, $f28 + mfc1 ta0, $f28 b get_ft_s_done get_ft_s_f30: - mfc1 t4, $f30 + mfc1 ta0, $f30 get_ft_s_done: - srl t5, t4, 23 # get exponent - and t5, t5, 0xFF - and t6, t4, 0x7FFFFF # get fraction - srl t4, t4, 31 # get sign - bne t5, SEXP_INF, 1f # is it a signaling NAN? - and v0, t6, SSIGNAL_NAN + srl ta1, ta0, 23 # get exponent + and ta1, ta1, 0xFF + and ta2, ta0, 0x7FFFFF # get fraction + srl ta0, ta0, 31 # get sign + bne ta1, SEXP_INF, 1f # is it a signaling NAN? + and v0, ta2, SSIGNAL_NAN bne v0, zero, invalid_s 1: /* fall through to get FS */ @@ -2557,10 +2557,10 @@ END(get_ft_fs_s) * t1 contains the FS (biased) exponent * t2 contains the FS fraction * t3 contains the FS remaining fraction - * t4 contains the FT sign - * t5 contains the FT (biased) exponent - * t6 contains the FT fraction - * t7 contains the FT remaining fraction + * ta0 contains the FT sign + * ta1 contains the FT (biased) exponent + * ta2 contains the FT fraction + * ta3 contains the FT remaining fraction * *---------------------------------------------------------------------------- */ @@ -2591,75 +2591,75 @@ get_ft_d_tbl: .text get_ft_d_f0: - mfc1 t7, $f0 - mfc1 t4, $f1 + mfc1 ta3, $f0 + mfc1 ta0, $f1 b get_ft_d_done get_ft_d_f2: - mfc1 t7, $f2 - mfc1 t4, $f3 + mfc1 ta3, $f2 + mfc1 ta0, $f3 b get_ft_d_done get_ft_d_f4: - mfc1 t7, $f4 - mfc1 t4, $f5 + mfc1 ta3, $f4 + mfc1 ta0, $f5 b get_ft_d_done get_ft_d_f6: - mfc1 t7, $f6 - mfc1 t4, $f7 + mfc1 ta3, $f6 + mfc1 ta0, $f7 b get_ft_d_done get_ft_d_f8: - mfc1 t7, $f8 - mfc1 t4, $f9 + mfc1 ta3, $f8 + mfc1 ta0, $f9 b get_ft_d_done get_ft_d_f10: - mfc1 t7, $f10 - mfc1 t4, $f11 + mfc1 ta3, $f10 + mfc1 ta0, $f11 b get_ft_d_done get_ft_d_f12: - mfc1 t7, $f12 - mfc1 t4, $f13 + mfc1 ta3, $f12 + mfc1 ta0, $f13 b get_ft_d_done get_ft_d_f14: - mfc1 t7, $f14 - mfc1 t4, $f15 + mfc1 ta3, $f14 + mfc1 ta0, $f15 b get_ft_d_done get_ft_d_f16: - mfc1 t7, $f16 - mfc1 t4, $f17 + mfc1 ta3, $f16 + mfc1 ta0, $f17 b get_ft_d_done get_ft_d_f18: - mfc1 t7, $f18 - mfc1 t4, $f19 + mfc1 ta3, $f18 + mfc1 ta0, $f19 b get_ft_d_done get_ft_d_f20: - mfc1 t7, $f20 - mfc1 t4, $f21 + mfc1 ta3, $f20 + mfc1 ta0, $f21 b get_ft_d_done get_ft_d_f22: - mfc1 t7, $f22 - mfc1 t4, $f23 + mfc1 ta3, $f22 + mfc1 ta0, $f23 b get_ft_d_done get_ft_d_f24: - mfc1 t7, $f24 - mfc1 t4, $f25 + mfc1 ta3, $f24 + mfc1 ta0, $f25 b get_ft_d_done get_ft_d_f26: - mfc1 t7, $f26 - mfc1 t4, $f27 + mfc1 ta3, $f26 + mfc1 ta0, $f27 b get_ft_d_done get_ft_d_f28: - mfc1 t7, $f28 - mfc1 t4, $f29 + mfc1 ta3, $f28 + mfc1 ta0, $f29 b get_ft_d_done get_ft_d_f30: - mfc1 t7, $f30 - mfc1 t4, $f31 + mfc1 ta3, $f30 + mfc1 ta0, $f31 get_ft_d_done: - srl t5, t4, 20 # get exponent - and t5, t5, 0x7FF - and t6, t4, 0xFFFFF # get fraction - srl t4, t4, 31 # get sign - bne t5, DEXP_INF, 1f # is it a signaling NAN? - and v0, t6, DSIGNAL_NAN + srl ta1, ta0, 20 # get exponent + and ta1, ta1, 0x7FF + and ta2, ta0, 0xFFFFF # get fraction + srl ta0, ta0, 31 # get sign + bne ta1, DEXP_INF, 1f # is it a signaling NAN? + and v0, ta2, DSIGNAL_NAN bne v0, zero, invalid_d 1: /* fall through to get FS */ @@ -2791,9 +2791,9 @@ END(get_ft_fs_d) * t0 contains the sign * t1 contains the (biased) exponent * t2 contains the fraction - * t4 contains the sign - * t5 contains the (biased) exponent - * t6 contains the fraction + * ta0 contains the sign + * ta1 contains the (biased) exponent + * ta2 contains the fraction * *---------------------------------------------------------------------------- */ @@ -2902,57 +2902,57 @@ cmp_ft_s_tbl: .text cmp_ft_s_f0: - mfc1 t4, $f0 + mfc1 ta0, $f0 b cmp_ft_s_done cmp_ft_s_f2: - mfc1 t4, $f2 + mfc1 ta0, $f2 b cmp_ft_s_done cmp_ft_s_f4: - mfc1 t4, $f4 + mfc1 ta0, $f4 b cmp_ft_s_done cmp_ft_s_f6: - mfc1 t4, $f6 + mfc1 ta0, $f6 b cmp_ft_s_done cmp_ft_s_f8: - mfc1 t4, $f8 + mfc1 ta0, $f8 b cmp_ft_s_done cmp_ft_s_f10: - mfc1 t4, $f10 + mfc1 ta0, $f10 b cmp_ft_s_done cmp_ft_s_f12: - mfc1 t4, $f12 + mfc1 ta0, $f12 b cmp_ft_s_done cmp_ft_s_f14: - mfc1 t4, $f14 + mfc1 ta0, $f14 b cmp_ft_s_done cmp_ft_s_f16: - mfc1 t4, $f16 + mfc1 ta0, $f16 b cmp_ft_s_done cmp_ft_s_f18: - mfc1 t4, $f18 + mfc1 ta0, $f18 b cmp_ft_s_done cmp_ft_s_f20: - mfc1 t4, $f20 + mfc1 ta0, $f20 b cmp_ft_s_done cmp_ft_s_f22: - mfc1 t4, $f22 + mfc1 ta0, $f22 b cmp_ft_s_done cmp_ft_s_f24: - mfc1 t4, $f24 + mfc1 ta0, $f24 b cmp_ft_s_done cmp_ft_s_f26: - mfc1 t4, $f26 + mfc1 ta0, $f26 b cmp_ft_s_done cmp_ft_s_f28: - mfc1 t4, $f28 + mfc1 ta0, $f28 b cmp_ft_s_done cmp_ft_s_f30: - mfc1 t4, $f30 + mfc1 ta0, $f30 cmp_ft_s_done: - srl t5, t4, 23 # get exponent - and t5, t5, 0xFF - and t6, t4, 0x7FFFFF # get fraction - srl t4, t4, 31 # get sign + srl ta1, ta0, 23 # get exponent + and ta1, ta1, 0xFF + and ta2, ta0, 0x7FFFFF # get fraction + srl ta0, ta0, 31 # get sign j ra END(get_cmp_s) @@ -2968,10 +2968,10 @@ END(get_cmp_s) * t1 contains the (biased) exponent * t2 contains the fraction * t3 contains the remaining fraction - * t4 contains the sign - * t5 contains the (biased) exponent - * t6 contains the fraction - * t7 contains the remaining fraction + * ta0 contains the sign + * ta1 contains the (biased) exponent + * ta2 contains the fraction + * ta3 contains the remaining fraction * *---------------------------------------------------------------------------- */ @@ -3096,73 +3096,73 @@ cmp_ft_d_tbl: .text cmp_ft_d_f0: - mfc1 t7, $f0 - mfc1 t4, $f1 + mfc1 ta3, $f0 + mfc1 ta0, $f1 b cmp_ft_d_done cmp_ft_d_f2: - mfc1 t7, $f2 - mfc1 t4, $f3 + mfc1 ta3, $f2 + mfc1 ta0, $f3 b cmp_ft_d_done cmp_ft_d_f4: - mfc1 t7, $f4 - mfc1 t4, $f5 + mfc1 ta3, $f4 + mfc1 ta0, $f5 b cmp_ft_d_done cmp_ft_d_f6: - mfc1 t7, $f6 - mfc1 t4, $f7 + mfc1 ta3, $f6 + mfc1 ta0, $f7 b cmp_ft_d_done cmp_ft_d_f8: - mfc1 t7, $f8 - mfc1 t4, $f9 + mfc1 ta3, $f8 + mfc1 ta0, $f9 b cmp_ft_d_done cmp_ft_d_f10: - mfc1 t7, $f10 - mfc1 t4, $f11 + mfc1 ta3, $f10 + mfc1 ta0, $f11 b cmp_ft_d_done cmp_ft_d_f12: - mfc1 t7, $f12 - mfc1 t4, $f13 + mfc1 ta3, $f12 + mfc1 ta0, $f13 b cmp_ft_d_done cmp_ft_d_f14: - mfc1 t7, $f14 - mfc1 t4, $f15 + mfc1 ta3, $f14 + mfc1 ta0, $f15 b cmp_ft_d_done cmp_ft_d_f16: - mfc1 t7, $f16 - mfc1 t4, $f17 + mfc1 ta3, $f16 + mfc1 ta0, $f17 b cmp_ft_d_done cmp_ft_d_f18: - mfc1 t7, $f18 - mfc1 t4, $f19 + mfc1 ta3, $f18 + mfc1 ta0, $f19 b cmp_ft_d_done cmp_ft_d_f20: - mfc1 t7, $f20 - mfc1 t4, $f21 + mfc1 ta3, $f20 + mfc1 ta0, $f21 b cmp_ft_d_done cmp_ft_d_f22: - mfc1 t7, $f22 - mfc1 t4, $f23 + mfc1 ta3, $f22 + mfc1 ta0, $f23 b cmp_ft_d_done cmp_ft_d_f24: - mfc1 t7, $f24 - mfc1 t4, $f25 + mfc1 ta3, $f24 + mfc1 ta0, $f25 b cmp_ft_d_done cmp_ft_d_f26: - mfc1 t7, $f26 - mfc1 t4, $f27 + mfc1 ta3, $f26 + mfc1 ta0, $f27 b cmp_ft_d_done cmp_ft_d_f28: - mfc1 t7, $f28 - mfc1 t4, $f29 + mfc1 ta3, $f28 + mfc1 ta0, $f29 b cmp_ft_d_done cmp_ft_d_f30: - mfc1 t7, $f30 - mfc1 t4, $f31 + mfc1 ta3, $f30 + mfc1 ta0, $f31 cmp_ft_d_done: - srl t5, t4, 20 # get exponent - and t5, t5, 0x7FF - and t6, t4, 0xFFFFF # get fraction - srl t4, t4, 31 # get sign + srl ta1, ta0, 20 # get exponent + and ta1, ta1, 0x7FF + and ta2, ta0, 0xFFFFF # get fraction + srl ta0, ta0, 31 # get sign j ra END(get_cmp_d) @@ -3498,16 +3498,16 @@ END(renorm_fs_d) * renorm_ft_s -- * * Results: - * t5 unbiased exponent - * t6 normalized fraction + * ta1 unbiased exponent + * ta2 normalized fraction * *---------------------------------------------------------------------------- */ LEAF(renorm_ft_s) /* - * Find out how many leading zero bits are in t6 and put in t9. + * Find out how many leading zero bits are in ta2 and put in t9. */ - move v0, t6 + move v0, ta2 move t9, zero srl v1, v0, 16 bne v1, zero, 1f @@ -3533,13 +3533,13 @@ LEAF(renorm_ft_s) bne v1, zero, 1f addu t9, 1 /* - * Now shift t6 the correct number of bits. + * Now shift ta2 the correct number of bits. */ 1: subu t9, t9, SLEAD_ZEROS # dont count normal leading zeros - li t5, SEXP_MIN - subu t5, t5, t9 # adjust exponent - sll t6, t6, t9 + li ta1, SEXP_MIN + subu ta1, ta1, t9 # adjust exponent + sll ta2, ta2, t9 j ra END(renorm_ft_s) @@ -3547,19 +3547,19 @@ END(renorm_ft_s) * renorm_ft_d -- * * Results: - * t5 unbiased exponent - * t6,t7 normalized fraction + * ta1 unbiased exponent + * ta2,ta3 normalized fraction * *---------------------------------------------------------------------------- */ LEAF(renorm_ft_d) /* - * Find out how many leading zero bits are in t6,t7 and put in t9. + * Find out how many leading zero bits are in ta2,ta3 and put in t9. */ - move v0, t6 + move v0, ta2 move t9, zero - bne t6, zero, 1f - move v0, t7 + bne ta2, zero, 1f + move v0, ta3 addu t9, 32 1: srl v1, v0, 16 @@ -3586,23 +3586,23 @@ LEAF(renorm_ft_d) bne v1, zero, 1f addu t9, 1 /* - * Now shift t6,t7 the correct number of bits. + * Now shift ta2,ta3 the correct number of bits. */ 1: subu t9, t9, DLEAD_ZEROS # dont count normal leading zeros - li t5, DEXP_MIN - subu t5, t5, t9 # adjust exponent + li ta1, DEXP_MIN + subu ta1, ta1, t9 # adjust exponent li v0, 32 blt t9, v0, 1f subu t9, t9, v0 # shift fraction left >= 32 bits - sll t6, t7, t9 - move t7, zero + sll ta2, ta3, t9 + move ta3, zero j ra 1: subu v0, v0, t9 # shift fraction left < 32 bits - sll t6, t6, t9 - srl v1, t7, v0 - or t6, t6, v1 - sll t7, t7, t9 + sll ta2, ta2, t9 + srl v1, ta3, v0 + or ta2, ta2, v1 + sll ta3, ta3, t9 j ra END(renorm_ft_d) From 52efe5c569df92df4710d9db649f25e82fa35ff5 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 10 Jul 2009 19:06:15 +0000 Subject: [PATCH 210/380] Fixed aligned macros... # I'm not sure bde will like this, but I want to commit it for others to review # as well. :) --- sys/mips/include/param.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/mips/include/param.h b/sys/mips/include/param.h index 49a74f58af9..9945e1a1cde 100644 --- a/sys/mips/include/param.h +++ b/sys/mips/include/param.h @@ -80,11 +80,11 @@ /* * Round p (pointer or byte index) up to a correctly-aligned value for all * data types (int, long, ...). The result is u_int and must be cast to - * any desired pointer type. + * any desired pointer type. XXX u_int isn't big enough to hod a pointer. */ #define _ALIGNBYTES 7 -#define _ALIGN(p) (((u_int)(p) + _ALIGNBYTES) &~ _ALIGNBYTES) -#define ALIGNED_POINTER(p, t) ((((u_int32_t)(p)) & (sizeof (t) - 1)) == 0) +#define _ALIGN(p) (((uintptr_t)(p) + _ALIGNBYTES) &~ _ALIGNBYTES) +#define ALIGNED_POINTER(p, t) ((((uintptr_t)(p)) & (sizeof (t) - 1)) == 0) #define ALIGNBYTES _ALIGNBYTES #define ALIGN(p) _ALIGN(p) From 4d8c18e0d73629498dd40c390bf4bd6d8fbb2e4a Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 10 Jul 2009 19:06:43 +0000 Subject: [PATCH 211/380] Better definitions for a few types for n32/n64. --- sys/mips/include/_types.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sys/mips/include/_types.h b/sys/mips/include/_types.h index 694b02a32d0..6ee30e3737f 100644 --- a/sys/mips/include/_types.h +++ b/sys/mips/include/_types.h @@ -102,7 +102,7 @@ typedef __int8_t __int_least8_t; typedef __int16_t __int_least16_t; typedef __int32_t __int_least32_t; typedef __int64_t __int_least64_t; -#if defined(__mips_n64) || defined(ISA_MIPS64) +#if defined(__mips_n64) || defined(__mips_n32) typedef __int64_t __register_t; typedef __int64_t f_register_t; #else @@ -134,13 +134,16 @@ typedef __uint8_t __uint_least8_t; typedef __uint16_t __uint_least16_t; typedef __uint32_t __uint_least32_t; typedef __uint64_t __uint_least64_t; -#if defined(__mips_n64) || defined(ISA_MIPS64) +#if defined(__mips_n64) || defined(__mips_n32) typedef __uint64_t __u_register_t; +#else +typedef __uint32_t __u_register_t; +#endif +#if defined(__mips_n64) typedef __uint64_t __vm_offset_t; typedef __uint64_t __vm_paddr_t; typedef __uint64_t __vm_size_t; #else -typedef __uint32_t __u_register_t; typedef __uint32_t __vm_offset_t; typedef __uint32_t __vm_paddr_t; typedef __uint32_t __vm_size_t; From df92abe375ae9d2cf2b172ab6c642a76b9ef2660 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 10 Jul 2009 19:07:07 +0000 Subject: [PATCH 212/380] fix prototype for MipsEmulateBranch. --- sys/mips/include/md_var.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/include/md_var.h b/sys/mips/include/md_var.h index 4101ee6a8dd..8755fd0302d 100644 --- a/sys/mips/include/md_var.h +++ b/sys/mips/include/md_var.h @@ -48,7 +48,7 @@ extern vm_offset_t kstack0; void MipsSaveCurFPState(struct thread *); void fork_trampoline(void); void cpu_swapin(struct proc *); -u_int MipsEmulateBranch(struct trapframe *, int, int, u_int); +uintptr_t MipsEmulateBranch(struct trapframe *, uintptr_t, int, uintptr_t); u_long kvtop(void *addr); int is_physical_memory(vm_offset_t addr); int is_cacheable_mem(vm_offset_t pa); From de13b5d0f94ec0d4250b4790d07e2d3ae0665f33 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 10 Jul 2009 19:08:48 +0000 Subject: [PATCH 213/380] Use PTR_* macros to deal with pointers. --- sys/mips/mips/exception.S | 92 +++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 48 deletions(-) diff --git a/sys/mips/mips/exception.S b/sys/mips/mips/exception.S index 6223e80e129..2fc1bb83839 100644 --- a/sys/mips/mips/exception.S +++ b/sys/mips/mips/exception.S @@ -139,12 +139,14 @@ VECTOR_END(MipsTLBMiss) *---------------------------------------------------------------------------- */ MipsDoTLBMiss: +#xxx mips64 unsafe? #ifndef SMP lui k1, %hi(_C_LABEL(pcpup)) #endif #k0 already has BadVA bltz k0, 1f #02: k0<0 -> 1f (kernel fault) srl k0, k0, SEGSHIFT - 2 #03: k0=seg offset (almost) +#xxx mips64 unsafe? #ifdef SMP GET_CPU_PCPU(k1) #else @@ -153,6 +155,7 @@ MipsDoTLBMiss: lw k1, PC_SEGBASE(k1) beqz k1, 2f #05: make sure segbase is not null andi k0, k0, 0x7fc #06: k0=seg offset (mask 0x3) +#xxx mips64 unsafe? addu k1, k0, k1 #07: k1=seg entry address lw k1, 0(k1) #08: k1=seg entry mfc0 k0, COP_0_BAD_VADDR #09: k0=bad address (again) @@ -160,6 +163,7 @@ MipsDoTLBMiss: srl k0, PGSHIFT - 2 #0b: k0=VPN (aka va>>10) andi k0, k0, ((NPTEPG/2) - 1) << 3 #0c: k0=page tab offset +#xxx mips64 unsafe? addu k1, k1, k0 #0d: k1=pte address lw k0, 0(k1) #0e: k0=lo0 pte lw k1, 4(k1) #0f: k1=lo1 pte @@ -199,8 +203,8 @@ VECTOR(MipsException, unknown) and k1, k1, CR_EXC_CODE # Mask out the cause bits. or k1, k1, k0 # change index to user table 1: - la k0, _C_LABEL(machExceptionTable) # get base of the jump table - addu k0, k0, k1 # Get the address of the + PTR_LA k0, _C_LABEL(machExceptionTable) # get base of the jump table + PTR_ADDU k0, k0, k1 # Get the address of the # function entry. Note that # the cause is already # shifted left by 2 bits so @@ -315,10 +319,10 @@ SlowFault: SAVE_REG(ra, RA, sp) ;\ SAVE_REG(a2, BADVADDR, sp) ;\ SAVE_REG(a3, PC, sp) ;\ - addu v0, sp, KERN_EXC_FRAME_SIZE ;\ + PTR_ADDU v0, sp, KERN_EXC_FRAME_SIZE ;\ SAVE_REG(v0, SP, sp) ;\ CLEAR_STATUS ;\ - addu a0, sp, STAND_ARG_SIZE ;\ + PTR_ADDU a0, sp, STAND_ARG_SIZE ;\ ITLBNOPFIX #define RESTORE_REG(reg, offs, base) \ @@ -361,7 +365,7 @@ SlowFault: RESTORE_REG(s8, S8, sp) ;\ RESTORE_REG(gp, GP, sp) ;\ RESTORE_REG(ra, RA, sp) ;\ - addu sp, sp, KERN_EXC_FRAME_SIZE;\ + PTR_ADDU sp, sp, KERN_EXC_FRAME_SIZE;\ mtc0 k0, COP_0_STATUS_REG @@ -384,8 +388,8 @@ NNON_LEAF(MipsKernGenException, KERN_EXC_FRAME_SIZE, ra) /* * Call the exception handler. a0 points at the saved frame. */ - la gp, _C_LABEL(_gp) - la k0, _C_LABEL(trap) + PTR_LA gp, _C_LABEL(_gp) + PTR_LA k0, _C_LABEL(trap) jalr k0 sw a3, STAND_RA_OFFSET + KERN_REG_SIZE(sp) # for debugging @@ -481,20 +485,20 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra) SAVE_U_PCB_REG(a2, BADVADDR, k1) SAVE_U_PCB_REG(a3, PC, k1) sw a3, STAND_RA_OFFSET(sp) # for debugging - la gp, _C_LABEL(_gp) # switch to kernel GP + PTR_LA gp, _C_LABEL(_gp) # switch to kernel GP # Turn off fpu and enter kernel mode and t0, a0, ~(SR_COP_1_BIT | SR_EXL | SR_KSU_MASK | SR_INT_ENAB) #ifdef TARGET_OCTEON or t0, t0, (MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX) #endif mtc0 t0, COP_0_STATUS_REG - addu a0, k1, U_PCB_REGS + PTR_ADDU a0, k1, U_PCB_REGS ITLBNOPFIX /* * Call the exception handler. */ - la k0, _C_LABEL(trap) + PTR_LA k0, _C_LABEL(trap) jalr k0 nop @@ -615,9 +619,9 @@ NNON_LEAF(MipsKernIntr, KERN_EXC_FRAME_SIZE, ra) /* * Call the interrupt handler. */ - la gp, _C_LABEL(_gp) - addu a0, sp, STAND_ARG_SIZE - la k0, _C_LABEL(cpu_intr) + PTR_LA gp, _C_LABEL(_gp) + PTR_ADDU a0, sp, STAND_ARG_SIZE + PTR_LA k0, _C_LABEL(cpu_intr) jalr k0 sw a3, STAND_RA_OFFSET + KERN_REG_SIZE(sp) /* Why no AST processing here? */ @@ -717,7 +721,7 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra) SAVE_U_PCB_REG(a1, CAUSE, k1) SAVE_U_PCB_REG(a3, PC, k1) # PC in a3, note used later! subu sp, k1, STAND_FRAME_SIZE # switch to kernel SP - la gp, _C_LABEL(_gp) # switch to kernel GP + PTR_LA gp, _C_LABEL(_gp) # switch to kernel GP # Turn off fpu, disable interrupts, set kernel mode kernel mode, clear exception level. and t0, a0, ~(SR_COP_1_BIT | SR_EXL | SR_INT_ENAB | SR_KSU_MASK) @@ -726,11 +730,11 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra) #endif mtc0 t0, COP_0_STATUS_REG ITLBNOPFIX - addu a0, k1, U_PCB_REGS + PTR_ADDU a0, k1, U_PCB_REGS /* * Call the interrupt handler. */ - la k0, _C_LABEL(cpu_intr) + PTR_LA k0, _C_LABEL(cpu_intr) jalr k0 sw a3, STAND_RA_OFFSET(sp) # for debugging @@ -879,6 +883,7 @@ NLEAF(MipsKernTLBInvalidException) 2: srl k0, 20 # k0=seg offset (almost) andi k0, k0, 0xffc # k0=seg offset (mask 0x3) +#xxx mips64 unsafe? addu k1, k0, k1 # k1=seg entry address lw k1, 0(k1) # k1=seg entry mfc0 k0, COP_0_BAD_VADDR # k0=bad address (again) @@ -886,6 +891,7 @@ NLEAF(MipsKernTLBInvalidException) srl k0, k0, PGSHIFT-2 andi k0, k0, 0xffc # compute offset from index tlbp # Probe the invalid entry +#xxx mips64 unsafe? addu k1, k1, k0 and k0, k0, 4 # check even/odd page nop # required for QED 5230 @@ -951,6 +957,7 @@ NLEAF(MipsUserTLBInvalidException) sltu k1, k0, k1 beqz k1, _C_LABEL(MipsUserGenException) nop +#xxx mips64 unsafe? #ifdef SMP GET_CPU_PCPU(k1) #else @@ -963,6 +970,7 @@ NLEAF(MipsUserTLBInvalidException) 2: srl k0, 20 # k0=seg offset (almost) andi k0, k0, 0xffc # k0=seg offset (mask 0x3) +#xxx mips64 unsafe? addu k1, k0, k1 # k1=seg entry address lw k1, 0(k1) # k1=seg entry mfc0 k0, COP_0_BAD_VADDR # k0=bad address (again) @@ -970,6 +978,7 @@ NLEAF(MipsUserTLBInvalidException) srl k0, k0, PGSHIFT-2 andi k0, k0, 0xffc # compute offset from index tlbp # Probe the invalid entry +#xxx mips64 unsafe? addu k1, k1, k0 and k0, k0, 4 # check even/odd page nop # required for QED 5230 @@ -1053,12 +1062,14 @@ NLEAF(MipsTLBMissException) lw k1, %lo(_C_LABEL(kernel_segmap))(k1) # k1=segment tab base beq k1, zero, _C_LABEL(MipsKernGenException) # ==0 -- no seg tab andi k0, k0, 0xffc # k0=seg offset (mask 0x3) +#xxx mips64 unsafe addu k1, k0, k1 # k1=seg entry address lw k1, 0(k1) # k1=seg entry mfc0 k0, COP_0_BAD_VADDR # k0=bad address (again) beq k1, zero, _C_LABEL(MipsKernGenException) # ==0 -- no page table srl k0, 10 # k0=VPN (aka va>>10) andi k0, k0, 0xff8 # k0=page tab offset +#xxx mips64 unsafe addu k1, k1, k0 # k1=pte address lw k0, 0(k1) # k0=lo0 pte lw k1, 4(k1) # k1=lo1 pte @@ -1083,31 +1094,31 @@ sys_stk_chk: nop # stack overflow - la a0, _C_LABEL(_start) - START_FRAME - 8 # set sp to a valid place + PTR_LA a0, _C_LABEL(_start) - START_FRAME - 8 # set sp to a valid place sw sp, 24(a0) move sp, a0 - la a0, 1f + PTR_LA a0, 1f mfc0 a2, COP_0_STATUS_REG mfc0 a3, COP_0_CAUSE_REG _MFC0 a1, COP_0_EXC_PC sw a2, 16(sp) sw a3, 20(sp) move a2, ra - la k0, _C_LABEL(printf) + PTR_LA k0, _C_LABEL(printf) jalr k0 mfc0 a3, COP_0_BAD_VADDR - la sp, _C_LABEL(_start) - START_FRAME # set sp to a valid place + PTR_LA sp, _C_LABEL(_start) - START_FRAME # set sp to a valid place #if !defined(SMP) && defined(DDB) - la a0, 2f - la k0, _C_LABEL(trapDump) + PTR_LA a0, 2f + PTR_LA k0, _C_LABEL(trapDump) jalr k0 nop li a0, 0 lw a1, _C_LABEL(num_tlbentries) - la k0, _C_LABEL(db_dump_tlb) + PTR_LA k0, _C_LABEL(db_dump_tlb) jalr k0 addu a1, -1 @@ -1184,11 +1195,12 @@ NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra) */ sw a2, STAND_FRAME_SIZE + 8(sp) GET_CPU_PCPU(a0) +#mips64 unsafe? lw a0, PC_CURPCB(a0) - addu a0, a0, U_PCB_REGS # first arg is ptr to CPU registers + PTR_ADDU a0, a0, U_PCB_REGS # first arg is ptr to CPU registers move a1, a2 # second arg is instruction PC move a2, t1 # third arg is floating point CSR - la t3, _C_LABEL(MipsEmulateBranch) # compute PC after branch + PTR_LA t3, _C_LABEL(MipsEmulateBranch) # compute PC after branch jalr t3 # compute PC after branch move a3, zero # fourth arg is FALSE /* @@ -1204,6 +1216,7 @@ NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra) */ 1: lw a0, 0(a2) # a0 = coproc instruction +#xxx mips64 unsafe? addu v0, a2, 4 # v0 = next pc 2: GET_CPU_PCPU(t2) @@ -1224,7 +1237,7 @@ NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra) lw a0, PC_CURTHREAD(a0) # get current thread cfc1 a2, FPC_CSR # code = FP execptions ctc1 zero, FPC_CSR # Clear exceptions - la t3, _C_LABEL(trapsignal) + PTR_LA t3, _C_LABEL(trapsignal) jalr t3 li a1, SIGFPE b FPReturn @@ -1234,7 +1247,7 @@ NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra) * Finally, we can call MipsEmulateFP() where a0 is the instruction to emulate. */ 4: - la t3, _C_LABEL(MipsEmulateFP) + PTR_LA t3, _C_LABEL(MipsEmulateFP) jalr t3 nop @@ -1248,26 +1261,9 @@ FPReturn: mtc0 t0, COP_0_STATUS_REG ITLBNOPFIX j ra - addu sp, sp, STAND_FRAME_SIZE + PTR_ADDU sp, sp, STAND_FRAME_SIZE END(MipsFPTrap) - -#if 0 -/* - * Atomic ipending update - */ -LEAF(set_sint) - la v1, ipending -1: - ll v0, 0(v1) - or v0, a0 - sc v0, 0(v1) - beqz v0, 1b - j ra - nop -END(set_sint) -#endif - /* * Interrupt counters for vmstat. */ @@ -1294,7 +1290,7 @@ eintrcnt: */ .text VECTOR(MipsCache, unknown) - la k0, _C_LABEL(MipsCacheException) + PTR_LA k0, _C_LABEL(MipsCacheException) li k1, MIPS_PHYS_MASK and k0, k1 li k1, MIPS_UNCACHED_MEMORY_ADDR @@ -1313,8 +1309,8 @@ VECTOR_END(MipsCache) NESTED_NOPROFILE(MipsCacheException, KERN_EXC_FRAME_SIZE, ra) .set noat .mask 0x80000000, -4 - la k0, _C_LABEL(panic) # return to panic - la a0, 9f # panicstr + PTR_LA k0, _C_LABEL(panic) # return to panic + PTR_LA a0, 9f # panicstr _MFC0 a1, COP_0_ERROR_PC mfc0 a2, COP_0_CACHE_ERR # 3rd arg cache error From 1e0b0febf65adc557e24e6d3dfa40596ca81943d Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 10 Jul 2009 19:09:34 +0000 Subject: [PATCH 214/380] Use PTR_* macros for pointers, and not potentially mips64 unsafe operations. --- sys/mips/mips/copystr.S | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/sys/mips/mips/copystr.S b/sys/mips/mips/copystr.S index 4d5d921c494..35e79057a53 100644 --- a/sys/mips/mips/copystr.S +++ b/sys/mips/mips/copystr.S @@ -67,13 +67,13 @@ ENTRY(copystr) move v0, zero beqz a2, 2f move t1, zero -1: subu a2, 1 +1: subu a2, 1 /*XXX mips64 unsafe -- long */ lbu t0, 0(a0) - addu a0, 1 + PTR_ADDU a0, 1 sb t0, 0(a1) - addu a1, 1 + PTR_ADDU a1, 1 beqz t0, 3f /* NULL - end of string*/ - addu t1, 1 + addu t1, 1 /*XXX mips64 unsafe -- long */ bnez a2, 1b nop 2: /* ENAMETOOLONG */ @@ -81,7 +81,7 @@ ENTRY(copystr) 3: /* done != NULL -> how many bytes were copied */ beqz a3, 4f nop - sw t1, 0(a3) + sw t1, 0(a3) /*XXX mips64 unsafe -- long */ 4: jr ra nop .set reorder @@ -100,25 +100,25 @@ LEAF(copyinstr) .set noat lw t2, pcpup lw v1, PC_CURPCB(t2) - la v0, _C_LABEL(copystrerr) + PTR_LA v0, _C_LABEL(copystrerr) blt a0, zero, _C_LABEL(copystrerr) sw v0, PCB_ONFAULT(v1) move t0, a2 beq a2, zero, 4f 1: lbu v0, 0(a0) - subu a2, a2, 1 + subu a2, a2, 1 /*xxx mips64 unsafe -- long */ beq v0, zero, 2f sb v0, 0(a1) - addu a0, a0, 1 + PTR_ADDU a0, a0, 1 bne a2, zero, 1b - addu a1, a1, 1 + PTR_ADDU a1, a1, 1 4: li v0, ENAMETOOLONG 2: beq a3, zero, 3f - subu a2, t0, a2 - sw a2, 0(a3) + subu a2, t0, a2 /*xxx mips64 unsafe -- long */ + sw a2, 0(a3) /*xxx mips64 unsafe -- long */ 3: j ra # v0 is 0 or ENAMETOOLONG sw zero, PCB_ONFAULT(v1) @@ -138,25 +138,25 @@ LEAF(copyoutstr) .set noat lw t2, pcpup lw v1, PC_CURPCB(t2) - la v0, _C_LABEL(copystrerr) + PTR_LA v0, _C_LABEL(copystrerr) blt a1, zero, _C_LABEL(copystrerr) sw v0, PCB_ONFAULT(v1) move t0, a2 beq a2, zero, 4f 1: lbu v0, 0(a0) - subu a2, a2, 1 + subu a2, a2, 1 /*xxx mips64 unsafe -- long */ beq v0, zero, 2f sb v0, 0(a1) - addu a0, a0, 1 + PTR_ADDU a0, a0, 1 bne a2, zero, 1b - addu a1, a1, 1 + PTR_ADDU a1, a1, 1 4: li v0, ENAMETOOLONG 2: beq a3, zero, 3f - subu a2, t0, a2 - sw a2, 0(a3) + subu a2, t0, a2 /*xxx mips64 unsafe -- long */ + sw a2, 0(a3) /*xxx mips64 unsafe -- long */ 3: j ra # v0 is 0 or ENAMETOOLONG sw zero, PCB_ONFAULT(v1) From 3f792ee53a082ddb9005619f21f439eb29423ed3 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 13 Jul 2009 23:01:12 +0000 Subject: [PATCH 215/380] - Get rid of ugly TARGET_CPU_DEFAULT default. 16 is MASK_DSP and was set there due to my ignroance. --- gnu/usr.bin/cc/Makefile.tgt | 3 --- 1 file changed, 3 deletions(-) diff --git a/gnu/usr.bin/cc/Makefile.tgt b/gnu/usr.bin/cc/Makefile.tgt index dc6cc81f39a..3cb9678a002 100644 --- a/gnu/usr.bin/cc/Makefile.tgt +++ b/gnu/usr.bin/cc/Makefile.tgt @@ -15,9 +15,6 @@ GCC_CPU= ${TARGET_ARCH} .if ${TARGET_ARCH} == "ia64" TARGET_CPU_DEFAULT= MASK_GNU_AS|MASK_GNU_LD .endif -.if ${TARGET_ARCH} == "mips" -TARGET_CPU_DEFAULT= 16 -.endif .if ${TARGET_ARCH} == "sparc64" TARGET_CPU_DEFAULT= TARGET_CPU_ultrasparc .endif From 23a9b716a1e3230743bce396b872b8cdc5456a10 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 13 Jul 2009 23:03:44 +0000 Subject: [PATCH 216/380] - Remove -mno-dsp from CFLAGS. MIPS DSP ASE is off by default now (as it should be) --- share/mk/bsd.cpu.mk | 2 +- sys/conf/Makefile.mips | 2 +- sys/conf/kern.mk | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/share/mk/bsd.cpu.mk b/share/mk/bsd.cpu.mk index 8278d47c582..d4582d7f29e 100644 --- a/share/mk/bsd.cpu.mk +++ b/share/mk/bsd.cpu.mk @@ -210,7 +210,7 @@ CFLAGS += -EL LDFLAGS += -Wl,-EL LD += -EL . endif -CFLAGS += -msoft-float -G0 -mno-dsp -mabicalls +CFLAGS += -msoft-float -G0 -mabicalls .endif # NB: COPTFLAGS is handled in /usr/src/sys/conf/kern.pre.mk diff --git a/sys/conf/Makefile.mips b/sys/conf/Makefile.mips index 89a2bd50ada..779e7060a2e 100644 --- a/sys/conf/Makefile.mips +++ b/sys/conf/Makefile.mips @@ -44,7 +44,7 @@ MKMODULESENV+= MACHINE=${MACHINE} MACHINE_ARCH=${MACHINE_ARCH} # We default to the MIPS32 ISA, if none specified in the # kernel configuration file. ARCH_FLAGS?=-march=mips32 -EXTRA_FLAGS=-fno-pic -mno-abicalls -mno-dsp -G0 +EXTRA_FLAGS=-fno-pic -mno-abicalls -G0 HACK_EXTRA_FLAGS=-shared .if defined(TARGET_BIG_ENDIAN) diff --git a/sys/conf/kern.mk b/sys/conf/kern.mk index f9618ef10a6..afff7c9d22b 100644 --- a/sys/conf/kern.mk +++ b/sys/conf/kern.mk @@ -90,7 +90,7 @@ INLINE_LIMIT?= 15000 # disable MIPS DSP ASE Instruction set. # .if ${MACHINE_ARCH} == "mips" -CFLAGS+= -msoft-float -mno-dsp +CFLAGS+= -msoft-float INLINE_LIMIT?= 8000 .endif From aa1e98d04d9cc05ae1e1cf5c5281ad35239a4bb6 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 17 Jul 2009 02:28:27 +0000 Subject: [PATCH 217/380] - Add DES and Blowfish implementstions to build. Required by crypto(4) --- sys/conf/files.mips | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/conf/files.mips b/sys/conf/files.mips index 2828d441aff..ca09e6cffea 100644 --- a/sys/conf/files.mips +++ b/sys/conf/files.mips @@ -73,6 +73,8 @@ mips/mips/support.S standard mips/mips/sys_machdep.c standard mips/mips/swtch.S standard mips/mips/uio_machdep.c standard +crypto/blowfish/bf_enc.c optional crypto | ipsec +crypto/des/des_enc.c optional crypto | ipsec | netsmb geom/geom_bsd.c optional geom_bsd geom/geom_bsd_enc.c optional geom_bsd geom/geom_mbr.c optional geom_mbr From 1367982697e3de0c792512a83a932bb15a2e54b7 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 30 Jul 2009 23:29:59 +0000 Subject: [PATCH 218/380] - mark map as coherent if requested by flags - explicitly set memory allocation method in map flags instead of duplicating conditions for malloc/contigalloc --- sys/mips/mips/busdma_machdep.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/sys/mips/mips/busdma_machdep.c b/sys/mips/mips/busdma_machdep.c index 350a85139a5..d371cbdb026 100644 --- a/sys/mips/mips/busdma_machdep.c +++ b/sys/mips/mips/busdma_machdep.c @@ -123,9 +123,11 @@ SYSCTL_INT(_hw_busdma, OID_AUTO, total_bpages, CTLFLAG_RD, &total_bpages, 0, #define DMAMAP_LINEAR 0x1 #define DMAMAP_MBUF 0x2 #define DMAMAP_UIO 0x4 -#define DMAMAP_ALLOCATED 0x10 #define DMAMAP_TYPE_MASK (DMAMAP_LINEAR|DMAMAP_MBUF|DMAMAP_UIO) #define DMAMAP_COHERENT 0x8 +#define DMAMAP_ALLOCATED 0x10 +#define DMAMAP_MALLOCUSED 0x20 + struct bus_dmamap { struct bp_list bpages; int pagesneeded; @@ -514,6 +516,10 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) } bz->map_count++; } + + if (flags & BUS_DMA_COHERENT) + newmap->flags |= DMAMAP_COHERENT; + CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", __func__, dmat, dmat->flags, error); @@ -570,12 +576,16 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, dmat->map_count++; *mapp = newmap; newmap->dmat = dmat; + + if (flags & BUS_DMA_COHERENT) + newmap->flags |= DMAMAP_COHERENT; if (dmat->maxsize <= PAGE_SIZE && (dmat->alignment < dmat->maxsize) && !_bus_dma_can_bounce(dmat->lowaddr, dmat->highaddr) && !(flags & BUS_DMA_COHERENT)) { *vaddr = malloc(dmat->maxsize, M_DEVBUF, mflags); + newmap->flags |= DMAMAP_MALLOCUSED; } else { /* * XXX Use Contigmalloc until it is merged into this facility @@ -639,13 +649,12 @@ bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map) ("Trying to freeing the wrong DMA buffer")); vaddr = map->origbuffer; } - if (dmat->maxsize <= PAGE_SIZE && - dmat->alignment < dmat->maxsize && - !_bus_dma_can_bounce(dmat->lowaddr, dmat->highaddr)) + + if (map->flags & DMAMAP_MALLOCUSED) free(vaddr, M_DEVBUF); - else { + else contigfree(vaddr, dmat->maxsize, M_DEVBUF); - } + dmat->map_count--; _busdma_free_dmamap(map); CTR3(KTR_BUSDMA, "%s: tag %p flags 0x%x", __func__, dmat, dmat->flags); From 13a77922c89d78b3fb5a268c50bb09873e5ba50f Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 30 Jul 2009 23:48:29 +0000 Subject: [PATCH 219/380] - Properly unwind stack for functions with __noreturn__ attribute Submitted by: Neelkanth Natu --- sys/mips/mips/trap.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c index 76a1371ac08..36cd51ba697 100644 --- a/sys/mips/mips/trap.c +++ b/sys/mips/mips/trap.c @@ -1229,8 +1229,25 @@ MipsEmulateBranch(struct trapframe *framePtr, int instPC, int fpcCSR, #if defined(DDB) || defined(DEBUG) -#define MIPS_JR_RA 0x03e00008 /* instruction code for jr ra */ +/* + * A function using a stack frame has the following instruction as the first + * one: addiu sp,sp,- + * + * We make use of this to detect starting address of a function. This works + * better than using 'j ra' instruction to signify end of the previous + * function (for e.g. functions like boot() or panic() do not actually + * emit a 'j ra' instruction). + * + * XXX the abi does not require that the addiu instruction be the first one. + */ +#define MIPS_START_OF_FUNCTION(ins) (((ins) & 0xffff8000) == 0x27bd8000) +/* + * MIPS ABI 3.0 requires that all functions return using the 'j ra' instruction + * + * XXX gcc doesn't do this true for functions with __noreturn__ attribute. + */ +#define MIPS_END_OF_FUNCTION(ins) ((ins) == 0x03e00008) /* forward */ char *fn_name(unsigned addr); @@ -1326,9 +1343,21 @@ loop: */ if (!subr) { va = pc - sizeof(int); - while ((instr = kdbpeek((int *)va)) != MIPS_JR_RA) - va -= sizeof(int); - va += 2 * sizeof(int); /* skip back over branch & delay slot */ + while (1) { + instr = kdbpeek((int *)va); + + if (MIPS_START_OF_FUNCTION(instr)) + break; + + if (MIPS_END_OF_FUNCTION(instr)) { + /* skip over branch-delay slot instruction */ + va += 2 * sizeof(int); + break; + } + + va -= sizeof(int); + } + /* skip over nulls which might separate .o files */ while ((instr = kdbpeek((int *)va)) == 0) va += sizeof(int); From 143acbd6fedfe329716229bf2d6e5ee75ca9c078 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 30 Jul 2009 23:54:00 +0000 Subject: [PATCH 220/380] - Make USB part of AR71XX kernel buildable again --- sys/mips/atheros/ar71xx_ehci.c | 9 ++++++--- sys/mips/atheros/ar71xx_ohci.c | 14 +++++++++++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/sys/mips/atheros/ar71xx_ehci.c b/sys/mips/atheros/ar71xx_ehci.c index cb716678758..5f2e0bbc853 100644 --- a/sys/mips/atheros/ar71xx_ehci.c +++ b/sys/mips/atheros/ar71xx_ehci.c @@ -35,11 +35,14 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include +#include #include -#include #include +#include #include #include @@ -129,7 +132,7 @@ ar71xx_ehci_attach(device_t self) sc->sc_bus.devices_max = EHCI_MAX_DEVICES; /* get all DMA memory */ - if (usb2_bus_mem_alloc_all(&sc->sc_bus, + if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc)) { return (ENOMEM); } @@ -257,7 +260,7 @@ ar71xx_ehci_detach(device_t self) sc->sc_io_res); sc->sc_io_res = NULL; } - usb2_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc); + usb_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc); return (0); } diff --git a/sys/mips/atheros/ar71xx_ohci.c b/sys/mips/atheros/ar71xx_ohci.c index f13279d3ef4..c996b4252ab 100644 --- a/sys/mips/atheros/ar71xx_ohci.c +++ b/sys/mips/atheros/ar71xx_ohci.c @@ -28,8 +28,16 @@ #include __FBSDID("$FreeBSD$"); -#include +#include +#include +#include +#include +#include +#include +#include + #include +#include #include #include @@ -71,7 +79,7 @@ ar71xx_ohci_attach(device_t dev) sc->sc_ohci.sc_bus.devices_max = OHCI_MAX_DEVICES; /* get all DMA memory */ - if (usb2_bus_mem_alloc_all(&sc->sc_ohci.sc_bus, + if (usb_bus_mem_alloc_all(&sc->sc_ohci.sc_bus, USB_GET_DMA_TAG(dev), &ohci_iterate_hw_softc)) { return (ENOMEM); } @@ -177,7 +185,7 @@ ar71xx_ohci_detach(device_t dev) sc->sc_ohci.sc_io_tag = 0; sc->sc_ohci.sc_io_hdl = 0; } - usb2_bus_mem_free_all(&sc->sc_ohci.sc_bus, &ohci_iterate_hw_softc); + usb_bus_mem_free_all(&sc->sc_ohci.sc_bus, &ohci_iterate_hw_softc); return (0); } From 8f0bf9b807f67aa62d5922a76fe3baed1e3b5cd7 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 4 Aug 2009 17:32:55 +0000 Subject: [PATCH 221/380] - Use register_t for registers values --- sys/mips/mips/vm_machdep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c index 9d39401119c..f0ee573da71 100644 --- a/sys/mips/mips/vm_machdep.c +++ b/sys/mips/mips/vm_machdep.c @@ -334,14 +334,14 @@ cpu_set_upcall_kse(struct thread *td, void (*entry)(void *), void *arg, stack_t *stack) { struct trapframe *tf; - u_int32_t sp; + register_t sp; /* * At the point where a function is called, sp must be 8 * byte aligned[for compatibility with 64-bit CPUs] * in ``See MIPS Run'' by D. Sweetman, p. 269 * align stack */ - sp = ((uint32_t)(stack->ss_sp + stack->ss_size) & ~0x7) - + sp = ((register_t)(stack->ss_sp + stack->ss_size) & ~0x7) - STAND_FRAME_SIZE; /* From 5bbfa759e27b38f6d9c68bc06d4c37e94d09f2ce Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 10 Aug 2009 01:49:59 +0000 Subject: [PATCH 222/380] - Make i/d cache size field 32-bit to prevent overflow Submited by: Neelkanth Natu --- sys/mips/include/cpuinfo.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/mips/include/cpuinfo.h b/sys/mips/include/cpuinfo.h index bf3208626d3..4378c6af2f2 100644 --- a/sys/mips/include/cpuinfo.h +++ b/sys/mips/include/cpuinfo.h @@ -57,11 +57,11 @@ struct mips_cpuinfo { u_int16_t tlb_nentries; u_int8_t icache_virtual; struct { - u_int8_t ic_size; + u_int32_t ic_size; u_int8_t ic_linesize; u_int8_t ic_nways; u_int16_t ic_nsets; - u_int8_t dc_size; + u_int32_t dc_size; u_int8_t dc_linesize; u_int8_t dc_nways; u_int16_t dc_nsets; From 323ba97c65a4fcb0df3bcf188a927a758aebfcdb Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 13 Aug 2009 19:47:13 +0000 Subject: [PATCH 223/380] Use unsigned long instead of unsigned for the integer casts here. The former works for both ILP32 and LP64 programming models, while the latter fails LP64. # uintpr_t is better, but iirc, we can't pollute the name space to use it # I likely need to audit all my uintptr_t changes for that issue... --- sys/mips/include/param.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/mips/include/param.h b/sys/mips/include/param.h index 250de77ba7e..80441d91432 100644 --- a/sys/mips/include/param.h +++ b/sys/mips/include/param.h @@ -152,10 +152,10 @@ /* * Conversion macros */ -#define mips_round_page(x) ((((unsigned)(x)) + NBPG - 1) & ~(NBPG-1)) -#define mips_trunc_page(x) ((unsigned)(x) & ~(NBPG-1)) -#define mips_btop(x) ((unsigned)(x) >> PGSHIFT) -#define mips_ptob(x) ((unsigned)(x) << PGSHIFT) +#define mips_round_page(x) ((((unsigned long)(x)) + NBPG - 1) & ~(NBPG-1)) +#define mips_trunc_page(x) ((unsigned long)(x) & ~(NBPG-1)) +#define mips_btop(x) ((unsigned long)(x) >> PGSHIFT) +#define mips_ptob(x) ((unsigned long)(x) << PGSHIFT) #define round_page mips_round_page #define trunc_page mips_trunc_page #define atop(x) ((unsigned long)(x) >> PAGE_SHIFT) From 778355f6c17898d6115c00026919105fc8aaf8b5 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 14 Aug 2009 16:15:18 +0000 Subject: [PATCH 224/380] (u_int) is the wrong type here. Use unsigned long instead, even though that's only less wrong... # This gets the kernel building again to the point it was at before # the last IFC for the OCTEON1 kernel config. --- sys/mips/include/param.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/mips/include/param.h b/sys/mips/include/param.h index 80441d91432..53ea0902b58 100644 --- a/sys/mips/include/param.h +++ b/sys/mips/include/param.h @@ -83,7 +83,7 @@ * any desired pointer type. */ #define _ALIGNBYTES 7 -#define _ALIGN(p) (((u_int)(p) + _ALIGNBYTES) &~ _ALIGNBYTES) +#define _ALIGN(p) (((unsigned long)(p) + _ALIGNBYTES) &~ _ALIGNBYTES) #define ALIGNBYTES _ALIGNBYTES #define ALIGN(p) _ALIGN(p) @@ -93,7 +93,7 @@ * This does not reflect the optimal alignment, just the possibility * (within reasonable limits). */ -#define ALIGNED_POINTER(p, t) ((((unsigned)(p)) & (sizeof (t) - 1)) == 0) +#define ALIGNED_POINTER(p, t) ((((unsigned long)(p)) & (sizeof (t) - 1)) == 0) /* * CACHE_LINE_SIZE is the compile-time maximum cache line size for an From 19aa4fea4c5466e0ca260ad3e3b673c203031da1 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 15 Aug 2009 01:03:13 +0000 Subject: [PATCH 225/380] Fix style error replicated multiple times. Move to mips_bus_space_generic for octeon obio impl. --- sys/mips/malta/obio.c | 8 +++----- sys/mips/octeon1/obio.c | 13 +++++-------- sys/mips/sentry5/obio.c | 6 ++---- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/sys/mips/malta/obio.c b/sys/mips/malta/obio.c index 39025d5b737..21958375fa6 100644 --- a/sys/mips/malta/obio.c +++ b/sys/mips/malta/obio.c @@ -63,20 +63,18 @@ int obio_attach(device_t); * A bit tricky and hackish. Since we need OBIO to rely * on PCI we make it pseudo-pci device. But there should * be only one such device, so we use this static flag - * to prevent false positives on every realPCI device probe. + * to prevent false positives on every real PCI device probe. */ static int have_one = 0; int obio_probe(device_t dev) { - if(!have_one) - { + if (!have_one) { have_one = 1; return 0; } - else - return (ENXIO); + return (ENXIO); } int diff --git a/sys/mips/octeon1/obio.c b/sys/mips/octeon1/obio.c index 7f573c29e0b..de3910ba4e8 100644 --- a/sys/mips/octeon1/obio.c +++ b/sys/mips/octeon1/obio.c @@ -60,22 +60,19 @@ int obio_probe(device_t); int obio_attach(device_t); /* - * We need only one obio. - * Any other device hanging off of it, shouldn't cause multiple of - * these to be found. + * We need only one obio. Any other device hanging off of it, + * shouldn't cause multiple of these to be found. */ static int have_one = 0; int obio_probe(device_t dev) { - if(!have_one) - { + if (!have_one) { have_one = 1; return 0; } - else - return (ENXIO); + return (ENXIO); } int @@ -83,7 +80,7 @@ obio_attach(device_t dev) { struct obio_softc *sc = device_get_softc(dev); - sc->oba_st = MIPS_BUS_SPACE_IO; + sc->oba_st = mips_bus_space_generic; sc->oba_addr = OCTEON_UART0ADR; sc->oba_size = 0x10000; sc->oba_rman.rm_type = RMAN_ARRAY; diff --git a/sys/mips/sentry5/obio.c b/sys/mips/sentry5/obio.c index 65c76aba382..51eaa9d4e9a 100644 --- a/sys/mips/sentry5/obio.c +++ b/sys/mips/sentry5/obio.c @@ -72,13 +72,11 @@ static int have_one = 0; int obio_probe(device_t dev) { - if(!have_one) - { + if (!have_one) { have_one = 1; return 0; } - else - return (ENXIO); + return (ENXIO); } int From 232f85fdf4fc7907fa8f231ffcce6eb3ee95ceaf Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 15 Aug 2009 02:03:41 +0000 Subject: [PATCH 226/380] Include Octeon specific registers since we mess with them here... --- sys/mips/octeon1/uart_dev_oct16550.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/mips/octeon1/uart_dev_oct16550.c b/sys/mips/octeon1/uart_dev_oct16550.c index 53c8ee2af62..3b96a6889cb 100644 --- a/sys/mips/octeon1/uart_dev_oct16550.c +++ b/sys/mips/octeon1/uart_dev_oct16550.c @@ -70,6 +70,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include "uart_if.h" From 961a7d3a7d4ceb7c2bfd32596460008bd9b56d37 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 15 Aug 2009 02:04:09 +0000 Subject: [PATCH 227/380] Add a couple of extra defines needed by the octeon uart. Not sure this is the right place... --- sys/dev/ic/ns16550.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sys/dev/ic/ns16550.h b/sys/dev/ic/ns16550.h index 400088c1a0c..635270c4a3d 100644 --- a/sys/dev/ic/ns16550.h +++ b/sys/dev/ic/ns16550.h @@ -52,6 +52,7 @@ #define REG_IIR com_iir #define IIR_IMASK 0xf #define IIR_RXTOUT 0xc +#define IIR_BUSY 0x7 #define IIR_RLS 0x6 #define IIR_RXRDY 0x4 #define IIR_TXRDY 0x2 @@ -181,6 +182,10 @@ #define com_xoff1 6 /* XOFF 1 character (R/W) */ #define com_xoff2 7 /* XOFF 2 character (R/W) */ +#define com_usr 39 /* Octeon 16750/16550 Uart Status Reg */ +#define REG_USR com_usr +#define USR_TXFIFO_NOTFULL 2 /* Uart TX FIFO Not full */ + /* 16950 register #1. Access enabled by ACR[7]. Also requires !LCR[7]. */ #define com_asr 1 /* additional status register (R[0-7]/W[0-1]) */ From 1d184a6dd9b20c9374080b84a7d8a21265af7e5f Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 15 Aug 2009 04:27:57 +0000 Subject: [PATCH 228/380] New script to produce mips64 ELF64 binaries. --- sys/conf/ldscript.mips.mips64 | 303 ++++++++++++++++++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100644 sys/conf/ldscript.mips.mips64 diff --git a/sys/conf/ldscript.mips.mips64 b/sys/conf/ldscript.mips.mips64 new file mode 100644 index 00000000000..4762abfaf10 --- /dev/null +++ b/sys/conf/ldscript.mips.mips64 @@ -0,0 +1,303 @@ +/*- + * Copyright (c) 2001, 2004, 2008, Juniper Networks, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Juniper Networks, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JUNIPER NETWORKS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL JUNIPER NETWORKS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * JNPR: ldscript.mips,v 1.3 2006/10/11 06:12:04 + * $FreeBSD: projects/mips/sys/conf/ldscript.mips 191079 2009-04-14 22:53:22Z gonzo $ + */ + +OUTPUT_FORMAT("elf64-tradbigmips", "elf64-tradbigmips", + "elf64-tradlittlemips") + +OUTPUT_ARCH(mips) +ENTRY(_start) +SEARCH_DIR(/usr/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; +PROVIDE (_DYNAMIC = 0); +*/ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = KERNLOADADDR + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.init : { *(.rel.init) } + .rela.init : { *(.rela.init) } + .rel.text : + { + *(.rel.text) + *(.rel.text.*) + *(.rel.gnu.linkonce.t.*) + } + .rela.text : + { + *(.rela.text) + *(.rela.text.*) + *(.rela.gnu.linkonce.t.*) + } + .rel.fini : { *(.rel.fini) } + .rela.fini : { *(.rela.fini) } + .rel.rodata : + { + *(.rel.rodata) + *(.rel.rodata.*) + *(.rel.gnu.linkonce.r.*) + } + .rela.rodata : + { + *(.rela.rodata) + *(.rela.rodata.*) + *(.rela.gnu.linkonce.r.*) + } + .rel.data : + { + *(.rel.data) + *(.rel.data.*) + *(.rel.gnu.linkonce.d.*) + } + .rela.data : + { + *(.rela.data) + *(.rela.data.*) + *(.rela.gnu.linkonce.d.*) + } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.sdata : + { + *(.rel.sdata) + *(.rel.sdata.*) + *(.rel.gnu.linkonce.s.*) + } + .rela.sdata : + { + *(.rela.sdata) + *(.rela.sdata.*) + *(.rela.gnu.linkonce.s.*) + } + .rel.sbss : + { + *(.rel.sbss) + *(.rel.sbss.*) + *(.rel.gnu.linkonce.sb.*) + } + .rela.sbss : + { + *(.rela.sbss) + *(.rela.sbss.*) + *(.rel.gnu.linkonce.sb.*) + } + .rel.sdata2 : + { + *(.rel.sdata2) + *(.rel.sdata2.*) + *(.rel.gnu.linkonce.s2.*) + } + .rela.sdata2 : + { + *(.rela.sdata2) + *(.rela.sdata2.*) + *(.rela.gnu.linkonce.s2.*) + } + .rel.sbss2 : + { + *(.rel.sbss2) + *(.rel.sbss2.*) + *(.rel.gnu.linkonce.sb2.*) + } + .rela.sbss2 : + { + *(.rela.sbss2) + *(.rela.sbss2.*) + *(.rela.gnu.linkonce.sb2.*) + } + .rel.bss : + { + *(.rel.bss) + *(.rel.bss.*) + *(.rel.gnu.linkonce.b.*) + } + .rela.bss : + { + *(.rela.bss) + *(.rela.bss.*) + *(.rela.gnu.linkonce.b.*) + } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : + { + KEEP (*(.init)) + } =0x1000000 + .text : + { + *(.trap) + *(.text) + *(.text.*) + *(.stub) + /* .gnu.warning sections are handled specially by elf64.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t.*) + } =0x1000000 + .fini : + { + KEEP (*(.fini)) + } =0x1000000 + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .reginfo : { *(.reginfo) } + .sdata2 : { *(.sdata2) *(.sdata2.*) *(.gnu.linkonce.s2.*) } + .sbss2 : { *(.sbss2) *(.sbss2.*) *(.gnu.linkonce.sb2.*) } + . = ALIGN(0x2000) + (. & (0x2000 - 1)); + .data : + { + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + .eh_frame : { KEEP (*(.eh_frame)) } + .gcc_except_table : { *(.gcc_except_table) } + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .plt : { *(.plt) } + _gp = ALIGN(16) + 0x7ff0; + .got : { *(.got.plt) *(.got) } + .dynamic : { *(.dynamic) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : + { + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + .sbss : + { + PROVIDE (__sbss_start = .); + PROVIDE (___sbss_start = .); + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + PROVIDE (__sbss_end = .); + PROVIDE (___sbss_end = .); + } + .bss : + { + *(.dynbss) + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. */ + . = ALIGN(64 / 8); + } + . = ALIGN(64 / 8); + _end = .; + PROVIDE (end = .); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* These must appear regardless of . */ +} From 6d53fe9b81d95dc9c4ffc554019cc919517d6e82 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 15 Aug 2009 04:29:18 +0000 Subject: [PATCH 229/380] Use new ldscript.mips.mips64 Also, declare this to be a 64-bit target. We get to the final link now and die in the linker script.. --- sys/mips/conf/OCTEON1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/mips/conf/OCTEON1 b/sys/mips/conf/OCTEON1 index 40536642c7c..6c7810c6f0b 100644 --- a/sys/mips/conf/OCTEON1 +++ b/sys/mips/conf/OCTEON1 @@ -22,10 +22,12 @@ cpu CPU_MIPS4KC ident OCTEON1 makeoptions ARCH_FLAGS="-march=mips64 -mabi=64" +makeoptions LDSCRIPT_NAME= ldscript.mips.mips64 # Don't build any modules yet. makeoptions MODULES_OVERRIDE="" makeoptions TARGET_BIG_ENDIAN=defined +makeoptions TARGET_64BIT=defined options KERNVIRTADDR=0x80100000 include "../octeon1/std.octeon1" From b0f42e724af04149c086c257aae080c4200c8068 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 15 Aug 2009 19:43:15 +0000 Subject: [PATCH 230/380] Pick an arbitrary address to load the kernel at. 1MB seems as good as any other. --- sys/conf/ldscript.mips.mips64 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/conf/ldscript.mips.mips64 b/sys/conf/ldscript.mips.mips64 index 4762abfaf10..83a5066ee7a 100644 --- a/sys/conf/ldscript.mips.mips64 +++ b/sys/conf/ldscript.mips.mips64 @@ -43,7 +43,7 @@ PROVIDE (_DYNAMIC = 0); SECTIONS { /* Read-only sections, merged into text segment: */ - . = KERNLOADADDR + SIZEOF_HEADERS; + . = 0x80100000 + SIZEOF_HEADERS; .interp : { *(.interp) } .hash : { *(.hash) } .dynsym : { *(.dynsym) } From 1cc75127dc0ea13e8f10b68bcda4f61ae8b1c2a2 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 15 Aug 2009 19:48:14 +0000 Subject: [PATCH 231/380] The UART device infrasturcture wants these defined. Define them just like we do in Malta. We may want to look at consolidating things because *ALL* mips will *ALWAYS* be memory mapped. The only wrinkle is that the tag may need to be a custom one (see endian issues with the Atheros port for one example). --- sys/mips/octeon1/uart_cpu_octeonusart.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sys/mips/octeon1/uart_cpu_octeonusart.c b/sys/mips/octeon1/uart_cpu_octeonusart.c index 016d71c0b87..fbbe9a7fda1 100644 --- a/sys/mips/octeon1/uart_cpu_octeonusart.c +++ b/sys/mips/octeon1/uart_cpu_octeonusart.c @@ -50,6 +50,9 @@ __FBSDID("$FreeBSD$"); #include +bus_space_tag_t uart_bus_space_io; +bus_space_tag_t uart_bus_space_mem; + extern struct uart_class uart_oct16550_class; extern struct uart_ops octeon_usart_ops; extern struct bus_space octeon_bs_tag; @@ -80,5 +83,8 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) di->bas.bsh = OCTEON_UART0ADR; uart_getenv(devtype, di, class); + + uart_bus_space_io = NULL; + uart_bus_space_mem = mips_bus_space_generic; return (0); } From 8a81b7075269017fedd53b68aba2b3daebe0ec6b Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 15 Aug 2009 21:42:04 +0000 Subject: [PATCH 232/380] First cut at a platform_start. It is likely wrong, but it is better than nothing :) --- sys/mips/octeon1/octeon_machdep.c | 118 +++++++++++++++++++++++++++--- 1 file changed, 109 insertions(+), 9 deletions(-) diff --git a/sys/mips/octeon1/octeon_machdep.c b/sys/mips/octeon1/octeon_machdep.c index 907f7a4e4ff..2bf9f3dec1d 100644 --- a/sys/mips/octeon1/octeon_machdep.c +++ b/sys/mips/octeon1/octeon_machdep.c @@ -29,20 +29,57 @@ __FBSDID("$FreeBSD$"); #include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include #include #include #include #include -#include +#include +#include +#include +#include #include +#include +#include +#include #if defined(__mips_n64) - #define MAX_APP_DESC_ADDR 0xffffffffafffffff +#define MAX_APP_DESC_ADDR 0xffffffffafffffff #else - #define MAX_APP_DESC_ADDR 0xafffffff +#define MAX_APP_DESC_ADDR 0xafffffff #endif +extern int *edata; +extern int *end; + /* * Perform a board-level soft-reset. @@ -625,17 +662,80 @@ void ciu_enable_interrupts (int core_num, int intx, int enx, uint64_t set_these_ octeon_set_interrupts(cpu_status_bits); } - -extern void mips_platform_init(void); - -void mips_platform_init (void) +void +platform_start(__register_t a0, __register_t a1, + __register_t a2 __unused, __register_t a3 __unused) { + uint64_t platform_counter_freq; + vm_offset_t kernend; + int argc = a0; + char **argv = (char **)a1; + int i, mem; + + /* clear the BSS and SBSS segments */ + kernend = round_page((vm_offset_t)&end); + memset(&edata, 0, kernend - (vm_offset_t)(&edata)); + octeon_ciu_reset(); octeon_uart_write_string(0, "\nPlatform Starting"); + +/* From here on down likely is bogus */ + /* + * Looking for mem=XXM argument + */ + mem = 0; /* Just something to start with */ + for (i=0; i < argc; i++) { + if (strncmp(argv[i], "mem=", 4) == 0) { + mem = strtol(argv[i] + 4, NULL, 0); + break; + } + } + + bootverbose = 1; + if (mem > 0) + realmem = btoc(mem << 20); + else + realmem = btoc(32 << 20); + + for (i = 0; i < 10; i++) { + phys_avail[i] = 0; + } + + /* phys_avail regions are in bytes */ + phys_avail[0] = MIPS_KSEG0_TO_PHYS((vm_offset_t)&end); + phys_avail[1] = ctob(realmem); + + physmem = realmem; + + /* + * ns8250 uart code uses DELAY so ticker should be inititalized + * before cninit. And tick_init_params refers to hz, so * init_param1 + * should be called first. + */ + init_param1(); + /* TODO: parse argc,argv */ + platform_counter_freq = 330000000UL; /* XXX: from idt */ + mips_timer_init_params(platform_counter_freq, 1); + cninit(); + /* Panic here, after cninit */ + if (mem == 0) + panic("No mem=XX parameter in arguments"); + + printf("cmd line: "); + for (i=0; i < argc; i++) + printf("%s ", argv[i]); + printf("\n"); + + init_param2(physmem); + mips_cpu_init(); + pmap_bootstrap(); + mips_proc0_init(); + mutex_init(); +#ifdef DDB + kdb_init(); +#endif } - - /* **************************************************************************************** * From fa1d3852f7e774310df65a622fd46251c7f807af Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 15 Aug 2009 22:45:46 +0000 Subject: [PATCH 233/380] (1) Some CPUs have a range to map I/O cyces on the pci bus. So allow them to work by allowding the nexus to assign ports. (2) Remove some Octeon junk that shouldn't be necessary. Submitted by: neel@ (#1) for SB1 port. --- sys/mips/mips/nexus.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/sys/mips/mips/nexus.c b/sys/mips/mips/nexus.c index b2d2b481e69..b939bc6b7c1 100644 --- a/sys/mips/mips/nexus.c +++ b/sys/mips/mips/nexus.c @@ -77,6 +77,7 @@ struct nexus_device { static struct rman irq_rman; static struct rman mem_rman; +static struct rman port_rman; static struct resource * nexus_alloc_resource(device_t, device_t, int, int *, u_long, @@ -160,6 +161,21 @@ nexus_probe(device_t dev) panic("%s: mem_rman", __func__); } + /* + * MIPS has no concept of the x86 I/O address space but some cpus + * provide a memory mapped window to access the PCI I/O BARs. + */ + port_rman.rm_start = 0; +#ifdef PCI_IOSPACE_SIZE + port_rman.rm_end = PCI_IOSPACE_SIZE - 1; +#endif + port_rman.rm_type = RMAN_ARRAY; + port_rman.rm_descr = "I/O ports"; + if (rman_init(&port_rman) != 0 || + rman_manage_region(&port_rman, 0, port_rman.rm_end) != 0) + panic("%s: port_rman", __func__); + + return (0); } @@ -225,6 +241,7 @@ nexus_print_all_resources(device_t dev) retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx"); retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld"); + retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#lx"); return (retval); } @@ -345,6 +362,9 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, case SYS_RES_MEMORY: rm = &mem_rman; break; + case SYS_RES_IOPORT: + rm = &port_rman; + break; default: printf("%s: unknown resource type %d\n", __func__, type); return (0); @@ -374,9 +394,6 @@ static int nexus_activate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { -#ifdef TARGET_OCTEON - uint64_t temp; -#endif /* * If this is a memory resource, track the direct mapping * in the uncached MIPS KSEG1 segment. @@ -394,13 +411,7 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid, rman_set_virtual(r, vaddr); rman_set_bustag(r, mips_bus_space_generic); -#ifdef TARGET_OCTEON - temp = 0x0000000000000000; - temp |= (uint32_t)vaddr; - rman_set_bushandle(r, (bus_space_handle_t)temp); -#else rman_set_bushandle(r, (bus_space_handle_t)vaddr); -#endif } return (rman_activate_resource(r)); @@ -481,6 +492,12 @@ static int nexus_deactivate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { + vm_offset_t va; + + if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) { + va = (vm_offset_t)rman_get_virtual(r); + pmap_unmapdev(va, rman_get_size(r)); + } return (rman_deactivate_resource(r)); } From bcd2a38933dbe690a0265860442683f82393ae0a Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 15 Aug 2009 22:48:09 +0000 Subject: [PATCH 234/380] Various 32/64-bit confusion cleanups. --- sys/mips/mips/trap.c | 61 ++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c index 36cd51ba697..f44dda32c2a 100644 --- a/sys/mips/mips/trap.c +++ b/sys/mips/mips/trap.c @@ -98,7 +98,6 @@ __FBSDID("$FreeBSD$"); #ifdef TRAP_DEBUG int trap_debug = 1; - #endif extern unsigned onfault_table[]; @@ -251,7 +250,7 @@ extern void MipsSwitchFPState(struct thread *, struct trapframe *); extern void MipsFPTrap(u_int, u_int, u_int); u_int trap(struct trapframe *); -u_int MipsEmulateBranch(struct trapframe *, int, int, u_int); +u_int MipsEmulateBranch(struct trapframe *, uintptr_t, int, uintptr_t); #define KERNLAND(x) ((int)(x) < 0) #define DELAYBRANCH(x) ((int)(x) < 0) @@ -260,7 +259,6 @@ u_int MipsEmulateBranch(struct trapframe *, int, int, u_int); * kdbpeekD(addr) - skip one word starting at 'addr', then read the second word */ #define kdbpeekD(addr) kdbpeek(((int *)(addr)) + 1) -int rrs_debug = 0; /* * MIPS load/store access type @@ -305,8 +303,7 @@ extern char *syscallnames[]; * p->p_addr->u_pcb.pcb_onfault is set, otherwise, return old pc. */ u_int -trap(trapframe) - struct trapframe *trapframe; +trap(struct trapframe *trapframe) { int type, usermode; int i = 0; @@ -848,7 +845,7 @@ dofault: case T_BREAK + T_USER: { - unsigned int va, instr; + uintptr_t va, instr; /* compute address of break instruction */ va = trapframe->pc; @@ -881,13 +878,13 @@ dofault: case T_IWATCH + T_USER: case T_DWATCH + T_USER: { - unsigned int va; + uintptr_t va; /* compute address of trapped instruction */ va = trapframe->pc; if (DELAYBRANCH(trapframe->cause)) va += sizeof(int); - printf("watch exception @ 0x%x\n", va); + printf("watch exception @ %p\n", (void *)va); i = SIGTRAP; addr = va; break; @@ -895,7 +892,7 @@ dofault: case T_TRAP + T_USER: { - unsigned int va, instr; + uintptr_t va, instr; struct trapframe *locr0 = td->td_frame; /* compute address of trap instruction */ @@ -1090,26 +1087,26 @@ trapDump(char *msg) * Return the resulting PC as if the branch was executed. */ u_int -MipsEmulateBranch(struct trapframe *framePtr, int instPC, int fpcCSR, - u_int instptr) +MipsEmulateBranch(struct trapframe *framePtr, uintptr_t instPC, int fpcCSR, + uintptr_t instptr) { InstFmt inst; register_t *regsPtr = (register_t *) framePtr; - unsigned retAddr = 0; + uintptr_t retAddr = 0; int condition; #define GetBranchDest(InstPtr, inst) \ - ((unsigned)InstPtr + 4 + ((short)inst.IType.imm << 2)) + (InstPtr + 4 + ((short)inst.IType.imm << 2)) if (instptr) { if (instptr < MIPS_KSEG0_START) - inst.word = fuword((void *)instptr); + inst.word = fuword32((void *)instptr); else inst = *(InstFmt *) instptr; } else { if ((vm_offset_t)instPC < MIPS_KSEG0_START) - inst.word = fuword((void *)instPC); + inst.word = fuword32((void *)instPC); else inst = *(InstFmt *) instPC; } @@ -1249,7 +1246,7 @@ MipsEmulateBranch(struct trapframe *framePtr, int instPC, int fpcCSR, */ #define MIPS_END_OF_FUNCTION(ins) ((ins) == 0x03e00008) /* forward */ -char *fn_name(unsigned addr); +static char *fn_name(uintptr_t addr); /* * Print a stack backtrace. @@ -1264,7 +1261,7 @@ void stacktrace_subr(struct trapframe *regs, int (*printfn) (const char *,...)) { InstFmt i; - unsigned a0, a1, a2, a3, pc, sp, fp, ra, va, subr; + uintptr_t a0, a1, a2, a3, pc, sp, fp, ra, va, subr; unsigned instr, mask; unsigned int frames = 0; int more, stksize; @@ -1291,6 +1288,7 @@ loop: goto finish; /* XXX */ } /* check for bad SP: could foul up next frame */ + /*XXX MIPS64 bad: this hard-coded SP is lame */ if (sp & 3 || sp < 0x80000000) { (*printfn) ("SP 0x%x: not in kernel\n", sp); ra = 0; @@ -1300,7 +1298,7 @@ loop: #define Between(x, y, z) \ ( ((x) <= (y)) && ((y) < (z)) ) #define pcBetween(a,b) \ - Between((unsigned)a, pc, (unsigned)b) + Between((uintptr_t)a, pc, (uintptr_t)b) /* * Check for current PC in exception handler code that don't have a @@ -1308,30 +1306,31 @@ loop: * on relative ordering of functions in exception.S, swtch.S. */ if (pcBetween(MipsKernGenException, MipsUserGenException)) - subr = (unsigned)MipsKernGenException; + subr = (uintptr_t)MipsKernGenException; else if (pcBetween(MipsUserGenException, MipsKernIntr)) - subr = (unsigned)MipsUserGenException; + subr = (uintptr_t)MipsUserGenException; else if (pcBetween(MipsKernIntr, MipsUserIntr)) - subr = (unsigned)MipsKernIntr; + subr = (uintptr_t)MipsKernIntr; else if (pcBetween(MipsUserIntr, MipsTLBInvalidException)) - subr = (unsigned)MipsUserIntr; + subr = (uintptr_t)MipsUserIntr; else if (pcBetween(MipsTLBInvalidException, MipsKernTLBInvalidException)) - subr = (unsigned)MipsTLBInvalidException; + subr = (uintptr_t)MipsTLBInvalidException; else if (pcBetween(MipsKernTLBInvalidException, MipsUserTLBInvalidException)) - subr = (unsigned)MipsKernTLBInvalidException; + subr = (uintptr_t)MipsKernTLBInvalidException; else if (pcBetween(MipsUserTLBInvalidException, MipsTLBMissException)) - subr = (unsigned)MipsUserTLBInvalidException; + subr = (uintptr_t)MipsUserTLBInvalidException; else if (pcBetween(cpu_switch, MipsSwitchFPState)) - subr = (unsigned)cpu_switch; + subr = (uintptr_t)cpu_switch; else if (pcBetween(_locore, _locoreEnd)) { - subr = (unsigned)_locore; + subr = (uintptr_t)_locore; ra = 0; goto done; } /* check for bad PC */ - if (pc & 3 || pc < (unsigned)0x80000000 || pc >= (unsigned)edata) { + /*XXX MIPS64 bad: These hard coded constants are lame */ + if (pc & 3 || pc < (uintptr_t)0x80000000 || pc >= (uintptr_t)edata) { (*printfn) ("PC 0x%x: not in kernel\n", pc); ra = 0; goto done; @@ -1535,8 +1534,8 @@ static struct { /* * Map a function address to a string name, if known; or a hex string. */ -char * -fn_name(unsigned addr) +static char * +fn_name(uintptr_t addr) { static char buf[17]; int i = 0; @@ -1557,7 +1556,7 @@ fn_name(unsigned addr) for (i = 0; names[i].name; i++) if (names[i].addr == (void *)addr) return (names[i].name); - sprintf(buf, "%x", addr); + sprintf(buf, "%jx", (uintmax_t)addr); return (buf); } From e47ea02f05b8436e195ba1a4c0d2bbd27e7e7db6 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 15 Aug 2009 22:51:11 +0000 Subject: [PATCH 235/380] (1) Fix a few 32/64-bit bugs. (2) Also, always allocate 2 pages for the stack to optimize TLB usage. Submitted by: neel@ (2) --- sys/mips/mips/machdep.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c index 37a25b14e2f..9a28b2485ea 100644 --- a/sys/mips/mips/machdep.c +++ b/sys/mips/mips/machdep.c @@ -104,6 +104,7 @@ SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, cpu_model, 0, "Machine model"); int cold = 1; long realmem = 0; +long Maxmem = 0; int cpu_clock = MIPS_DEFAULT_HZ; SYSCTL_INT(_hw, OID_AUTO, clockrate, CTLFLAG_RD, &cpu_clock, 0, "CPU instruction clock rate"); @@ -170,11 +171,13 @@ cpu_startup(void *dummy) printf("Physical memory chunk(s):\n"); for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { - int size1 = phys_avail[indx + 1] - phys_avail[indx]; + uintptr_t size1 = phys_avail[indx + 1] - phys_avail[indx]; - printf("0x%08x - 0x%08x, %u bytes (%u pages)\n", - phys_avail[indx], phys_avail[indx + 1] - 1, size1, - size1 / PAGE_SIZE); + printf("0x%08llx - 0x%08llx, %llu bytes (%llu pages)\n", + (unsigned long long)phys_avail[indx], + (unsigned long long)phys_avail[indx + 1] - 1, + (unsigned long long)size1, + (unsigned long long)size1 / PAGE_SIZE); } } @@ -255,10 +258,7 @@ mips_proc0_init(void) proc_linkup(&proc0, &thread0); thread0.td_kstack = kstack0; thread0.td_kstack_pages = KSTACK_PAGES - 1; - if (thread0.td_kstack & (1 << PAGE_SHIFT)) - thread0.td_md.md_realstack = thread0.td_kstack + PAGE_SIZE; - else - thread0.td_md.md_realstack = thread0.td_kstack; + thread0.td_md.md_realstack = roundup2(thread0.td_kstack, PAGE_SIZE * 2); /* Initialize pcpu info of cpu-zero */ #ifdef SMP pcpu_init(&__pcpu[0], 0, sizeof(struct pcpu)); From a54c4d85904c3cabe0390b83b1c70e675a5805e8 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 17 Aug 2009 12:14:40 +0000 Subject: [PATCH 236/380] suword64 and csuword64. Needed by ELF64 stuff... --- sys/mips/mips/elf_machdep.c | 54 ++++++++++++++++++++++++++ sys/mips/mips/pmap.c | 45 +++++++++++++--------- sys/mips/mips/support.S | 75 ++++++++++++++++++++++++------------- 3 files changed, 130 insertions(+), 44 deletions(-) diff --git a/sys/mips/mips/elf_machdep.c b/sys/mips/mips/elf_machdep.c index fd780e4f5cc..b30879c9905 100644 --- a/sys/mips/mips/elf_machdep.c +++ b/sys/mips/mips/elf_machdep.c @@ -47,6 +47,59 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef __mips_n64 +struct sysentvec elf64_freebsd_sysvec = { + .sv_size = SYS_MAXSYSCALL, + .sv_table = sysent, + .sv_mask = 0, + .sv_sigsize = 0, + .sv_sigtbl = NULL, + .sv_errsize = 0, + .sv_errtbl = NULL, + .sv_transtrap = NULL, + .sv_fixup = __elfN(freebsd_fixup), + .sv_sendsig = sendsig, + .sv_sigcode = sigcode, + .sv_szsigcode = &szsigcode, + .sv_prepsyscall = NULL, + .sv_name = "FreeBSD ELF64", + .sv_coredump = __elfN(coredump), + .sv_imgact_try = NULL, + .sv_minsigstksz = MINSIGSTKSZ, + .sv_pagesize = PAGE_SIZE, + .sv_minuser = VM_MIN_ADDRESS, + .sv_maxuser = VM_MAXUSER_ADDRESS, + .sv_usrstack = USRSTACK, + .sv_psstrings = PS_STRINGS, + .sv_stackprot = VM_PROT_ALL, + .sv_copyout_strings = exec_copyout_strings, + .sv_setregs = exec_setregs, + .sv_fixlimit = NULL, + .sv_maxssiz = NULL, + .sv_flags = SV_ABI_FREEBSD | SV_LP64 +}; + +static Elf64_Brandinfo freebsd_brand_info = { + .brand = ELFOSABI_FREEBSD, + .machine = EM_MIPS, + .compat_3_brand = "FreeBSD", + .emul_path = NULL, + .interp_path = "/libexec/ld-elf.so.1", + .sysvec = &elf64_freebsd_sysvec, + .interp_newpath = NULL, + .flags = 0 +}; + +SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY, + (sysinit_cfunc_t) elf64_insert_brand_entry, + &freebsd_brand_info); + +void +elf64_dump_thread(struct thread *td __unused, void *dst __unused, + size_t *off __unused) +{ +} +#else struct sysentvec elf32_freebsd_sysvec = { .sv_size = SYS_MAXSYSCALL, .sv_table = sysent, @@ -98,6 +151,7 @@ elf32_dump_thread(struct thread *td __unused, void *dst __unused, size_t *off __unused) { } +#endif /* Process one elf relocation with addend. */ static int diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index 9d3a0b9b40f..50a744a180f 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -314,6 +314,8 @@ again: } } + Maxmem = atop(phys_avail[i - 1]); + if (bootverbose) { printf("Physical memory chunk(s):\n"); for (i = 0; phys_avail[i + 1] != 0; i += 2) { @@ -325,6 +327,7 @@ again: (uintmax_t) phys_avail[i + 1] - 1, (uintmax_t) size, (uintmax_t) size / PAGE_SIZE); } + printf("Maxmem is 0x%0lx\n", ptoa(Maxmem)); } /* * Steal the message buffer from the beginning of memory. @@ -398,21 +401,15 @@ again: for (i = 0, pte = pgtab; i < (nkpt * NPTEPG); i++, pte++) *pte = PTE_G; - printf("Va=0x%x Ve=%x\n", virtual_avail, virtual_end); /* * The segment table contains the KVA of the pages in the second * level page table. */ - printf("init kernel_segmap va >> = %d nkpt:%d\n", - (virtual_avail >> SEGSHIFT), - nkpt); for (i = 0, j = (virtual_avail >> SEGSHIFT); i < nkpt; i++, j++) kernel_segmap[j] = (pd_entry_t)(pgtab + (i * NPTEPG)); for (i = 0; phys_avail[i + 2]; i += 2) continue; - printf("avail_start:0x%x avail_end:0x%x\n", - phys_avail[0], phys_avail[i + 1]); /* * The kernel's pmap is statically allocated so we don't have to use @@ -1793,8 +1790,8 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t access, vm_page_t m, * Page Directory table entry not valid, we need a new PT page */ if (pte == NULL) { - panic("pmap_enter: invalid page directory, pdir=%p, va=0x%x\n", - (void *)pmap->pm_segtab, va); + panic("pmap_enter: invalid page directory, pdir=%p, va=%p\n", + (void *)pmap->pm_segtab, (void *)va); } pa = VM_PAGE_TO_PHYS(m); om = NULL; @@ -1855,7 +1852,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t access, vm_page_t m, mpte->wire_count--; KASSERT(mpte->wire_count > 0, ("pmap_enter: missing reference to page table page," - " va: 0x%x", va)); + " va: %p", (void *)va)); } } else pmap->pm_stats.resident_count++; @@ -1917,7 +1914,7 @@ validate: if (origpte & PTE_M) { KASSERT((origpte & PTE_RW), ("pmap_enter: modified page not writable:" - " va: 0x%x, pte: 0x%lx", va, origpte)); + " va: %p, pte: 0x%lx", (void *)va, origpte)); if (page_is_managed(opa)) vm_page_dirty(om); } @@ -2254,7 +2251,7 @@ pmap_zero_page(vm_page_t m) #endif if (phys < MIPS_KSEG0_LARGEST_PHYS) { - va = MIPS_PHYS_TO_UNCACHED(phys); + va = MIPS_PHYS_TO_CACHED(phys); bzero((caddr_t)va, PAGE_SIZE); mips_dcache_wbinv_range(va, PAGE_SIZE); @@ -2310,7 +2307,7 @@ pmap_zero_page_area(vm_page_t m, int off, int size) } else #endif if (phys < MIPS_KSEG0_LARGEST_PHYS) { - va = MIPS_PHYS_TO_UNCACHED(phys); + va = MIPS_PHYS_TO_CACHED(phys); bzero((char *)(caddr_t)va + off, size); mips_dcache_wbinv_range(va + off, size); } else { @@ -2349,7 +2346,7 @@ pmap_zero_page_idle(vm_page_t m) } else #endif if (phys < MIPS_KSEG0_LARGEST_PHYS) { - va = MIPS_PHYS_TO_UNCACHED(phys); + va = MIPS_PHYS_TO_CACHED(phys); bzero((caddr_t)va, PAGE_SIZE); mips_dcache_wbinv_range(va, PAGE_SIZE); } else { @@ -2835,11 +2832,12 @@ pmap_mapdev(vm_offset_t pa, vm_size_t size) return (void *)MIPS_PHYS_TO_KSEG1(pa); else { offset = pa & PAGE_MASK; - size = roundup(size, PAGE_SIZE); + size = roundup(size + offset, PAGE_SIZE); va = kmem_alloc_nofault(kernel_map, size); if (!va) panic("pmap_mapdev: Couldn't alloc kernel virtual memory"); + pa = trunc_page(pa); for (tmpva = va; size > 0;) { pmap_kenter(tmpva, pa); size -= PAGE_SIZE; @@ -2854,6 +2852,18 @@ pmap_mapdev(vm_offset_t pa, vm_size_t size) void pmap_unmapdev(vm_offset_t va, vm_size_t size) { + vm_offset_t base, offset, tmpva; + + /* If the address is within KSEG1 then there is nothing to do */ + if (va >= MIPS_KSEG1_START && va <= MIPS_KSEG1_END) + return; + + base = trunc_page(va); + offset = va & PAGE_MASK; + size = roundup(size + offset, PAGE_SIZE); + for (tmpva = base; tmpva < base + size; tmpva += PAGE_SIZE) + pmap_kremove(tmpva); + kmem_free(kernel_map, base, size); } /* @@ -2990,7 +3000,7 @@ pmap_pid_dump(int pid) pde = &pmap->pm_segtab[i]; if (pde && pmap_pde_v(pde)) { for (j = 0; j < 1024; j++) { - unsigned va = base + + vm_offset_t va = base + (j << PAGE_SHIFT); pte = pmap_pte(pmap, va); @@ -3000,8 +3010,9 @@ pmap_pid_dump(int pid) pa = mips_tlbpfn_to_paddr(*pte); m = PHYS_TO_VM_PAGE(pa); - printf("va: 0x%x, pt: 0x%x, h: %d, w: %d, f: 0x%x", - va, pa, + printf("va: %p, pt: %p, h: %d, w: %d, f: 0x%x", + (void *)va, + (void *)pa, m->hold_count, m->wire_count, m->flags); diff --git a/sys/mips/mips/support.S b/sys/mips/mips/support.S index 19a2b4569d4..5bde74034fb 100644 --- a/sys/mips/mips/support.S +++ b/sys/mips/mips/support.S @@ -460,8 +460,10 @@ ALEAF(fuibyte) sw zero, U_PCB_ONFAULT(v1) END(fubyte) -LEAF(suword) -XLEAF(suword32) +LEAF(suword32) +#ifndef __mips_n64 +XLEAF(suword) +#endif blt a0, zero, fswberr # make sure address is in user space li v0, FSWBERR GET_CPU_PCPU(v1) @@ -471,44 +473,36 @@ XLEAF(suword32) sw zero, U_PCB_ONFAULT(v1) j ra move v0, zero -END(suword) +END(suword32) -/* - * XXXMIPS: ATM it's the same as casuword32, but MIPS64 will require - * own implementation - * casuword(9) - * u_long casuword(u_long *p, u_long oldval, u_long newval) - */ -ENTRY(casuword) +#ifdef __mips_n64 +LEAF(suword64) +XLEAF(suword) blt a0, zero, fswberr # make sure address is in user space li v0, FSWBERR GET_CPU_PCPU(v1) lw v1, PC_CURPCB(v1) sw v0, U_PCB_ONFAULT(v1) -1: - move t0, a2 - ll v0, 0(a0) - bne a1, v0, 2f - nop - sc t0, 0(a0) # store word - beqz t0, 1b - nop - j 3f - nop -2: - li v0, -1 -3: + sd a1, 0(a0) # store word sw zero, U_PCB_ONFAULT(v1) - jr ra - nop -END(casuword) + j ra + move v0, zero +END(suword64) +#endif +/* + * casuword(9) + * u_long casuword(u_long *p, u_long oldval, u_long newval) + */ /* * casuword32(9) * uint32_t casuword(uint32_t *p, uint32_t oldval, * uint32_t newval) */ -ENTRY(casuword32) +LEAF(casuword32) +#ifndef __mips_n64 +XLEAF(casuword) +#endif blt a0, zero, fswberr # make sure address is in user space li v0, FSWBERR GET_CPU_PCPU(v1) @@ -532,6 +526,33 @@ ENTRY(casuword32) nop END(casuword32) +#ifdef __mips_n64 +LEAF(casuword64) +XLEAF(casuword) + blt a0, zero, fswberr # make sure address is in user space + li v0, FSWBERR + GET_CPU_PCPU(v1) + lw v1, PC_CURPCB(v1) + sw v0, U_PCB_ONFAULT(v1) +1: + move t0, a2 + lld v0, 0(a0) + bne a1, v0, 2f + nop + scd t0, 0(a0) # store double word + beqz t0, 1b + nop + j 3f + nop +2: + li v0, -1 +3: + sw zero, U_PCB_ONFAULT(v1) + jr ra + nop +END(casuword64) +#endif + #if 0 /* unused in FreeBSD */ /* From 2004aa74c30fd230d7c16446270f17a69e2c5aa3 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 17 Aug 2009 12:23:58 +0000 Subject: [PATCH 237/380] Implement platform_reset. Also, make the code a tiny bit easier to read with ninja-C magic coupled with an illuminating comment. --- sys/mips/octeon1/octeon_machdep.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/mips/octeon1/octeon_machdep.c b/sys/mips/octeon1/octeon_machdep.c index 2bf9f3dec1d..e3e9e838463 100644 --- a/sys/mips/octeon1/octeon_machdep.c +++ b/sys/mips/octeon1/octeon_machdep.c @@ -85,10 +85,10 @@ extern int *end; * Perform a board-level soft-reset. * Note that this is not emulated by gxemul. */ -void octeon_reset (void) +void +platform_reset(void) { - void (*reset_func)(void) = (void (*)(void) )0x1fc00000; - reset_func(); + ((void(*)(void))0x1fc00000)(); /* Jump to this hex address */ } From 6b3a0aef3f65afda881bc2b398fc5e19dbaaa39d Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 17 Aug 2009 12:37:06 +0000 Subject: [PATCH 238/380] Like qdivrem, remove the other quad_t support stuff from 64-bit kernels. # OCTEON1 now links! --- sys/conf/files.mips | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/conf/files.mips b/sys/conf/files.mips index ca09e6cffea..708d6c700fd 100644 --- a/sys/conf/files.mips +++ b/sys/conf/files.mips @@ -81,16 +81,16 @@ geom/geom_mbr.c optional geom_mbr geom/geom_mbr_enc.c optional geom_mbr libkern/ashldi3.c standard libkern/ashrdi3.c standard -libkern/divdi3.c standard +libkern/divdi3.c optional isa_mips32 libkern/ffsl.c standard libkern/fls.c standard libkern/flsl.c standard libkern/lshrdi3.c standard libkern/memmove.c standard -libkern/moddi3.c standard +libkern/moddi3.c optional isa_mips32 libkern/qdivrem.c optional isa_mips32 -libkern/udivdi3.c standard -libkern/umoddi3.c standard +libkern/udivdi3.c optional isa_mips32 +libkern/umoddi3.c optional isa_mips32 #XXX: We can't use these versions, as strcmp.c is included conf/files #libkern/mips/strcmp.S standard From d0c60705f10a101b3e31409064363d27b3a59ba3 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 3 Sep 2009 18:23:23 +0000 Subject: [PATCH 239/380] - Fix phy address calculation --- sys/mips/atheros/if_arge.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index 88d4384e47d..c0c4c1a1008 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -477,7 +477,7 @@ arge_miibus_readreg(device_t dev, int phy, int reg) { struct arge_softc * sc = device_get_softc(dev); int i, result; - uint32_t addr = 0x1000 | (phy << MAC_MII_PHY_ADDR_SHIFT) + uint32_t addr = (phy << MAC_MII_PHY_ADDR_SHIFT) | (reg & MAC_MII_REG_MASK); if (phy != sc->arge_phy_num) @@ -511,8 +511,8 @@ arge_miibus_writereg(device_t dev, int phy, int reg, int data) { struct arge_softc * sc = device_get_softc(dev); int i; - uint32_t addr = 0x1000 - | (phy << MAC_MII_PHY_ADDR_SHIFT) | (reg & MAC_MII_REG_MASK); + uint32_t addr = + (phy << MAC_MII_PHY_ADDR_SHIFT) | (reg & MAC_MII_REG_MASK); dprintf("%s: phy=%d, reg=%02x, value=%04x\n", __func__, phy, reg, data); From a7420595db2ef9cb2194653e8e73a34bb3977f03 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 3 Sep 2009 18:27:55 +0000 Subject: [PATCH 240/380] - Remove flags accidently brought by dumb cut'n'paste coding --- sys/mips/atheros/ar71xx_ehci.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/sys/mips/atheros/ar71xx_ehci.c b/sys/mips/atheros/ar71xx_ehci.c index 5f2e0bbc853..cf89cc513e7 100644 --- a/sys/mips/atheros/ar71xx_ehci.c +++ b/sys/mips/atheros/ar71xx_ehci.c @@ -190,12 +190,7 @@ ar71xx_ehci_attach(device_t self) * which means port speed must be read from the Port Status * register following a port enable. */ - sc->sc_flags |= EHCI_SCFLG_TT - | EHCI_SCFLG_SETMODE - | EHCI_SCFLG_BIGEDESC - | EHCI_SCFLG_BIGEMMIO - | EHCI_SCFLG_NORESTERM - ; + sc->sc_flags = EHCI_SCFLG_SETMODE; (void) ehci_reset(sc); err = ehci_init(sc); From 6dbde1f3f9da01ff7ec28c0b82e4c55f2cc46264 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Thu, 3 Sep 2009 23:04:33 +0000 Subject: [PATCH 241/380] o enable mesh support o add bridge support o no need for explicit ar5212 support; ath_hal drags it in --- sys/mips/conf/AR71XX | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/mips/conf/AR71XX b/sys/mips/conf/AR71XX index 8e8fff4ae78..cfdd82da10d 100644 --- a/sys/mips/conf/AR71XX +++ b/sys/mips/conf/AR71XX @@ -48,6 +48,7 @@ device pci # Wireless NIC cards options IEEE80211_DEBUG +options IEEE80211_SUPPORT_MESH options IEEE80211_SUPPORT_TDMA device wlan # 802.11 support device wlan_wep # 802.11 WEP support @@ -56,9 +57,8 @@ device wlan_tkip # 802.11 TKIP support device ath # Atheros pci/cardbus NIC's options ATH_DEBUG -option AH_SUPPORT_AR5416 device ath_hal -device ath_ar5212 # Atheros HAL (Hardware Access Layer) +option AH_SUPPORT_AR5416 device ath_rate_sample device mii @@ -83,3 +83,4 @@ device ether device md device bpf device random +device if_bridge From 002c0b94ea67a50706f5d2d6c78af57ce55e2392 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 4 Sep 2009 19:02:11 +0000 Subject: [PATCH 242/380] - Clean out some XXXMIPS comments that's not relevant now --- sys/mips/malta/uart_bus_maltausart.c | 7 ------- sys/mips/malta/uart_cpu_maltausart.c | 4 ---- 2 files changed, 11 deletions(-) diff --git a/sys/mips/malta/uart_bus_maltausart.c b/sys/mips/malta/uart_bus_maltausart.c index e82384f0558..e075fff62e5 100644 --- a/sys/mips/malta/uart_bus_maltausart.c +++ b/sys/mips/malta/uart_bus_maltausart.c @@ -28,10 +28,6 @@ * code written by Olivier Houchard. */ -/* - * XXXMIPS: This file is hacked from arm/... . XXXMIPS here means this file is - * experimental and was written for MIPS32 port. - */ #include "opt_uart.h" #include @@ -53,9 +49,6 @@ __FBSDID("$FreeBSD$"); #include #include -/* - * XXXMIPS: - */ #include #include "uart_if.h" diff --git a/sys/mips/malta/uart_cpu_maltausart.c b/sys/mips/malta/uart_cpu_maltausart.c index d65ddfaffa1..07ea548a0a1 100644 --- a/sys/mips/malta/uart_cpu_maltausart.c +++ b/sys/mips/malta/uart_cpu_maltausart.c @@ -29,10 +29,6 @@ * Skeleton of this file was based on respective code for ARM * code written by Olivier Houchard. */ -/* - * XXXMIPS: This file is hacked from arm/... . XXXMIPS here means this file is - * experimental and was written for MIPS32 port. - */ #include "opt_uart.h" #include From 01316fcb763c48b45f5d9611a73fd2acad420a6d Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 8 Sep 2009 05:24:09 +0000 Subject: [PATCH 243/380] - Add commented hint required for RouterStation(non PRO) board --- sys/mips/conf/AR71XX.hints | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/mips/conf/AR71XX.hints b/sys/mips/conf/AR71XX.hints index 2b97880c60c..c44d6958a00 100644 --- a/sys/mips/conf/AR71XX.hints +++ b/sys/mips/conf/AR71XX.hints @@ -29,6 +29,9 @@ hint.arge.0.at="nexus0" hint.arge.0.maddr=0x19000000 hint.arge.0.msize=0x1000 hint.arge.0.irq=2 +# Uncomment this hint for RS (not PRO) +# hint.arge.0.phy=20 + # hint.arge.1.at="nexus0" # hint.arge.1.maddr=0x1A000000 # hint.arge.1.msize=0x1000 From fea06c66bfb189a1d2a198ec1552562a35dc0b39 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 9 Sep 2009 00:46:11 +0000 Subject: [PATCH 244/380] Put back KERNLOADADDR. --- sys/conf/ldscript.mips.mips64 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/conf/ldscript.mips.mips64 b/sys/conf/ldscript.mips.mips64 index 83a5066ee7a..4762abfaf10 100644 --- a/sys/conf/ldscript.mips.mips64 +++ b/sys/conf/ldscript.mips.mips64 @@ -43,7 +43,7 @@ PROVIDE (_DYNAMIC = 0); SECTIONS { /* Read-only sections, merged into text segment: */ - . = 0x80100000 + SIZEOF_HEADERS; + . = KERNLOADADDR + SIZEOF_HEADERS; .interp : { *(.interp) } .hash : { *(.hash) } .dynsym : { *(.dynsym) } From a73a4028d13a5ccefbbfe7cbefec478cdf2af4c5 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 9 Sep 2009 00:47:12 +0000 Subject: [PATCH 245/380] Use ${LDSCRIPT_NAME} in preference to ldscript.$M. --- sys/conf/Makefile.mips | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/sys/conf/Makefile.mips b/sys/conf/Makefile.mips index 779e7060a2e..88a2c94eeb4 100644 --- a/sys/conf/Makefile.mips +++ b/sys/conf/Makefile.mips @@ -28,8 +28,9 @@ S= ../../.. .endif .include "$S/conf/kern.pre.mk" -SYSTEM_LD:= ${SYSTEM_LD:$S/conf/ldscript.$M=ldscript.$M} -SYSTEM_DEP:= ${SYSTEM_DEP:$S/conf/ldscript.$M=ldscript.$M} +LDSCRIPT_NAME?=ldscript.$M +SYSTEM_LD:= ${SYSTEM_LD:$S/conf/${LDSCRIPT_NAME}=${LDSCRIPT_NAME}} +SYSTEM_DEP:= ${SYSTEM_DEP:$S/conf/${LDSCRIPT_NAME}=${LDSCRIPT_NAME}} # XXX: Such sweeping assumptions... MACHINE=mips @@ -84,8 +85,8 @@ ${KERNEL_KO}.tramp.bin: ${KERNEL_KO} $S/$M/$M/elf_trampoline.c \ $S/$M/$M/inckern.S ${OBJCOPY} --strip-symbol '$$d' --strip-symbol '$$a' \ -g --strip-symbol '$$t' ${FULLKERNEL} ${KERNEL_KO}.tmp - sed s/${KERNLOADADDR}/${TRAMPLOADADDR}/ ldscript.$M | \ - sed s/" + SIZEOF_HEADERS"// > ldscript.$M.tramp.noheader + sed s/${KERNLOADADDR}/${TRAMPLOADADDR}/ ${LDSCRIPT_NAME} | \ + sed s/" + SIZEOF_HEADERS"// > ${LDSCRIPT_NAME}.tramp.noheader # Generate .S file that setups stack and jumps to trampoline echo "#include " >tmphack.S echo "ENTRY(_start)" >>tmphack.S @@ -98,7 +99,7 @@ ${KERNEL_KO}.tramp.bin: ${KERNEL_KO} $S/$M/$M/elf_trampoline.c \ echo "END(_start)" >>tmphack.S echo "#define KERNNAME \"${KERNEL_KO}.tmp\"" >opt_kernname.h ${CC} -O -nostdlib -I. -I$S ${EXTRA_FLAGS} ${TRAMP_LDFLAGS} -Xlinker \ - -T -Xlinker ldscript.$M.tramp.noheader tmphack.S \ + -T -Xlinker ${LDSCRIPT_NAME}.tramp.noheader tmphack.S \ $S/$M/$M/elf_trampoline.c $S/$M/$M/inckern.S \ -o ${KERNEL_KO}.tramp.noheader ${OBJCOPY} -S -O binary ${KERNEL_KO}.tramp.noheader \ @@ -116,12 +117,12 @@ ${KERNEL_KO}.tramp.bin: ${KERNEL_KO} $S/$M/$M/elf_trampoline.c \ %CLEAN -CLEAN+= ldscript.$M ldscript.$M.tramp.noheader \ +CLEAN+= ${LDSCRIPT_NAME} ${LDSCRIPT_NAME}.tramp.noheader \ ${KERNEL_KO}.tramp.noheader ${KERNEL_KO}.tramp.bin -ldscript.$M: $S/conf/ldscript.$M - cat $S/conf/ldscript.$M|sed s/KERNLOADADDR/${KERNLOADADDR}/g \ - > ldscript.$M +${LDSCRIPT_NAME}: $S/conf/${LDSCRIPT_NAME} + cat $S/conf/${LDSCRIPT_NAME}|sed s/KERNLOADADDR/${KERNLOADADDR}/g \ + > ${LDSCRIPT_NAME} %RULES .include "$S/conf/kern.post.mk" From eeebbca3a3b447d316e8fa00e911ac1076374c17 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 9 Sep 2009 00:50:17 +0000 Subject: [PATCH 246/380] Set the ldscript for malta64 correctly. --- sys/mips/conf/MALTA64 | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/mips/conf/MALTA64 b/sys/mips/conf/MALTA64 index 70be8fef7ad..8545d6b9920 100644 --- a/sys/mips/conf/MALTA64 +++ b/sys/mips/conf/MALTA64 @@ -22,6 +22,7 @@ ident MALTA makeoptions ARCH_FLAGS="-march=mips64 -mabi=64" makeoptions MIPS_LITTLE_ENDIAN=defined makeoptions TARGET_64BIT=t +makeoptions LDSCRIPT_NAME= ldscript.mips.mips64 options YAMON From fe265c729689dbdda59ded04bd5e5bddd9ad8cfd Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 9 Sep 2009 03:46:04 +0000 Subject: [PATCH 247/380] Use proper set of flags to build the tramp. this gets 64-bit almost building and lets me debug the 'almost' :) --- sys/conf/Makefile.mips | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/conf/Makefile.mips b/sys/conf/Makefile.mips index 88a2c94eeb4..14a75d2d87a 100644 --- a/sys/conf/Makefile.mips +++ b/sys/conf/Makefile.mips @@ -98,7 +98,7 @@ ${KERNEL_KO}.tramp.bin: ${KERNEL_KO} $S/$M/$M/elf_trampoline.c \ echo "j t0" >>tmphack.S echo "END(_start)" >>tmphack.S echo "#define KERNNAME \"${KERNEL_KO}.tmp\"" >opt_kernname.h - ${CC} -O -nostdlib -I. -I$S ${EXTRA_FLAGS} ${TRAMP_LDFLAGS} -Xlinker \ + ${CC} -O -nostdlib -I. -I$S ${HACK_EXTRA_FLAGS} ${TRAMP_LDFLAGS} -Xlinker \ -T -Xlinker ${LDSCRIPT_NAME}.tramp.noheader tmphack.S \ $S/$M/$M/elf_trampoline.c $S/$M/$M/inckern.S \ -o ${KERNEL_KO}.tramp.noheader From 90d1a515348c180fe6b53dd92ef90a888936e8dd Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 9 Sep 2009 03:54:55 +0000 Subject: [PATCH 248/380] First half of making this 64-bit clean: fix prototypes. --- sys/mips/mips/elf_trampoline.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/mips/mips/elf_trampoline.c b/sys/mips/mips/elf_trampoline.c index 0f2ccc95e31..a10919d3132 100644 --- a/sys/mips/mips/elf_trampoline.c +++ b/sys/mips/mips/elf_trampoline.c @@ -26,6 +26,7 @@ __FBSDID("$FreeBSD$"); #include #include + #include #include #include @@ -43,7 +44,7 @@ extern char kernel_start[]; extern char kernel_end[]; static __inline void * -memcpy(void *dst, const void *src, int len) +memcpy(void *dst, const void *src, size_t len) { const char *s = src; char *d = dst; @@ -64,7 +65,7 @@ memcpy(void *dst, const void *src, int len) } static __inline void -bzero(void *addr, int count) +bzero(void *addr, size_t count) { char *tmp = (char *)addr; From 97b83d313daaea23d1374a253f24e325637115e1 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 9 Sep 2009 03:57:10 +0000 Subject: [PATCH 249/380] Ugly hack to get this to compile. I'm sure there's a better way... --- sys/mips/mips/elf_trampoline.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sys/mips/mips/elf_trampoline.c b/sys/mips/mips/elf_trampoline.c index a10919d3132..d98b8468442 100644 --- a/sys/mips/mips/elf_trampoline.c +++ b/sys/mips/mips/elf_trampoline.c @@ -27,7 +27,11 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef __mips_n64 +#include +#else #include +#endif #include #include #include @@ -89,12 +93,21 @@ bzero(void *addr, size_t count) void * load_kernel(void * kstart) { +#ifdef __mips_n64 + Elf64_Ehdr *eh; + Elf64_Phdr phdr[64] /* XXX */; +#else Elf32_Ehdr *eh; Elf32_Phdr phdr[64] /* XXX */; +#endif int i; void *entry_point; +#ifdef __mips_n64 + eh = (Elf64_Ehdr *)kstart; +#else eh = (Elf32_Ehdr *)kstart; +#endif entry_point = (void*)eh->e_entry; memcpy(phdr, (void *)(kstart + eh->e_phoff ), eh->e_phnum * sizeof(phdr[0])); From f5152fe8e7896c7acabcdd8d3fedbd583682c362 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 9 Sep 2009 03:59:46 +0000 Subject: [PATCH 250/380] Prefer PTR_LA over a naked la to work with 64-bits.. --- sys/conf/Makefile.mips | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/conf/Makefile.mips b/sys/conf/Makefile.mips index 14a75d2d87a..0b56bb72518 100644 --- a/sys/conf/Makefile.mips +++ b/sys/conf/Makefile.mips @@ -90,11 +90,11 @@ ${KERNEL_KO}.tramp.bin: ${KERNEL_KO} $S/$M/$M/elf_trampoline.c \ # Generate .S file that setups stack and jumps to trampoline echo "#include " >tmphack.S echo "ENTRY(_start)" >>tmphack.S - echo "la t0, kernel_end" >>tmphack.S + echo "PTR_LA t0, kernel_end" >>tmphack.S echo "move sp, t0" >>tmphack.S echo "add sp, 0x2000" >>tmphack.S echo "and sp, ~0x7" >>tmphack.S - echo "la t0, _startC" >>tmphack.S + echo "PTR_LA t0, _startC" >>tmphack.S echo "j t0" >>tmphack.S echo "END(_start)" >>tmphack.S echo "#define KERNNAME \"${KERNEL_KO}.tmp\"" >opt_kernname.h From 1c4059d5ea73bdf86f6be3fd6be7fadd6ba8a4b5 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 1 Oct 2009 20:05:36 +0000 Subject: [PATCH 251/380] - Sync caches properly when dealing with sf_buf --- sys/mips/include/pmap.h | 1 + sys/mips/mips/pmap.c | 6 +++--- sys/mips/mips/vm_machdep.c | 11 +++++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/sys/mips/include/pmap.h b/sys/mips/include/pmap.h index 4546cffd0a7..3e4231350f6 100644 --- a/sys/mips/include/pmap.h +++ b/sys/mips/include/pmap.h @@ -172,6 +172,7 @@ void *pmap_kenter_temporary(vm_paddr_t pa, int i); void pmap_kenter_temporary_free(vm_paddr_t pa); int pmap_compute_pages_to_dump(void); void pmap_update_page(pmap_t pmap, vm_offset_t va, pt_entry_t pte); +void pmap_flush_pvcache(vm_page_t m); /* * floating virtual pages (FPAGES) diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index 50a744a180f..52d28645aba 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -187,7 +187,6 @@ static int init_pte_prot(vm_offset_t va, vm_page_t m, vm_prot_t prot); static void pmap_TLB_invalidate_kernel(vm_offset_t); static void pmap_TLB_update_kernel(vm_offset_t, pt_entry_t); static void pmap_init_fpage(void); -static void pmap_flush_pvcache(vm_page_t m); #ifdef SMP static void pmap_invalidate_page_action(void *arg); @@ -744,11 +743,12 @@ pmap_qenter(vm_offset_t va, vm_page_t *m, int count) vm_offset_t origva = va; for (i = 0; i < count; i++) { + pmap_flush_pvcache(m[i]); pmap_kenter(va, VM_PAGE_TO_PHYS(m[i])); va += PAGE_SIZE; } - mips_dcache_wbinv_range_index(origva, PAGE_SIZE*count); + mips_dcache_inv_range(origva, PAGE_SIZE*count); } /* @@ -3313,7 +3313,7 @@ pmap_kextract(vm_offset_t va) return pa; } -static void +void pmap_flush_pvcache(vm_page_t m) { pv_entry_t pv; diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c index f0ee573da71..7e815e26b93 100644 --- a/sys/mips/mips/vm_machdep.c +++ b/sys/mips/mips/vm_machdep.c @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -474,6 +475,12 @@ sf_buf_alloc(struct vm_page *m, int flags) nsfbufsused++; nsfbufspeak = imax(nsfbufspeak, nsfbufsused); } + /* + * Flush all mappings in order to have up to date + * physycal memory + */ + pmap_flush_pvcache(sf->m); + mips_dcache_inv_range(sf->kva, PAGE_SIZE); goto done; } } @@ -515,6 +522,10 @@ sf_buf_free(struct sf_buf *sf) { mtx_lock(&sf_buf_lock); sf->ref_count--; + /* + * Make sure all changes in KVA end up in physical memory + */ + mips_dcache_wbinv_range(sf->kva, PAGE_SIZE); if (sf->ref_count == 0) { TAILQ_INSERT_TAIL(&sf_buf_freelist, sf, free_entry); nsfbufsused--; From 5c0509f9c03755969df954832366cbdc7a48d13f Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 2 Oct 2009 23:48:42 +0000 Subject: [PATCH 252/380] - Fix the problem presented by r196988. svn merge was erroneously interrupted and after re-run new files were not added to repo though respective revisions were marked as merged. This commit presents latest versions of these files. --- etc/rc.d/static_arp | 74 + share/colldef/la_LN.ISO8859-13.src | 37 + share/mklocale/la_LN.ISO8859-13.src | 49 + share/monetdef/lv_LV.ISO8859-13.src | 36 + share/msgdef/lv_LV.ISO8859-13.src | 14 + share/msgdef/lv_LV.UTF-8.src | 14 + share/timedef/lv_LV.ISO8859-13.src | 101 ++ share/timedef/lv_LV.UTF-8.src | 101 ++ sys/dev/drm/r600_blit.c | 1990 +++++++++++++++++++++++++++ sys/dev/drm/radeon_cs.c | 856 ++++++++++++ 10 files changed, 3272 insertions(+) create mode 100644 etc/rc.d/static_arp create mode 100644 share/colldef/la_LN.ISO8859-13.src create mode 100644 share/mklocale/la_LN.ISO8859-13.src create mode 100644 share/monetdef/lv_LV.ISO8859-13.src create mode 100644 share/msgdef/lv_LV.ISO8859-13.src create mode 100644 share/msgdef/lv_LV.UTF-8.src create mode 100644 share/timedef/lv_LV.ISO8859-13.src create mode 100644 share/timedef/lv_LV.UTF-8.src create mode 100644 sys/dev/drm/r600_blit.c create mode 100644 sys/dev/drm/radeon_cs.c diff --git a/etc/rc.d/static_arp b/etc/rc.d/static_arp new file mode 100644 index 00000000000..6283b56ef08 --- /dev/null +++ b/etc/rc.d/static_arp @@ -0,0 +1,74 @@ +#!/bin/sh +# +# Copyright (c) 2009 Xin LI +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# Configure static ARP table +# +# $FreeBSD$ +# + +# PROVIDE: static_arp +# REQUIRE: netif +# KEYWORD: nojail + +. /etc/rc.subr +. /etc/network.subr + +name="static_arp" +start_cmd="static_arp_start" +stop_cmd="static_arp_stop" + +static_arp_start() +{ + local e arp_args + + if [ -n "${static_arp_pairs}" ]; then + echo -n 'Binding static ARP pair(s):' + for e in ${static_arp_pairs}; do + echo -n " ${e}" + eval arp_args=\$static_arp_${e} + arp -S ${arp_args} >/dev/null 2>&1 + done + echo '.' + fi +} + +static_arp_stop() +{ + local e arp_args + + if [ -n "${static_arp_pairs}" ]; then + echo -n 'Unbinding static ARP pair(s):' + for e in ${static_arp_pairs}; do + echo -n " ${e}" + eval arp_args=\$static_arp_${e} + arp -d ${arp_args%%[ ]*} > /dev/null 2>&1 + done + echo '.' + fi +} + +load_rc_config $name +run_rc_command "$1" diff --git a/share/colldef/la_LN.ISO8859-13.src b/share/colldef/la_LN.ISO8859-13.src new file mode 100644 index 00000000000..828e478131b --- /dev/null +++ b/share/colldef/la_LN.ISO8859-13.src @@ -0,0 +1,37 @@ +# Latin-7 / Baltic Rim (backward compatible with ASCII) +# +# $FreeBSD$ +# +charmap map.ISO8859-13 +order \ +# controls + ;...;;;...;;\ +# + ;;!;\";<"">;;\ + ;;;;\ + %;&;';\(;\);*;+;<-:>;<*X>;<.M>;\,;<,,>;<``>;<-->;<+->;-;.;<'.>;/;\ +# digits + 0;...;9;\ +# + :;\;;\<;=;>;<<<>;/>>;?;;;;\ +# capital + (A,,,,,);\ + B;(C,,);D;(E,,,,);\ + F;(G,);H;(I,,);Y;\ + J;(K,);(L,,);M;(N,,);(O,,,,,);\ + P;Q;(R,);(S,,);T;\ + (U,,,);\ + V;W;X;(Z,,,);\ +# + [;\\;];^;_;`;\ +# small + (a,,,,,);\ + b;(c,,);d;(e,,,,);\ + f;(g,);h;(i,,);y;\ + j;(k,);(l,,);m;(n,,);(o,,,,,);\ + p;q;(r,);(s,,,);t;\ + (u,,,);\ + v;w;x;(z,,,);\ +# + \{;|;;\};~;;
;;;;;<1S>;<2S>;<3S>;\ + <14>;<12>;<34> diff --git a/share/mklocale/la_LN.ISO8859-13.src b/share/mklocale/la_LN.ISO8859-13.src new file mode 100644 index 00000000000..ddd248f1cc1 --- /dev/null +++ b/share/mklocale/la_LN.ISO8859-13.src @@ -0,0 +1,49 @@ +/* + * LOCALE_CTYPE for the iso_8859_13 Locale + * + * $FreeBSD$ + */ + +ENCODING "NONE" +VARIABLE ISO 8859-13 Latin-7 character set + +# +# This is a comment +# +ALPHA 'A' - 'Z' 'a' - 'z' +ALPHA 0xaa 0xba 0xc0 - 0xd6 0xd8 - 0xde 0xe0 - 0xf6 0xf8 - 0xfe +CONTROL 0x00 - 0x1f 0x7f - 0x9f +DIGIT '0' - '9' +GRAPH 0x21 - 0x7e 0xa1 - 0xff +LOWER 'a' - 'z' +LOWER 0xba 0xdf - 0xf6 0xf8 - 0xfe +PUNCT 0x21 - 0x2f 0x3a - 0x40 0x5b - 0x60 0x7b - 0x7e +PUNCT 0xa1 - 0xa9 0xab - 0xb9 0xbb -0xbf 0xd7 0xdf 0xf7 0xff +SPACE 0x09 - 0x0d 0x20 0xa0 +UPPER 'A' - 'Z' +UPPER 0xaa 0xc0 - 0xd6 0xd8 - 0xde +XDIGIT '0' - '9' 'a' - 'f' 'A' - 'F' +BLANK ' ' '\t' 0xa0 +PRINT 0x20 - 0x7e 0xa0 - 0xff + +MAPLOWER <'A' - 'Z' : 'a'> +MAPLOWER <'a' - 'z' : 'a'> +MAPLOWER <0xaa 0xba> +MAPLOWER <0xba 0xba> +MAPLOWER <0xc0 - 0xd6 : 0xe0> +MAPLOWER <0xd8 - 0xde : 0xf8> +MAPLOWER <0xe0 - 0xf6 : 0xe0> +MAPLOWER <0xf8 - 0xfe : 0xf8> + +MAPUPPER <'A' - 'Z' : 'A'> +MAPUPPER <'a' - 'z' : 'A'> +MAPUPPER <0xaa 0xaa> +MAPUPPER <0xba 0xaa> +MAPUPPER <0xc0 - 0xd6 : 0xc0> +MAPUPPER <0xd8 - 0xdf : 0xd8> +MAPUPPER <0xe0 - 0xf6 : 0xc0> +MAPUPPER <0xf8 - 0xfe : 0xd8> + +TODIGIT <'0' - '9' : 0> +TODIGIT <'A' - 'F' : 10> +TODIGIT <'a' - 'f' : 10> diff --git a/share/monetdef/lv_LV.ISO8859-13.src b/share/monetdef/lv_LV.ISO8859-13.src new file mode 100644 index 00000000000..647c4e69935 --- /dev/null +++ b/share/monetdef/lv_LV.ISO8859-13.src @@ -0,0 +1,36 @@ +# $FreeBSD$ +# +# WARNING: spaces may be essential at the end of lines +# WARNING: empty lines are essential too +# +# int_curr_symbol (last character always SPACE) +LVL +# currency_symbol +Ls +# mon_decimal_point +, +# mon_thousands_sep + +# mon_grouping, separated by ; +3;3 +# positive_sign + +# negative_sign +- +# int_frac_digits +2 +# frac_digits +2 +# p_cs_precedes +0 +# p_sep_by_space +1 +# n_cs_precedes +0 +# n_sep_by_space +1 +# p_sign_posn +1 +# n_sign_posn +1 +# EOF diff --git a/share/msgdef/lv_LV.ISO8859-13.src b/share/msgdef/lv_LV.ISO8859-13.src new file mode 100644 index 00000000000..d744ad86b30 --- /dev/null +++ b/share/msgdef/lv_LV.ISO8859-13.src @@ -0,0 +1,14 @@ +# $FreeBSD$ +# +# WARNING: spaces may be essential at the end of lines +# WARNING: empty lines are essential too +# +# yesexpr +^[jJyY].* +# noexpr +^[nN].* +# yesstr +jâ +# nostr +nç +# EOF diff --git a/share/msgdef/lv_LV.UTF-8.src b/share/msgdef/lv_LV.UTF-8.src new file mode 100644 index 00000000000..85f1a73fc1e --- /dev/null +++ b/share/msgdef/lv_LV.UTF-8.src @@ -0,0 +1,14 @@ +# $FreeBSD$ +# +# WARNING: spaces may be essential at the end of lines +# WARNING: empty lines are essential too +# +# yesexpr +^[jJyY].* +# noexpr +^[nN].* +# yesstr +jÄ +# nostr +nÄ“ +# EOF diff --git a/share/timedef/lv_LV.ISO8859-13.src b/share/timedef/lv_LV.ISO8859-13.src new file mode 100644 index 00000000000..5e5e3d1f40d --- /dev/null +++ b/share/timedef/lv_LV.ISO8859-13.src @@ -0,0 +1,101 @@ +# $FreeBSD$ +# WARNING: spaces may be essential at the end of lines +# WARNING: empty lines are essential too +# +# Short month names +# +Jan +Feb +Mar +Apr +Mai +Jûn +Jûl +Aug +Sep +Okt +Nov +Dec +# +# Long month names +# +janvâris +februâris +marts +aprîlis +maijs +jûnijs +jûlijs +augusts +septembris +oktobris +novembris +decembris +# +# Short weekday names +# +Sv +Pr +Ot +Tr +Ct +Pk +Ss +# +# Long weekday names +# +Svçtdiena +Pirmdiena +Otrdiena +Treðdiena +Ceturtdiena +Piektdiena +Sestdiena +# +# X_fmt +# +%H:%M:%S +# +# x_fmt +# +%d/%m/%Y +# +# c_fmt +# %A, %Y m. %B %e d. %T +%e. %b, %Y. gads %X +# +# am +# + +# +# pm +# + +# +# date_fmt +# +%A, %Y. gada %e. %B %T %Z +# +# Long month names in alternative form +# +janvâris +februâris +marts +aprîlis +maijs +jûnijs +jûlijs +augusts +septembris +oktobris +novembris +decembris +# +# md_order +# +md +# +# ampm_fmt +# + +# EOF diff --git a/share/timedef/lv_LV.UTF-8.src b/share/timedef/lv_LV.UTF-8.src new file mode 100644 index 00000000000..56d1cb40927 --- /dev/null +++ b/share/timedef/lv_LV.UTF-8.src @@ -0,0 +1,101 @@ +# $FreeBSD$ +# WARNING: spaces may be essential at the end of lines +# WARNING: empty lines are essential too +# +# Short month names +# +Jan +Feb +Mar +Apr +Mai +JÅ«n +JÅ«l +Aug +Sep +Okt +Nov +Dec +# +# Long month names +# +janvÄris +februÄris +marts +aprÄ«lis +maijs +jÅ«nijs +jÅ«lijs +augusts +septembris +oktobris +novembris +decembris +# +# Short weekday names +# +Sv +Pr +Ot +Tr +Ct +Pk +Ss +# +# Long weekday names +# +SvÄ“tdiena +Pirmdiena +Otrdiena +TreÅ¡diena +Ceturtdiena +Piektdiena +Sestdiena +# +# X_fmt +# +%H:%M:%S +# +# x_fmt +# +%d/%m/%Y +# +# c_fmt +# %A, %Y m. %B %e d. %T +%e. %b, %Y. gads %X +# +# am +# + +# +# pm +# + +# +# date_fmt +# +%A, %Y. gada %e. %B %T %Z +# +# Long month names in alternative form +# +janvÄris +februÄris +marts +aprÄ«lis +maijs +jÅ«nijs +jÅ«lijs +augusts +septembris +oktobris +novembris +decembris +# +# md_order +# +md +# +# ampm_fmt +# + +# EOF diff --git a/sys/dev/drm/r600_blit.c b/sys/dev/drm/r600_blit.c new file mode 100644 index 00000000000..6443d843f98 --- /dev/null +++ b/sys/dev/drm/r600_blit.c @@ -0,0 +1,1990 @@ +/*- + * Copyright 2009 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Alex Deucher + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "dev/drm/drmP.h" +#include "dev/drm/drm.h" +#include "dev/drm/radeon_drm.h" +#include "dev/drm/radeon_drv.h" + +static u32 r6xx_default_state[] = +{ + 0xc0002400, + 0x00000000, + 0xc0012800, + 0x80000000, + 0x80000000, + 0xc0004600, + 0x00000016, + 0xc0016800, + 0x00000010, + 0x00028000, + 0xc0016800, + 0x00000010, + 0x00008000, + 0xc0016800, + 0x00000542, + 0x07000003, + 0xc0016800, + 0x000005c5, + 0x00000000, + 0xc0016800, + 0x00000363, + 0x00000000, + 0xc0016800, + 0x0000060c, + 0x82000000, + 0xc0016800, + 0x0000060e, + 0x01020204, + 0xc0016f00, + 0x00000000, + 0x00000000, + 0xc0016f00, + 0x00000001, + 0x00000000, + 0xc0096900, + 0x0000022a, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0016900, + 0x00000004, + 0x00000000, + 0xc0016900, + 0x0000000a, + 0x00000000, + 0xc0016900, + 0x0000000b, + 0x00000000, + 0xc0016900, + 0x0000010c, + 0x00000000, + 0xc0016900, + 0x0000010d, + 0x00000000, + 0xc0016900, + 0x00000200, + 0x00000000, + 0xc0016900, + 0x00000343, + 0x00000060, + 0xc0016900, + 0x00000344, + 0x00000040, + 0xc0016900, + 0x00000351, + 0x0000aa00, + 0xc0016900, + 0x00000104, + 0x00000000, + 0xc0016900, + 0x0000010e, + 0x00000000, + 0xc0046900, + 0x00000105, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0036900, + 0x00000109, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0046900, + 0x0000030c, + 0x01000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0046900, + 0x00000048, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x3f800000, + 0xc0016900, + 0x0000008e, + 0x0000000f, + 0xc0016900, + 0x00000080, + 0x00000000, + 0xc0016900, + 0x00000083, + 0x0000ffff, + 0xc0016900, + 0x00000084, + 0x00000000, + 0xc0016900, + 0x00000085, + 0x20002000, + 0xc0016900, + 0x00000086, + 0x00000000, + 0xc0016900, + 0x00000087, + 0x20002000, + 0xc0016900, + 0x00000088, + 0x00000000, + 0xc0016900, + 0x00000089, + 0x20002000, + 0xc0016900, + 0x0000008a, + 0x00000000, + 0xc0016900, + 0x0000008b, + 0x20002000, + 0xc0016900, + 0x0000008c, + 0x00000000, + 0xc0016900, + 0x00000094, + 0x80000000, + 0xc0016900, + 0x00000095, + 0x20002000, + 0xc0026900, + 0x000000b4, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x00000096, + 0x80000000, + 0xc0016900, + 0x00000097, + 0x20002000, + 0xc0026900, + 0x000000b6, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x00000098, + 0x80000000, + 0xc0016900, + 0x00000099, + 0x20002000, + 0xc0026900, + 0x000000b8, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x0000009a, + 0x80000000, + 0xc0016900, + 0x0000009b, + 0x20002000, + 0xc0026900, + 0x000000ba, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x0000009c, + 0x80000000, + 0xc0016900, + 0x0000009d, + 0x20002000, + 0xc0026900, + 0x000000bc, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x0000009e, + 0x80000000, + 0xc0016900, + 0x0000009f, + 0x20002000, + 0xc0026900, + 0x000000be, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000a0, + 0x80000000, + 0xc0016900, + 0x000000a1, + 0x20002000, + 0xc0026900, + 0x000000c0, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000a2, + 0x80000000, + 0xc0016900, + 0x000000a3, + 0x20002000, + 0xc0026900, + 0x000000c2, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000a4, + 0x80000000, + 0xc0016900, + 0x000000a5, + 0x20002000, + 0xc0026900, + 0x000000c4, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000a6, + 0x80000000, + 0xc0016900, + 0x000000a7, + 0x20002000, + 0xc0026900, + 0x000000c6, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000a8, + 0x80000000, + 0xc0016900, + 0x000000a9, + 0x20002000, + 0xc0026900, + 0x000000c8, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000aa, + 0x80000000, + 0xc0016900, + 0x000000ab, + 0x20002000, + 0xc0026900, + 0x000000ca, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000ac, + 0x80000000, + 0xc0016900, + 0x000000ad, + 0x20002000, + 0xc0026900, + 0x000000cc, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000ae, + 0x80000000, + 0xc0016900, + 0x000000af, + 0x20002000, + 0xc0026900, + 0x000000ce, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000b0, + 0x80000000, + 0xc0016900, + 0x000000b1, + 0x20002000, + 0xc0026900, + 0x000000d0, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000b2, + 0x80000000, + 0xc0016900, + 0x000000b3, + 0x20002000, + 0xc0026900, + 0x000000d2, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x00000293, + 0x00004010, + 0xc0016900, + 0x00000300, + 0x00000000, + 0xc0016900, + 0x00000301, + 0x00000000, + 0xc0016900, + 0x00000312, + 0xffffffff, + 0xc0016900, + 0x00000307, + 0x00000000, + 0xc0016900, + 0x00000308, + 0x00000000, + 0xc0016900, + 0x00000283, + 0x00000000, + 0xc0016900, + 0x00000292, + 0x00000000, + 0xc0066900, + 0x0000010f, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0016900, + 0x00000206, + 0x00000000, + 0xc0016900, + 0x00000207, + 0x00000000, + 0xc0016900, + 0x00000208, + 0x00000000, + 0xc0046900, + 0x00000303, + 0x3f800000, + 0x3f800000, + 0x3f800000, + 0x3f800000, + 0xc0016900, + 0x00000205, + 0x00000004, + 0xc0016900, + 0x00000280, + 0x00000000, + 0xc0016900, + 0x00000281, + 0x00000000, + 0xc0016900, + 0x0000037e, + 0x00000000, + 0xc0016900, + 0x00000382, + 0x00000000, + 0xc0016900, + 0x00000380, + 0x00000000, + 0xc0016900, + 0x00000383, + 0x00000000, + 0xc0016900, + 0x00000381, + 0x00000000, + 0xc0016900, + 0x00000282, + 0x00000008, + 0xc0016900, + 0x00000302, + 0x0000002d, + 0xc0016900, + 0x0000037f, + 0x00000000, + 0xc0016900, + 0x000001b2, + 0x00000000, + 0xc0016900, + 0x000001b6, + 0x00000000, + 0xc0016900, + 0x000001b7, + 0x00000000, + 0xc0016900, + 0x000001b8, + 0x00000000, + 0xc0016900, + 0x000001b9, + 0x00000000, + 0xc0016900, + 0x00000225, + 0x00000000, + 0xc0016900, + 0x00000229, + 0x00000000, + 0xc0016900, + 0x00000237, + 0x00000000, + 0xc0016900, + 0x00000100, + 0x00000800, + 0xc0016900, + 0x00000101, + 0x00000000, + 0xc0016900, + 0x00000102, + 0x00000000, + 0xc0016900, + 0x000002a8, + 0x00000000, + 0xc0016900, + 0x000002a9, + 0x00000000, + 0xc0016900, + 0x00000103, + 0x00000000, + 0xc0016900, + 0x00000284, + 0x00000000, + 0xc0016900, + 0x00000290, + 0x00000000, + 0xc0016900, + 0x00000285, + 0x00000000, + 0xc0016900, + 0x00000286, + 0x00000000, + 0xc0016900, + 0x00000287, + 0x00000000, + 0xc0016900, + 0x00000288, + 0x00000000, + 0xc0016900, + 0x00000289, + 0x00000000, + 0xc0016900, + 0x0000028a, + 0x00000000, + 0xc0016900, + 0x0000028b, + 0x00000000, + 0xc0016900, + 0x0000028c, + 0x00000000, + 0xc0016900, + 0x0000028d, + 0x00000000, + 0xc0016900, + 0x0000028e, + 0x00000000, + 0xc0016900, + 0x0000028f, + 0x00000000, + 0xc0016900, + 0x000002a1, + 0x00000000, + 0xc0016900, + 0x000002a5, + 0x00000000, + 0xc0016900, + 0x000002ac, + 0x00000000, + 0xc0016900, + 0x000002ad, + 0x00000000, + 0xc0016900, + 0x000002ae, + 0x00000000, + 0xc0016900, + 0x000002c8, + 0x00000000, + 0xc0016900, + 0x00000206, + 0x00000100, + 0xc0016900, + 0x00000204, + 0x00010000, + 0xc0036e00, + 0x00000000, + 0x00000012, + 0x00000000, + 0x00000000, + 0xc0016900, + 0x0000008f, + 0x0000000f, + 0xc0016900, + 0x000001e8, + 0x00000001, + 0xc0016900, + 0x00000202, + 0x00cc0000, + 0xc0016900, + 0x00000205, + 0x00000244, + 0xc0016900, + 0x00000203, + 0x00000210, + 0xc0016900, + 0x000001b1, + 0x00000000, + 0xc0016900, + 0x00000185, + 0x00000000, + 0xc0016900, + 0x000001b3, + 0x00000001, + 0xc0016900, + 0x000001b4, + 0x00000000, + 0xc0016900, + 0x00000191, + 0x00000b00, + 0xc0016900, + 0x000001b5, + 0x00000000, +}; + +static u32 r7xx_default_state[] = +{ + 0xc0012800, + 0x80000000, + 0x80000000, + 0xc0004600, + 0x00000016, + 0xc0016800, + 0x00000010, + 0x00028000, + 0xc0016800, + 0x00000010, + 0x00008000, + 0xc0016800, + 0x00000542, + 0x07000002, + 0xc0016800, + 0x000005c5, + 0x00000000, + 0xc0016800, + 0x00000363, + 0x00004000, + 0xc0016800, + 0x0000060c, + 0x00000000, + 0xc0016800, + 0x0000060e, + 0x00420204, + 0xc0016f00, + 0x00000000, + 0x00000000, + 0xc0016f00, + 0x00000001, + 0x00000000, + 0xc0096900, + 0x0000022a, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0016900, + 0x00000004, + 0x00000000, + 0xc0016900, + 0x0000000a, + 0x00000000, + 0xc0016900, + 0x0000000b, + 0x00000000, + 0xc0016900, + 0x0000010c, + 0x00000000, + 0xc0016900, + 0x0000010d, + 0x00000000, + 0xc0016900, + 0x00000200, + 0x00000000, + 0xc0016900, + 0x00000343, + 0x00000060, + 0xc0016900, + 0x00000344, + 0x00000000, + 0xc0016900, + 0x00000351, + 0x0000aa00, + 0xc0016900, + 0x00000104, + 0x00000000, + 0xc0016900, + 0x0000010e, + 0x00000000, + 0xc0046900, + 0x00000105, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0046900, + 0x0000030c, + 0x01000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0016900, + 0x0000008e, + 0x0000000f, + 0xc0016900, + 0x00000080, + 0x00000000, + 0xc0016900, + 0x00000083, + 0x0000ffff, + 0xc0016900, + 0x00000084, + 0x00000000, + 0xc0016900, + 0x00000085, + 0x20002000, + 0xc0016900, + 0x00000086, + 0x00000000, + 0xc0016900, + 0x00000087, + 0x20002000, + 0xc0016900, + 0x00000088, + 0x00000000, + 0xc0016900, + 0x00000089, + 0x20002000, + 0xc0016900, + 0x0000008a, + 0x00000000, + 0xc0016900, + 0x0000008b, + 0x20002000, + 0xc0016900, + 0x0000008c, + 0xaaaaaaaa, + 0xc0016900, + 0x00000094, + 0x80000000, + 0xc0016900, + 0x00000095, + 0x20002000, + 0xc0026900, + 0x000000b4, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x00000096, + 0x80000000, + 0xc0016900, + 0x00000097, + 0x20002000, + 0xc0026900, + 0x000000b6, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x00000098, + 0x80000000, + 0xc0016900, + 0x00000099, + 0x20002000, + 0xc0026900, + 0x000000b8, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x0000009a, + 0x80000000, + 0xc0016900, + 0x0000009b, + 0x20002000, + 0xc0026900, + 0x000000ba, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x0000009c, + 0x80000000, + 0xc0016900, + 0x0000009d, + 0x20002000, + 0xc0026900, + 0x000000bc, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x0000009e, + 0x80000000, + 0xc0016900, + 0x0000009f, + 0x20002000, + 0xc0026900, + 0x000000be, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000a0, + 0x80000000, + 0xc0016900, + 0x000000a1, + 0x20002000, + 0xc0026900, + 0x000000c0, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000a2, + 0x80000000, + 0xc0016900, + 0x000000a3, + 0x20002000, + 0xc0026900, + 0x000000c2, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000a4, + 0x80000000, + 0xc0016900, + 0x000000a5, + 0x20002000, + 0xc0026900, + 0x000000c4, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000a6, + 0x80000000, + 0xc0016900, + 0x000000a7, + 0x20002000, + 0xc0026900, + 0x000000c6, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000a8, + 0x80000000, + 0xc0016900, + 0x000000a9, + 0x20002000, + 0xc0026900, + 0x000000c8, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000aa, + 0x80000000, + 0xc0016900, + 0x000000ab, + 0x20002000, + 0xc0026900, + 0x000000ca, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000ac, + 0x80000000, + 0xc0016900, + 0x000000ad, + 0x20002000, + 0xc0026900, + 0x000000cc, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000ae, + 0x80000000, + 0xc0016900, + 0x000000af, + 0x20002000, + 0xc0026900, + 0x000000ce, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000b0, + 0x80000000, + 0xc0016900, + 0x000000b1, + 0x20002000, + 0xc0026900, + 0x000000d0, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000b2, + 0x80000000, + 0xc0016900, + 0x000000b3, + 0x20002000, + 0xc0026900, + 0x000000d2, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x00000293, + 0x00514000, + 0xc0016900, + 0x00000300, + 0x00000000, + 0xc0016900, + 0x00000301, + 0x00000000, + 0xc0016900, + 0x00000312, + 0xffffffff, + 0xc0016900, + 0x00000307, + 0x00000000, + 0xc0016900, + 0x00000308, + 0x00000000, + 0xc0016900, + 0x00000283, + 0x00000000, + 0xc0016900, + 0x00000292, + 0x00000000, + 0xc0066900, + 0x0000010f, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0016900, + 0x00000206, + 0x00000000, + 0xc0016900, + 0x00000207, + 0x00000000, + 0xc0016900, + 0x00000208, + 0x00000000, + 0xc0046900, + 0x00000303, + 0x3f800000, + 0x3f800000, + 0x3f800000, + 0x3f800000, + 0xc0016900, + 0x00000205, + 0x00000004, + 0xc0016900, + 0x00000280, + 0x00000000, + 0xc0016900, + 0x00000281, + 0x00000000, + 0xc0016900, + 0x0000037e, + 0x00000000, + 0xc0016900, + 0x00000382, + 0x00000000, + 0xc0016900, + 0x00000380, + 0x00000000, + 0xc0016900, + 0x00000383, + 0x00000000, + 0xc0016900, + 0x00000381, + 0x00000000, + 0xc0016900, + 0x00000282, + 0x00000008, + 0xc0016900, + 0x00000302, + 0x0000002d, + 0xc0016900, + 0x0000037f, + 0x00000000, + 0xc0016900, + 0x000001b2, + 0x00000001, + 0xc0016900, + 0x000001b6, + 0x00000000, + 0xc0016900, + 0x000001b7, + 0x00000000, + 0xc0016900, + 0x000001b8, + 0x00000000, + 0xc0016900, + 0x000001b9, + 0x00000000, + 0xc0016900, + 0x00000225, + 0x00000000, + 0xc0016900, + 0x00000229, + 0x00000000, + 0xc0016900, + 0x00000237, + 0x00000000, + 0xc0016900, + 0x00000100, + 0x00000800, + 0xc0016900, + 0x00000101, + 0x00000000, + 0xc0016900, + 0x00000102, + 0x00000000, + 0xc0016900, + 0x000002a8, + 0x00000000, + 0xc0016900, + 0x000002a9, + 0x00000000, + 0xc0016900, + 0x00000103, + 0x00000000, + 0xc0016900, + 0x00000284, + 0x00000000, + 0xc0016900, + 0x00000290, + 0x00000000, + 0xc0016900, + 0x00000285, + 0x00000000, + 0xc0016900, + 0x00000286, + 0x00000000, + 0xc0016900, + 0x00000287, + 0x00000000, + 0xc0016900, + 0x00000288, + 0x00000000, + 0xc0016900, + 0x00000289, + 0x00000000, + 0xc0016900, + 0x0000028a, + 0x00000000, + 0xc0016900, + 0x0000028b, + 0x00000000, + 0xc0016900, + 0x0000028c, + 0x00000000, + 0xc0016900, + 0x0000028d, + 0x00000000, + 0xc0016900, + 0x0000028e, + 0x00000000, + 0xc0016900, + 0x0000028f, + 0x00000000, + 0xc0016900, + 0x000002a1, + 0x00000000, + 0xc0016900, + 0x000002a5, + 0x00000000, + 0xc0016900, + 0x000002ac, + 0x00000000, + 0xc0016900, + 0x000002ad, + 0x00000000, + 0xc0016900, + 0x000002ae, + 0x00000000, + 0xc0016900, + 0x000002c8, + 0x00000000, + 0xc0016900, + 0x00000206, + 0x00000100, + 0xc0016900, + 0x00000204, + 0x00010000, + 0xc0036e00, + 0x00000000, + 0x00000012, + 0x00000000, + 0x00000000, + 0xc0016900, + 0x0000008f, + 0x0000000f, + 0xc0016900, + 0x000001e8, + 0x00000001, + 0xc0016900, + 0x00000202, + 0x00cc0000, + 0xc0016900, + 0x00000205, + 0x00000244, + 0xc0016900, + 0x00000203, + 0x00000210, + 0xc0016900, + 0x000001b1, + 0x00000000, + 0xc0016900, + 0x00000185, + 0x00000000, + 0xc0016900, + 0x000001b3, + 0x00000001, + 0xc0016900, + 0x000001b4, + 0x00000000, + 0xc0016900, + 0x00000191, + 0x00000b00, + 0xc0016900, + 0x000001b5, + 0x00000000, +}; + +/* same for r6xx/r7xx */ +static u32 r6xx_vs[] = +{ + 0x00000004, + 0x81000000, + 0x0000203c, + 0x94000b08, + 0x00004000, + 0x14200b1a, + 0x00000000, + 0x00000000, + 0x3c000000, + 0x68cd1000, + 0x00080000, + 0x00000000, +}; + +static u32 r6xx_ps[] = +{ + 0x00000002, + 0x80800000, + 0x00000000, + 0x94200688, + 0x00000010, + 0x000d1000, + 0xb0800000, + 0x00000000, +}; + +#define DI_PT_RECTLIST 0x11 +#define DI_INDEX_SIZE_16_BIT 0x0 +#define DI_SRC_SEL_AUTO_INDEX 0x2 + +#define FMT_8 1 +#define FMT_5_6_5 8 +#define FMT_8_8_8_8 0x1a +#define COLOR_8 1 +#define COLOR_5_6_5 8 +#define COLOR_8_8_8_8 0x1a + +#define R600_CB0_DEST_BASE_ENA (1 << 6) +#define R600_TC_ACTION_ENA (1 << 23) +#define R600_VC_ACTION_ENA (1 << 24) +#define R600_CB_ACTION_ENA (1 << 25) +#define R600_DB_ACTION_ENA (1 << 26) +#define R600_SH_ACTION_ENA (1 << 27) +#define R600_SMX_ACTION_ENA (1 << 28) + +#define R600_CB_COLOR0_SIZE 0x28060 +#define R600_CB_COLOR0_VIEW 0x28080 +#define R600_CB_COLOR0_INFO 0x280a0 +#define R600_CB_COLOR0_TILE 0x280c0 +#define R600_CB_COLOR0_FRAG 0x280e0 +#define R600_CB_COLOR0_MASK 0x28100 + +#define R600_SQ_PGM_START_VS 0x28858 +#define R600_SQ_PGM_RESOURCES_VS 0x28868 +#define R600_SQ_PGM_CF_OFFSET_VS 0x288d0 +#define R600_SQ_PGM_START_PS 0x28840 +#define R600_SQ_PGM_RESOURCES_PS 0x28850 +#define R600_SQ_PGM_EXPORTS_PS 0x28854 +#define R600_SQ_PGM_CF_OFFSET_PS 0x288cc + +#define R600_VGT_PRIMITIVE_TYPE 0x8958 + +#define R600_PA_SC_SCREEN_SCISSOR_TL 0x28030 +#define R600_PA_SC_GENERIC_SCISSOR_TL 0x28240 +#define R600_PA_SC_WINDOW_SCISSOR_TL 0x28204 + +#define R600_SQ_TEX_VTX_INVALID_TEXTURE 0x0 +#define R600_SQ_TEX_VTX_INVALID_BUFFER 0x1 +#define R600_SQ_TEX_VTX_VALID_TEXTURE 0x2 +#define R600_SQ_TEX_VTX_VALID_BUFFER 0x3 + +/* packet 3 type offsets */ +#define R600_SET_CONFIG_REG_OFFSET 0x00008000 +#define R600_SET_CONFIG_REG_END 0x0000ac00 +#define R600_SET_CONTEXT_REG_OFFSET 0x00028000 +#define R600_SET_CONTEXT_REG_END 0x00029000 +#define R600_SET_ALU_CONST_OFFSET 0x00030000 +#define R600_SET_ALU_CONST_END 0x00032000 +#define R600_SET_RESOURCE_OFFSET 0x00038000 +#define R600_SET_RESOURCE_END 0x0003c000 +#define R600_SET_SAMPLER_OFFSET 0x0003c000 +#define R600_SET_SAMPLER_END 0x0003cff0 +#define R600_SET_CTL_CONST_OFFSET 0x0003cff0 +#define R600_SET_CTL_CONST_END 0x0003e200 +#define R600_SET_LOOP_CONST_OFFSET 0x0003e200 +#define R600_SET_LOOP_CONST_END 0x0003e380 +#define R600_SET_BOOL_CONST_OFFSET 0x0003e380 +#define R600_SET_BOOL_CONST_END 0x00040000 + +/* Packet 3 types */ +#define R600_IT_INDIRECT_BUFFER_END 0x00001700 +#define R600_IT_SET_PREDICATION 0x00002000 +#define R600_IT_REG_RMW 0x00002100 +#define R600_IT_COND_EXEC 0x00002200 +#define R600_IT_PRED_EXEC 0x00002300 +#define R600_IT_START_3D_CMDBUF 0x00002400 +#define R600_IT_DRAW_INDEX_2 0x00002700 +#define R600_IT_CONTEXT_CONTROL 0x00002800 +#define R600_IT_DRAW_INDEX_IMMD_BE 0x00002900 +#define R600_IT_INDEX_TYPE 0x00002A00 +#define R600_IT_DRAW_INDEX 0x00002B00 +#define R600_IT_DRAW_INDEX_AUTO 0x00002D00 +#define R600_IT_DRAW_INDEX_IMMD 0x00002E00 +#define R600_IT_NUM_INSTANCES 0x00002F00 +#define R600_IT_STRMOUT_BUFFER_UPDATE 0x00003400 +#define R600_IT_INDIRECT_BUFFER_MP 0x00003800 +#define R600_IT_MEM_SEMAPHORE 0x00003900 +#define R600_IT_MPEG_INDEX 0x00003A00 +#define R600_IT_WAIT_REG_MEM 0x00003C00 +#define R600_IT_MEM_WRITE 0x00003D00 +#define R600_IT_INDIRECT_BUFFER 0x00003200 +#define R600_IT_CP_INTERRUPT 0x00004000 +#define R600_IT_SURFACE_SYNC 0x00004300 +#define R600_IT_ME_INITIALIZE 0x00004400 +#define R600_IT_COND_WRITE 0x00004500 +#define R600_IT_EVENT_WRITE 0x00004600 +#define R600_IT_EVENT_WRITE_EOP 0x00004700 +#define R600_IT_ONE_REG_WRITE 0x00005700 +#define R600_IT_SET_CONFIG_REG 0x00006800 +#define R600_IT_SET_CONTEXT_REG 0x00006900 +#define R600_IT_SET_ALU_CONST 0x00006A00 +#define R600_IT_SET_BOOL_CONST 0x00006B00 +#define R600_IT_SET_LOOP_CONST 0x00006C00 +#define R600_IT_SET_RESOURCE 0x00006D00 +#define R600_IT_SET_SAMPLER 0x00006E00 +#define R600_IT_SET_CTL_CONST 0x00006F00 +#define R600_IT_SURFACE_BASE_UPDATE 0x00007300 + +static inline void +set_render_target(drm_radeon_private_t *dev_priv, int format, int w, int h, u64 gpu_addr) +{ + u32 cb_color_info; + int pitch, slice; + RING_LOCALS; + DRM_DEBUG("\n"); + + h = (h + 7) & ~7; + if (h < 8) + h = 8; + + cb_color_info = ((format << 2) | (1 << 27)); + pitch = (w / 8) - 1; + slice = ((w * h) / 64) - 1; + + if (((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_R600) && + ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV770)) { + BEGIN_RING(21 + 2); + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_CB_COLOR0_BASE - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(gpu_addr >> 8); + OUT_RING(CP_PACKET3(R600_IT_SURFACE_BASE_UPDATE, 0)); + OUT_RING(2 << 0); + } else { + BEGIN_RING(21); + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_CB_COLOR0_BASE - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(gpu_addr >> 8); + } + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_CB_COLOR0_SIZE - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING((pitch << 0) | (slice << 10)); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_CB_COLOR0_VIEW - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(0); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_CB_COLOR0_INFO - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(cb_color_info); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_CB_COLOR0_TILE - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(0); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_CB_COLOR0_FRAG - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(0); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_CB_COLOR0_MASK - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(0); + + ADVANCE_RING(); +} + +static inline void +cp_set_surface_sync(drm_radeon_private_t *dev_priv, + u32 sync_type, u32 size, u64 mc_addr) +{ + u32 cp_coher_size; + RING_LOCALS; + DRM_DEBUG("\n"); + + if (size == 0xffffffff) + cp_coher_size = 0xffffffff; + else + cp_coher_size = ((size + 255) >> 8); + + BEGIN_RING(5); + OUT_RING(CP_PACKET3(R600_IT_SURFACE_SYNC, 3)); + OUT_RING(sync_type); + OUT_RING(cp_coher_size); + OUT_RING((mc_addr >> 8)); + OUT_RING(10); /* poll interval */ + ADVANCE_RING(); +} + +static inline void +set_shaders(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + u64 gpu_addr; + int shader_size, i; + u32 *vs, *ps; + uint32_t sq_pgm_resources; + RING_LOCALS; + DRM_DEBUG("\n"); + + /* load shaders */ + vs = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset); + ps = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset + 256); + + shader_size = sizeof(r6xx_vs) / 4; + for (i= 0; i < shader_size; i++) + vs[i] = r6xx_vs[i]; + shader_size = sizeof(r6xx_ps) / 4; + for (i= 0; i < shader_size; i++) + ps[i] = r6xx_ps[i]; + + dev_priv->blit_vb->used = 512; + + gpu_addr = dev_priv->gart_buffers_offset + dev_priv->blit_vb->offset; + + /* setup shader regs */ + sq_pgm_resources = (1 << 0); + + BEGIN_RING(9 + 12); + /* VS */ + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_SQ_PGM_START_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(gpu_addr >> 8); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_SQ_PGM_RESOURCES_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(sq_pgm_resources); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_SQ_PGM_CF_OFFSET_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(0); + + /* PS */ + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_SQ_PGM_START_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING((gpu_addr + 256) >> 8); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_SQ_PGM_RESOURCES_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(sq_pgm_resources | (1 << 28)); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_SQ_PGM_EXPORTS_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(2); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_SQ_PGM_CF_OFFSET_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(0); + ADVANCE_RING(); + + cp_set_surface_sync(dev_priv, + R600_SH_ACTION_ENA, 512, gpu_addr); +} + +static inline void +set_vtx_resource(drm_radeon_private_t *dev_priv, u64 gpu_addr) +{ + uint32_t sq_vtx_constant_word2; + RING_LOCALS; + DRM_DEBUG("\n"); + + sq_vtx_constant_word2 = (((gpu_addr >> 32) & 0xff) | (16 << 8)); + + BEGIN_RING(9); + OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7)); + OUT_RING(0x460); + OUT_RING(gpu_addr & 0xffffffff); + OUT_RING(48 - 1); + OUT_RING(sq_vtx_constant_word2); + OUT_RING(1 << 0); + OUT_RING(0); + OUT_RING(0); + OUT_RING(R600_SQ_TEX_VTX_VALID_BUFFER << 30); + ADVANCE_RING(); + + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || + /*((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880) ||*/ + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)) + cp_set_surface_sync(dev_priv, + R600_TC_ACTION_ENA, 48, gpu_addr); + else + cp_set_surface_sync(dev_priv, + R600_VC_ACTION_ENA, 48, gpu_addr); +} + +static inline void +set_tex_resource(drm_radeon_private_t *dev_priv, + int format, int w, int h, int pitch, u64 gpu_addr) +{ + uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4; + RING_LOCALS; + DRM_DEBUG("\n"); + + if (h < 1) + h = 1; + + sq_tex_resource_word0 = (1 << 0); + sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 8) | + ((w - 1) << 19)); + + sq_tex_resource_word1 = (format << 26); + sq_tex_resource_word1 |= ((h - 1) << 0); + + sq_tex_resource_word4 = ((1 << 14) | + (0 << 16) | + (1 << 19) | + (2 << 22) | + (3 << 25)); + + BEGIN_RING(9); + OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7)); + OUT_RING(0); + OUT_RING(sq_tex_resource_word0); + OUT_RING(sq_tex_resource_word1); + OUT_RING(gpu_addr >> 8); + OUT_RING(gpu_addr >> 8); + OUT_RING(sq_tex_resource_word4); + OUT_RING(0); + OUT_RING(R600_SQ_TEX_VTX_VALID_TEXTURE << 30); + ADVANCE_RING(); + +} + +static inline void +set_scissors(drm_radeon_private_t *dev_priv, int x1, int y1, int x2, int y2) +{ + RING_LOCALS; + DRM_DEBUG("\n"); + + BEGIN_RING(12); + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2)); + OUT_RING((R600_PA_SC_SCREEN_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING((x1 << 0) | (y1 << 16)); + OUT_RING((x2 << 0) | (y2 << 16)); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2)); + OUT_RING((R600_PA_SC_GENERIC_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING((x1 << 0) | (y1 << 16) | (1 << 31)); + OUT_RING((x2 << 0) | (y2 << 16)); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2)); + OUT_RING((R600_PA_SC_WINDOW_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING((x1 << 0) | (y1 << 16) | (1 << 31)); + OUT_RING((x2 << 0) | (y2 << 16)); + ADVANCE_RING(); +} + +static inline void +draw_auto(drm_radeon_private_t *dev_priv) +{ + RING_LOCALS; + DRM_DEBUG("\n"); + + BEGIN_RING(10); + OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); + OUT_RING((R600_VGT_PRIMITIVE_TYPE - R600_SET_CONFIG_REG_OFFSET) >> 2); + OUT_RING(DI_PT_RECTLIST); + + OUT_RING(CP_PACKET3(R600_IT_INDEX_TYPE, 0)); + OUT_RING(DI_INDEX_SIZE_16_BIT); + + OUT_RING(CP_PACKET3(R600_IT_NUM_INSTANCES, 0)); + OUT_RING(1); + + OUT_RING(CP_PACKET3(R600_IT_DRAW_INDEX_AUTO, 1)); + OUT_RING(3); + OUT_RING(DI_SRC_SEL_AUTO_INDEX); + + ADVANCE_RING(); + COMMIT_RING(); +} + +static inline void +set_default_state(drm_radeon_private_t *dev_priv) +{ + int default_state_dw, i; + u32 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2; + u32 sq_thread_resource_mgmt, sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2; + int num_ps_gprs, num_vs_gprs, num_temp_gprs, num_gs_gprs, num_es_gprs; + int num_ps_threads, num_vs_threads, num_gs_threads, num_es_threads; + int num_ps_stack_entries, num_vs_stack_entries, num_gs_stack_entries, num_es_stack_entries; + RING_LOCALS; + + switch ((dev_priv->flags & RADEON_FAMILY_MASK)) { + case CHIP_R600: + num_ps_gprs = 192; + num_vs_gprs = 56; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 136; + num_vs_threads = 48; + num_gs_threads = 4; + num_es_threads = 4; + num_ps_stack_entries = 128; + num_vs_stack_entries = 128; + num_gs_stack_entries = 0; + num_es_stack_entries = 0; + break; + case CHIP_RV630: + case CHIP_RV635: + num_ps_gprs = 84; + num_vs_gprs = 36; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 144; + num_vs_threads = 40; + num_gs_threads = 4; + num_es_threads = 4; + num_ps_stack_entries = 40; + num_vs_stack_entries = 40; + num_gs_stack_entries = 32; + num_es_stack_entries = 16; + break; + case CHIP_RV610: + case CHIP_RV620: + case CHIP_RS780: + /*case CHIP_RS880:*/ + default: + num_ps_gprs = 84; + num_vs_gprs = 36; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 136; + num_vs_threads = 48; + num_gs_threads = 4; + num_es_threads = 4; + num_ps_stack_entries = 40; + num_vs_stack_entries = 40; + num_gs_stack_entries = 32; + num_es_stack_entries = 16; + break; + case CHIP_RV670: + num_ps_gprs = 144; + num_vs_gprs = 40; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 136; + num_vs_threads = 48; + num_gs_threads = 4; + num_es_threads = 4; + num_ps_stack_entries = 40; + num_vs_stack_entries = 40; + num_gs_stack_entries = 32; + num_es_stack_entries = 16; + break; + case CHIP_RV770: + num_ps_gprs = 192; + num_vs_gprs = 56; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 188; + num_vs_threads = 60; + num_gs_threads = 0; + num_es_threads = 0; + num_ps_stack_entries = 256; + num_vs_stack_entries = 256; + num_gs_stack_entries = 0; + num_es_stack_entries = 0; + break; + case CHIP_RV730: + case CHIP_RV740: + num_ps_gprs = 84; + num_vs_gprs = 36; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 188; + num_vs_threads = 60; + num_gs_threads = 0; + num_es_threads = 0; + num_ps_stack_entries = 128; + num_vs_stack_entries = 128; + num_gs_stack_entries = 0; + num_es_stack_entries = 0; + break; + case CHIP_RV710: + num_ps_gprs = 192; + num_vs_gprs = 56; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 144; + num_vs_threads = 48; + num_gs_threads = 0; + num_es_threads = 0; + num_ps_stack_entries = 128; + num_vs_stack_entries = 128; + num_gs_stack_entries = 0; + num_es_stack_entries = 0; + break; + } + + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || + /*((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880) ||*/ + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)) + sq_config = 0; + else + sq_config = R600_VC_ENABLE; + + sq_config |= (R600_DX9_CONSTS | + R600_ALU_INST_PREFER_VECTOR | + R600_PS_PRIO(0) | + R600_VS_PRIO(1) | + R600_GS_PRIO(2) | + R600_ES_PRIO(3)); + + sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(num_ps_gprs) | + R600_NUM_VS_GPRS(num_vs_gprs) | + R600_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs)); + sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(num_gs_gprs) | + R600_NUM_ES_GPRS(num_es_gprs)); + sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(num_ps_threads) | + R600_NUM_VS_THREADS(num_vs_threads) | + R600_NUM_GS_THREADS(num_gs_threads) | + R600_NUM_ES_THREADS(num_es_threads)); + sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(num_ps_stack_entries) | + R600_NUM_VS_STACK_ENTRIES(num_vs_stack_entries)); + sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(num_gs_stack_entries) | + R600_NUM_ES_STACK_ENTRIES(num_es_stack_entries)); + + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) { + default_state_dw = sizeof(r7xx_default_state) / 4; + BEGIN_RING(default_state_dw + 10); + for (i = 0; i < default_state_dw; i++) + OUT_RING(r7xx_default_state[i]); + } else { + default_state_dw = sizeof(r6xx_default_state) / 4; + BEGIN_RING(default_state_dw + 10); + for (i = 0; i < default_state_dw; i++) + OUT_RING(r6xx_default_state[i]); + } + OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0)); + OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT); + /* SQ config */ + OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 6)); + OUT_RING((R600_SQ_CONFIG - R600_SET_CONFIG_REG_OFFSET) >> 2); + OUT_RING(sq_config); + OUT_RING(sq_gpr_resource_mgmt_1); + OUT_RING(sq_gpr_resource_mgmt_2); + OUT_RING(sq_thread_resource_mgmt); + OUT_RING(sq_stack_resource_mgmt_1); + OUT_RING(sq_stack_resource_mgmt_2); + ADVANCE_RING(); +} + +static inline uint32_t i2f(uint32_t input) +{ + u32 result, i, exponent, fraction; + + if ((input & 0x3fff) == 0) + result = 0; /* 0 is a special case */ + else { + exponent = 140; /* exponent biased by 127; */ + fraction = (input & 0x3fff) << 10; /* cheat and only + handle numbers below 2^^15 */ + for (i = 0; i < 14; i++) { + if (fraction & 0x800000) + break; + else { + fraction = fraction << 1; /* keep + shifting left until top bit = 1 */ + exponent = exponent -1; + } + } + result = exponent << 23 | (fraction & 0x7fffff); /* mask + off top bit; assumed 1 */ + } + return result; +} + +int +r600_prepare_blit_copy(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG("\n"); + + dev_priv->blit_vb = radeon_freelist_get(dev); + if (!dev_priv->blit_vb) { + DRM_ERROR("Unable to allocate vertex buffer for blit\n"); + return -EAGAIN; + } + + set_default_state(dev_priv); + set_shaders(dev); + + return 0; +} + +void +r600_done_blit_copy(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + DRM_DEBUG("\n"); + + BEGIN_RING(5); + OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0)); + OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT); + /* wait for 3D idle clean */ + OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); + OUT_RING((R600_WAIT_UNTIL - R600_SET_CONFIG_REG_OFFSET) >> 2); + OUT_RING(RADEON_WAIT_3D_IDLE | RADEON_WAIT_3D_IDLECLEAN); + + ADVANCE_RING(); + COMMIT_RING(); + + dev_priv->blit_vb->used = 0; + radeon_cp_discard_buffer(dev, dev_priv->blit_vb); +} + +void +r600_blit_copy(struct drm_device *dev, + uint64_t src_gpu_addr, uint64_t dst_gpu_addr, + int size_bytes) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + int max_bytes; + u64 vb_addr; + u32 *vb; + + vb = (u32 *) ((char *)dev->agp_buffer_map->handle + + dev_priv->blit_vb->offset + dev_priv->blit_vb->used); + + if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) { + max_bytes = 8192; + + while (size_bytes) { + int cur_size = size_bytes; + int src_x = src_gpu_addr & 255; + int dst_x = dst_gpu_addr & 255; + int h = 1; + src_gpu_addr = src_gpu_addr & ~255; + dst_gpu_addr = dst_gpu_addr & ~255; + + if (!src_x && !dst_x) { + h = (cur_size / max_bytes); + if (h > 8192) + h = 8192; + if (h == 0) + h = 1; + else + cur_size = max_bytes; + } else { + if (cur_size > max_bytes) + cur_size = max_bytes; + if (cur_size > (max_bytes - dst_x)) + cur_size = (max_bytes - dst_x); + if (cur_size > (max_bytes - src_x)) + cur_size = (max_bytes - src_x); + } + + if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) { + dev_priv->blit_vb->used = 0; + radeon_cp_discard_buffer(dev, dev_priv->blit_vb); + dev_priv->blit_vb = radeon_freelist_get(dev); + if (!dev_priv->blit_vb) + return; + set_shaders(dev); + vb = (u32 *) ((char *)dev->agp_buffer_map->handle + + dev_priv->blit_vb->offset + dev_priv->blit_vb->used); + } + + vb[0] = i2f(dst_x); + vb[1] = 0; + vb[2] = i2f(src_x); + vb[3] = 0; + + vb[4] = i2f(dst_x); + vb[5] = i2f(h); + vb[6] = i2f(src_x); + vb[7] = i2f(h); + + vb[8] = i2f(dst_x + cur_size); + vb[9] = i2f(h); + vb[10] = i2f(src_x + cur_size); + vb[11] = i2f(h); + + /* src */ + set_tex_resource(dev_priv, FMT_8, + src_x + cur_size, h, src_x + cur_size, + src_gpu_addr); + + cp_set_surface_sync(dev_priv, + R600_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr); + + /* dst */ + set_render_target(dev_priv, COLOR_8, + dst_x + cur_size, h, + dst_gpu_addr); + + /* scissors */ + set_scissors(dev_priv, dst_x, 0, dst_x + cur_size, h); + + /* Vertex buffer setup */ + vb_addr = dev_priv->gart_buffers_offset + + dev_priv->blit_vb->offset + + dev_priv->blit_vb->used; + set_vtx_resource(dev_priv, vb_addr); + + /* draw */ + draw_auto(dev_priv); + + cp_set_surface_sync(dev_priv, + R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA, + cur_size * h, dst_gpu_addr); + + vb += 12; + dev_priv->blit_vb->used += 12 * 4; + + src_gpu_addr += cur_size * h; + dst_gpu_addr += cur_size * h; + size_bytes -= cur_size * h; + } + } else { + max_bytes = 8192 * 4; + + while (size_bytes) { + int cur_size = size_bytes; + int src_x = (src_gpu_addr & 255); + int dst_x = (dst_gpu_addr & 255); + int h = 1; + src_gpu_addr = src_gpu_addr & ~255; + dst_gpu_addr = dst_gpu_addr & ~255; + + if (!src_x && !dst_x) { + h = (cur_size / max_bytes); + if (h > 8192) + h = 8192; + if (h == 0) + h = 1; + else + cur_size = max_bytes; + } else { + if (cur_size > max_bytes) + cur_size = max_bytes; + if (cur_size > (max_bytes - dst_x)) + cur_size = (max_bytes - dst_x); + if (cur_size > (max_bytes - src_x)) + cur_size = (max_bytes - src_x); + } + + if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) { + dev_priv->blit_vb->used = 0; + radeon_cp_discard_buffer(dev, dev_priv->blit_vb); + dev_priv->blit_vb = radeon_freelist_get(dev); + if (!dev_priv->blit_vb) + return; + set_shaders(dev); + vb = (u32 *) ((char *)dev->agp_buffer_map->handle + + dev_priv->blit_vb->offset + dev_priv->blit_vb->used); + } + + vb[0] = i2f(dst_x / 4); + vb[1] = 0; + vb[2] = i2f(src_x / 4); + vb[3] = 0; + + vb[4] = i2f(dst_x / 4); + vb[5] = i2f(h); + vb[6] = i2f(src_x / 4); + vb[7] = i2f(h); + + vb[8] = i2f((dst_x + cur_size) / 4); + vb[9] = i2f(h); + vb[10] = i2f((src_x + cur_size) / 4); + vb[11] = i2f(h); + + /* src */ + set_tex_resource(dev_priv, FMT_8_8_8_8, + (src_x + cur_size) / 4, + h, (src_x + cur_size) / 4, + src_gpu_addr); + + cp_set_surface_sync(dev_priv, + R600_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr); + + /* dst */ + set_render_target(dev_priv, COLOR_8_8_8_8, + (dst_x + cur_size) / 4, h, + dst_gpu_addr); + + /* scissors */ + set_scissors(dev_priv, (dst_x / 4), 0, (dst_x + cur_size / 4), h); + + /* Vertex buffer setup */ + vb_addr = dev_priv->gart_buffers_offset + + dev_priv->blit_vb->offset + + dev_priv->blit_vb->used; + set_vtx_resource(dev_priv, vb_addr); + + /* draw */ + draw_auto(dev_priv); + + cp_set_surface_sync(dev_priv, + R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA, + cur_size * h, dst_gpu_addr); + + vb += 12; + dev_priv->blit_vb->used += 12 * 4; + + src_gpu_addr += cur_size * h; + dst_gpu_addr += cur_size * h; + size_bytes -= cur_size * h; + } + } +} + +void +r600_blit_swap(struct drm_device *dev, + uint64_t src_gpu_addr, uint64_t dst_gpu_addr, + int sx, int sy, int dx, int dy, + int w, int h, int src_pitch, int dst_pitch, int cpp) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + int cb_format, tex_format; + u64 vb_addr; + u32 *vb; + + vb = (u32 *) ((char *)dev->agp_buffer_map->handle + + dev_priv->blit_vb->offset + dev_priv->blit_vb->used); + + if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) { + dev_priv->blit_vb->used = 0; + radeon_cp_discard_buffer(dev, dev_priv->blit_vb); + dev_priv->blit_vb = radeon_freelist_get(dev); + if (!dev_priv->blit_vb) + return; + set_shaders(dev); + vb = (u32 *) ((char *)dev->agp_buffer_map->handle + + dev_priv->blit_vb->offset + dev_priv->blit_vb->used); + } + + if (cpp == 4) { + cb_format = COLOR_8_8_8_8; + tex_format = FMT_8_8_8_8; + } else if (cpp == 2) { + cb_format = COLOR_5_6_5; + tex_format = FMT_5_6_5; + } else { + cb_format = COLOR_8; + tex_format = FMT_8; + } + + vb[0] = i2f(dx); + vb[1] = i2f(dy); + vb[2] = i2f(sx); + vb[3] = i2f(sy); + + vb[4] = i2f(dx); + vb[5] = i2f(dy + h); + vb[6] = i2f(sx); + vb[7] = i2f(sy + h); + + vb[8] = i2f(dx + w); + vb[9] = i2f(dy + h); + vb[10] = i2f(sx + w); + vb[11] = i2f(sy + h); + + /* src */ + set_tex_resource(dev_priv, tex_format, + src_pitch / cpp, + sy + h, src_pitch / cpp, + src_gpu_addr); + + cp_set_surface_sync(dev_priv, + R600_TC_ACTION_ENA, (src_pitch * (sy + h)), src_gpu_addr); + + /* dst */ + set_render_target(dev_priv, cb_format, + dst_pitch / cpp, dy + h, + dst_gpu_addr); + + /* scissors */ + set_scissors(dev_priv, dx, dy, dx + w, dy + h); + + /* Vertex buffer setup */ + vb_addr = dev_priv->gart_buffers_offset + + dev_priv->blit_vb->offset + + dev_priv->blit_vb->used; + set_vtx_resource(dev_priv, vb_addr); + + /* draw */ + draw_auto(dev_priv); + + cp_set_surface_sync(dev_priv, + R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA, + dst_pitch * (dy + h), dst_gpu_addr); + + dev_priv->blit_vb->used += 12 * 4; +} diff --git a/sys/dev/drm/radeon_cs.c b/sys/dev/drm/radeon_cs.c new file mode 100644 index 00000000000..b523126b947 --- /dev/null +++ b/sys/dev/drm/radeon_cs.c @@ -0,0 +1,856 @@ +/*- + * Copyright 2008 Jerome Glisse. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Jerome Glisse + */ + +#include +__FBSDID("$FreeBSD$"); +#include "dev/drm/drmP.h" +#include "dev/drm/radeon_drm.h" +#include "dev/drm/radeon_drv.h" + +/* regs */ +#define AVIVO_D1MODE_VLINE_START_END 0x6538 +#define AVIVO_D2MODE_VLINE_START_END 0x6d38 +#define R600_CP_COHER_BASE 0x85f8 +#define R600_DB_DEPTH_BASE 0x2800c +#define R600_CB_COLOR0_BASE 0x28040 +#define R600_CB_COLOR1_BASE 0x28044 +#define R600_CB_COLOR2_BASE 0x28048 +#define R600_CB_COLOR3_BASE 0x2804c +#define R600_CB_COLOR4_BASE 0x28050 +#define R600_CB_COLOR5_BASE 0x28054 +#define R600_CB_COLOR6_BASE 0x28058 +#define R600_CB_COLOR7_BASE 0x2805c +#define R600_SQ_PGM_START_FS 0x28894 +#define R600_SQ_PGM_START_ES 0x28880 +#define R600_SQ_PGM_START_VS 0x28858 +#define R600_SQ_PGM_START_GS 0x2886c +#define R600_SQ_PGM_START_PS 0x28840 +#define R600_VGT_DMA_BASE 0x287e8 +#define R600_VGT_DMA_BASE_HI 0x287e4 +#define R600_VGT_STRMOUT_BASE_OFFSET_0 0x28b10 +#define R600_VGT_STRMOUT_BASE_OFFSET_1 0x28b14 +#define R600_VGT_STRMOUT_BASE_OFFSET_2 0x28b18 +#define R600_VGT_STRMOUT_BASE_OFFSET_3 0x28b1c +#define R600_VGT_STRMOUT_BASE_OFFSET_HI_0 0x28b44 +#define R600_VGT_STRMOUT_BASE_OFFSET_HI_1 0x28b48 +#define R600_VGT_STRMOUT_BASE_OFFSET_HI_2 0x28b4c +#define R600_VGT_STRMOUT_BASE_OFFSET_HI_3 0x28b50 +#define R600_VGT_STRMOUT_BUFFER_BASE_0 0x28ad8 +#define R600_VGT_STRMOUT_BUFFER_BASE_1 0x28ae8 +#define R600_VGT_STRMOUT_BUFFER_BASE_2 0x28af8 +#define R600_VGT_STRMOUT_BUFFER_BASE_3 0x28b08 +#define R600_VGT_STRMOUT_BUFFER_OFFSET_0 0x28adc +#define R600_VGT_STRMOUT_BUFFER_OFFSET_1 0x28aec +#define R600_VGT_STRMOUT_BUFFER_OFFSET_2 0x28afc +#define R600_VGT_STRMOUT_BUFFER_OFFSET_3 0x28b0c + +/* resource type */ +#define R600_SQ_TEX_VTX_INVALID_TEXTURE 0x0 +#define R600_SQ_TEX_VTX_INVALID_BUFFER 0x1 +#define R600_SQ_TEX_VTX_VALID_TEXTURE 0x2 +#define R600_SQ_TEX_VTX_VALID_BUFFER 0x3 + +/* packet 3 type offsets */ +#define R600_SET_CONFIG_REG_OFFSET 0x00008000 +#define R600_SET_CONFIG_REG_END 0x0000ac00 +#define R600_SET_CONTEXT_REG_OFFSET 0x00028000 +#define R600_SET_CONTEXT_REG_END 0x00029000 +#define R600_SET_ALU_CONST_OFFSET 0x00030000 +#define R600_SET_ALU_CONST_END 0x00032000 +#define R600_SET_RESOURCE_OFFSET 0x00038000 +#define R600_SET_RESOURCE_END 0x0003c000 +#define R600_SET_SAMPLER_OFFSET 0x0003c000 +#define R600_SET_SAMPLER_END 0x0003cff0 +#define R600_SET_CTL_CONST_OFFSET 0x0003cff0 +#define R600_SET_CTL_CONST_END 0x0003e200 +#define R600_SET_LOOP_CONST_OFFSET 0x0003e200 +#define R600_SET_LOOP_CONST_END 0x0003e380 +#define R600_SET_BOOL_CONST_OFFSET 0x0003e380 +#define R600_SET_BOOL_CONST_END 0x00040000 + +/* Packet 3 types */ +#define R600_IT_INDIRECT_BUFFER_END 0x00001700 +#define R600_IT_SET_PREDICATION 0x00002000 +#define R600_IT_REG_RMW 0x00002100 +#define R600_IT_COND_EXEC 0x00002200 +#define R600_IT_PRED_EXEC 0x00002300 +#define R600_IT_START_3D_CMDBUF 0x00002400 +#define R600_IT_DRAW_INDEX_2 0x00002700 +#define R600_IT_CONTEXT_CONTROL 0x00002800 +#define R600_IT_DRAW_INDEX_IMMD_BE 0x00002900 +#define R600_IT_INDEX_TYPE 0x00002A00 +#define R600_IT_DRAW_INDEX 0x00002B00 +#define R600_IT_DRAW_INDEX_AUTO 0x00002D00 +#define R600_IT_DRAW_INDEX_IMMD 0x00002E00 +#define R600_IT_NUM_INSTANCES 0x00002F00 +#define R600_IT_STRMOUT_BUFFER_UPDATE 0x00003400 +#define R600_IT_INDIRECT_BUFFER_MP 0x00003800 +#define R600_IT_MEM_SEMAPHORE 0x00003900 +#define R600_IT_MPEG_INDEX 0x00003A00 +#define R600_IT_WAIT_REG_MEM 0x00003C00 +#define R600_IT_MEM_WRITE 0x00003D00 +#define R600_IT_INDIRECT_BUFFER 0x00003200 +#define R600_IT_CP_INTERRUPT 0x00004000 +#define R600_IT_SURFACE_SYNC 0x00004300 +#define R600_IT_ME_INITIALIZE 0x00004400 +#define R600_IT_COND_WRITE 0x00004500 +#define R600_IT_EVENT_WRITE 0x00004600 +#define R600_IT_EVENT_WRITE_EOP 0x00004700 +#define R600_IT_ONE_REG_WRITE 0x00005700 +#define R600_IT_SET_CONFIG_REG 0x00006800 +#define R600_IT_SET_CONTEXT_REG 0x00006900 +#define R600_IT_SET_ALU_CONST 0x00006A00 +#define R600_IT_SET_BOOL_CONST 0x00006B00 +#define R600_IT_SET_LOOP_CONST 0x00006C00 +#define R600_IT_SET_RESOURCE 0x00006D00 +#define R600_IT_SET_SAMPLER 0x00006E00 +#define R600_IT_SET_CTL_CONST 0x00006F00 +#define R600_IT_SURFACE_BASE_UPDATE 0x00007300 + +int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) +{ + struct drm_radeon_cs_parser parser; + struct drm_radeon_private *dev_priv = dev->dev_private; + struct drm_radeon_cs *cs = data; + uint32_t cs_id; + struct drm_radeon_cs_chunk __user **chunk_ptr = NULL; + uint64_t *chunk_array; + uint64_t *chunk_array_ptr; + long size; + int r, i; + + mtx_lock(&dev_priv->cs.cs_mutex); + /* set command stream id to 0 which is fake id */ + cs_id = 0; + cs->cs_id = cs_id; + + if (dev_priv == NULL) { + DRM_ERROR("called with no initialization\n"); + mtx_unlock(&dev_priv->cs.cs_mutex); + return -EINVAL; + } + if (!cs->num_chunks) { + mtx_unlock(&dev_priv->cs.cs_mutex); + return 0; + } + + + chunk_array = drm_calloc(cs->num_chunks, sizeof(uint64_t), DRM_MEM_DRIVER); + if (!chunk_array) { + mtx_unlock(&dev_priv->cs.cs_mutex); + return -ENOMEM; + } + + chunk_array_ptr = (uint64_t *)(unsigned long)(cs->chunks); + + if (DRM_COPY_FROM_USER(chunk_array, chunk_array_ptr, sizeof(uint64_t)*cs->num_chunks)) { + r = -EFAULT; + goto out; + } + + parser.dev = dev; + parser.file_priv = fpriv; + parser.reloc_index = -1; + parser.ib_index = -1; + parser.num_chunks = cs->num_chunks; + /* copy out the chunk headers */ + parser.chunks = drm_calloc(parser.num_chunks, sizeof(struct drm_radeon_kernel_chunk), DRM_MEM_DRIVER); + if (!parser.chunks) { + r = -ENOMEM; + goto out; + } + + for (i = 0; i < parser.num_chunks; i++) { + struct drm_radeon_cs_chunk user_chunk; + + chunk_ptr = (void __user *)(unsigned long)chunk_array[i]; + + if (DRM_COPY_FROM_USER(&user_chunk, chunk_ptr, sizeof(struct drm_radeon_cs_chunk))){ + r = -EFAULT; + goto out; + } + parser.chunks[i].chunk_id = user_chunk.chunk_id; + + if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS) + parser.reloc_index = i; + + if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_IB) + parser.ib_index = i; + + if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_OLD) { + parser.ib_index = i; + parser.reloc_index = -1; + } + + parser.chunks[i].length_dw = user_chunk.length_dw; + parser.chunks[i].chunk_data = (uint32_t *)(unsigned long)user_chunk.chunk_data; + + parser.chunks[i].kdata = NULL; + size = parser.chunks[i].length_dw * sizeof(uint32_t); + + switch(parser.chunks[i].chunk_id) { + case RADEON_CHUNK_ID_IB: + case RADEON_CHUNK_ID_OLD: + if (size == 0) { + r = -EINVAL; + goto out; + } + case RADEON_CHUNK_ID_RELOCS: + if (size) { + parser.chunks[i].kdata = drm_alloc(size, DRM_MEM_DRIVER); + if (!parser.chunks[i].kdata) { + r = -ENOMEM; + goto out; + } + + if (DRM_COPY_FROM_USER(parser.chunks[i].kdata, parser.chunks[i].chunk_data, size)) { + r = -EFAULT; + goto out; + } + } else + parser.chunks[i].kdata = NULL; + break; + default: + break; + } + DRM_DEBUG("chunk %d %d %d %p\n", i, parser.chunks[i].chunk_id, parser.chunks[i].length_dw, + parser.chunks[i].chunk_data); + } + + if (parser.chunks[parser.ib_index].length_dw > (16 * 1024)) { + DRM_ERROR("cs->dwords too big: %d\n", parser.chunks[parser.ib_index].length_dw); + r = -EINVAL; + goto out; + } + + /* get ib */ + r = dev_priv->cs.ib_get(&parser); + if (r) { + DRM_ERROR("ib_get failed\n"); + goto out; + } + + /* now parse command stream */ + r = dev_priv->cs.parse(&parser); + if (r) { + goto out; + } + +out: + dev_priv->cs.ib_free(&parser, r); + + /* emit cs id sequence */ + dev_priv->cs.id_emit(&parser, &cs_id); + + cs->cs_id = cs_id; + + mtx_unlock(&dev_priv->cs.cs_mutex); + + for (i = 0; i < parser.num_chunks; i++) { + if (parser.chunks[i].kdata) + drm_free(parser.chunks[i].kdata, parser.chunks[i].length_dw * sizeof(uint32_t), DRM_MEM_DRIVER); + } + + drm_free(parser.chunks, sizeof(struct drm_radeon_kernel_chunk)*parser.num_chunks, DRM_MEM_DRIVER); + drm_free(chunk_array, sizeof(uint64_t)*parser.num_chunks, DRM_MEM_DRIVER); + + return r; +} + +/* for non-mm */ +static int r600_nomm_relocate(struct drm_radeon_cs_parser *parser, uint32_t *reloc, uint64_t *offset) +{ + struct drm_device *dev = parser->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_radeon_kernel_chunk *reloc_chunk = &parser->chunks[parser->reloc_index]; + uint32_t offset_dw = reloc[1]; + + //DRM_INFO("reloc: 0x%08x 0x%08x\n", reloc[0], reloc[1]); + //DRM_INFO("length: %d\n", reloc_chunk->length_dw); + + if (!reloc_chunk->kdata) + return -EINVAL; + + if (offset_dw > reloc_chunk->length_dw) { + DRM_ERROR("Offset larger than chunk 0x%x %d\n", offset_dw, reloc_chunk->length_dw); + return -EINVAL; + } + + /* 40 bit addr */ + *offset = reloc_chunk->kdata[offset_dw + 3]; + *offset <<= 32; + *offset |= reloc_chunk->kdata[offset_dw + 0]; + + //DRM_INFO("offset 0x%lx\n", *offset); + + if (!radeon_check_offset(dev_priv, *offset)) { + DRM_ERROR("bad offset! 0x%lx\n", (unsigned long)*offset); + return -EINVAL; + } + + return 0; +} + +static inline int r600_cs_packet0(struct drm_radeon_cs_parser *parser, uint32_t *offset_dw_p) +{ + uint32_t hdr, num_dw, reg; + int count_dw = 1; + int ret = 0; + uint32_t offset_dw = *offset_dw_p; + int incr = 2; + + hdr = parser->chunks[parser->ib_index].kdata[offset_dw]; + num_dw = ((hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2; + reg = (hdr & 0xffff) << 2; + + while (count_dw < num_dw) { + switch (reg) { + case AVIVO_D1MODE_VLINE_START_END: + case AVIVO_D2MODE_VLINE_START_END: + break; + default: + ret = -EINVAL; + DRM_ERROR("bad packet 0 reg: 0x%08x\n", reg); + break; + } + if (ret) + break; + count_dw++; + reg += 4; + } + *offset_dw_p += incr; + return ret; +} + +static inline int r600_cs_packet3(struct drm_radeon_cs_parser *parser, uint32_t *offset_dw_p) +{ + struct drm_device *dev = parser->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + uint32_t hdr, num_dw, start_reg, end_reg, reg; + uint32_t *reloc; + uint64_t offset; + int ret = 0; + uint32_t offset_dw = *offset_dw_p; + int incr = 2; + int i; + struct drm_radeon_kernel_chunk *ib_chunk; + + ib_chunk = &parser->chunks[parser->ib_index]; + + hdr = ib_chunk->kdata[offset_dw]; + num_dw = ((hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2; + + /* just the ones we use for now, add more later */ + switch (hdr & 0xff00) { + case R600_IT_START_3D_CMDBUF: + //DRM_INFO("R600_IT_START_3D_CMDBUF\n"); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) + ret = -EINVAL; + if (num_dw != 2) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad START_3D\n"); + break; + case R600_IT_CONTEXT_CONTROL: + //DRM_INFO("R600_IT_CONTEXT_CONTROL\n"); + if (num_dw != 3) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad CONTEXT_CONTROL\n"); + break; + case R600_IT_INDEX_TYPE: + case R600_IT_NUM_INSTANCES: + //DRM_INFO("R600_IT_INDEX_TYPE/R600_IT_NUM_INSTANCES\n"); + if (num_dw != 2) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES\n"); + break; + case R600_IT_DRAW_INDEX: + //DRM_INFO("R600_IT_DRAW_INDEX\n"); + if (num_dw != 5) { + ret = -EINVAL; + DRM_ERROR("bad DRAW_INDEX\n"); + break; + } + reloc = ib_chunk->kdata + offset_dw + num_dw; + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) { + DRM_ERROR("bad DRAW_INDEX\n"); + break; + } + ib_chunk->kdata[offset_dw + 1] += (offset & 0xffffffff); + ib_chunk->kdata[offset_dw + 2] += (upper_32_bits(offset) & 0xff); + break; + case R600_IT_DRAW_INDEX_AUTO: + //DRM_INFO("R600_IT_DRAW_INDEX_AUTO\n"); + if (num_dw != 3) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad DRAW_INDEX_AUTO\n"); + break; + case R600_IT_DRAW_INDEX_IMMD_BE: + case R600_IT_DRAW_INDEX_IMMD: + //DRM_INFO("R600_IT_DRAW_INDEX_IMMD\n"); + if (num_dw < 4) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad DRAW_INDEX_IMMD\n"); + break; + case R600_IT_WAIT_REG_MEM: + //DRM_INFO("R600_IT_WAIT_REG_MEM\n"); + if (num_dw != 7) + ret = -EINVAL; + /* bit 4 is reg (0) or mem (1) */ + if (ib_chunk->kdata[offset_dw + 1] & 0x10) { + reloc = ib_chunk->kdata + offset_dw + num_dw; + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) { + DRM_ERROR("bad WAIT_REG_MEM\n"); + break; + } + ib_chunk->kdata[offset_dw + 2] += (offset & 0xffffffff); + ib_chunk->kdata[offset_dw + 3] += (upper_32_bits(offset) & 0xff); + } + if (ret) + DRM_ERROR("bad WAIT_REG_MEM\n"); + break; + case R600_IT_SURFACE_SYNC: + //DRM_INFO("R600_IT_SURFACE_SYNC\n"); + if (num_dw != 5) + ret = -EINVAL; + /* 0xffffffff/0x0 is flush all cache flag */ + else if ((ib_chunk->kdata[offset_dw + 2] == 0xffffffff) && + (ib_chunk->kdata[offset_dw + 3] == 0)) + ret = 0; + else { + reloc = ib_chunk->kdata + offset_dw + num_dw; + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) { + DRM_ERROR("bad SURFACE_SYNC\n"); + break; + } + ib_chunk->kdata[offset_dw + 3] += ((offset >> 8) & 0xffffffff); + } + break; + case R600_IT_EVENT_WRITE: + //DRM_INFO("R600_IT_EVENT_WRITE\n"); + if ((num_dw != 4) && (num_dw != 2)) + ret = -EINVAL; + if (num_dw > 2) { + reloc = ib_chunk->kdata + offset_dw + num_dw; + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) { + DRM_ERROR("bad EVENT_WRITE\n"); + break; + } + ib_chunk->kdata[offset_dw + 2] += (offset & 0xffffffff); + ib_chunk->kdata[offset_dw + 3] += (upper_32_bits(offset) & 0xff); + } + if (ret) + DRM_ERROR("bad EVENT_WRITE\n"); + break; + case R600_IT_EVENT_WRITE_EOP: + //DRM_INFO("R600_IT_EVENT_WRITE_EOP\n"); + if (num_dw != 6) { + ret = -EINVAL; + DRM_ERROR("bad EVENT_WRITE_EOP\n"); + break; + } + reloc = ib_chunk->kdata + offset_dw + num_dw; + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) { + DRM_ERROR("bad EVENT_WRITE_EOP\n"); + break; + } + ib_chunk->kdata[offset_dw + 2] += (offset & 0xffffffff); + ib_chunk->kdata[offset_dw + 3] += (upper_32_bits(offset) & 0xff); + break; + case R600_IT_SET_CONFIG_REG: + //DRM_INFO("R600_IT_SET_CONFIG_REG\n"); + start_reg = (ib_chunk->kdata[offset_dw + 1] << 2) + R600_SET_CONFIG_REG_OFFSET; + end_reg = 4 * (num_dw - 2) + start_reg - 4; + if ((start_reg < R600_SET_CONFIG_REG_OFFSET) || + (start_reg >= R600_SET_CONFIG_REG_END) || + (end_reg >= R600_SET_CONFIG_REG_END)) + ret = -EINVAL; + else { + for (i = 0; i < (num_dw - 2); i++) { + reg = start_reg + (4 * i); + switch (reg) { + case R600_CP_COHER_BASE: + /* use R600_IT_SURFACE_SYNC */ + ret = -EINVAL; + break; + default: + break; + } + if (ret) + break; + } + } + if (ret) + DRM_ERROR("bad SET_CONFIG_REG\n"); + break; + case R600_IT_SET_CONTEXT_REG: + //DRM_INFO("R600_IT_SET_CONTEXT_REG\n"); + start_reg = ib_chunk->kdata[offset_dw + 1] << 2; + start_reg += R600_SET_CONTEXT_REG_OFFSET; + end_reg = 4 * (num_dw - 2) + start_reg - 4; + if ((start_reg < R600_SET_CONTEXT_REG_OFFSET) || + (start_reg >= R600_SET_CONTEXT_REG_END) || + (end_reg >= R600_SET_CONTEXT_REG_END)) + ret = -EINVAL; + else { + for (i = 0; i < (num_dw - 2); i++) { + reg = start_reg + (4 * i); + switch (reg) { + case R600_DB_DEPTH_BASE: + case R600_CB_COLOR0_BASE: + case R600_CB_COLOR1_BASE: + case R600_CB_COLOR2_BASE: + case R600_CB_COLOR3_BASE: + case R600_CB_COLOR4_BASE: + case R600_CB_COLOR5_BASE: + case R600_CB_COLOR6_BASE: + case R600_CB_COLOR7_BASE: + case R600_SQ_PGM_START_FS: + case R600_SQ_PGM_START_ES: + case R600_SQ_PGM_START_VS: + case R600_SQ_PGM_START_GS: + case R600_SQ_PGM_START_PS: + //DRM_INFO("reg: 0x%08x\n", reg); + reloc = ib_chunk->kdata + offset_dw + num_dw + (i * 2); + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) { + DRM_ERROR("bad SET_CONTEXT_REG\n"); + break; + } + ib_chunk->kdata[offset_dw + 2 + i] += + ((offset >> 8) & 0xffffffff); + break; + case R600_VGT_DMA_BASE: + case R600_VGT_DMA_BASE_HI: + /* These should be handled by DRAW_INDEX packet 3 */ + case R600_VGT_STRMOUT_BASE_OFFSET_0: + case R600_VGT_STRMOUT_BASE_OFFSET_1: + case R600_VGT_STRMOUT_BASE_OFFSET_2: + case R600_VGT_STRMOUT_BASE_OFFSET_3: + case R600_VGT_STRMOUT_BASE_OFFSET_HI_0: + case R600_VGT_STRMOUT_BASE_OFFSET_HI_1: + case R600_VGT_STRMOUT_BASE_OFFSET_HI_2: + case R600_VGT_STRMOUT_BASE_OFFSET_HI_3: + case R600_VGT_STRMOUT_BUFFER_BASE_0: + case R600_VGT_STRMOUT_BUFFER_BASE_1: + case R600_VGT_STRMOUT_BUFFER_BASE_2: + case R600_VGT_STRMOUT_BUFFER_BASE_3: + case R600_VGT_STRMOUT_BUFFER_OFFSET_0: + case R600_VGT_STRMOUT_BUFFER_OFFSET_1: + case R600_VGT_STRMOUT_BUFFER_OFFSET_2: + case R600_VGT_STRMOUT_BUFFER_OFFSET_3: + /* These should be handled by STRMOUT_BUFFER packet 3 */ + DRM_ERROR("bad context reg: 0x%08x\n", reg); + ret = -EINVAL; + break; + default: + break; + } + if (ret) + break; + } + } + if (ret) + DRM_ERROR("bad SET_CONTEXT_REG\n"); + break; + case R600_IT_SET_RESOURCE: + //DRM_INFO("R600_IT_SET_RESOURCE\n"); + if ((num_dw - 2) % 7) + ret = -EINVAL; + start_reg = ib_chunk->kdata[offset_dw + 1] << 2; + start_reg += R600_SET_RESOURCE_OFFSET; + end_reg = 4 * (num_dw - 2) + start_reg - 4; + if ((start_reg < R600_SET_RESOURCE_OFFSET) || + (start_reg >= R600_SET_RESOURCE_END) || + (end_reg >= R600_SET_RESOURCE_END)) + ret = -EINVAL; + else { + for (i = 0; i < ((num_dw - 2) / 7); i++) { + switch ((ib_chunk->kdata[offset_dw + (i * 7) + 6 + 2] & 0xc0000000) >> 30) { + case R600_SQ_TEX_VTX_INVALID_TEXTURE: + case R600_SQ_TEX_VTX_INVALID_BUFFER: + default: + ret = -EINVAL; + break; + case R600_SQ_TEX_VTX_VALID_TEXTURE: + /* tex base */ + reloc = ib_chunk->kdata + offset_dw + num_dw + (i * 4); + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) + break; + ib_chunk->kdata[offset_dw + (i * 7) + 2 + 2] += + ((offset >> 8) & 0xffffffff); + /* tex mip base */ + reloc = ib_chunk->kdata + offset_dw + num_dw + (i * 4) + 2; + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) + break; + ib_chunk->kdata[offset_dw + (i * 7) + 3 + 2] += + ((offset >> 8) & 0xffffffff); + break; + case R600_SQ_TEX_VTX_VALID_BUFFER: + /* vtx base */ + reloc = ib_chunk->kdata + offset_dw + num_dw + (i * 2); + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) + break; + ib_chunk->kdata[offset_dw + (i * 7) + 0 + 2] += (offset & 0xffffffff); + ib_chunk->kdata[offset_dw + (i * 7) + 2 + 2] += (upper_32_bits(offset) & 0xff); + break; + } + if (ret) + break; + } + } + if (ret) + DRM_ERROR("bad SET_RESOURCE\n"); + break; + case R600_IT_SET_ALU_CONST: + //DRM_INFO("R600_IT_SET_ALU_CONST\n"); + start_reg = ib_chunk->kdata[offset_dw + 1] << 2; + start_reg += R600_SET_ALU_CONST_OFFSET; + end_reg = 4 * (num_dw - 2) + start_reg - 4; + if ((start_reg < R600_SET_ALU_CONST_OFFSET) || + (start_reg >= R600_SET_ALU_CONST_END) || + (end_reg >= R600_SET_ALU_CONST_END)) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad SET_ALU_CONST\n"); + break; + case R600_IT_SET_BOOL_CONST: + //DRM_INFO("R600_IT_SET_BOOL_CONST\n"); + start_reg = ib_chunk->kdata[offset_dw + 1] << 2; + start_reg += R600_SET_BOOL_CONST_OFFSET; + end_reg = 4 * (num_dw - 2) + start_reg - 4; + if ((start_reg < R600_SET_BOOL_CONST_OFFSET) || + (start_reg >= R600_SET_BOOL_CONST_END) || + (end_reg >= R600_SET_BOOL_CONST_END)) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad SET_BOOL_CONST\n"); + break; + case R600_IT_SET_LOOP_CONST: + //DRM_INFO("R600_IT_SET_LOOP_CONST\n"); + start_reg = ib_chunk->kdata[offset_dw + 1] << 2; + start_reg += R600_SET_LOOP_CONST_OFFSET; + end_reg = 4 * (num_dw - 2) + start_reg - 4; + if ((start_reg < R600_SET_LOOP_CONST_OFFSET) || + (start_reg >= R600_SET_LOOP_CONST_END) || + (end_reg >= R600_SET_LOOP_CONST_END)) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad SET_LOOP_CONST\n"); + break; + case R600_IT_SET_CTL_CONST: + //DRM_INFO("R600_IT_SET_CTL_CONST\n"); + start_reg = ib_chunk->kdata[offset_dw + 1] << 2; + start_reg += R600_SET_CTL_CONST_OFFSET; + end_reg = 4 * (num_dw - 2) + start_reg - 4; + if ((start_reg < R600_SET_CTL_CONST_OFFSET) || + (start_reg >= R600_SET_CTL_CONST_END) || + (end_reg >= R600_SET_CTL_CONST_END)) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad SET_CTL_CONST\n"); + break; + case R600_IT_SET_SAMPLER: + //DRM_INFO("R600_IT_SET_SAMPLER\n"); + if ((num_dw - 2) % 3) + ret = -EINVAL; + start_reg = ib_chunk->kdata[offset_dw + 1] << 2; + start_reg += R600_SET_SAMPLER_OFFSET; + end_reg = 4 * (num_dw - 2) + start_reg - 4; + if ((start_reg < R600_SET_SAMPLER_OFFSET) || + (start_reg >= R600_SET_SAMPLER_END) || + (end_reg >= R600_SET_SAMPLER_END)) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad SET_SAMPLER\n"); + break; + case R600_IT_SURFACE_BASE_UPDATE: + //DRM_INFO("R600_IT_SURFACE_BASE_UPDATE\n"); + if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600)) + ret = -EINVAL; + if (num_dw != 2) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad SURFACE_BASE_UPDATE\n"); + break; + case RADEON_CP_NOP: + //DRM_INFO("NOP: %d\n", ib_chunk->kdata[offset_dw + 1]); + break; + default: + DRM_ERROR("invalid packet 3 0x%08x\n", 0xff00); + ret = -EINVAL; + break; + } + + *offset_dw_p += incr; + return ret; +} + +static int r600_cs_parse(struct drm_radeon_cs_parser *parser) +{ + volatile int rb; + struct drm_radeon_kernel_chunk *ib_chunk; + /* scan the packet for various things */ + int count_dw = 0, size_dw; + int ret = 0; + + ib_chunk = &parser->chunks[parser->ib_index]; + size_dw = ib_chunk->length_dw; + + while (count_dw < size_dw && ret == 0) { + int hdr = ib_chunk->kdata[count_dw]; + int num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16; + + switch (hdr & RADEON_CP_PACKET_MASK) { + case RADEON_CP_PACKET0: + ret = r600_cs_packet0(parser, &count_dw); + break; + case RADEON_CP_PACKET1: + ret = -EINVAL; + break; + case RADEON_CP_PACKET2: + DRM_DEBUG("Packet 2\n"); + num_dw += 1; + break; + case RADEON_CP_PACKET3: + ret = r600_cs_packet3(parser, &count_dw); + break; + } + + count_dw += num_dw; + } + + if (ret) + return ret; + + + /* copy the packet into the IB */ + memcpy(parser->ib, ib_chunk->kdata, ib_chunk->length_dw * sizeof(uint32_t)); + + /* read back last byte to flush WC buffers */ + rb = readl(((vm_offset_t)parser->ib + (ib_chunk->length_dw-1) * sizeof(uint32_t))); + + return 0; +} + +static uint32_t radeon_cs_id_get(struct drm_radeon_private *radeon) +{ + /* FIXME: protect with a spinlock */ + /* FIXME: check if wrap affect last reported wrap & sequence */ + radeon->cs.id_scnt = (radeon->cs.id_scnt + 1) & 0x00FFFFFF; + if (!radeon->cs.id_scnt) { + /* increment wrap counter */ + radeon->cs.id_wcnt += 0x01000000; + /* valid sequence counter start at 1 */ + radeon->cs.id_scnt = 1; + } + return (radeon->cs.id_scnt | radeon->cs.id_wcnt); +} + +static void r600_cs_id_emit(struct drm_radeon_cs_parser *parser, uint32_t *id) +{ + drm_radeon_private_t *dev_priv = parser->dev->dev_private; + RING_LOCALS; + + //dev_priv->irq_emitted = radeon_update_breadcrumb(parser->dev); + + *id = radeon_cs_id_get(dev_priv); + + /* SCRATCH 2 */ + BEGIN_RING(3); + R600_CLEAR_AGE(*id); + ADVANCE_RING(); + COMMIT_RING(); +} + +static uint32_t r600_cs_id_last_get(struct drm_device *dev) +{ + //drm_radeon_private_t *dev_priv = dev->dev_private; + + //return GET_R600_SCRATCH(dev_priv, 2); + return 0; +} + +static int r600_ib_get(struct drm_radeon_cs_parser *parser) +{ + struct drm_device *dev = parser->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_buf *buf; + + buf = radeon_freelist_get(dev); + if (!buf) { + dev_priv->cs_buf = NULL; + return -EBUSY; + } + buf->file_priv = parser->file_priv; + dev_priv->cs_buf = buf; + parser->ib = (void *)((vm_offset_t)dev->agp_buffer_map->handle + + buf->offset); + + return 0; +} + +static void r600_ib_free(struct drm_radeon_cs_parser *parser, int error) +{ + struct drm_device *dev = parser->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_buf *buf = dev_priv->cs_buf; + + if (buf) { + if (!error) + r600_cp_dispatch_indirect(dev, buf, 0, + parser->chunks[parser->ib_index].length_dw * sizeof(uint32_t)); + radeon_cp_discard_buffer(dev, buf); + COMMIT_RING(); + } +} + +int r600_cs_init(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + + dev_priv->cs.ib_get = r600_ib_get; + dev_priv->cs.ib_free = r600_ib_free; + dev_priv->cs.id_emit = r600_cs_id_emit; + dev_priv->cs.id_last_get = r600_cs_id_last_get; + dev_priv->cs.parse = r600_cs_parse; + dev_priv->cs.relocate = r600_nomm_relocate; + return 0; +} From b3d484edeec9adbcb347738661b1154a4f987aee Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 5 Oct 2009 23:19:51 +0000 Subject: [PATCH 253/380] - Revert part of r197685 because this change leads to wrong data in cache. --- sys/mips/mips/pmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index 52d28645aba..33b8040c1a5 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -748,7 +748,7 @@ pmap_qenter(vm_offset_t va, vm_page_t *m, int count) va += PAGE_SIZE; } - mips_dcache_inv_range(origva, PAGE_SIZE*count); + mips_dcache_wbinv_range_index(origva, PAGE_SIZE*count); } /* From ca2b541cb08f7081eec151b905c07009d4b13ee5 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 6 Oct 2009 06:35:52 +0000 Subject: [PATCH 254/380] - curbrk variable for sbrk and brk should be the same - Add correct variable names to Symbol.map --- lib/libc/mips/Symbol.map | 4 ++-- lib/libc/mips/sys/brk.S | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/lib/libc/mips/Symbol.map b/lib/libc/mips/Symbol.map index 589c8c1c183..3f24c1149f7 100644 --- a/lib/libc/mips/Symbol.map +++ b/lib/libc/mips/Symbol.map @@ -56,8 +56,8 @@ FBSDprivate_1.0 { __siglongjmp; __sys_vfork; _vfork; - end; /* XXX - Should this be _end (see sys/brk.S)? */ - curbrk; + _end; + __curbrk; minbrk; _brk; _sbrk; diff --git a/lib/libc/mips/sys/brk.S b/lib/libc/mips/sys/brk.S index 580d7fa5ed3..aeaf7912f35 100644 --- a/lib/libc/mips/sys/brk.S +++ b/lib/libc/mips/sys/brk.S @@ -42,15 +42,12 @@ __FBSDID("$FreeBSD$"); #endif /* LIBC_SCCS and not lint */ .globl _C_LABEL(minbrk) - .globl _C_LABEL(curbrk) + .globl _C_LABEL(__curbrk) .globl _C_LABEL(_end) .data _C_LABEL(minbrk): .word _C_LABEL(_end) -_C_LABEL(curbrk): - .word _C_LABEL(_end) - .text LEAF(__sys_brk) WEAK_ALIAS(brk, __sys_brk) @@ -67,7 +64,7 @@ LEAF(__sys_brk) li v0, SYS_break syscall bne a3, zero, 2f - sw a0, _C_LABEL(curbrk) + sw a0, _C_LABEL(__curbrk) move v0, zero j ra 2: From cb00f8cae545f4ebd1c65125e5006531ebef820e Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sun, 11 Oct 2009 21:28:56 +0000 Subject: [PATCH 255/380] - Fix CPU divisor mask Repored by: Luiz Otavio O Souza --- sys/mips/atheros/ar71xxreg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/atheros/ar71xxreg.h b/sys/mips/atheros/ar71xxreg.h index cc331d4c59d..3f6b50a97fb 100644 --- a/sys/mips/atheros/ar71xxreg.h +++ b/sys/mips/atheros/ar71xxreg.h @@ -143,7 +143,7 @@ #define PLL_DDR_DIV_SEL_SHIFT 18 #define PLL_DDR_DIV_SEL_MASK 3 #define PLL_CPU_DIV_SEL_SHIFT 16 -#define PLL_CPU_DIV_SEL_MASK 2 +#define PLL_CPU_DIV_SEL_MASK 3 #define PLL_LOOP_BW_SHIFT 12 #define PLL_LOOP_BW_MASK 0xf #define PLL_DIV_IN_SHIFT 10 From 33df61e1077ad6d4e13edbe64963ad25f46837e0 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 13 Oct 2009 00:43:31 +0000 Subject: [PATCH 256/380] - Enable fdisk build for MIPS --- sbin/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sbin/Makefile b/sbin/Makefile index 8ece390460d..7f58233b1f9 100644 --- a/sbin/Makefile +++ b/sbin/Makefile @@ -148,6 +148,10 @@ _fdisk= fdisk _mca= mca .endif +.if ${MACHINE_ARCH} == "mips" +_fdisk= fdisk +.endif + .if ${MACHINE_ARCH} == "sparc64" _sunlabel= sunlabel .endif From 3a5e117a7bf72d9f766771701311a053e38985e1 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 14 Oct 2009 01:43:53 +0000 Subject: [PATCH 257/380] - Move stack tracing function to db_trace.c - Axe unused extern MipsXXX declarations - Move all declarations for functions in exceptions.S/swtch.S from trap.c to respective headers --- sys/mips/include/db_machdep.h | 1 + sys/mips/include/md_var.h | 1 + sys/mips/include/trap.h | 12 ++ sys/mips/mips/db_trace.c | 334 +++++++++++++++++++++++++++++++ sys/mips/mips/trap.c | 359 +--------------------------------- 5 files changed, 350 insertions(+), 357 deletions(-) diff --git a/sys/mips/include/db_machdep.h b/sys/mips/include/db_machdep.h index 77700c15af6..3bb8a7e06d6 100644 --- a/sys/mips/include/db_machdep.h +++ b/sys/mips/include/db_machdep.h @@ -95,5 +95,6 @@ int db_inst_type(int); void db_dump_tlb(int, int); db_addr_t branch_taken(int inst, db_addr_t pc); void stacktrace_subr(db_regs_t *, int (*)(const char *, ...)); +int kdbpeek(int *); #endif /* !_MIPS_DB_MACHDEP_H_ */ diff --git a/sys/mips/include/md_var.h b/sys/mips/include/md_var.h index 8755fd0302d..f53074f39bf 100644 --- a/sys/mips/include/md_var.h +++ b/sys/mips/include/md_var.h @@ -49,6 +49,7 @@ void MipsSaveCurFPState(struct thread *); void fork_trampoline(void); void cpu_swapin(struct proc *); uintptr_t MipsEmulateBranch(struct trapframe *, uintptr_t, int, uintptr_t); +void MipsSwitchFPState(struct thread *, struct trapframe *); u_long kvtop(void *addr); int is_physical_memory(vm_offset_t addr); int is_cacheable_mem(vm_offset_t pa); diff --git a/sys/mips/include/trap.h b/sys/mips/include/trap.h index a00ca908f2f..3d0470eb3ce 100644 --- a/sys/mips/include/trap.h +++ b/sys/mips/include/trap.h @@ -108,6 +108,18 @@ void trapDump(char *msg); #endif +void MipsFPTrap(u_int, u_int, u_int); +void MipsKernGenException(void); +void MipsKernIntr(void); +void MipsKernTLBInvalidException(void); +void MipsTLBInvalidException(void); +void MipsTLBMissException(void); +void MipsUserGenException(void); +void MipsUserIntr(void); +void MipsUserTLBInvalidException(void); + +u_int trap(struct trapframe *); + #ifndef LOCORE /* XXX */ int check_address(void *); void platform_trap_enter(void); diff --git a/sys/mips/mips/db_trace.c b/sys/mips/mips/db_trace.c index fe2aa6e2442..ebc02a60df5 100644 --- a/sys/mips/mips/db_trace.c +++ b/sys/mips/mips/db_trace.c @@ -17,9 +17,343 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include +#include #include +#include + +extern char _locore[]; +extern char _locoreEnd[]; +extern char edata[]; + +/* + * A function using a stack frame has the following instruction as the first + * one: addiu sp,sp,- + * + * We make use of this to detect starting address of a function. This works + * better than using 'j ra' instruction to signify end of the previous + * function (for e.g. functions like boot() or panic() do not actually + * emit a 'j ra' instruction). + * + * XXX the abi does not require that the addiu instruction be the first one. + */ +#define MIPS_START_OF_FUNCTION(ins) (((ins) & 0xffff8000) == 0x27bd8000) + +/* + * MIPS ABI 3.0 requires that all functions return using the 'j ra' instruction + * + * XXX gcc doesn't do this for functions with __noreturn__ attribute. + */ +#define MIPS_END_OF_FUNCTION(ins) ((ins) == 0x03e00008) + +/* + * kdbpeekD(addr) - skip one word starting at 'addr', then read the second word + */ +#define kdbpeekD(addr) kdbpeek(((int *)(addr)) + 1) + +/* + * Functions ``special'' enough to print by name + */ +#ifdef __STDC__ +#define Name(_fn) { (void*)_fn, # _fn } +#else +#define Name(_fn) { _fn, "_fn"} +#endif +static struct { + void *addr; + char *name; +} names[] = { + + Name(trap), + Name(MipsKernGenException), + Name(MipsUserGenException), + Name(MipsKernIntr), + Name(MipsUserIntr), + Name(cpu_switch), + { + 0, 0 + } +}; + +/* + * Map a function address to a string name, if known; or a hex string. + */ +static char * +fn_name(uintptr_t addr) +{ + static char buf[17]; + int i = 0; + + db_expr_t diff; + c_db_sym_t sym; + char *symname; + + diff = 0; + symname = NULL; + sym = db_search_symbol((db_addr_t)addr, DB_STGY_ANY, &diff); + db_symbol_values(sym, (const char **)&symname, (db_expr_t *)0); + if (symname && diff == 0) + return (symname); + + for (i = 0; names[i].name; i++) + if (names[i].addr == (void *)addr) + return (names[i].name); + sprintf(buf, "%jx", (uintmax_t)addr); + return (buf); +} + +void +stacktrace_subr(struct trapframe *regs, int (*printfn) (const char *,...)) +{ + InstFmt i; + uintptr_t a0, a1, a2, a3, pc, sp, fp, ra, va, subr; + unsigned instr, mask; + unsigned int frames = 0; + int more, stksize; + + /* get initial values from the exception frame */ + sp = regs->sp; + pc = regs->pc; + fp = regs->s8; + ra = regs->ra; /* May be a 'leaf' function */ + a0 = regs->a0; + a1 = regs->a1; + a2 = regs->a2; + a3 = regs->a3; + +/* Jump here when done with a frame, to start a new one */ +loop: + +/* Jump here after a nonstandard (interrupt handler) frame */ + stksize = 0; + subr = 0; + if (frames++ > 100) { + (*printfn) ("\nstackframe count exceeded\n"); + /* return breaks stackframe-size heuristics with gcc -O2 */ + goto finish; /* XXX */ + } + /* check for bad SP: could foul up next frame */ + /*XXX MIPS64 bad: this hard-coded SP is lame */ + if (sp & 3 || sp < 0x80000000) { + (*printfn) ("SP 0x%x: not in kernel\n", sp); + ra = 0; + subr = 0; + goto done; + } +#define Between(x, y, z) \ + ( ((x) <= (y)) && ((y) < (z)) ) +#define pcBetween(a,b) \ + Between((uintptr_t)a, pc, (uintptr_t)b) + + /* + * Check for current PC in exception handler code that don't have a + * preceding "j ra" at the tail of the preceding function. Depends + * on relative ordering of functions in exception.S, swtch.S. + */ + if (pcBetween(MipsKernGenException, MipsUserGenException)) + subr = (uintptr_t)MipsKernGenException; + else if (pcBetween(MipsUserGenException, MipsKernIntr)) + subr = (uintptr_t)MipsUserGenException; + else if (pcBetween(MipsKernIntr, MipsUserIntr)) + subr = (uintptr_t)MipsKernIntr; + else if (pcBetween(MipsUserIntr, MipsTLBInvalidException)) + subr = (uintptr_t)MipsUserIntr; + else if (pcBetween(MipsTLBInvalidException, + MipsKernTLBInvalidException)) + subr = (uintptr_t)MipsTLBInvalidException; + else if (pcBetween(MipsKernTLBInvalidException, + MipsUserTLBInvalidException)) + subr = (uintptr_t)MipsKernTLBInvalidException; + else if (pcBetween(MipsUserTLBInvalidException, MipsTLBMissException)) + subr = (uintptr_t)MipsUserTLBInvalidException; + else if (pcBetween(cpu_switch, MipsSwitchFPState)) + subr = (uintptr_t)cpu_switch; + else if (pcBetween(_locore, _locoreEnd)) { + subr = (uintptr_t)_locore; + ra = 0; + goto done; + } + /* check for bad PC */ + /*XXX MIPS64 bad: These hard coded constants are lame */ + if (pc & 3 || pc < (uintptr_t)0x80000000 || pc >= (uintptr_t)edata) { + (*printfn) ("PC 0x%x: not in kernel\n", pc); + ra = 0; + goto done; + } + /* + * Find the beginning of the current subroutine by scanning + * backwards from the current PC for the end of the previous + * subroutine. + */ + if (!subr) { + va = pc - sizeof(int); + while (1) { + instr = kdbpeek((int *)va); + + if (MIPS_START_OF_FUNCTION(instr)) + break; + + if (MIPS_END_OF_FUNCTION(instr)) { + /* skip over branch-delay slot instruction */ + va += 2 * sizeof(int); + break; + } + + va -= sizeof(int); + } + + /* skip over nulls which might separate .o files */ + while ((instr = kdbpeek((int *)va)) == 0) + va += sizeof(int); + subr = va; + } + /* scan forwards to find stack size and any saved registers */ + stksize = 0; + more = 3; + mask = 0; + for (va = subr; more; va += sizeof(int), + more = (more == 3) ? 3 : more - 1) { + /* stop if hit our current position */ + if (va >= pc) + break; + instr = kdbpeek((int *)va); + i.word = instr; + switch (i.JType.op) { + case OP_SPECIAL: + switch (i.RType.func) { + case OP_JR: + case OP_JALR: + more = 2; /* stop after next instruction */ + break; + + case OP_SYSCALL: + case OP_BREAK: + more = 1; /* stop now */ + }; + break; + + case OP_BCOND: + case OP_J: + case OP_JAL: + case OP_BEQ: + case OP_BNE: + case OP_BLEZ: + case OP_BGTZ: + more = 2; /* stop after next instruction */ + break; + + case OP_COP0: + case OP_COP1: + case OP_COP2: + case OP_COP3: + switch (i.RType.rs) { + case OP_BCx: + case OP_BCy: + more = 2; /* stop after next instruction */ + }; + break; + + case OP_SW: + /* look for saved registers on the stack */ + if (i.IType.rs != 29) + break; + /* only restore the first one */ + if (mask & (1 << i.IType.rt)) + break; + mask |= (1 << i.IType.rt); + switch (i.IType.rt) { + case 4:/* a0 */ + a0 = kdbpeek((int *)(sp + (short)i.IType.imm)); + break; + + case 5:/* a1 */ + a1 = kdbpeek((int *)(sp + (short)i.IType.imm)); + break; + + case 6:/* a2 */ + a2 = kdbpeek((int *)(sp + (short)i.IType.imm)); + break; + + case 7:/* a3 */ + a3 = kdbpeek((int *)(sp + (short)i.IType.imm)); + break; + + case 30: /* fp */ + fp = kdbpeek((int *)(sp + (short)i.IType.imm)); + break; + + case 31: /* ra */ + ra = kdbpeek((int *)(sp + (short)i.IType.imm)); + } + break; + + case OP_SD: + /* look for saved registers on the stack */ + if (i.IType.rs != 29) + break; + /* only restore the first one */ + if (mask & (1 << i.IType.rt)) + break; + mask |= (1 << i.IType.rt); + switch (i.IType.rt) { + case 4:/* a0 */ + a0 = kdbpeekD((int *)(sp + (short)i.IType.imm)); + break; + + case 5:/* a1 */ + a1 = kdbpeekD((int *)(sp + (short)i.IType.imm)); + break; + + case 6:/* a2 */ + a2 = kdbpeekD((int *)(sp + (short)i.IType.imm)); + break; + + case 7:/* a3 */ + a3 = kdbpeekD((int *)(sp + (short)i.IType.imm)); + break; + + case 30: /* fp */ + fp = kdbpeekD((int *)(sp + (short)i.IType.imm)); + break; + + case 31: /* ra */ + ra = kdbpeekD((int *)(sp + (short)i.IType.imm)); + } + break; + + case OP_ADDI: + case OP_ADDIU: + /* look for stack pointer adjustment */ + if (i.IType.rs != 29 || i.IType.rt != 29) + break; + stksize = -((short)i.IType.imm); + } + } + +done: + (*printfn) ("%s+%x (%x,%x,%x,%x) ra %x sz %d\n", + fn_name(subr), pc - subr, a0, a1, a2, a3, ra, stksize); + + if (ra) { + if (pc == ra && stksize == 0) + (*printfn) ("stacktrace: loop!\n"); + else { + pc = ra; + sp += stksize; + ra = 0; + goto loop; + } + } else { +finish: + if (curproc) + (*printfn) ("pid %d\n", curproc->p_pid); + else + (*printfn) ("curproc NULL\n"); + } +} + int db_md_set_watchpoint(db_expr_t addr, db_expr_t size) diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c index f44dda32c2a..a20f54cf451 100644 --- a/sys/mips/mips/trap.c +++ b/sys/mips/mips/trap.c @@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -102,23 +103,13 @@ int trap_debug = 1; extern unsigned onfault_table[]; -extern void MipsKernGenException(void); -extern void MipsUserGenException(void); -extern void MipsKernIntr(void); -extern void MipsUserIntr(void); -extern void MipsTLBInvalidException(void); -extern void MipsKernTLBInvalidException(void); -extern void MipsUserTLBInvalidException(void); -extern void MipsTLBMissException(void); static void log_bad_page_fault(char *, struct trapframe *, int); static void log_frame_dump(struct trapframe *frame); static void get_mapping_info(vm_offset_t, pd_entry_t **, pt_entry_t **); #ifdef TRAP_DEBUG static void trap_frame_dump(struct trapframe *frame); - #endif -extern char edata[]; void (*machExceptionTable[]) (void)= { /* @@ -230,36 +221,16 @@ char *trap_type[] = { #if !defined(SMP) && (defined(DDB) || defined(DEBUG)) struct trapdebug trapdebug[TRAPSIZE], *trp = trapdebug; - #endif #if defined(DDB) || defined(DEBUG) void stacktrace(struct trapframe *); void logstacktrace(struct trapframe *); -int kdbpeek(int *); - -/* extern functions printed by name in stack backtraces */ -extern void MipsTLBMiss(void); -extern void MipsUserSyscallException(void); -extern char _locore[]; -extern char _locoreEnd[]; - -#endif /* DDB || DEBUG */ - -extern void MipsSwitchFPState(struct thread *, struct trapframe *); -extern void MipsFPTrap(u_int, u_int, u_int); - -u_int trap(struct trapframe *); -u_int MipsEmulateBranch(struct trapframe *, uintptr_t, int, uintptr_t); +#endif #define KERNLAND(x) ((int)(x) < 0) #define DELAYBRANCH(x) ((int)(x) < 0) -/* - * kdbpeekD(addr) - skip one word starting at 'addr', then read the second word - */ -#define kdbpeekD(addr) kdbpeek(((int *)(addr)) + 1) - /* * MIPS load/store access type */ @@ -1226,28 +1197,6 @@ MipsEmulateBranch(struct trapframe *framePtr, uintptr_t instPC, int fpcCSR, #if defined(DDB) || defined(DEBUG) -/* - * A function using a stack frame has the following instruction as the first - * one: addiu sp,sp,- - * - * We make use of this to detect starting address of a function. This works - * better than using 'j ra' instruction to signify end of the previous - * function (for e.g. functions like boot() or panic() do not actually - * emit a 'j ra' instruction). - * - * XXX the abi does not require that the addiu instruction be the first one. - */ -#define MIPS_START_OF_FUNCTION(ins) (((ins) & 0xffff8000) == 0x27bd8000) - -/* - * MIPS ABI 3.0 requires that all functions return using the 'j ra' instruction - * - * XXX gcc doesn't do this true for functions with __noreturn__ attribute. - */ -#define MIPS_END_OF_FUNCTION(ins) ((ins) == 0x03e00008) -/* forward */ -static char *fn_name(uintptr_t addr); - /* * Print a stack backtrace. */ @@ -1256,311 +1205,7 @@ stacktrace(struct trapframe *regs) { stacktrace_subr(regs, printf); } - -void -stacktrace_subr(struct trapframe *regs, int (*printfn) (const char *,...)) -{ - InstFmt i; - uintptr_t a0, a1, a2, a3, pc, sp, fp, ra, va, subr; - unsigned instr, mask; - unsigned int frames = 0; - int more, stksize; - - /* get initial values from the exception frame */ - sp = regs->sp; - pc = regs->pc; - fp = regs->s8; - ra = regs->ra; /* May be a 'leaf' function */ - a0 = regs->a0; - a1 = regs->a1; - a2 = regs->a2; - a3 = regs->a3; - -/* Jump here when done with a frame, to start a new one */ -loop: - -/* Jump here after a nonstandard (interrupt handler) frame */ - stksize = 0; - subr = 0; - if (frames++ > 100) { - (*printfn) ("\nstackframe count exceeded\n"); - /* return breaks stackframe-size heuristics with gcc -O2 */ - goto finish; /* XXX */ - } - /* check for bad SP: could foul up next frame */ - /*XXX MIPS64 bad: this hard-coded SP is lame */ - if (sp & 3 || sp < 0x80000000) { - (*printfn) ("SP 0x%x: not in kernel\n", sp); - ra = 0; - subr = 0; - goto done; - } -#define Between(x, y, z) \ - ( ((x) <= (y)) && ((y) < (z)) ) -#define pcBetween(a,b) \ - Between((uintptr_t)a, pc, (uintptr_t)b) - - /* - * Check for current PC in exception handler code that don't have a - * preceding "j ra" at the tail of the preceding function. Depends - * on relative ordering of functions in exception.S, swtch.S. - */ - if (pcBetween(MipsKernGenException, MipsUserGenException)) - subr = (uintptr_t)MipsKernGenException; - else if (pcBetween(MipsUserGenException, MipsKernIntr)) - subr = (uintptr_t)MipsUserGenException; - else if (pcBetween(MipsKernIntr, MipsUserIntr)) - subr = (uintptr_t)MipsKernIntr; - else if (pcBetween(MipsUserIntr, MipsTLBInvalidException)) - subr = (uintptr_t)MipsUserIntr; - else if (pcBetween(MipsTLBInvalidException, - MipsKernTLBInvalidException)) - subr = (uintptr_t)MipsTLBInvalidException; - else if (pcBetween(MipsKernTLBInvalidException, - MipsUserTLBInvalidException)) - subr = (uintptr_t)MipsKernTLBInvalidException; - else if (pcBetween(MipsUserTLBInvalidException, MipsTLBMissException)) - subr = (uintptr_t)MipsUserTLBInvalidException; - else if (pcBetween(cpu_switch, MipsSwitchFPState)) - subr = (uintptr_t)cpu_switch; - else if (pcBetween(_locore, _locoreEnd)) { - subr = (uintptr_t)_locore; - ra = 0; - goto done; - } - /* check for bad PC */ - /*XXX MIPS64 bad: These hard coded constants are lame */ - if (pc & 3 || pc < (uintptr_t)0x80000000 || pc >= (uintptr_t)edata) { - (*printfn) ("PC 0x%x: not in kernel\n", pc); - ra = 0; - goto done; - } - /* - * Find the beginning of the current subroutine by scanning - * backwards from the current PC for the end of the previous - * subroutine. - */ - if (!subr) { - va = pc - sizeof(int); - while (1) { - instr = kdbpeek((int *)va); - - if (MIPS_START_OF_FUNCTION(instr)) - break; - - if (MIPS_END_OF_FUNCTION(instr)) { - /* skip over branch-delay slot instruction */ - va += 2 * sizeof(int); - break; - } - - va -= sizeof(int); - } - - /* skip over nulls which might separate .o files */ - while ((instr = kdbpeek((int *)va)) == 0) - va += sizeof(int); - subr = va; - } - /* scan forwards to find stack size and any saved registers */ - stksize = 0; - more = 3; - mask = 0; - for (va = subr; more; va += sizeof(int), - more = (more == 3) ? 3 : more - 1) { - /* stop if hit our current position */ - if (va >= pc) - break; - instr = kdbpeek((int *)va); - i.word = instr; - switch (i.JType.op) { - case OP_SPECIAL: - switch (i.RType.func) { - case OP_JR: - case OP_JALR: - more = 2; /* stop after next instruction */ - break; - - case OP_SYSCALL: - case OP_BREAK: - more = 1; /* stop now */ - }; - break; - - case OP_BCOND: - case OP_J: - case OP_JAL: - case OP_BEQ: - case OP_BNE: - case OP_BLEZ: - case OP_BGTZ: - more = 2; /* stop after next instruction */ - break; - - case OP_COP0: - case OP_COP1: - case OP_COP2: - case OP_COP3: - switch (i.RType.rs) { - case OP_BCx: - case OP_BCy: - more = 2; /* stop after next instruction */ - }; - break; - - case OP_SW: - /* look for saved registers on the stack */ - if (i.IType.rs != 29) - break; - /* only restore the first one */ - if (mask & (1 << i.IType.rt)) - break; - mask |= (1 << i.IType.rt); - switch (i.IType.rt) { - case 4:/* a0 */ - a0 = kdbpeek((int *)(sp + (short)i.IType.imm)); - break; - - case 5:/* a1 */ - a1 = kdbpeek((int *)(sp + (short)i.IType.imm)); - break; - - case 6:/* a2 */ - a2 = kdbpeek((int *)(sp + (short)i.IType.imm)); - break; - - case 7:/* a3 */ - a3 = kdbpeek((int *)(sp + (short)i.IType.imm)); - break; - - case 30: /* fp */ - fp = kdbpeek((int *)(sp + (short)i.IType.imm)); - break; - - case 31: /* ra */ - ra = kdbpeek((int *)(sp + (short)i.IType.imm)); - } - break; - - case OP_SD: - /* look for saved registers on the stack */ - if (i.IType.rs != 29) - break; - /* only restore the first one */ - if (mask & (1 << i.IType.rt)) - break; - mask |= (1 << i.IType.rt); - switch (i.IType.rt) { - case 4:/* a0 */ - a0 = kdbpeekD((int *)(sp + (short)i.IType.imm)); - break; - - case 5:/* a1 */ - a1 = kdbpeekD((int *)(sp + (short)i.IType.imm)); - break; - - case 6:/* a2 */ - a2 = kdbpeekD((int *)(sp + (short)i.IType.imm)); - break; - - case 7:/* a3 */ - a3 = kdbpeekD((int *)(sp + (short)i.IType.imm)); - break; - - case 30: /* fp */ - fp = kdbpeekD((int *)(sp + (short)i.IType.imm)); - break; - - case 31: /* ra */ - ra = kdbpeekD((int *)(sp + (short)i.IType.imm)); - } - break; - - case OP_ADDI: - case OP_ADDIU: - /* look for stack pointer adjustment */ - if (i.IType.rs != 29 || i.IType.rt != 29) - break; - stksize = -((short)i.IType.imm); - } - } - -done: - (*printfn) ("%s+%x (%x,%x,%x,%x) ra %x sz %d\n", - fn_name(subr), pc - subr, a0, a1, a2, a3, ra, stksize); - - if (ra) { - if (pc == ra && stksize == 0) - (*printfn) ("stacktrace: loop!\n"); - else { - pc = ra; - sp += stksize; - ra = 0; - goto loop; - } - } else { -finish: - if (curproc) - (*printfn) ("pid %d\n", curproc->p_pid); - else - (*printfn) ("curproc NULL\n"); - } -} - -/* - * Functions ``special'' enough to print by name - */ -#ifdef __STDC__ -#define Name(_fn) { (void*)_fn, # _fn } -#else -#define Name(_fn) { _fn, "_fn"} #endif -static struct { - void *addr; - char *name; -} names[] = { - - Name(trap), - Name(MipsKernGenException), - Name(MipsUserGenException), - Name(MipsKernIntr), - Name(MipsUserIntr), - Name(cpu_switch), - { - 0, 0 - } -}; - -/* - * Map a function address to a string name, if known; or a hex string. - */ -static char * -fn_name(uintptr_t addr) -{ - static char buf[17]; - int i = 0; - -#ifdef DDB - db_expr_t diff; - c_db_sym_t sym; - char *symname; - - diff = 0; - symname = NULL; - sym = db_search_symbol((db_addr_t)addr, DB_STGY_ANY, &diff); - db_symbol_values(sym, (const char **)&symname, (db_expr_t *)0); - if (symname && diff == 0) - return (symname); -#endif - - for (i = 0; names[i].name; i++) - if (names[i].addr == (void *)addr) - return (names[i].name); - sprintf(buf, "%jx", (uintmax_t)addr); - return (buf); -} - -#endif /* DDB */ static void log_frame_dump(struct trapframe *frame) From 3f907e3338936bfceb9b2c9cdfdf13797e6a7890 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Thu, 15 Oct 2009 21:03:32 +0000 Subject: [PATCH 258/380] Does 4 things: 1) Adds future RMI directories 2) Places intr_machdep.c in specfic files.arch pointing to the generic intr_machdep.c. This allows us to have an architecture dependant intr_machdep.c (which we will need for RMI) in the machine specific directory 3) removes intr_machdep.c from files.mips 4) Adds some TARGET_XLR_XLS ifdef's for the machine specific intra_machdep.h. We may need to look at finding a better place to put this. But first I want to get this thing compiling. --- sys/conf/files.mips | 1 - sys/mips/adm5120/files.adm5120 | 1 + sys/mips/alchemy/files.alchemy | 1 + sys/mips/atheros/files.ar71xx | 1 + sys/mips/idt/files.idt | 1 + sys/mips/include/intr_machdep.h | 19 +++++++++++++++++++ sys/mips/malta/files.malta | 1 + sys/mips/octeon1/files.octeon1 | 1 + sys/mips/sentry5/files.sentry5 | 1 + sys/mips/sibyte/files.sibyte | 2 +- 10 files changed, 27 insertions(+), 2 deletions(-) diff --git a/sys/conf/files.mips b/sys/conf/files.mips index 708d6c700fd..025556b4de6 100644 --- a/sys/conf/files.mips +++ b/sys/conf/files.mips @@ -64,7 +64,6 @@ mips/mips/db_interface.c optional ddb mips/mips/db_trace.c optional ddb mips/mips/dump_machdep.c standard mips/mips/in_cksum.c optional inet -mips/mips/intr_machdep.c standard mips/mips/locore.S standard no-obj mips/mips/mem.c optional mem mips/mips/nexus.c standard diff --git a/sys/mips/adm5120/files.adm5120 b/sys/mips/adm5120/files.adm5120 index 489ea733ba2..0645f406a25 100644 --- a/sys/mips/adm5120/files.adm5120 +++ b/sys/mips/adm5120/files.adm5120 @@ -9,3 +9,4 @@ mips/adm5120/obio.c standard mips/adm5120/uart_bus_adm5120.c optional uart mips/adm5120/uart_cpu_adm5120.c optional uart mips/adm5120/uart_dev_adm5120.c optional uart +mips/mips/intr_machdep.c standard diff --git a/sys/mips/alchemy/files.alchemy b/sys/mips/alchemy/files.alchemy index 8534431d020..2e0f0e74853 100644 --- a/sys/mips/alchemy/files.alchemy +++ b/sys/mips/alchemy/files.alchemy @@ -5,3 +5,4 @@ mips/alchemy/alchemy_machdep.c standard mips/alchemy/obio.c standard mips/alchemy/uart_bus_alchemy.c optional uart mips/alchemy/uart_cpu_alchemy.c optional uart +mips/mips/intr_machdep.c standard diff --git a/sys/mips/atheros/files.ar71xx b/sys/mips/atheros/files.ar71xx index b3db957512e..ccad05751ea 100644 --- a/sys/mips/atheros/files.ar71xx +++ b/sys/mips/atheros/files.ar71xx @@ -12,3 +12,4 @@ mips/atheros/if_arge.c optional arge mips/atheros/uart_bus_ar71xx.c optional uart mips/atheros/uart_cpu_ar71xx.c optional uart mips/atheros/ar71xx_bus_space_reversed.c standard +mips/mips/intr_machdep.c standard diff --git a/sys/mips/idt/files.idt b/sys/mips/idt/files.idt index 4148ac4a6aa..b8920a7d30c 100644 --- a/sys/mips/idt/files.idt +++ b/sys/mips/idt/files.idt @@ -6,3 +6,4 @@ mips/idt/if_kr.c optional kr mips/idt/obio.c standard mips/idt/uart_cpu_rc32434.c optional uart mips/idt/uart_bus_rc32434.c optional uart +mips/mips/intr_machdep.c standard diff --git a/sys/mips/include/intr_machdep.h b/sys/mips/include/intr_machdep.h index d5f26d9296b..1e3e075b189 100644 --- a/sys/mips/include/intr_machdep.h +++ b/sys/mips/include/intr_machdep.h @@ -29,8 +29,26 @@ #ifndef _MACHINE_INTR_MACHDEP_H_ #define _MACHINE_INTR_MACHDEP_H_ +#ifdef TARGET_XLR_XLS +/* + * XLR/XLS uses its own intr_machdep.c and has + * a different number of interupts. This probably + * should be placed somewhere else. + */ + +struct mips_intrhand { + struct intr_event *mih_event; + driver_intr_t *mih_disable; + volatile long *cntp; /* interrupt counter */ +}; + +extern struct mips_intrhand mips_intr_handlers[]; +#define XLR_MAX_INTR 64 + +#else #define NHARD_IRQS 6 #define NSOFT_IRQS 2 +#endif struct trapframe; @@ -40,4 +58,5 @@ void cpu_establish_softintr(const char *, int (*)(void*), void (*)(void*), void *, int, int, void **); void cpu_intr(struct trapframe *); + #endif /* !_MACHINE_INTR_MACHDEP_H_ */ diff --git a/sys/mips/malta/files.malta b/sys/mips/malta/files.malta index 6ade95f4e36..fe805461cdd 100644 --- a/sys/mips/malta/files.malta +++ b/sys/mips/malta/files.malta @@ -7,3 +7,4 @@ mips/malta/uart_bus_maltausart.c optional uart dev/uart/uart_dev_ns8250.c optional uart mips/malta/malta_machdep.c standard mips/malta/yamon.c standard +mips/mips/intr_machdep.c standard diff --git a/sys/mips/octeon1/files.octeon1 b/sys/mips/octeon1/files.octeon1 index 6e7d658f247..8415a47563c 100644 --- a/sys/mips/octeon1/files.octeon1 +++ b/sys/mips/octeon1/files.octeon1 @@ -13,3 +13,4 @@ mips/octeon1/octeon_machdep.c standard mips/octeon1/uart_bus_octeonusart.c optional uart mips/octeon1/uart_cpu_octeonusart.c optional uart mips/octeon1/uart_dev_oct16550.c optional uart +mips/mips/intr_machdep.c standard diff --git a/sys/mips/sentry5/files.sentry5 b/sys/mips/sentry5/files.sentry5 index 79925094a2d..07043d557fd 100644 --- a/sys/mips/sentry5/files.sentry5 +++ b/sys/mips/sentry5/files.sentry5 @@ -5,3 +5,4 @@ # which are believed to be devices we have drivers for # which just need to be tweaked for attachment to an SSB system bus. mips/sentry5/s5_machdep.c standard +mips/mips/intr_machdep.c standard diff --git a/sys/mips/sibyte/files.sibyte b/sys/mips/sibyte/files.sibyte index 56f317d31e3..677796c1c78 100644 --- a/sys/mips/sibyte/files.sibyte +++ b/sys/mips/sibyte/files.sibyte @@ -5,5 +5,5 @@ mips/sibyte/sb_zbbus.c standard mips/sibyte/sb_zbpci.c standard mips/sibyte/sb_scd.c standard mips/sibyte/ata_zbbus.c standard - +mips/mips/intr_machdep.c standard mips/sibyte/sb_asm.S standard From 8f28855b076ad87e9ef034dede9d7236e0fa1e4f Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Thu, 15 Oct 2009 21:05:09 +0000 Subject: [PATCH 259/380] Adds the first files from the RMI work with my re-work of their intr_machdep.c to use updated interfaces etc. More coming.. and some day it may compile ;-) --- sys/mips/rmi/files.xlr | 24 +++++ sys/mips/rmi/intr_machdep.c | 175 ++++++++++++++++++++++++++++++++++++ sys/mips/rmi/std.xlr | 10 +++ 3 files changed, 209 insertions(+) create mode 100644 sys/mips/rmi/files.xlr create mode 100644 sys/mips/rmi/intr_machdep.c create mode 100644 sys/mips/rmi/std.xlr diff --git a/sys/mips/rmi/files.xlr b/sys/mips/rmi/files.xlr new file mode 100644 index 00000000000..736e434ffb8 --- /dev/null +++ b/sys/mips/rmi/files.xlr @@ -0,0 +1,24 @@ +# $FreeBSD$ +mips/rmi/xlr_boot1_console.c standard +mips/rmi/xlr_machdep.c standard +#mips/rmi/clock.c standard +mips/rmi/iodi.c standard +mips/rmi/msgring.c standard +mips/rmi/msgring_xls.c standard +mips/rmi/board.c standard +mips/rmi/on_chip.c standard +mips/rmip/intr_machdep.c standard +mips/rmi/xlr_i2c.c optional iic +mips/rmi/uart_bus_xlr_iodi.c optional uart +mips/rmi/uart_cpu_mips_xlr.c optional uart +mips/rmi/perfmon_kern.c optional xlr_perfmon +mips/rmi/perfmon_percpu.c optional xlr_perfmon +mips/rmi/pcibus.c optional pci +mips/rmi/xlr_pci.c optional pci +mips/rmi/xls_ehci.c optional usb ehci +dev/rmi/xlr/rge.c optional rge +dev/iicbus/xlr_rtc.c optional xlr_rtc +dev/iicbus/xlr_temperature.c optional xlr_temperature +dev/iicbus/xlr_eeprom.c optional xlr_eeprom +dev/rmi/sec/rmisec.c optional rmisec +dev/rmi/sec/rmilib.c optional rmisec diff --git a/sys/mips/rmi/intr_machdep.c b/sys/mips/rmi/intr_machdep.c new file mode 100644 index 00000000000..40fda6f74ae --- /dev/null +++ b/sys/mips/rmi/intr_machdep.c @@ -0,0 +1,175 @@ +/*- + * Copyright (c) 2006 Fill this file and put your name here + * Copyright (c) 2002-2004 Juli Mallett + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct mips_intrhand mips_intr_handlers[XLR_MAX_INTR]; + +static void +mips_mask_hard_irq(void *source) +{ + uintptr_t irq = (uintptr_t)source; + + write_c0_eimr64(read_c0_eimr64() & ~(1ULL< XLR_MAX_INTR) + panic("%s called for unknown hard intr %d", __func__, intr); + + /* FIXME locking - not needed now, because we do this only on startup from + CPU0 */ + mih = &mips_intr_handlers[irq]; + mih->cntp = &intrcnt[irq]; + ie = mih->mih_event; + if (ie == NULL) { + errcode = intr_event_create(&event, (void *)(uintptr_t)irq, 0, + irq, mips_mask_hard_irq, mips_unmask_hard_irq, + NULL, NULL, "hard intr%d:", irq); + + if (errcode) { + printf("Could not create event for intr %d\n", irq); + return; + } + } + intr_event_add_handler(event, name, filt, handler, arg, + intr_priority(flags), flags, cookiep); + mih->mih_event = ie; + mips_unmask_hard_irq((void*)(uintptr_t)irq); +} + + +void +cpu_establish_softintr(const char *name, driver_filter_t *filt, + void (*handler)(void*), void *arg, int irq, int flags, + void **cookiep) +{ + /* we don't separate them into soft/hard like other mips */ + cpu_establish_hardintr(name, filt, handler, arg, intr, flags, cookiep); +} + +void +cpu_intr(struct trapframe *tf) +{ + struct mips_intrhand *mih; + struct intr_handler *ih; + struct intr_event *ie; + register_t eirr; + int i, thread, error; + + critical_enter(); + eirr = read_c0_eirr64(); + if (eirr == 0) { + critical_exit(); + return; + } + + /* No need to clear the EIRR here. the handler is gonna + * write to compare which clears eirr also + */ + if (eirr & (1 << IRQ_TIMER)) { + count_compare_clockhandler(tf); + critical_exit(); + return; + } + + /* FIXME sched pin >? LOCK>? */ + for(i = sizeof(eirr)*8 - 1; i>=0; i--) { + if ((eirr & 1ULL<cntp, 1); + ie = mih->mih_event; + + write_c0_eirr64(1ULL << i); + if (!ie || TAILQ_EMPTY(&ie->ie_handlers)) { + printf("stray interrupt %d\n", i); + continue; + } + + if (intr_event_handle(ie, tf) != 0) { + printf("stray %s interrupt %d\n", + hard ? "hard" : "soft", i); + } + + } + critical_exit(); +} diff --git a/sys/mips/rmi/std.xlr b/sys/mips/rmi/std.xlr new file mode 100644 index 00000000000..da42ffeff05 --- /dev/null +++ b/sys/mips/rmi/std.xlr @@ -0,0 +1,10 @@ +# $FreeBSD$ +files "../xlr/files.xlr" + +# +# XXXMIPS: It's a stub, isn't it? +# +cpu CPU_MIPSXLR +option NOFPU +# Kludge for now +options TARGET_XLR_XLS From b398a6322f278f4f4109e2097251a1c836b91ae4 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Thu, 15 Oct 2009 21:06:59 +0000 Subject: [PATCH 260/380] These don't compile yet, but they are some of the first drivers that will need working on to fit from 6.x -> head. But first I must get the base to compile (wanted to get as much in the tree as I could before my flight to India). --- sys/dev/iicbus/xlr_eeprom.c | 156 ++++++++++++++++++++++++++++++ sys/dev/iicbus/xlr_rtc.c | 140 +++++++++++++++++++++++++++ sys/dev/iicbus/xlr_temperature.c | 161 +++++++++++++++++++++++++++++++ 3 files changed, 457 insertions(+) create mode 100644 sys/dev/iicbus/xlr_eeprom.c create mode 100644 sys/dev/iicbus/xlr_rtc.c create mode 100644 sys/dev/iicbus/xlr_temperature.c diff --git a/sys/dev/iicbus/xlr_eeprom.c b/sys/dev/iicbus/xlr_eeprom.c new file mode 100644 index 00000000000..613655a00cc --- /dev/null +++ b/sys/dev/iicbus/xlr_eeprom.c @@ -0,0 +1,156 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ + +#include +/* + * reading eeprom for the mac address . + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "iicbus_if.h" + +#define IIC_M_WR 0 /* write operation */ +#define XLR_EEPROM_ADDR 0xa0 /* slave address */ +#define XLR_EEPROM_ETH_MAC_ADDR 0x20 + + +struct xlr_eeprom_softc { + device_t sc_dev; + struct mtx sc_mtx; + uint8_t mac_address[6]; +}; + +static void xlr_eeprom_read_mac(struct xlr_eeprom_softc *); + +static int +xlr_eeprom_probe(device_t dev) +{ + /* XXX really probe? */ + device_set_desc(dev, "reading eeprom for mac address"); + return (0); +} + +static int +xlr_eeprom_mac_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct xlr_eeprom_softc *sc = arg1; + int temp ; + + xlr_eeprom_read_mac(sc); + return sysctl_handle_int(oidp, &temp, 0, req); +} + + +static int +xlr_eeprom_attach(device_t dev) +{ + struct xlr_eeprom_softc *sc = device_get_softc(dev); + struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev); + struct sysctl_oid *tree = device_get_sysctl_tree(dev); + + sc->sc_dev = dev; + + + mtx_init(&sc->sc_mtx, "eeprom", "eeprom", MTX_DEF); + + SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "eeprom-mac", CTLTYPE_INT | CTLFLAG_RD, sc, 0, + xlr_eeprom_mac_sysctl, "I", "mac address"); + + return (0); +} + +static int +xlr_eeprom_read(device_t dev, int reg) +{ + uint8_t addr = reg; + uint8_t data[1]; + struct iic_msg msgs[2] = { + { XLR_EEPROM_ADDR, IIC_M_WR, 1, &addr }, + { XLR_EEPROM_ADDR, IIC_M_RD, 1, data }, + }; + + return iicbus_transfer(dev, msgs, 2) != 0 ? -1 : data[0]; +} + + +static void +xlr_eeprom_read_mac(struct xlr_eeprom_softc *sc) +{ + int v; + int i; + + mtx_lock(&sc->sc_mtx); + printf("\nmac address is: \n"); + for(i=0; i<6; i++){ + v = xlr_eeprom_read(sc->sc_dev, XLR_EEPROM_ETH_MAC_ADDR+i); + sc->mac_address[i] = v; + if(i != 5) + printf("%x:", sc->mac_address[i]); + else + printf("%x\n", sc->mac_address[i]); + } + mtx_unlock(&sc->sc_mtx); +} + +static device_method_t xlr_eeprom_methods[] = { + DEVMETHOD(device_probe, xlr_eeprom_probe), + DEVMETHOD(device_attach, xlr_eeprom_attach), + + {0, 0}, +}; + +static driver_t xlr_eeprom_driver = { + "xlr_eeprom", + xlr_eeprom_methods, + sizeof(struct xlr_eeprom_softc), +}; +static devclass_t xlr_eeprom_devclass; + +DRIVER_MODULE(xlr_eeprom, iicbus, xlr_eeprom_driver, xlr_eeprom_devclass, 0, 0); +MODULE_VERSION(xlr_eeprom, 1); +MODULE_DEPEND(xlr_eeprom, iicbus, 1, 1, 1); diff --git a/sys/dev/iicbus/xlr_rtc.c b/sys/dev/iicbus/xlr_rtc.c new file mode 100644 index 00000000000..b53c1002b66 --- /dev/null +++ b/sys/dev/iicbus/xlr_rtc.c @@ -0,0 +1,140 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ + +#include +/* + * RTC chip sitting on the I2C bus. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "iicbus_if.h" +#include "clock_if.h" + +#define IIC_M_WR 0 /* write operation */ +#define XLR_SLAVE_ADDR (0xd0 ) /* slave address */ +#define XLR_RTC_COUNTER 0 /* counter (bytes 0-3) */ +#define NANOSEC 1000000000 + +struct xlr_rtc_softc { + device_t sc_dev; +}; + +static int +xlr_rtc_probe(device_t dev) +{ + device_set_desc(dev, "RTC on XLR board"); + return (0); +} + +static int +xlr_rtc_attach(device_t dev) +{ + struct xlr_rtc_softc *sc = device_get_softc(dev); + + sc->sc_dev = dev; + + clock_register(dev, 1000); + return (0); +} + +static int +xlr_rtc_gettime(device_t dev, struct timespec *ts) +{ + uint8_t addr[1] = { XLR_RTC_COUNTER }; + uint8_t secs[4]; + struct iic_msg msgs[2] = { + { XLR_SLAVE_ADDR, IIC_M_WR, 1, addr }, + { XLR_SLAVE_ADDR, IIC_M_RD, 4, secs }, + }; + int error; + + error = iicbus_transfer(dev, msgs, 2); + if (error == 0) { + /* counter has seconds since epoch */ + ts->tv_sec = (secs[3] << 24) | (secs[2] << 16) + | (secs[1] << 8) | (secs[0] << 0); + ts->tv_nsec = NANOSEC / 2; + } + return error; +} + +static int +xlr_rtc_settime(device_t dev, struct timespec *ts) +{ + /* NB: register pointer precedes actual data */ + uint8_t data[5] = { XLR_RTC_COUNTER }; + struct iic_msg msgs[1] = { + { XLR_SLAVE_ADDR, IIC_M_WR, 5, data }, + }; + + data[1] = (ts->tv_sec >> 0) & 0xff; + data[2] = (ts->tv_sec >> 8) & 0xff; + data[3] = (ts->tv_sec >> 16) & 0xff; + data[4] = (ts->tv_sec >> 24) & 0xff; + + return iicbus_transfer(dev, msgs, 1); +} + +static device_method_t xlr_rtc_methods[] = { + DEVMETHOD(device_probe, xlr_rtc_probe), + DEVMETHOD(device_attach, xlr_rtc_attach), + + DEVMETHOD(clock_gettime, xlr_rtc_gettime), + DEVMETHOD(clock_settime, xlr_rtc_settime), + + {0, 0}, +}; + +static driver_t xlr_rtc_driver = { + "xlr_rtc", + xlr_rtc_methods, + sizeof(struct xlr_rtc_softc), +}; +static devclass_t xlr_rtc_devclass; + +DRIVER_MODULE(xlr_rtc, iicbus, xlr_rtc_driver, xlr_rtc_devclass, 0, 0); +MODULE_VERSION(xlr_rtc, 1); +MODULE_DEPEND(xlr_rtc, iicbus, 1, 1, 1); diff --git a/sys/dev/iicbus/xlr_temperature.c b/sys/dev/iicbus/xlr_temperature.c new file mode 100644 index 00000000000..48d8490bbde --- /dev/null +++ b/sys/dev/iicbus/xlr_temperature.c @@ -0,0 +1,161 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ + +#include +/* + * temperature sensor chip sitting on the I2C bus. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "iicbus_if.h" + +#define IIC_M_WR 0 /* write operation */ +#define XLR_TEMPSENSOR_ADDR 0x98 /* slave address */ +#define XLR_ATX8_TEMPSENSOR_ADDR 0x9a /* slave address */ +#define XLR_TEMPSENSOR_EXT_TEMP 1 + + +struct xlr_temperature_softc { + device_t sc_dev; + struct mtx sc_mtx; + int sc_curtemp; + int sc_lastupdate; /* in ticks */ +}; + +static void xlr_temperature_update(struct xlr_temperature_softc *); + +static int +xlr_temperature_probe(device_t dev) +{ + /* XXX really probe? */ + device_set_desc(dev, "temperature sensor on XLR"); + return (0); +} + +static int +xlr_temperature_sysctl_temp(SYSCTL_HANDLER_ARGS) +{ + struct xlr_temperature_softc *sc = arg1; + int temp; + + xlr_temperature_update(sc); + temp = sc->sc_curtemp ; + return sysctl_handle_int(oidp, &temp, 0, req); +} + + +static int +xlr_temperature_attach(device_t dev) +{ + struct xlr_temperature_softc *sc = device_get_softc(dev); + struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev); + struct sysctl_oid *tree = device_get_sysctl_tree(dev); + + sc->sc_dev = dev; + mtx_init(&sc->sc_mtx, "xlr_temperature", "xlr_temperature", MTX_DEF); + + SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "temp", CTLTYPE_INT | CTLFLAG_RD, sc, 0, + xlr_temperature_sysctl_temp, "I", "operating temperature"); + + return (0); +} + +static int +xlr_temperature_read(device_t dev, int reg) +{ + uint8_t addr = reg; + uint8_t data[1]; + struct iic_msg msgs[2] = { + { XLR_TEMPSENSOR_ADDR, IIC_M_WR, 1, &addr }, + { XLR_TEMPSENSOR_ADDR, IIC_M_RD, 1, data }, + }; + + if(xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_VIII) + { + msgs[0].slave = XLR_ATX8_TEMPSENSOR_ADDR ; + msgs[1].slave = XLR_ATX8_TEMPSENSOR_ADDR ; + } + + return iicbus_transfer(dev, msgs, 2) != 0 ? -1 : data[0]; +} + + +static void +xlr_temperature_update(struct xlr_temperature_softc *sc) +{ + int v; + + mtx_lock(&sc->sc_mtx); + /* NB: no point in updating any faster than the chip */ + if (ticks - sc->sc_lastupdate > hz) { + v = xlr_temperature_read(sc->sc_dev, XLR_TEMPSENSOR_EXT_TEMP); + if (v >= 0) + sc->sc_curtemp = v; + sc->sc_lastupdate = ticks; + } + mtx_unlock(&sc->sc_mtx); +} + +static device_method_t xlr_temperature_methods[] = { + DEVMETHOD(device_probe, xlr_temperature_probe), + DEVMETHOD(device_attach, xlr_temperature_attach), + + {0, 0}, +}; + +static driver_t xlr_temperature_driver = { + "xlr_temperature", + xlr_temperature_methods, + sizeof(struct xlr_temperature_softc), +}; +static devclass_t xlr_temperature_devclass; + +DRIVER_MODULE(xlr_temperature, iicbus, xlr_temperature_driver, xlr_temperature_devclass, 0, 0); +MODULE_VERSION(xlr_temperature, 1); +MODULE_DEPEND(xlr_temperature, iicbus, 1, 1, 1); From 022e93cf87f3cd8ad0dddfb54c23286febcce00f Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Thu, 15 Oct 2009 21:08:06 +0000 Subject: [PATCH 261/380] Adds the untouched code from the RMI 6.4 stuff. This has a security device and the gig ethernet device. Note the 10gig device driver is yet missing. --- sys/dev/rmi/sec/desc.h | 3066 ++++++++++++++++++++++++++++++++ sys/dev/rmi/sec/rmilib.c | 3193 ++++++++++++++++++++++++++++++++++ sys/dev/rmi/sec/rmilib.h | 991 +++++++++++ sys/dev/rmi/sec/rmisec.c | 617 +++++++ sys/dev/rmi/sec/stats.h | 469 +++++ sys/dev/rmi/xlr/atx_cpld.h | 53 + sys/dev/rmi/xlr/rge.c | 2815 ++++++++++++++++++++++++++++++ sys/dev/rmi/xlr/rge.h | 978 +++++++++++ sys/dev/rmi/xlr/xgmac_mdio.h | 127 ++ 9 files changed, 12309 insertions(+) create mode 100755 sys/dev/rmi/sec/desc.h create mode 100644 sys/dev/rmi/sec/rmilib.c create mode 100644 sys/dev/rmi/sec/rmilib.h create mode 100644 sys/dev/rmi/sec/rmisec.c create mode 100644 sys/dev/rmi/sec/stats.h create mode 100644 sys/dev/rmi/xlr/atx_cpld.h create mode 100644 sys/dev/rmi/xlr/rge.c create mode 100644 sys/dev/rmi/xlr/rge.h create mode 100644 sys/dev/rmi/xlr/xgmac_mdio.h diff --git a/sys/dev/rmi/sec/desc.h b/sys/dev/rmi/sec/desc.h new file mode 100755 index 00000000000..cb76637805d --- /dev/null +++ b/sys/dev/rmi/sec/desc.h @@ -0,0 +1,3066 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ +#ifndef _DESC_H_ +#define _DESC_H_ + + +#define ONE_BIT 0x0000000000000001ULL +#define TWO_BITS 0x0000000000000003ULL +#define THREE_BITS 0x0000000000000007ULL +#define FOUR_BITS 0x000000000000000fULL +#define FIVE_BITS 0x000000000000001fULL +#define SIX_BITS 0x000000000000003fULL +#define SEVEN_BITS 0x000000000000007fULL +#define EIGHT_BITS 0x00000000000000ffULL +#define NINE_BITS 0x00000000000001ffULL +#define ELEVEN_BITS 0x00000000000007ffULL +#define TWELVE_BITS 0x0000000000000fffULL +#define FOURTEEN_BITS 0x0000000000003fffULL +#define TWENTYFOUR_BITS 0x0000000000ffffffULL +#define THIRTY_TWO_BITS 0x00000000ffffffffULL +#define THIRTY_FIVE_BITS 0x00000007ffffffffULL +#define FOURTY_BITS 0x000000ffffffffffULL + +#define MSG_IN_CTL_LEN_BASE 40 +#define MSG_IN_CTL_ADDR_BASE 0 + +#define GET_FIELD(word,field) \ + ((word) & (field ## _MASK)) >> (field ## _LSB) + +#define FIELD_VALUE(field,value) (((value) & (field ## _BITS)) << (field ## _LSB)) + +/* + * NOTE: this macro expects 'word' to be uninitialized (i.e. zeroed) + */ +#define SET_FIELD(word,field,value) \ + { (word) |= (((value) & (field ## _BITS)) << (field ## _LSB)); } + +/* + * This macro clears 'word', then sets the value + */ +#define CLEAR_SET_FIELD(word,field,value) \ + { (word) &= ~((field ## _BITS) << (field ## _LSB)); \ + (word) |= (((value) & (field ## _BITS)) << (field ## _LSB)); } + +/* + * NOTE: May be used to build value specific mask + * (e.g. GEN_MASK(CTL_DSC_CPHR_3DES,CTL_DSC_CPHR_LSB) + */ +#define GEN_MASK(bits,lsb) ((bits) << (lsb)) + + + + +/* + * Security block data and control exchange + * + * A 2-word message ring descriptor is used to pass a pointer to the control descriptor data structure + * and a pointer to the packet descriptor data structure: + * + * 63 61 60 54 53 52 49 48 45 44 40 + * 39 5 4 0 + * --------------------------------------------------------------------------------------------------------------------------------------------------------- + * | Ctrl | Resp Dest Id Entry0 | IF_L2ALLOC | UNUSED | Control Length | UNUSED + * | 35 MSB of address of control descriptor data structure | Software Scratch0 + * | + * --------------------------------------------------------------------------------------------------------------------------------------------------------- + * 3 7 1 4 4 5 + * 35 5 + * + * 63 61 60 54 53 52 51 50 46 45 44 40 39 5 4 0 + * --------------------------------------------------------------------------------------------------------------------------------------------------------- + * | Ctrl | UNUSED | WRB_COH | WRB_L2ALLOC | DF_PTR_L2ALLOC | UNUSED | Data Length | UNUSED | 35 MSB of address of packet descriptor data structure | UNUSED | + * --------------------------------------------------------------------------------------------------------------------------------------------------------- + * 3 7 1 1 1 5 1 5 35 5 + * + * Addresses assumed to be cache-line aligned, i.e., Address[4:0] ignored (using 5'h00 instead) + * + * Control length is the number of control cachelines to be read so user needs + * to round up + * the control length to closest integer multiple of 32 bytes. Note that at + * present (08/12/04) + * the longest (sensical) ctrl structure is <= 416 bytes, i.e., 13 cachelines. + * + * The packet descriptor data structure size is fixed at 1 cacheline (32 bytes). + * This effectively makes "Data Length" a Load/NoLoad bit. NoLoad causes an abort. + * + * + * Upon completion of operation, the security block returns a 2-word free descriptor + * in the following format: + * + * 63 61 60 54 53 52 51 49 48 47 40 39 0 + * ---------------------------------------------------------------------------------------------------------------------------- + * | Ctrl | Destination Id | 2'b00 | Desc Ctrl | 1'b0 | Instruction Error | Address of control descriptor data structure | + * ---------------------------------------------------------------------------------------------------------------------------- + * | Ctrl | Destination Id | 2'b00 | Desc Ctrl | 1'b0 | Data Error | Address of packet descriptor data structure | + * ---------------------------------------------------------------------------------------------------------------------------- + * + * The Instruction and Data Error codes are enumerated in the + * ControlDescriptor and PacketDescriptor sections below + * + */ + + +/* + * Operating assumptions + * ===================== + * + * + * -> For all IpSec ops, I assume that all the IP/IPSec/TCP headers + * and the data are present at the specified source addresses. + * I also assume that all necessary header data already exists + * at the destination. Additionally, in AH I assume that all + * mutable fields (IP.{TOS, Flags, Offset, TTL, Header_Checksum}) + * and the AH.Authentication_Data have been zeroed by the client. + * + * + * -> In principle, the HW can calculate TCP checksums on both + * incoming and outgoing data; however, since the TCP header + * contains the TCP checksum of the plain payload and the header + * is encrypted, two passes would be necessary to do checksum + encryption + * for outgoing messages; + * therefore the checksum engine will likely only be used during decryption + * (incoming). + * + * + * -> For all operations involving TCP checksum, I assume the client has filled + * the TCP checksum field with the appropriate value: + * + * - 0 for generation phase + * - actual value for verification phase (expecting 0 result) + * + * + * -> For ESP tunnel, the original IP header exists between the end of the + * ESP header and the beginning of the TCP header; it is assumed that the + * maximum length of this header is 16 k(32bit)words (used in CkSum_Offset). + * + * + * -> The authentication data is merely written to the destination address; + * the client is left with the task of comparing to the data in packet + * in decrypt. + * + * -> PacketDescriptor_t.dstLLWMask relevant to AES CTR mode only but it will + * affect all AES-related operations. It will not affect DES/3DES/bypass ops. + * The mask is applied to data as it emerges from the AES engine for the sole + * purpose of providing the authenticator and cksum engines with correct data. + * CAVEAT: the HW does not mask the incoming data. It is the user's responsibility + * to set to 0 the corresponding data in memory. If the surplus data is not masked + * in memory, cksum/auth results will be incorrect if those engines receive data + * straight from memory (i.e., not from cipher, as it happens while decoding) + */ + +/* + * Fragmentation and offset related notes + * ====================================== + * + * + * A) Rebuilding packets from fragments on dword boundaries. The discussion + * below is exemplified by tests memcpy_all_off_frags and memcpy_same_off_frags + * + * 1) The Offset before data/iv on first fragment is ALWAYS written back + * Non-zero dst dword or global offsets may cause more data to be + * written than the user-specified length. + * + * + * Example: + * -------- + * + * Below is a source (first fragment) packet (@ ADD0 cache-aligned address). + * Assume we just copy it and relevant data starts on + * dword 3 so Cipher_Offset = IV_Offset = 3 (dwords). + * D0X denotes relevant data and G denotes dont care data. + * Offset data is also copied so Packet_Legth = 9 (dwords) * 8 = 72 (bytes) + * Segment_src_address = ADD0 + * + * If we want to, e.g., copy so that the relevant (i.e., D0X) data + * starts at (cache-aligned address) ADD1, we need to specify + * Dst_dword_offset = 1 so D00 is moved from dword position 3 to 0 on next cache-line + * Cipher_dst_address = ADD1 - 0x20 so D00 is written to ADD1 + * + * Note that the security engine always writes full cachelines + * therefore, data written to dword0 0 of ADD1 (denoted w/ ?) is what the sec pipe + * write back buffer contained from previous op. + * + * + * SOURCE: DESTINATION: + * ------- ------------ + * + * Segment_src_address = ADD0 Cipher_dst_address = ADD1 - 0x20 + * Packet_Legth = 72 Dst_dword_offset = 1 + * Cipher_Offset = 3 + * IV_Offset = 3 + * Use_IV = ANY + * + * + * + * 3 2 1 0 3 2 1 0 + * ----------------------- ----------------------- + * | D00 | G | G | G | <- ADD0 | G | G | G | ? | <- ADD1 - 0x20 + * ----------------------- ----------------------- + * | D04 | D03 | D02 | D01 | | D03 | D02 | D01 | D00 | <- ADD1 + * ----------------------- ----------------------- + * | | | | D05 | | | | D05 | D04 | + * ----------------------- ----------------------- + * + * 2) On fragments following the first, IV_Offset is overloaded to mean data offset + * (number of dwords to skip from beginning of cacheline before starting processing) + * and Use_IV is overloaded to mean do writeback the offset (in the clear). + * These fields in combination with Dst_dword_offset allow packet fragments with + * arbitrary boundaries/lengthd to be reasembled. + * + * + * Example: + * -------- + * + * Assume data above was first fragment of a packet we'd like to merge to + * (second) fragment below located at ADD2. The written data should follow + * the previous data without gaps or overwrites. To achieve this, one should + * assert the "Next" field on the previous fragment and use self-explanatory + * set of parameters below + * + * + * SOURCE: DESTINATION: + * ------- ------------ + * + * Segment_src_address = ADD2 Cipher_dst_address = ADD1 + 0x20 + * Packet_Legth = 104 Dst_dword_offset = 1 + * IV_Offset = 1 + * Use_IV = 0 + * + * + * + * 3 2 1 0 3 2 1 0 + * ----------------------- ----------------------- + * | D12 | D11 | D10 | G | <- ADD2 | G | G | G | ? | <- ADD1 - 0x20 + * ----------------------- ----------------------- + * | D16 | D15 | D14 | D13 | | D03 | D02 | D01 | D00 | <- ADD1 + * ----------------------- ----------------------- + * | D1a | D19 | D18 | D17 | | D11 | D10 | D05 | D04 | <- ADD1 + 0x20 + * ----------------------- ----------------------- + * | | | | D1b | | D15 | D14 | D13 | D12 | + * ----------------------- ----------------------- + * | D19 | D18 | D17 | D16 | + * ----------------------- + * | | | D1b | D1a | + * ----------------------- + * + * It is note-worthy that the merging can only be achieved if Use_IV is 0. Indeed, the security + * engine always writes full lines, therefore ADD1 + 0x20 will be re-written. Setting Use_IV to 0 + * will allow the sec pipe write back buffer to preserve D04, D05 from previous frag and only + * receive D10, D11 thereby preserving the integrity of the previous data. + * + * 3) On fragments following the first, !UseIV in combination w/ Dst_dword_offset >= (4 - IV_Offset) + * will cause a wraparound of the write thus achieving all 16 possible (Initial_Location, Final_Location) + * combinations for the data. + * + * + * Example: + * -------- + * + * Contiguously merging 2 data sets above with a third located at ADD3. If this is the last fragment, + * reset its Next bit. + * + * + * SOURCE: DESTINATION: + * ------- ------------ + * + * Segment_src_address = ADD3 Cipher_dst_address = ADD1 + 0x80 + * Packet_Legth = 152 Dst_dword_offset = 3 + * IV_Offset = 3 + * Use_IV = 0 + * + * + * + * 3 2 1 0 3 2 1 0 + * ----------------------- ----------------------- + * | D20 | G | G | G | <- ADD2 | G | G | G | ? | <- ADD1 - 0x20 + * ----------------------- ----------------------- + * | D24 | D23 | D22 | D21 | | D03 | D02 | D01 | D00 | <- ADD1 + * ----------------------- ----------------------- + * | D28 | D27 | D26 | D25 | | D11 | D10 | D05 | D04 | <- ADD1 + 0x20 + * ----------------------- ----------------------- + * | D2c | D2b | D2a | D29 | | D15 | D14 | D13 | D12 | + * ----------------------- ----------------------- + * | | D2f | D2e | D2d | | D19 | D18 | D17 | D16 | + * ----------------------- ----------------------- + * | D21 | D20 | D1b | D1a | <- ADD1 + 0x80 + * ----------------------- + * | D25 | D24 | D23 | D22 | + * ----------------------- + * | D29 | D28 | D27 | D26 | + * ----------------------- + * | D2d | D2c | D2b | D2a | + * ----------------------- + * |(D2d)|(D2c)| D2f | D2e | + * ----------------------- + * + * It is worth noticing that always writing full-lines causes the last 2 dwords in the reconstituted + * packet to be unnecessarily written: (D2d) and (D2c) + * + * + * + * B) Implications of fragmentation on AES + * + * 1) AES is a 128 bit block cipher; therefore it requires an even dword total data length + * Data fragments (provided there are more than 1) are allowed to have odd dword + * data lengths provided the total length (cumulated over fragments) is an even dword + * count; an error will be generated otherwise, upon receiving the last fragment descriptor + * (see error conditions below). + * + * 2) While using fragments with AES, a fragment (other than first) starting with a != 0 (IV) offset + * while the subsequent total dword count given to AES is odd may not be required to write + * its offset (UseIV). Doing so will cause an error (see error conditions below). + * + * + * Example: + * -------- + * + * Suppose the first fragment has an odd DATA dword count and USES AES (as seen below) + * + * SOURCE: DESTINATION: + * ------- ------------ + * + * Segment_src_address = ADD0 Cipher_dst_address = ADD1 + * Packet_Legth = 64 Dst_dword_offset = 1 + * Cipher_Offset = 3 + * IV_Offset = 1 + * Use_IV = 1 + * Cipher = Any AES + * Next = 1 + * + * + * + * + * 3 2 1 0 3 2 1 0 + * ----------------------- ----------------------- + * | D00 | IV1 | IV0 | G | <- ADD0 | E00 | IV1 | IV0 | G | <- ADD1 + * ----------------------- ----------------------- + * | D04 | D03 | D02 | D01 | | X | E03 | E02 | E01 | + * ----------------------- ----------------------- + * + * At the end of processing of the previous fragment, the AES engine input buffer has D04 + * and waits for next dword, therefore the writeback buffer cannot finish writing the fragment + * to destination (X instead of E04). + * + * If a second fragment now arrives with a non-0 offset and requires the offset data to be + * written to destination, the previous write (still needing the arrival of the last dword + * required by the AES to complete the previous operation) cannot complete before the present + * should start causing a deadlock. + */ + +/* + * Command Control Word for Message Ring Descriptor + */ + +/* #define MSG_CMD_CTL_CTL */ +#define MSG_CMD_CTL_CTL_LSB 61 +#define MSG_CMD_CTL_CTL_BITS THREE_BITS +#define MSG_CMD_CTL_CTL_MASK (MSG_CMD_CTL_CTL_BITS << MSG_CMD_CTL_CTL_LSB) + +/* #define MSG_CMD_CTL_ID */ +#define MSG_CMD_CTL_ID_LSB 54 +#define MSG_CMD_CTL_ID_BITS SEVEN_BITS +#define MSG_CMD_CTL_ID_MASK (MSG_CMD_CTL_ID_BITS << MSG_CMD_CTL_ID_LSB) + +/* #define MSG_CMD_CTL_LEN */ +#define MSG_CMD_CTL_LEN_LSB 45 +#define MSG_CMD_CTL_LEN_BITS FOUR_BITS +#define MSG_CMD_CTL_LEN_MASK (MSG_CMD_CTL_LEN_BITS << MSG_CMD_CTL_LEN_LSB) + + +/* #define MSG_CMD_CTL_ADDR */ +#define MSG_CMD_CTL_ADDR_LSB 0 +#define MSG_CMD_CTL_ADDR_BITS FOURTY_BITS +#define MSG_CMD_CTL_ADDR_MASK (MSG_CMD_CTL_ADDR_BITS << MSG_CMD_CTL_ADDR_LSB) + +#define MSG_CMD_CTL_MASK (MSG_CMD_CTL_CTL_MASK | \ + MSG_CMD_CTL_LEN_MASK | MSG_CMD_CTL_ADDR_MASK) + +/* + * Command Data Word for Message Ring Descriptor + */ + +/* #define MSG_IN_DATA_CTL */ +#define MSG_CMD_DATA_CTL_LSB 61 +#define MSG_CMD_DATA_CTL_BITS THREE_BITS +#define MSG_CMD_DATA_CTL_MASK (MSG_CMD_DATA_CTL_BITS << MSG_CMD_DATA_CTL_LSB) + +/* #define MSG_CMD_DATA_LEN */ +#define MSG_CMD_DATA_LEN_LOAD 1 +#define MSG_CMD_DATA_LEN_LSB 45 +#define MSG_CMD_DATA_LEN_BITS ONE_BIT +#define MSG_CMD_DATA_LEN_MASK (MSG_CMD_DATA_LEN_BITS << MSG_CMD_DATA_LEN_LSB) + +/* #define MSG_CMD_DATA_ADDR */ +#define MSG_CMD_DATA_ADDR_LSB 0 +#define MSG_CMD_DATA_ADDR_BITS FOURTY_BITS +#define MSG_CMD_DATA_ADDR_MASK (MSG_CMD_DATA_ADDR_BITS << MSG_CMD_DATA_ADDR_LSB) + +#define MSG_CMD_DATA_MASK (MSG_CMD_DATA_CTL_MASK | \ + MSG_CMD_DATA_LEN_MASK | MSG_CMD_DATA_ADDR_MASK) + + +/* + * Upon completion of operation, the Sec block returns a 2-word free descriptor + * in the following format: + * + * 63 61 60 54 53 52 51 49 48 40 39 0 + * ---------------------------------------------------------------------------- + * | Ctrl | Destination Id | 2'b00 | Desc Ctrl | Control Error | Source Address | + * ---------------------------------------------------------------------------- + * | Ctrl | Destination Id | 2'b00 | Desc Ctrl | Data Error | Dest Address | + * ---------------------------------------------------------------------------- + * + * The Control and Data Error codes are enumerated below + * + * Error conditions + * ================ + * + * Control Error Code Control Error Condition + * ------------------ --------------------------- + * 9'h000 No Error + * 9'h001 Unknown Cipher Op ( Cipher == 3'h{6,7}) + * 9'h002 Unknown or Illegal Mode ((Mode == 3'h{2,3,4} & !AES) | (Mode == 3'h{5,6,7})) + * 9'h004 Unsupported CkSum Src (CkSum_Src == 2'h{2,3} & CKSUM) + * 9'h008 Forbidden CFB Mask (AES & CFBMode & UseNewKeysCFBMask & CFBMask[7] & (| CFBMask[6:0])) + * 9'h010 Unknown Ctrl Op ((| Ctrl[63:37]) | (| Ctrl[15:14])) + * 9'h020 UNUSED + * 9'h040 UNUSED + * 9'h080 Data Read Error + * 9'h100 Descriptor Ctrl Field Error (D0.Ctrl != SOP || D1.Ctrl != EOP) + * + * Data Error Code Data Error Condition + * --------------- -------------------- + * 9'h000 No Error + * 9'h001 Insufficient Data To Cipher (Packet_Length <= (Cipher_Offset or IV_Offset)) + * 9'h002 Illegal IV Location ((Cipher_Offset < IV_Offset) | (Cipher_Offset <= IV_Offset & AES & ~CTR)) + * 9'h004 Illegal Wordcount To AES (Packet_Length[3] != Cipher_Offset[0] & AES) + * 9'h008 Illegal Pad And ByteCount Spec (Hash_Byte_Count != 0 & !Pad_Hash) + * 9'h010 Insufficient Data To CkSum ({Packet_Length, 1'b0} <= CkSum_Offset) + * 9'h020 Unknown Data Op ((| dstLLWMask[63:60]) | (| dstLLWMask[57:40]) | (| authDst[63:40]) | (| ckSumDst[63:40])) + * 9'h040 Insufficient Data To Auth ({Packet_Length} <= Auth_Offset) + * 9'h080 Data Read Error + * 9'h100 UNUSED + */ + +/* + * Result Control Word for Message Ring Descriptor + */ + +/* #define MSG_RSLT_CTL_CTL */ +#define MSG_RSLT_CTL_CTL_LSB 61 +#define MSG_RSLT_CTL_CTL_BITS THREE_BITS +#define MSG_RSLT_CTL_CTL_MASK \ + (MSG_RSLT_CTL_CTL_BITS << MSG_RSLT_CTL_CTL_LSB) + +/* #define MSG_RSLT_CTL_DST_ID */ +#define MSG_RSLT_CTL_DST_ID_LSB 54 +#define MSG_RSLT_CTL_DST_ID_BITS SEVEN_BITS +#define MSG_RSLT_CTL_DST_ID_MASK \ + (MSG_RSLT_CTL_DST_ID_BITS << MSG_RSLT_CTL_DST_ID_LSB) + +/* #define MSG_RSLT_CTL_DSC_CTL */ +#define MSG_RSLT_CTL_DSC_CTL_LSB 49 +#define MSG_RSLT_CTL_DSC_CTL_BITS THREE_BITS +#define MSG_RSLT_CTL_DSC_CTL_MASK \ + (MSG_RSLT_CTL_DSC_CTL_BITS << MSG_RSLT_CTL_DSC_CTL_LSB) + +/* #define MSG_RSLT_CTL_INST_ERR */ +#define MSG_RSLT_CTL_INST_ERR_LSB 40 +#define MSG_RSLT_CTL_INST_ERR_BITS NINE_BITS +#define MSG_RSLT_CTL_INST_ERR_MASK \ + (MSG_RSLT_CTL_INST_ERR_BITS << MSG_RSLT_CTL_INST_ERR_LSB) + +/* #define MSG_RSLT_CTL_DSC_ADDR */ +#define MSG_RSLT_CTL_DSC_ADDR_LSB 0 +#define MSG_RSLT_CTL_DSC_ADDR_BITS FOURTY_BITS +#define MSG_RSLT_CTL_DSC_ADDR_MASK \ + (MSG_RSLT_CTL_DSC_ADDR_BITS << MSG_RSLT_CTL_DSC_ADDR_LSB) + +/* #define MSG_RSLT_CTL_MASK */ +#define MSG_RSLT_CTL_MASK \ + (MSG_RSLT_CTL_CTRL_MASK | MSG_RSLT_CTL_DST_ID_MASK | \ + MSG_RSLT_CTL_DSC_CTL_MASK | MSG_RSLT_CTL_INST_ERR_MASK | \ + MSG_RSLT_CTL_DSC_ADDR_MASK) + +/* + * Result Data Word for Message Ring Descriptor + */ +/* #define MSG_RSLT_DATA_CTL */ +#define MSG_RSLT_DATA_CTL_LSB 61 +#define MSG_RSLT_DATA_CTL_BITS THREE_BITS +#define MSG_RSLT_DATA_CTL_MASK \ + (MSG_RSLT_DATA_CTL_BITS << MSG_RSLT_DATA_CTL_LSB) + +/* #define MSG_RSLT_DATA_DST_ID */ +#define MSG_RSLT_DATA_DST_ID_LSB 54 +#define MSG_RSLT_DATA_DST_ID_BITS SEVEN_BITS +#define MSG_RSLT_DATA_DST_ID_MASK \ + (MSG_RSLT_DATA_DST_ID_BITS << MSG_RSLT_DATA_DST_ID_LSB) + +/* #define MSG_RSLT_DATA_DSC_CTL */ +#define MSG_RSLT_DATA_DSC_CTL_LSB 49 +#define MSG_RSLT_DATA_DSC_CTL_BITS THREE_BITS +#define MSG_RSLT_DATA_DSC_CTL_MASK \ + (MSG_RSLT_DATA_DSC_CTL_BITS << MSG_RSLT_DATA_DSC_CTL_LSB) + +/* #define MSG_RSLT_DATA_INST_ERR */ +#define MSG_RSLT_DATA_INST_ERR_LSB 40 +#define MSG_RSLT_DATA_INST_ERR_BITS NINE_BITS +#define MSG_RSLT_DATA_INST_ERR_MASK \ + (MSG_RSLT_DATA_INST_ERR_BITS << MSG_RSLT_DATA_INST_ERR_LSB) + +/* #define MSG_RSLT_DATA_DSC_ADDR */ +#define MSG_RSLT_DATA_DSC_ADDR_LSB 0 +#define MSG_RSLT_DATA_DSC_ADDR_BITS FOURTY_BITS +#define MSG_RSLT_DATA_DSC_ADDR_MASK \ + (MSG_RSLT_DATA_DSC_ADDR_BITS << MSG_RSLT_DATA_DSC_ADDR_LSB) + +#define MSG_RSLT_DATA_MASK \ + (MSG_RSLT_DATA_CTRL_MASK | MSG_RSLT_DATA_DST_ID_MASK | \ + MSG_RSLT_DATA_DSC_CTL_MASK | MSG_RSLT_DATA_INST_ERR_MASK | \ + MSG_RSLT_DATA_DSC_ADDR_MASK) + + +/* + * Common Message Definitions + * + */ + +/* #define MSG_CTL_OP_ADDR */ +#define MSG_CTL_OP_ADDR_LSB 0 +#define MSG_CTL_OP_ADDR_BITS FOURTY_BITS +#define MSG_CTL_OP_ADDR_MASK (MSG_CTL_OP_ADDR_BITS << MSG_CTL_OP_ADDR_LSB) + +#define MSG_CTL_OP_TYPE +#define MSG_CTL_OP_TYPE_LSB 3 +#define MSG_CTL_OP_TYPE_BITS TWO_BITS +#define MSG_CTL_OP_TYPE_MASK \ + (MSG_CTL_OP_TYPE_BITS << MSG_CTL_OP_TYPE_LSB) + +#define MSG0_CTL_OP_ENGINE_SYMKEY 0x01 +#define MSG0_CTL_OP_ENGINE_PUBKEY 0x02 + +#define MSG1_CTL_OP_SYMKEY_PIPE0 0x00 +#define MSG1_CTL_OP_SYMKEY_PIPE1 0x01 +#define MSG1_CTL_OP_SYMKEY_PIPE2 0x02 +#define MSG1_CTL_OP_SYMKEY_PIPE3 0x03 + +#define MSG1_CTL_OP_PUBKEY_PIPE0 0x00 +#define MSG1_CTL_OP_PUBKEY_PIPE1 0x01 +#define MSG1_CTL_OP_PUBKEY_PIPE2 0x02 +#define MSG1_CTL_OP_PUBKEY_PIPE3 0x03 + + +/* /----------------------------------------\ + * | | + * | ControlDescriptor_s datastructure | + * | | + * \----------------------------------------/ + * + * + * ControlDescriptor_t.Instruction + * ------------------------------- + * + * 63 44 43 42 41 40 39 35 34 32 31 29 28 + * -------------------------------------------------------------------------------------------------------------------- + * || UNUSED || OverrideCipher | Arc4Wait4Save | SaveArc4State | LoadArc4State | Arc4KeyLen | Cipher | Mode | InCp_Key || ... CONT ... + * -------------------------------------------------------------------------------------------------------------------- + * 20 1 1 1 1 5 3 3 1 + * <-----------------------------------------------CIPHER---------------------------------------------------> + * + * 27 25 24 23 22 21 20 19 17 16 15 0 + * ----------------------------------------------------------------------------- + * || UNUSED | Hash_Hi | HMAC | Hash_Lo | InHs_Key || UNUSED || CkSum || UNUSED || + * ----------------------------------------------------------------------------- + * 3 1 1 2 1 3 1 16 + * <---------------------HASH---------------------><-----------CKSUM-----------> + * + * X0 CIPHER.Arc4Wait4Save = If op is Arc4 and it requires state saving, then + * setting this bit will cause the current op to + * delay subsequent op loading until saved state data + * becomes visible. + * CIPHER.OverrideCipher = Override encryption if PacketDescriptor_t.dstDataSettings.CipherPrefix + * is set; data will be copied out (and optionally auth/cksum) + * in the clear. This is used in GCM mode if auth only as we + * still need E(K, 0) calculated by cipher. Engine behavior is + * undefined if this bit is set and CipherPrefix is not. + * X0 SaveArc4State = Save Arc4 state at the end of Arc4 operation + * X0 LoadArc4State = Load Arc4 state at the beginning of an Arc4 operation + * This overriden by the InCp_Key setting for Arc4 + * Arc4KeyLen = Length in bytes of Arc4 key (0 is interpreted as 32) + * Ignored for other ciphers + * For ARC4, IFetch/IDecode will always read exactly 4 + * consecutive dwords into its CipherKey{0,3} regardless + * of this quantity; it will however only use the specified + * number of bytes. + * Cipher = 3'b000 Bypass + * 3'b001 DES + * 3'b010 3DES + * 3'b011 AES 128-bit key + * 3'b100 AES 192-bit key + * 3'b101 AES 256-bit key + * 3'b110 ARC4 + * 3'b111 Kasumi f8 + * Remainder UNDEFINED + * Mode = 3'b000 ECB + * 3'b001 CBC + * 3'b010 CFB (AES only, otherwise undefined) + * 3'b011 OFB (AES only, otherwise undefined) + * 3'b100 CTR (AES only, otherwise undefined) + * 3'b101 F8 (AES only, otherwise undefined) + * Remainder UNDEFINED + * InCp_Key = 1'b0 Preserve old Cipher Keys + * 1'b1 Load new Cipher Keys from memory to local registers + * and recalculate the Arc4 Sbox if Arc4 Cipher chosen; + * This overrides LoadArc4State setting. + * HASH.HMAC = 1'b0 Hash without HMAC + * 1'b1 Hash with HMAC + * Needs to be set to 0 for GCM and Kasumi F9 authenticators + * otherwise unpredictable results will be generated + * Hash = 2'b00 Hash NOP + * 2'b01 MD5 + * 2'b10 SHA-1 + * 2'b11 SHA-256 + * 3'b100 SHA-384 + * 3'b101 SHA-512 + * 3'b110 GCM + * 3'b111 Kasumi f9 + * InHs_Key = 1'b0 Preserve old HMAC Keys + * If GCM is selected as authenticator, leaving this bit + * at 0 will cause the engine to use the old H value. + * It will use the old SCI inside the decoder if + * CFBMask[1:0] == 2'b11. + * If Kasumi F9 authenticator, using 0 preserves + * old keys (IK) in decoder. + * 1'b1 Load new HMAC Keys from memory to local registers + * Setting this bit while Cipher=Arc4 and LoadArc4State=1 + * causes the decoder to load the Arc4 state from the + * cacheline following the HMAC keys (Whether HASH.HMAC + * is set or not). + * If GCM is selected as authenticator, setting this bit + * causes both H (16 bytes) and SCI (8 bytes) to be loaded + * from memory to the decoder. H will be loaded to the engine + * but SCI is only loaded to the engine if CFBMask[1:0] == 2'b11. + * If Kasumi F9 authenticator, using 1 loads new keys (IK) + * from memory to decoder. + * CHECKSUM.CkSum = 1'b0 CkSum NOP + * 1'b1 INTERNET_CHECKSUM + * + * + * + */ + + /* #define CTRL_DSC_OVERRIDECIPHER */ +#define CTL_DSC_OVERRIDECIPHER_OFF 0 +#define CTL_DSC_OVERRIDECIPHER_ON 1 +#define CTL_DSC_OVERRIDECIPHER_LSB 43 +#define CTL_DSC_OVERRIDECIPHER_BITS ONE_BIT +#define CTL_DSC_OVERRIDECIPHER_MASK (CTL_DSC_OVERRIDECIPHER_BITS << CTL_DSC_OVERRIDECIPHER_LSB) + +/* #define CTRL_DSC_ARC4_WAIT4SAVE */ +#define CTL_DSC_ARC4_WAIT4SAVE_OFF 0 +#define CTL_DSC_ARC4_WAIT4SAVE_ON 1 +#define CTL_DSC_ARC4_WAIT4SAVE_LSB 42 +#define CTL_DSC_ARC4_WAIT4SAVE_BITS ONE_BIT +#define CTL_DSC_ARC4_WAIT4SAVE_MASK (CTL_DSC_ARC4_WAIT4SAVE_BITS << CTL_DSC_ARC4_WAIT4SAVE_LSB) + +/* #define CTRL_DSC_ARC4_SAVESTATE */ +#define CTL_DSC_ARC4_SAVESTATE_OFF 0 +#define CTL_DSC_ARC4_SAVESTATE_ON 1 +#define CTL_DSC_ARC4_SAVESTATE_LSB 41 +#define CTL_DSC_ARC4_SAVESTATE_BITS ONE_BIT +#define CTL_DSC_ARC4_SAVESTATE_MASK (CTL_DSC_ARC4_SAVESTATE_BITS << CTL_DSC_ARC4_SAVESTATE_LSB) + +/* #define CTRL_DSC_ARC4_LOADSTATE */ +#define CTL_DSC_ARC4_LOADSTATE_OFF 0 +#define CTL_DSC_ARC4_LOADSTATE_ON 1 +#define CTL_DSC_ARC4_LOADSTATE_LSB 40 +#define CTL_DSC_ARC4_LOADSTATE_BITS ONE_BIT +#define CTL_DSC_ARC4_LOADSTATE_MASK (CTL_DSC_ARC4_LOADSTATE_BITS << CTL_DSC_ARC4_LOADSTATE_LSB) + +/* #define CTRL_DSC_ARC4_KEYLEN */ +#define CTL_DSC_ARC4_KEYLEN_LSB 35 +#define CTL_DSC_ARC4_KEYLEN_BITS FIVE_BITS +#define CTL_DSC_ARC4_KEYLEN_MASK (CTL_DSC_ARC4_KEYLEN_BITS << CTL_DSC_ARC4_KEYLEN_LSB) + +/* #define CTL_DSC_CPHR (cipher) */ +#define CTL_DSC_CPHR_BYPASS 0 /* undefined */ +#define CTL_DSC_CPHR_DES 1 +#define CTL_DSC_CPHR_3DES 2 +#define CTL_DSC_CPHR_AES128 3 +#define CTL_DSC_CPHR_AES192 4 +#define CTL_DSC_CPHR_AES256 5 +#define CTL_DSC_CPHR_ARC4 6 +#define CTL_DSC_CPHR_KASUMI_F8 7 +#define CTL_DSC_CPHR_LSB 32 +#define CTL_DSC_CPHR_BITS THREE_BITS +#define CTL_DSC_CPHR_MASK (CTL_DSC_CPHR_BITS << CTL_DSC_CPHR_LSB) + +/* #define CTL_DSC_MODE */ +#define CTL_DSC_MODE_ECB 0 +#define CTL_DSC_MODE_CBC 1 +#define CTL_DSC_MODE_CFB 2 +#define CTL_DSC_MODE_OFB 3 +#define CTL_DSC_MODE_CTR 4 +#define CTL_DSC_MODE_F8 5 +#define CTL_DSC_MODE_LSB 29 +#define CTL_DSC_MODE_BITS THREE_BITS +#define CTL_DSC_MODE_MASK (CTL_DSC_MODE_BITS << CTL_DSC_MODE_LSB) + +/* #define CTL_DSC_ICPHR */ +#define CTL_DSC_ICPHR_OKY 0 /* Old Keys */ +#define CTL_DSC_ICPHR_NKY 1 /* New Keys */ +#define CTL_DSC_ICPHR_LSB 28 +#define CTL_DSC_ICPHR_BITS ONE_BIT +#define CTL_DSC_ICPHR_MASK (CTL_DSC_ICPHR_BITS << CTL_DSC_ICPHR_LSB) + +/* #define CTL_DSC_HASHHI */ +#define CTL_DSC_HASHHI_LSB 24 +#define CTL_DSC_HASHHI_BITS ONE_BIT +#define CTL_DSC_HASHHI_MASK (CTL_DSC_HASHHI_BITS << CTL_DSC_HASHHI_LSB) + +/* #define CTL_DSC_HMAC */ +#define CTL_DSC_HMAC_OFF 0 +#define CTL_DSC_HMAC_ON 1 +#define CTL_DSC_HMAC_LSB 23 +#define CTL_DSC_HMAC_BITS ONE_BIT +#define CTL_DSC_HMAC_MASK (CTL_DSC_HMAC_BITS << CTL_DSC_HMAC_LSB) + +/* #define CTL_DSC_HASH */ +#define CTL_DSC_HASH_NOP 0 +#define CTL_DSC_HASH_MD5 1 +#define CTL_DSC_HASH_SHA1 2 +#define CTL_DSC_HASH_SHA256 3 +#define CTL_DSC_HASH_SHA384 4 +#define CTL_DSC_HASH_SHA512 5 +#define CTL_DSC_HASH_GCM 6 +#define CTL_DSC_HASH_KASUMI_F9 7 +#define CTL_DSC_HASH_LSB 21 +#define CTL_DSC_HASH_BITS TWO_BITS +#define CTL_DSC_HASH_MASK (CTL_DSC_HASH_BITS << CTL_DSC_HASH_LSB) + +/* #define CTL_DSC_IHASH */ +#define CTL_DSC_IHASH_OLD 0 +#define CTL_DSC_IHASH_NEW 1 +#define CTL_DSC_IHASH_LSB 20 +#define CTL_DSC_IHASH_BITS ONE_BIT +#define CTL_DSC_IHASH_MASK (CTL_DSC_IHASH_BITS << CTL_DSC_IHASH_LSB) + +/* #define CTL_DSC_CKSUM */ +#define CTL_DSC_CKSUM_NOP 0 +#define CTL_DSC_CKSUM_IP 1 +#define CTL_DSC_CKSUM_LSB 16 +#define CTL_DSC_CKSUM_BITS ONE_BIT +#define CTL_DSC_CKSUM_MASK (CTL_DSC_CKSUM_BITS << CTL_DSC_CKSUM_LSB) + + +/* + * Component strcts and unions defining CipherHashInfo_u + */ + +/* AES256, (ECB, CBC, OFB, CTR, CFB), HMAC (MD5, SHA-1, SHA-256) - 96 bytes */ +typedef struct AES256HMAC_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} AES256HMAC_t, *AES256HMAC_pt; + +/* AES256, (ECB, CBC, OFB, CTR, CFB), HMAC (SHA-384, SHA-512) - 160 bytes */ +typedef struct AES256HMAC2_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} AES256HMAC2_t, *AES256HMAC2_pt; + +/* AES256, (ECB, CBC, OFB, CTR, CFB), GCM - 56 bytes */ +typedef struct AES256GCM_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} AES256GCM_t, *AES256GCM_pt; + +/* AES256, (ECB, CBC, OFB, CTR, CFB), F9 - 56 bytes */ +typedef struct AES256F9_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t authKey0; + uint64_t authKey1; +} AES256F9_t, *AES256F9_pt; + +/* AES256, (ECB, CBC, OFB, CTR, CFB), Non-HMAC (MD5, SHA-1, SHA-256) - 32 bytes */ +typedef struct AES256_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; +} AES256_t, *AES256_pt; + + +/* All AES192 possibilities */ + +/* AES192, (ECB, CBC, OFB, CTR, CFB), HMAC (MD5, SHA-1, SHA-192) - 88 bytes */ +typedef struct AES192HMAC_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} AES192HMAC_t, *AES192HMAC_pt; + +/* AES192, (ECB, CBC, OFB, CTR, CFB), HMAC (SHA-384, SHA-512) - 152 bytes */ +typedef struct AES192HMAC2_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} AES192HMAC2_t, *AES192HMAC2_pt; + +/* AES192, (ECB, CBC, OFB, CTR, CFB), GCM - 48 bytes */ +typedef struct AES192GCM_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} AES192GCM_t, *AES192GCM_pt; + +/* AES192, (ECB, CBC, OFB, CTR, CFB), F9 - 48 bytes */ +typedef struct AES192F9_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t authKey0; + uint64_t authKey1; +} AES192F9_t, *AES192F9_pt; + +/* AES192, (ECB, CBC, OFB, CTR, CFB), Non-HMAC (MD5, SHA-1, SHA-192) - 24 bytes */ +typedef struct AES192_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; +} AES192_t, *AES192_pt; + + +/* All AES128 possibilities */ + +/* AES128, (ECB, CBC, OFB, CTR, CFB), HMAC (MD5, SHA-1, SHA-128) - 80 bytes */ +typedef struct AES128HMAC_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} AES128HMAC_t, *AES128HMAC_pt; + +/* AES128, (ECB, CBC, OFB, CTR, CFB), HMAC (SHA-384, SHA-612) - 144 bytes */ +typedef struct AES128HMAC2_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} AES128HMAC2_t, *AES128HMAC2_pt; + +/* AES128, (ECB, CBC, OFB, CTR, CFB), GCM - 40 bytes */ +typedef struct AES128GCM_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} AES128GCM_t, *AES128GCM_pt; + +/* AES128, (ECB, CBC, OFB, CTR, CFB), F9 - 48 bytes */ +typedef struct AES128F9_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t authKey0; + uint64_t authKey1; +} AES128F9_t, *AES128F9_pt; + +/* AES128, (ECB, CBC, OFB, CTR, CFB), Non-HMAC (MD5, SHA-1, SHA-128) - 16 bytes */ +typedef struct AES128_s { + uint64_t cipherKey0; + uint64_t cipherKey1; +} AES128_t, *AES128_pt; + +/* AES128, (OFB F8), Non-HMAC (MD5, SHA-1, SHA-256) - 32 bytes */ +typedef struct AES128F8_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKeyMask0; + uint64_t cipherKeyMask1; +} AES128F8_t, *AES128F8_pt; + +/* AES128, (OFB F8), HMAC (MD5, SHA-1, SHA-256) - 96 bytes */ +typedef struct AES128F8HMAC_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKeyMask0; + uint64_t cipherKeyMask1; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} AES128F8HMAC_t, *AES128F8HMAC_pt; + +/* AES128, (OFB F8), HMAC (SHA-384, SHA-512) - 160 bytes */ +typedef struct AES128F8HMAC2_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKeyMask0; + uint64_t cipherKeyMask1; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} AES128F8HMAC2_t, *AES128F8HMAC2_pt; + +/* AES192, (OFB F8), Non-HMAC (MD5, SHA-1, SHA-256) - 48 bytes */ +typedef struct AES192F8_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKeyMask0; + uint64_t cipherKeyMask1; + uint64_t cipherKeyMask2; +} AES192F8_t, *AES192F8_pt; + +/* AES192, (OFB F8), HMAC (MD5, SHA-1, SHA-256) - 112 bytes */ +typedef struct AES192F8HMAC_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKeyMask0; + uint64_t cipherKeyMask1; + uint64_t cipherKeyMask2; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} AES192F8HMAC_t, *AES192F8HMAC_pt; + +/* AES192, (OFB F8), HMAC (SHA-384, SHA-512) - 176 bytes */ +typedef struct AES192F8HMAC2_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKeyMask0; + uint64_t cipherKeyMask1; + uint64_t cipherKeyMask2; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} AES192F8HMAC2_t, *AES192F8HMAC2_pt; + +/* AES256, (OFB F8), Non-HMAC (MD5, SHA-1, SHA-256) - 64 bytes */ +typedef struct AES256F8_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t cipherKeyMask0; + uint64_t cipherKeyMask1; + uint64_t cipherKeyMask2; + uint64_t cipherKeyMask3; +} AES256F8_t, *AES256F8_pt; + +/* AES256, (OFB F8), HMAC (MD5, SHA-1, SHA-256) - 128 bytes */ +typedef struct AES256F8HMAC_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t cipherKeyMask0; + uint64_t cipherKeyMask1; + uint64_t cipherKeyMask2; + uint64_t cipherKeyMask3; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} AES256F8HMAC_t, *AES256F8HMAC_pt; + +/* AES256, (OFB F8), HMAC (SHA-384, SHA-512) - 192 bytes */ +typedef struct AES256F8HMAC2_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t cipherKeyMask0; + uint64_t cipherKeyMask1; + uint64_t cipherKeyMask2; + uint64_t cipherKeyMask3; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} AES256F8HMAC2_t, *AES256F8HMAC2_pt; + +/* AES256, (F8), GCM - 40 bytes */ +typedef struct AES128F8GCM_s { + uint64_t cipherKey0; + uint64_t cipherKey2; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} AES128F8GCM_t, *AES128F8GCM_pt; + +/* AES256, (F8), GCM - 48 bytes */ +typedef struct AES192F8GCM_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} AES192F8GCM_t, *AES192F8GCM_pt; + +/* AES256, (F8), GCM - 56 bytes */ +typedef struct AES256F8GCM_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} AES256F8GCM_t, *AES256F8GCM_pt; + +/* AES256, (F8), F9 - 40 bytes */ +typedef struct AES128F8F9_s { + uint64_t cipherKey0; + uint64_t cipherKey2; + uint64_t authKey0; + uint64_t authKey1; +} AES128F8F9_t, *AES128F8F9_pt; + +/* AES256, (F8), F9 - 48 bytes */ +typedef struct AES192F8F9_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t authKey0; + uint64_t authKey1; +} AES192F8F9_t, *AES192F8F9_pt; + +/* AES256F8, (F8), F9 - 56 bytes */ +typedef struct AES256F8F9_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t authKey0; + uint64_t authKey1; +} AES256F8F9_t, *AES256F8F9_pt; + +/* All DES possibilities */ + +/* DES, (ECB, CBC), HMAC (MD5, SHA-1, SHA-128) - 72 bytes */ +typedef struct DESHMAC_s { + uint64_t cipherKey0; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} DESHMAC_t, *DESHMAC_pt; + +/* DES, (ECB, CBC), HMAC (SHA-384, SHA-512) - 136 bytes */ +typedef struct DESHMAC2_s { + uint64_t cipherKey0; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} DESHMAC2_t, *DESHMAC2_pt; + +/* DES, (ECB, CBC), GCM - 32 bytes */ +typedef struct DESGCM_s { + uint64_t cipherKey0; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} DESGCM_t, *DESGCM_pt; + +/* DES, (ECB, CBC), F9 - 32 bytes */ +typedef struct DESF9_s { + uint64_t cipherKey0; + uint64_t authKey0; + uint64_t authKey1; +} DESF9_t, *DESF9_pt; + +/* DES, (ECB, CBC), Non-HMAC (MD5, SHA-1, SHA-128) - 9 bytes */ +typedef struct DES_s { + uint64_t cipherKey0; +} DES_t, *DES_pt; + + +/* All 3DES possibilities */ + +/* 3DES, (ECB, CBC), HMAC (MD5, SHA-1, SHA-128) - 88 bytes */ +typedef struct DES3HMAC_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} DES3HMAC_t, *DES3HMAC_pt; + +/* 3DES, (ECB, CBC), HMAC (SHA-384, SHA-512) - 152 bytes */ +typedef struct DES3HMAC2_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} DES3HMAC2_t, *DES3HMAC2_pt; + +/* 3DES, (ECB, CBC), GCM - 48 bytes */ +typedef struct DES3GCM_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} DES3GCM_t, *DES3GCM_pt; + +/* 3DES, (ECB, CBC), GCM - 48 bytes */ +typedef struct DES3F9_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t authKey0; + uint64_t authKey1; +} DES3F9_t, *DES3F9_pt; + +/* 3DES, (ECB, CBC), Non-HMAC (MD5, SHA-1, SHA-128) - 24 bytes */ +typedef struct DES3_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; +} DES3_t, *DES3_pt; + + +/* HMAC only - no cipher */ + +/* HMAC (MD5, SHA-1, SHA-128) - 64 bytes */ +typedef struct HMAC_s { + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} HMAC_t, *HMAC_pt; + +/* HMAC (SHA-384, SHA-512) - 128 bytes */ +typedef struct HMAC2_s { + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} HMAC2_t, *HMAC2_pt; + +/* GCM - 24 bytes */ +typedef struct GCM_s { + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} GCM_t, *GCM_pt; + +/* F9 - 24 bytes */ +typedef struct F9_s { + uint64_t authKey0; + uint64_t authKey1; +} F9_t, *F9_pt; + +/* All ARC4 possibilities */ +/* ARC4, HMAC (MD5, SHA-1, SHA-256) - 96 bytes */ +typedef struct ARC4HMAC_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} ARC4HMAC_t, *ARC4HMAC_pt; + +/* ARC4, HMAC (SHA-384, SHA-512) - 160 bytes */ +typedef struct ARC4HMAC2_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} ARC4HMAC2_t, *ARC4HMAC2_pt; + +/* ARC4, GCM - 56 bytes */ +typedef struct ARC4GCM_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} ARC4GCM_t, *ARC4GCM_pt; + +/* ARC4, F9 - 56 bytes */ +typedef struct ARC4F9_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t authKey0; + uint64_t authKey1; +} ARC4F9_t, *ARC4F9_pt; + +/* ARC4, HMAC (MD5, SHA-1, SHA-256) - 408 bytes (not including 8 bytes from instruction) */ +typedef struct ARC4StateHMAC_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t PAD0; + uint64_t PAD1; + uint64_t PAD2; + uint64_t Arc4SboxData0; + uint64_t Arc4SboxData1; + uint64_t Arc4SboxData2; + uint64_t Arc4SboxData3; + uint64_t Arc4SboxData4; + uint64_t Arc4SboxData5; + uint64_t Arc4SboxData6; + uint64_t Arc4SboxData7; + uint64_t Arc4SboxData8; + uint64_t Arc4SboxData9; + uint64_t Arc4SboxData10; + uint64_t Arc4SboxData11; + uint64_t Arc4SboxData12; + uint64_t Arc4SboxData13; + uint64_t Arc4SboxData14; + uint64_t Arc4SboxData15; + uint64_t Arc4SboxData16; + uint64_t Arc4SboxData17; + uint64_t Arc4SboxData18; + uint64_t Arc4SboxData19; + uint64_t Arc4SboxData20; + uint64_t Arc4SboxData21; + uint64_t Arc4SboxData22; + uint64_t Arc4SboxData23; + uint64_t Arc4SboxData24; + uint64_t Arc4SboxData25; + uint64_t Arc4SboxData26; + uint64_t Arc4SboxData27; + uint64_t Arc4SboxData28; + uint64_t Arc4SboxData29; + uint64_t Arc4SboxData30; + uint64_t Arc4SboxData31; + uint64_t Arc4IJData; + uint64_t PAD3; + uint64_t PAD4; + uint64_t PAD5; +} ARC4StateHMAC_t, *ARC4StateHMAC_pt; + +/* ARC4, HMAC (SHA-384, SHA-512) - 480 bytes (not including 8 bytes from instruction) */ +typedef struct ARC4StateHMAC2_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; + uint64_t PAD0; + uint64_t PAD1; + uint64_t PAD2; + uint64_t Arc4SboxData0; + uint64_t Arc4SboxData1; + uint64_t Arc4SboxData2; + uint64_t Arc4SboxData3; + uint64_t Arc4SboxData4; + uint64_t Arc4SboxData5; + uint64_t Arc4SboxData6; + uint64_t Arc4SboxData7; + uint64_t Arc4SboxData8; + uint64_t Arc4SboxData9; + uint64_t Arc4SboxData10; + uint64_t Arc4SboxData11; + uint64_t Arc4SboxData12; + uint64_t Arc4SboxData13; + uint64_t Arc4SboxData14; + uint64_t Arc4SboxData15; + uint64_t Arc4SboxData16; + uint64_t Arc4SboxData17; + uint64_t Arc4SboxData18; + uint64_t Arc4SboxData19; + uint64_t Arc4SboxData20; + uint64_t Arc4SboxData21; + uint64_t Arc4SboxData22; + uint64_t Arc4SboxData23; + uint64_t Arc4SboxData24; + uint64_t Arc4SboxData25; + uint64_t Arc4SboxData26; + uint64_t Arc4SboxData27; + uint64_t Arc4SboxData28; + uint64_t Arc4SboxData29; + uint64_t Arc4SboxData30; + uint64_t Arc4SboxData31; + uint64_t Arc4IJData; + uint64_t PAD3; + uint64_t PAD4; + uint64_t PAD5; +} ARC4StateHMAC2_t, *ARC4StateHMAC2_pt; + +/* ARC4, GCM - 408 bytes (not including 8 bytes from instruction) */ +typedef struct ARC4StateGCM_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; + uint64_t PAD0; + uint64_t PAD1; + uint64_t PAD2; + uint64_t PAD3; + uint64_t PAD4; + uint64_t PAD5; + uint64_t PAD6; + uint64_t PAD7; + uint64_t Arc4SboxData0; + uint64_t Arc4SboxData1; + uint64_t Arc4SboxData2; + uint64_t Arc4SboxData3; + uint64_t Arc4SboxData4; + uint64_t Arc4SboxData5; + uint64_t Arc4SboxData6; + uint64_t Arc4SboxData7; + uint64_t Arc4SboxData8; + uint64_t Arc4SboxData9; + uint64_t Arc4SboxData10; + uint64_t Arc4SboxData11; + uint64_t Arc4SboxData12; + uint64_t Arc4SboxData13; + uint64_t Arc4SboxData14; + uint64_t Arc4SboxData15; + uint64_t Arc4SboxData16; + uint64_t Arc4SboxData17; + uint64_t Arc4SboxData18; + uint64_t Arc4SboxData19; + uint64_t Arc4SboxData20; + uint64_t Arc4SboxData21; + uint64_t Arc4SboxData22; + uint64_t Arc4SboxData23; + uint64_t Arc4SboxData24; + uint64_t Arc4SboxData25; + uint64_t Arc4SboxData26; + uint64_t Arc4SboxData27; + uint64_t Arc4SboxData28; + uint64_t Arc4SboxData29; + uint64_t Arc4SboxData30; + uint64_t Arc4SboxData31; + uint64_t Arc4IJData; + uint64_t PAD8; + uint64_t PAD9; + uint64_t PAD10; +} ARC4StateGCM_t, *ARC4StateGCM_pt; + +/* ARC4, F9 - 408 bytes (not including 8 bytes from instruction) */ +typedef struct ARC4StateF9_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t authKey0; + uint64_t authKey1; + uint64_t PAD0; + uint64_t PAD1; + uint64_t PAD2; + uint64_t PAD3; + uint64_t PAD4; + uint64_t PAD5; + uint64_t PAD6; + uint64_t PAD7; + uint64_t PAD8; + uint64_t Arc4SboxData0; + uint64_t Arc4SboxData1; + uint64_t Arc4SboxData2; + uint64_t Arc4SboxData3; + uint64_t Arc4SboxData4; + uint64_t Arc4SboxData5; + uint64_t Arc4SboxData6; + uint64_t Arc4SboxData7; + uint64_t Arc4SboxData8; + uint64_t Arc4SboxData9; + uint64_t Arc4SboxData10; + uint64_t Arc4SboxData11; + uint64_t Arc4SboxData12; + uint64_t Arc4SboxData13; + uint64_t Arc4SboxData14; + uint64_t Arc4SboxData15; + uint64_t Arc4SboxData16; + uint64_t Arc4SboxData17; + uint64_t Arc4SboxData18; + uint64_t Arc4SboxData19; + uint64_t Arc4SboxData20; + uint64_t Arc4SboxData21; + uint64_t Arc4SboxData22; + uint64_t Arc4SboxData23; + uint64_t Arc4SboxData24; + uint64_t Arc4SboxData25; + uint64_t Arc4SboxData26; + uint64_t Arc4SboxData27; + uint64_t Arc4SboxData28; + uint64_t Arc4SboxData29; + uint64_t Arc4SboxData30; + uint64_t Arc4SboxData31; + uint64_t Arc4IJData; + uint64_t PAD9; + uint64_t PAD10; + uint64_t PAD11; +} ARC4StateF9_t, *ARC4StateF9_pt; + +/* ARC4, Non-HMAC (MD5, SHA-1, SHA-256) - 32 bytes */ +typedef struct ARC4_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; +} ARC4_t, *ARC4_pt; + +/* ARC4, Non-HMAC (MD5, SHA-1, SHA-256) - 344 bytes (not including 8 bytes from instruction) */ +typedef struct ARC4State_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t PAD0; + uint64_t PAD1; + uint64_t PAD2; + uint64_t Arc4SboxData0; + uint64_t Arc4SboxData1; + uint64_t Arc4SboxData2; + uint64_t Arc4SboxData3; + uint64_t Arc4SboxData4; + uint64_t Arc4SboxData5; + uint64_t Arc4SboxData6; + uint64_t Arc4SboxData7; + uint64_t Arc4SboxData8; + uint64_t Arc4SboxData9; + uint64_t Arc4SboxData10; + uint64_t Arc4SboxData11; + uint64_t Arc4SboxData12; + uint64_t Arc4SboxData13; + uint64_t Arc4SboxData14; + uint64_t Arc4SboxData15; + uint64_t Arc4SboxData16; + uint64_t Arc4SboxData17; + uint64_t Arc4SboxData18; + uint64_t Arc4SboxData19; + uint64_t Arc4SboxData20; + uint64_t Arc4SboxData21; + uint64_t Arc4SboxData22; + uint64_t Arc4SboxData23; + uint64_t Arc4SboxData24; + uint64_t Arc4SboxData25; + uint64_t Arc4SboxData26; + uint64_t Arc4SboxData27; + uint64_t Arc4SboxData28; + uint64_t Arc4SboxData29; + uint64_t Arc4SboxData30; + uint64_t Arc4SboxData31; + uint64_t Arc4IJData; + uint64_t PAD3; + uint64_t PAD4; + uint64_t PAD5; +} ARC4State_t, *ARC4State_pt; + +/* Kasumi f8 - 32 bytes */ +typedef struct KASUMIF8_s { + uint64_t cipherKey0; + uint64_t cipherKey1; +} KASUMIF8_t, *KASUMIF8_pt; + +/* Kasumi f8 + HMAC (MD5, SHA-1, SHA-256) - 80 bytes */ +typedef struct KASUMIF8HMAC_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} KASUMIF8HMAC_t, *KASUMIF8HMAC_pt; + +/* Kasumi f8 + HMAC (SHA-384, SHA-512) - 144 bytes */ +typedef struct KASUMIF8HMAC2_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} KASUMIF8HMAC2_t, *KASUMIF8HMAC2_pt; + +/* Kasumi f8 + GCM - 144 bytes */ +typedef struct KASUMIF8GCM_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} KASUMIF8GCM_t, *KASUMIF8GCM_pt; + +/* Kasumi f8 + f9 - 32 bytes */ +typedef struct KASUMIF8F9_s { + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t authKey0; + uint64_t authKey1; +} KASUMIF8F9_t, *KASUMIF8F9_pt; + +typedef union CipherHashInfo_u { + AES256HMAC_t infoAES256HMAC; + AES256_t infoAES256; + AES192HMAC_t infoAES192HMAC; + AES192_t infoAES192; + AES128HMAC_t infoAES128HMAC; + AES128_t infoAES128; + DESHMAC_t infoDESHMAC; + DES_t infoDES; + DES3HMAC_t info3DESHMAC; + DES3_t info3DES; + HMAC_t infoHMAC; + /* ARC4 */ + ARC4HMAC_t infoARC4HMAC; + ARC4StateHMAC_t infoARC4StateHMAC; + ARC4_t infoARC4; + ARC4State_t infoARC4State; + /* AES mode F8 */ + AES256F8HMAC_t infoAES256F8HMAC; + AES256F8_t infoAES256F8; + AES192F8HMAC_t infoAES192F8HMAC; + AES192F8_t infoAES192F8; + AES128F8HMAC_t infoAES128F8HMAC; + AES128F8_t infoAES128F8; + /* KASUMI F8 */ + KASUMIF8HMAC_t infoKASUMIF8HMAC; + KASUMIF8_t infoKASUMIF8; + /* GCM */ + GCM_t infoGCM; + AES256F8GCM_t infoAES256F8GCM; + AES192F8GCM_t infoAES192F8GCM; + AES128F8GCM_t infoAES128F8GCM; + AES256GCM_t infoAES256GCM; + AES192GCM_t infoAES192GCM; + AES128GCM_t infoAES128GCM; + DESGCM_t infoDESGCM; + DES3GCM_t info3DESGCM; + ARC4GCM_t infoARC4GCM; + ARC4StateGCM_t infoARC4StateGCM; + KASUMIF8GCM_t infoKASUMIF8GCM; + /* HMAC2 */ + HMAC2_t infoHMAC2; + AES256F8HMAC2_t infoAES256F8HMAC2; + AES192F8HMAC2_t infoAES192F8HMAC2; + AES128F8HMAC2_t infoAES128F8HMAC2; + AES256HMAC2_t infoAES256HMAC2; + AES192HMAC2_t infoAES192HMAC2; + AES128HMAC2_t infoAES128HMAC2; + DESHMAC2_t infoDESHMAC2; + DES3HMAC2_t info3DESHMAC2; + ARC4HMAC2_t infoARC4HMAC2; + ARC4StateHMAC2_t infoARC4StateHMAC2; + KASUMIF8HMAC2_t infoKASUMIF8HMAC2; + /* F9 */ + F9_t infoF9; + AES256F8F9_t infoAES256F8F9; + AES192F8F9_t infoAES192F8F9; + AES128F8F9_t infoAES128F8F9; + AES256F9_t infoAES256F9; + AES192F9_t infoAES192F9; + AES128F9_t infoAES128F9; + DESF9_t infoDESF9; + DES3F9_t info3DESF9; + ARC4F9_t infoARC4F9; + ARC4StateF9_t infoARC4StateF9; + KASUMIF8F9_t infoKASUMIF8F9; +} CipherHashInfo_t, *CipherHashInfo_pt; + + +/* + * + * ControlDescriptor_s datastructure + * + */ + +typedef struct ControlDescriptor_s { + uint64_t instruction; + CipherHashInfo_t cipherHashInfo; +} ControlDescriptor_t, *ControlDescriptor_pt; + + + + +/* ********************************************************************** + * PacketDescriptor_t + * ********************************************************************** + */ + +/* /--------------------------------------------\ + * | | + * | New PacketDescriptor_s datastructure | + * | | + * \--------------------------------------------/ + * + * + * + * PacketDescriptor_t.srcLengthIVOffUseIVNext + * ------------------------------------------ + * + * 63 62 61 59 58 57 56 54 53 43 + * ------------------------------------------------------------------------------------------------ + * || Load HMAC key || Pad Hash || Hash Byte Count || Next || Use IV || IV Offset || Packet length || ... CONT ... + * ------------------------------------------------------------------------------------------------ + * 1 1 3 1 1 3 11 + * + * + * 42 41 40 39 5 4 3 2 + * 0 + * ---------------------------------------------------------------------------------------------------- + * || NLHMAC || Break || Wait || Segment src address || SRTCP || Reserved || Global src data offset || + * ---------------------------------------------------------------------------------------------------- + * 1 1 1 35 1 1 3 + * + * + * + * Load HMAC key = 1'b0 Preserve old HMAC key stored in Auth engine (moot if HASH.HMAC == 0) + * 1'b1 Load HMAC key from ID registers at beginning of op + * If GCM is selected as authenticator, setting this bit + * will cause the H value from ID to be loaded to the engine + * If Kasumi F9 is selected as authenticator, setting this bit + * will cause the IK value from ID to be loaded to the engine. + * Pad Hash = 1'b0 HASH will assume the data was padded to be a multiple + * of 512 bits in length and that the last 64 bit word + * expresses the total datalength in bits seen by HASH engine + * 1'b1 The data was not padded to be a multiple of 512 bits in length; + * The Hash engine will do its own padding to generate the correct digest. + * Ignored by GCM (always does its own padding) + * Hash Byte Count Number of BYTES on last 64-bit data word to use in digest calculation RELEVANT ONLY IF Pad Hash IS SET + * 3'b000 Use all 8 + * 3'b001 Use first (MS) byte only (0-out rest), i.e., 0xddXXXXXXXXXXXXXX + * 3'b010 Use first 2 bytes only (0-out rest), i.e., 0xddddXXXXXXXXXXXX ... etc + * Next = 1'b0 Finish (return msg descriptor) at end of operation + * 1'b1 Grab the next PacketDescriptor (i.e. next cache-line) when the current is complete. + * This allows for fragmentation/defragmentation and processing of large (>16kB) packets. + * The sequence of adjacent PacketDescriptor acts as a contiguous linked list of + * pointers to the actual packets with Next==0 on the last PacketDescriptor to end processing. + * Use IV = 1'b0 On first frag: Use old IV + * On subsequent frags: Do not write out to DST the (dword) offset data + * 1'b1 On first frag: Use data @ Segment_address + IV_Offset as IV + * On subsequent frags: Do write out to DST the (dword) offset data + * IV Offset = On first frag: Offset IN NB OF 8 BYTE WORDS (dwords) from beginning of packet + * (i.e. (Potentially byte-shifted) Segment address) to cipher IV + * On subsequent frags: Offset to beginning of data to process; data to offset won't + * be given to engines and will be written out to dst in the clear. + * ON SUBSEQUENT FRAGS, IV_Offset MAY NOT EXCEED 3; LARGER VALUES WILL CAUSE AN ERROR + * SEE ERROR CONDITIONS BELOW + * Packet length = Nb double words to stream in (Including Segment address->CP/IV/Auth/CkSum offsets) + * This is the total amount of data (x8 in bytes) read (+1 dword if "Global src data offset" != 0) + * This is the total amount of data (x8 in bytes) written (+1 dword if "Global dst data offset" != 0, if Dst dword offset == 0) + * If Packet length == 11'h7ff and (Global src data offset != 0 or Global dst data offset != 0) + * the operation is aborted (no mem writes occur) + * and the "Insufficient Data To Cipher" error flag is raised + * NLHMAC = No last to hmac. Setting this to 1 will prevent the transmission of the last DWORD + * to the authenticator, i.e., the DWORD before last will be designated as last for the purposes of authentication. + * Break = Break a wait (see below) state - causes the operation to be flushed and free descriptor to be returned. + * Activated if DFetch blocked by Wait and Wait still active. + * AS OF 02/10/2005 THIS FEATURE IS EXPERIMENTAL + * Wait = Setting that bit causes the operation to block in DFetch stage. + * DFetch will keep polling the memory location until the bit is reset at which time + * the pipe resumes normal operation. This feature is convenient for software dealing with fragmented packets. + * AS OF 02/10/2005 THIS FEATURE IS EXPERIMENTAL + * Segment src address = 35 MSB of pointer to src data (i.e., cache-line aligned) + * SRTCP = Bypass the cipher for the last 4 bytes of data, i.e. the last 4 bytes will be sent to memory + * and the authenticator in the clear. Applicable to last packet descriptor andlast frag only. + * This accommodates a requirement of SRTCP. + * Global src data offset = Nb BYTES to right-shift data by before presenting it to engines + * (0-7); allows realignment of byte-aligned, non-double-word aligned data + * + * PacketDescriptor_t.dstDataSettings + * ---------------------------------- + * + * + * 63 62 60 59 58 56 55 54 53 52 41 40 + * ------------------------------------------------------------------------------------------------------------ + * || CipherPrefix | Arc4ByteCount | E/D | Cipher_Offset || Hash_Offset | Hash_Src || CkSum_Offset | CkSum_Src || ... CONT ... + * ------------------------------------------------------------------------------------------------------------ + * 1 3 1 3 2 1 12 1 + * <-----------------------CIPHER-----------------------><---------HASH-----------><-------CHECKSUM-----------> + * + * + * CipherPrefix = 128'b0 will be sent to the selected cipher + * KEEP VALUE ON ALL FRAGS after the IV is loaded, before the actual data goes in. + * The result of that encryption (aka E(K, 0))will be stored + * locally and XOR-ed with the auth digest to create the final + * digest at the end of the auth OP: + * This is covered by the GCM spec + * AesPrefix = 1'b1 -> Force E=Cipher(K,0) before start of data encr. + * -> Digest ^= E + * AesPrefix = 1'b0 -> Regular digest + * This flag is ignored if no cipher is chosen (Bypass condition) + * X0 Arc4ByteCount = Number of BYTES on last 64-bit data word to encrypt + * 3'b000 Encrypt all 8 + * 3'b001 Encrypt first (MS) byte only i.e., 0xddXXXXXXXXXXXXXX + * 3'b010 Encrypt first 2 bytes only i.e., 0xddddXXXXXXXXXXXX ... etc + * In reality, all are encrypted, however, the SBOX + * is not written past the last byte to encrypt + * E/D = 1'b0 Decrypt + * 1'b1 Encrypt + * Overloaded to also mean IV byte offset for first frag + * Cipher_Offset = Nb of words between the first data segment + * and word on which to start cipher operation + * (64 BIT WORDS !!!) + * Hash_Offset = Nb of words between the first data segment + * and word on which to start hashing + * (64 bit words) + * Hash_Src = 1'b0 DMA channel + * 1'b1 Cipher if word count exceeded Cipher_Offset; + * DMA channel otherwise + * CkSum_Offset = Nb of words between the first data segment + * and word on which to start + * checksum calculation (32 BIT WORDS !!!) + * CkSum_Src = 1'b0 DMA channel + * 1'b1 Cipher if word count exceeded Cipher_Offset + * DMA channel otherwise + * Cipher dst address = 35 MSB of pointer to dst location (i.e., cache-line aligned) + * Dst dword offset = Nb of double-words to left-shift data from spec'ed Cipher dst address before writing it to memory + * Global dst data offset = Nb BYTES to left-shift (double-word boundary aligned) data by before writing it to memory + * + * + * PacketDescriptor_t.authDstNonceLow + * ---------------------------------- + * + * 63 40 39 5 4 0 + * ----------------------------------------------------- + * || Nonce_Low || Auth_dst_address || Cipher_Offset_Hi || + * ----------------------------------------------------- + * 24 35 5 + * + * + * + * Nonce_Low = Nonce[23:0] 24 least significant bits of 32-bit long nonce + * Used by AES in counter mode + * Auth_dst_address = 35 MSB of pointer to authentication dst location (i.e., cache-line aligned) + * X0 Cipher_Offset_Hi = On first frag: 5 MSB of 8-bit Cipher_offset; will be concatenated to + * the top of PacketDescriptor_t.dstDataSettings.Cipher_Offset + * On subsequent frags: Ignored + * + * + * PacketDescriptor_t.ckSumDstNonceHiCFBMaskLLWMask + * ------------------------------------------------ + * + * + * 63 61 60 58 57 56 55 48 47 40 39 5 4 0 + * ------------------------------------------------------------------------------------------------------------------- + * || Hash_Byte_Offset || Packet length bytes || LLWMask || CFB_Mask || Nonce_Hi || CkSum_dst_address || IV_Offset_Hi || + * ------------------------------------------------------------------------------------------------------------------- + * 3 3 2 8 8 35 5 + * + * + * Hash_Byte_Offset = On first frag: Additional offset in bytes to be added to Hash_Offset + * to obtain the full offset applied to the data before + * submitting it to authenticator + * On subsequent frags: Same + * Packet length bytes = On one fragment payloads: Ignored (i.e. assumed to be 0, last dword used in its entirety) + * On fragments before last: Number of bytes on last fragment dword + * On last fragment: Ignored (i.e. assumed to be 0, last dword used in its entirety) + * LLWMask, aka, Last_long_word_mask = 2'b00 Give last 128 bit word from AES engine to auth/cksum/wrbbufer as is - applicable in AES CTR only + * 2'b11 Mask (zero-out) 32 least significant bits + * 2'b10 Mask 64 LSBs + * 2'b01 Mask 96 LSBs + * If the GCM authenticator is used, setting LLWMask to 2'b10 or 2'b01 + * will also prevent the transmission of the last DWORD + * to the authenticator, i.e., the DWORD before last will + * be designated as last for the purposes of authentication. + * CFB_Mask = 8 bit mask used by AES in CFB mode + * In CTR mode: + * CFB_Mask[1:0] = 2'b00 -> Counter[127:0] = {Nonce[31:0], IV0[63:0], 4'h00000001} (only 1 IV exp +ected) regular CTR + * 2'b01 -> Counter[127:0] = {Nonce[31:0], IV0[63:0], IV1[31:0]} (2 IV expected +) CCMP + * 2'b10 -> Counter[127:0] = {IV1[63:0], IV0[31:0], Nonce[31:0]} (2 IV expected +) GCM with SCI + * 2'b11 -> Counter[127:0] = {IDecode.SCI[63:0], IV0[31:0], Nonce[31:0]} (1 IV expected +) GCM w/o SCI + * Nonce_Hi = Nonce[31:24] 8 most significant bits of 32-bit long nonce + * Used by AES in counter mode + * CkSum_dst_address = 35 MSB of pointer to cksum dst location (i.e., cache-line aligned) + * X0 IV_Offset_Hi = On first frag: 5 MSB of 8-bit IV offset; will be concatenated to + * the top of PacketDescriptor_t.srcLengthIVOffUseIVNext.IV_Offset + * On subsequent frags: Ignored + */ + +/* #define PKT_DSC_LOADHMACKEY */ +#define PKT_DSC_LOADHMACKEY_OLD 0 +#define PKT_DSC_LOADHMACKEY_LOAD 1 +#define PKT_DSC_LOADHMACKEY_LSB 63 +#define PKT_DSC_LOADHMACKEY_BITS ONE_BIT +#define PKT_DSC_LOADHMACKEY_MASK \ + (PKT_DSC_LOADHMACKEY_BITS << PKT_DSC_LOADHMACKEY_LSB) + +/* #define PKT_DSC_PADHASH */ +#define PKT_DSC_PADHASH_PADDED 0 +#define PKT_DSC_PADHASH_PAD 1 /* requires padding */ +#define PKT_DSC_PADHASH_LSB 62 +#define PKT_DSC_PADHASH_BITS ONE_BIT +#define PKT_DSC_PADHASH_MASK (PKT_DSC_PADHASH_BITS << PKT_DSC_PADHASH_LSB) + +/* #define PKT_DSC_HASHBYTES */ +#define PKT_DSC_HASHBYTES_ALL8 0 +#define PKT_DSC_HASHBYTES_MSB 1 +#define PKT_DSC_HASHBYTES_MSW 2 +#define PKT_DSC_HASHBYTES_LSB 59 +#define PKT_DSC_HASHBYTES_BITS THREE_BITS +#define PKT_DSC_HASHBYTES_MASK \ + (PKT_DSC_HASHBYTES_BITS << PKT_DSC_HASHBYTES_LSB) + +/* #define PKT_DSC_NEXT */ +#define PKT_DSC_NEXT_FINISH 0 +#define PKT_DSC_NEXT_DO 1 +#define PKT_DSC_NEXT_LSB 58 +#define PKT_DSC_NEXT_BITS ONE_BIT +#define PKT_DSC_NEXT_MASK (PKT_DSC_NEXT_BITS << PKT_DSC_NEXT_LSB) + +/* #define PKT_DSC_IV */ +#define PKT_DSC_IV_OLD 0 +#define PKT_DSC_IV_NEW 1 +#define PKT_DSC_IV_LSB 57 +#define PKT_DSC_IV_BITS ONE_BIT +#define PKT_DSC_IV_MASK (PKT_DSC_IV_BITS << PKT_DSC_IV_LSB) + +/* #define PKT_DSC_IVOFF */ +#define PKT_DSC_IVOFF_LSB 54 +#define PKT_DSC_IVOFF_BITS THREE_BITS +#define PKT_DSC_IVOFF_MASK (PKT_DSC_IVOFF_BITS << PKT_DSC_IVOFF_LSB) + +/* #define PKT_DSC_PKTLEN */ +#define PKT_DSC_PKTLEN_LSB 43 +#define PKT_DSC_PKTLEN_BITS ELEVEN_BITS +#define PKT_DSC_PKTLEN_MASK (PKT_DSC_PKTLEN_BITS << PKT_DSC_PKTLEN_LSB) + +/* #define PKT_DSC_NLHMAC */ +#define PKT_DSC_NLHMAC_LSB 42 +#define PKT_DSC_NLHMAC_BITS ONE_BIT +#define PKT_DSC_NLHMAC_MASK (PKT_DSC_NLHMAC_BITS << PKT_DSC_NLHMAC_LSB) + +/* #define PKT_DSC_BREAK */ +#define PKT_DSC_BREAK_OLD 0 +#define PKT_DSC_BREAK_NEW 1 +#define PKT_DSC_BREAK_LSB 41 +#define PKT_DSC_BREAK_BITS ONE_BIT +#define PKT_DSC_BREAK_MASK (PKT_DSC_BREAK_BITS << PKT_DSC_BREAK_LSB) + +/* #define PKT_DSC_WAIT */ +#define PKT_DSC_WAIT_OLD 0 +#define PKT_DSC_WAIT_NEW 1 +#define PKT_DSC_WAIT_LSB 40 +#define PKT_DSC_WAIT_BITS ONE_BIT +#define PKT_DSC_WAIT_MASK (PKT_DSC_WAIT_BITS << PKT_DSC_WAIT_LSB) + +/* #define PKT_DSC_SEGADDR */ +#define PKT_DSC_SEGADDR_LSB 5 +#define PKT_DSC_SEGADDR_BITS FOURTY_BITS +#define PKT_DSC_SEGADDR_MASK \ + (PKT_DSC_SEGADDR_BITS << PKT_DSC_SEGADDR_LSB) + +/* #define PKT_DSC_SRTCP */ +#define PKT_DSC_SRTCP_OFF 0 +#define PKT_DSC_SRTCP_ON 1 +#define PKT_DSC_SRTCP_LSB 4 +#define PKT_DSC_SRTCP_BITS ONE_BIT +#define PKT_DSC_SRTCP_MASK (PKT_DSC_SRTCP_BITS << PKT_DSC_SRTCP_LSB) + +#define PKT_DSC_SEGOFFSET_LSB 0 +#define PKT_DSC_SEGOFFSET_BITS THREE_BITS +#define PKT_DSC_SEGOFFSET_MASK \ + (PKT_DSC_SEGOFFSET_BITS << PKT_DSC_SEGOFFSET_LSB) + +/* ********************************************************************** + * PacketDescriptor_t.dstDataSettings + * ********************************************************************** + */ +/* #define PKT_DSC_ARC4BYTECOUNT */ +#define PKT_DSC_ARC4BYTECOUNT_ALL8 0 +#define PKT_DSC_ARC4BYTECOUNT_MSB 1 +#define PKT_DSC_ARC4BYTECOUNT_MSW 2 +#define PKT_DSC_ARC4BYTECOUNT_LSB 60 +#define PKT_DSC_ARC4BYTECOUNT_BITS THREE_BITS +#define PKT_DSC_ARC4BYTECOUNT_MASK (PKT_DSC_ARC4BYTECOUNT_BITS << PKT_DSC_ARC4BYTECOUNT_LSB) + +/* #define PKT_DSC_SYM_OP (symmetric key operation) */ +#define PKT_DSC_SYM_OP_DECRYPT 0 +#define PKT_DSC_SYM_OP_ENCRYPT 1 +#define PKT_DSC_SYM_OP_LSB 59 +#define PKT_DSC_SYM_OP_BITS ONE_BIT +#define PKT_DSC_SYM_OP_MASK (PKT_DSC_SYM_OP_BITS << PKT_DSC_SYM_OP_LSB) + +/* #define PKT_DSC_CPHROFF */ +#define PKT_DSC_CPHROFF_LSB 56 +#define PKT_DSC_CPHROFF_BITS THREE_BITS +#define PKT_DSC_CPHROFF_MASK (PKT_DSC_CPHROFF_BITS << PKT_DSC_CPHROFF_LSB) + +/* #define PKT_DSC_HASHOFF */ +#define PKT_DSC_HASHOFF_LSB 54 +#define PKT_DSC_HASHOFF_BITS TWO_BITS +#define PKT_DSC_HASHOFF_MASK (PKT_DSC_HASHOFF_BITS << PKT_DSC_HASHOFF_LSB) + +/* #define PKT_DSC_HASHSRC */ +#define PKT_DSC_HASHSRC_DMA 0 +#define PKT_DSC_HASHSRC_CIPHER 1 +#define PKT_DSC_HASHSRC_LSB 53 +#define PKT_DSC_HASHSRC_BITS ONE_BIT +#define PKT_DSC_HASHSRC_MASK (PKT_DSC_HASHSRC_BITS << PKT_DSC_HASHSRC_LSB) + +/* #define PKT_DSC_CKSUMOFF */ +#define PKT_DSC_CKSUMOFF_LSB 41 +#define PKT_DSC_CKSUMOFF_BITS TWELVE_BITS +#define PKT_DSC_CKSUMOFF_MASK (PKT_DSC_CKSUMOFF_BITS << PKT_DSC_CKSUMOFF_LSB) + +/* #define PKT_DSC_CKSUMSRC */ +#define PKT_DSC_CKSUMSRC_DMA 0 +#define PKT_DSC_CKSUMSRC_CIPHER 1 +#define PKT_DSC_CKSUMSRC_LSB 40 +#define PKT_DSC_CKSUMSRC_BITS ONE_BIT +#define PKT_DSC_CKSUMSRC_MASK (PKT_DSC_CKSUMSRC_BITS << PKT_DSC_CKSUMSRC_LSB) + +/* #define PKT_DSC_CPHR_DST_ADDR */ +#define PKT_DSC_CPHR_DST_ADDR_LSB 0 +#define PKT_DSC_CPHR_DST_ADDR_BITS FOURTY_BITS +#define PKT_DSC_CPHR_DST_ADDR_MASK \ + (PKT_DSC_CPHR_DST_ADDR_BITS << PKT_DSC_CPHR_DST_ADDR_LSB) + +/* #define PKT_DSC_CPHR_DST_DWOFFSET */ +#define PKT_DSC_CPHR_DST_DWOFFSET_LSB 3 +#define PKT_DSC_CPHR_DST_DWOFFSET_BITS TWO_BITS +#define PKT_DSC_CPHR_DST_DWOFFSET_MASK \ + (PKT_DSC_CPHR_DST_DWOFFSET_BITS << PKT_DSC_CPHR_DST_DWOFFSET_LSB) + + /* #define PKT_DSC_CPHR_DST_OFFSET */ +#define PKT_DSC_CPHR_DST_OFFSET_LSB 0 +#define PKT_DSC_CPHR_DST_OFFSET_BITS THREE_BITS +#define PKT_DSC_CPHR_DST_OFFSET_MASK \ + (PKT_DSC_CPHR_DST_OFFSET_BITS << PKT_DSC_CPHR_DST_OFFSET_LSB) + +/* ********************************************************************** + * PacketDescriptor_t.authDstNonceLow + * ********************************************************************** + */ +/* #define PKT_DSC_NONCE_LOW */ +#define PKT_DSC_NONCE_LOW_LSB 40 +#define PKT_DSC_NONCE_LOW_BITS TWENTYFOUR_BITS +#define PKT_DSC_NONCE_LOW_MASK \ + (PKT_DSC_NONCE_LOW_BITS << PKT_DSC_NONCE_LOW_LSB) + +/* #define PKT_DSC_AUTH_DST_ADDR */ +#define PKT_DSC_AUTH_DST_ADDR_LSB 0 +#define PKT_DSC_AUTH_DST_ADDR_BITS FOURTY_BITS +#define PKT_DSC_AUTH_DST_ADDR_MASK \ + (PKT_DSC_AUTH_DST_ADDR_BITS << PKT_DSC_AUTH_DST_ADDR_LSB) + +/* #define PKT_DSC_CIPH_OFF_HI */ +#define PKT_DSC_CIPH_OFF_HI_LSB 0 +#define PKT_DSC_CIPH_OFF_HI_BITS FIVE_BITS +#define PKT_DSC_CIPH_OFF_HI_MASK (PKT_DSC_CIPH_OFF_HI_BITS << PKT_DSC_CIPH_OFF_HI_LSB) + +/* ********************************************************************** + * PacketDescriptor_t.ckSumDstNonceHiCFBMaskLLWMask + * ********************************************************************** + */ +/* #define PKT_DSC_HASH_BYTE_OFF */ +#define PKT_DSC_HASH_BYTE_OFF_LSB 61 +#define PKT_DSC_HASH_BYTE_OFF_BITS THREE_BITS +#define PKT_DSC_HASH_BYTE_OFF_MASK (PKT_DSC_HASH_BYTE_OFF_BITS << PKT_DSC_HASH_BYTE_OFF_LSB) + +/* #define PKT_DSC_PKTLEN_BYTES */ +#define PKT_DSC_PKTLEN_BYTES_LSB 58 +#define PKT_DSC_PKTLEN_BYTES_BITS THREE_BITS +#define PKT_DSC_PKTLEN_BYTES_MASK (PKT_DSC_PKTLEN_BYTES_BITS << PKT_DSC_PKTLEN_BYTES_LSB) + +/* #define PKT_DSC_LASTWORD */ +#define PKT_DSC_LASTWORD_128 0 +#define PKT_DSC_LASTWORD_96MASK 1 +#define PKT_DSC_LASTWORD_64MASK 2 +#define PKT_DSC_LASTWORD_32MASK 3 +#define PKT_DSC_LASTWORD_LSB 56 +#define PKT_DSC_LASTWORD_BITS TWO_BITS +#define PKT_DSC_LASTWORD_MASK (PKT_DSC_LASTWORD_BITS << PKT_DSC_LASTWORD_LSB) + +/* #define PKT_DSC_CFB_MASK */ +#define PKT_DSC_CFB_MASK_LSB 48 +#define PKT_DSC_CFB_MASK_BITS EIGHT_BITS +#define PKT_DSC_CFB_MASK_MASK (PKT_DSC_CFB_MASK_BITS << PKT_DSC_CFB_MASK_LSB) + +/* #define PKT_DSC_NONCE_HI */ +#define PKT_DSC_NONCE_HI_LSB 40 +#define PKT_DSC_NONCE_HI_BITS EIGHT_BITS +#define PKT_DSC_NONCE_HI_MASK (PKT_DSC_NONCE_HI_BITS << PKT_DSC_NONCE_HI_LSB) + +/* #define PKT_DSC_CKSUM_DST_ADDR */ +#define PKT_DSC_CKSUM_DST_ADDR_LSB 5 +#define PKT_DSC_CKSUM_DST_ADDR_BITS THIRTY_FIVE_BITS +#define PKT_DSC_CKSUM_DST_ADDR_MASK (PKT_DSC_CKSUM_DST_ADDR_BITS << PKT_DSC_CKSUM_DST_ADDR_LSB) + +/* #define PKT_DSC_IV_OFF_HI */ +#define PKT_DSC_IV_OFF_HI_LSB 0 +#define PKT_DSC_IV_OFF_HI_BITS FIVE_BITS +#define PKT_DSC_IV_OFF_HI_MASK (PKT_DSC_IV_OFF_HI_BITS << PKT_DSC_IV_OFF_HI_LSB) + + +/* ****************************************************************** + * Control Error Code and Conditions + * ****************************************************************** + */ +#define CTL_ERR_NONE 0x0000 /* No Error */ +#define CTL_ERR_CIPHER_OP 0x0001 /* Unknown Cipher Op */ +#define CTL_ERR_MODE 0x0002 /* Unknown or Not Allowed Mode */ +#define CTL_ERR_CHKSUM_SRC 0x0004 /* Unknown CkSum Src - UNUSED */ +#define CTL_ERR_CFB_MASK 0x0008 /* Forbidden CFB Mask - UNUSED */ +#define CTL_ERR_OP 0x0010 /* Unknown Ctrl Op - UNUSED */ +#define CTL_ERR_UNDEF1 0x0020 /* UNUSED */ +#define CTL_ERR_UNDEF2 0x0040 /* UNUSED */ +#define CTL_ERR_DATA_READ 0x0080 /* Data Read Error */ +#define CTL_ERR_DESC_CTRL 0x0100 /* Descriptor Ctrl Field Error */ + +#define CTL_ERR_TIMEOUT 0x1000 /* Message Response Timeout */ + +/* ****************************************************************** + * Data Error Code and Conditions + * ****************************************************************** + */ +#define DATA_ERR_NONE 0x0000 /* No Error */ +#define DATA_ERR_LEN_CIPHER 0x0001 /* Not Enough Data To Cipher */ +#define DATA_ERR_IV_ADDR 0x0002 /* Illegal IV Loacation */ +#define DATA_ERR_WD_LEN_AES 0x0004 /* Illegal Nb Words To AES */ +#define DATA_ERR_BYTE_COUNT 0x0008 /* Illegal Pad And ByteCount Spec */ +#define DATA_ERR_LEN_CKSUM 0x0010 /* Not Enough Data To CkSum */ +#define DATA_ERR_OP 0x0020 /* Unknown Data Op */ +#define DATA_ERR_UNDEF1 0x0040 /* UNUSED */ +#define DATA_ERR_READ 0x0080 /* Data Read Error */ +#define DATA_ERR_WRITE 0x0100 /* Data Write Error */ + + +/* + * Common Descriptor + * NOTE: Size of struct is size of cacheline. + */ + +typedef struct OperationDescriptor_s { + uint64_t phys_self; + uint32_t stn_id; + uint32_t flags; + uint32_t cpu; + uint32_t seq_num; + uint64_t reserved; +} OperationDescriptor_t, *OperationDescriptor_pt; + + +/* + * This defines the security data descriptor format + */ +typedef struct PacketDescriptor_s { + uint64_t srcLengthIVOffUseIVNext; + uint64_t dstDataSettings; + uint64_t authDstNonceLow; + uint64_t ckSumDstNonceHiCFBMaskLLWMask; +} PacketDescriptor_t, *PacketDescriptor_pt; + +typedef struct { + uint8_t *user_auth; + uint8_t *user_src; + uint8_t *user_dest; + uint8_t *user_state; + uint8_t *kern_auth; + uint8_t *kern_src; + uint8_t *kern_dest; + uint8_t *kern_state; + uint8_t *aligned_auth; + uint8_t *aligned_src; + uint8_t *aligned_dest; + uint8_t *aligned_state; +} xlr_sec_drv_user_t, *xlr_sec_drv_user_pt; + +typedef struct symkey_desc { + OperationDescriptor_t op_ctl; /* size is cacheline */ + PacketDescriptor_t pkt_desc[2]; /* size is cacheline */ + ControlDescriptor_t ctl_desc; /* makes this aligned */ + uint64_t control; /* message word0 */ + uint64_t data; /* message word1 */ + uint64_t ctl_result; + uint64_t data_result; + struct symkey_desc *alloc; /* real allocated addr */ + xlr_sec_drv_user_t user; +// volatile atomic_t flag_complete; +// struct semaphore sem_complete; +// wait_queue_t submit_wait; + + uint8_t *next_src_buf; + uint32_t next_src_len; + + uint8_t *next_dest_buf; + uint32_t next_dest_len; + + uint8_t* next_auth_dest; + uint8_t* next_cksum_dest; + + void* ses; +} symkey_desc_t, *symkey_desc_pt; + + +/* + * ************************************************************************** + * RSA Block + * ************************************************************************** + */ + +/* + * RSA and ECC Block + * ================= + * + * A 2-word message ring descriptor is used to pass all information + * pertaining to the RSA or ECC operation: + * + * 63 61 60 54 53 52 40 39 5 4 3 2 0 + * ----------------------------------------------------------------------------------------------------- + * | Ctrl | Op Class | Valid Op | Op Ctrl0 | Source Addr | Software Scratch0 | Global src data offset | + * ----------------------------------------------------------------------------------------------------- + * 3 7 1 13 35 2 3 + * + * + * 63 61 60 54 53 52 51 50 40 39 5 4 3 2 0 + * -------------------------------------------------------------------------------------------------------------------------------- + * | Ctrl | Destination Id | WRB_COH | WRB_L2ALLOC | DF_L2ALLOC | Op Ctrl1 | Dest Addr | Software Scratch1 | Global dst data offset | + * -------------------------------------------------------------------------------------------------------------------------------- + * 3 7 1 1 1 11 35 2 3 + * + * + * Op Class = 7'h0_0 Modular exponentiation + * 7'h0_1 ECC (including prime modular ops and binary GF ops) + * REMAINDER UNDEF + * + * Valid Op = 1'b1 Will cause operation to start; descriptors sent back at end of operation + * 1'b0 No operation performed; descriptors sent back right away + * + * RSA ECC + * === === + * Op Ctrl0 = BlockWidth[1] {TYPE[6:0], FUNCTION[5:0]} + * LoadConstant[1] + * ExponentWidth[10:0] + * RSA Only + * ======== + * Block Width = 1'b1 1024 bit op + * = 1'b0 512 bit op + * Load Constant = 1'b1 Load constant from data structure + * 1'b0 Preserve old constant (this assumes + * Source Addr points to RSAData_pt->Exponent + * or that the length of Constant is 0) + * Exponent Width = 11-bit expression of exponent width EXPRESSED IN NUMBER OF BITS + * + * ECC Only + * ======== + * + * TYPE = 7'h0_0 ECC prime 160 + * 7'h0_1 ECC prime 192 + * 7'h0_2 ECC prime 224 + * 7'h0_3 ECC prime 256 + * 7'h0_4 ECC prime 384 + * 7'h0_5 ECC prime 512 + * + * 7'h0_6 through 7'h1_f UNDEF + * + * 7'h2_0 ECC bin 163 + * 7'h2_1 ECC bin 191 + * 7'h2_2 ECC bin 233 + * + * 7'h2_3 through 7'h6_f UNDEF + * + * 7'h7_0 ECC UC load + * + * 7'b7_1 through 7'b7_f UNDEF + * + * Prime field Binary field + * =========== ============ + * FUNCTION = 6'h0_0 Point multiplication R = k.P Point multiplication R = k.P + * 6'h0_1 Point addition R = P + Q Binary GF inversion C(x) = 1 / A(x) mod F(x) + * 6'h0_2 Point double R = 2 x P Binary GF multiplication C(x) = B(x) * A(x) mod F(x) + * 6'h0_3 Point verification R ? Binary GF addition C(x) = B(x) + A(x) mod F(x) + * 6'h0_4 Modular addition c = x + y mod m UNDEF + * 6'h0_5 Modular substraction c = x - y mod m UNDEF + * 6'h0_6 Modular multiplication c = x * y mod m UNDEF + * 6'h0_7 Modular division c = x / y mod m UNDEF + * 6'h0_8 Modular inversion c = 1 / y mod m UNDEF + * 6'h0_9 Modular reduction c = x mod m UNDEF + * + * 6'h0_a + * through UNDEF UNDEF + * 6'h3_f + * + * Source Addr = 35 MSB of pointer to source address (i.e., cache-line aligned) + * + * Software Scratch0 = Two bit field ignored by engine and returned as is in free descriptor + * + * Global src data offset = Nb BYTES to right-shift data by before presenting it to engines + * (0-7); allows realignment of byte-aligned, non-double-word aligned data + * + * RSA ECC + * === === + * OpCtrl1 = ModulusWidth[10:0] Not used + * RSA Only + * ======== + * Modulus Width = 11-bit expression of modulus width EXPRESSED IN NUMBER OF BITS + * + * Dest Addr = 35 MSB of pointer to destination address (i.e., cache-line aligned) + * + * Software Scratch1 = Two bit field ignored by engine and returned as is in free descriptor + * + * Global dst data offset = Nb BYTES to left-shift (double-word boundary aligned) data by before writing it to memory + * + * + */ + +/* + * ECC data formats + */ + +/********************************************************** + * * + * ECC prime data formats * + * * + ********************************************************** + * + * + * The size of all quantities below is that of the precision + * of the chosen op (160, 192, ...) ROUNDED UP to a multiple + * of 8 bytes, i.e., 3 dwords (160, 192), 4 dwords (224, 256) + * 6 dwords (384) and 8 dwords (512) and padded with zeroes + * when necessary. + * + * The only exception to this is the key quantity (k) which + * needs to be rounded up to 32 bytes in all cases and padded + * with zeroes; therefore the key needs to be 4 dwords (160, 192, + * 224, 256) or 8 dwords (384, 512) + * + * The total lengths in dwords that are read and in + * bytes that are written, for each operation and + * length group, are specified at the bottom of each + * datastructure. + * + * In all that follows, m is the modulus and cst is the constant, + * cst = 2 ^ (2*length + 4) mod m . a and b are the curve + * parameters. + * + * 0) UC load + * + * DATA IN DATA OUT + * ======= ======== + * src+glb_off-> Dword_0 N/A + * . + * . + * . + * Dword_331 + * 332 dw + * + * 1) Point multiplication R(x_r, y_r) = k . P(x_p, y_p) + * + * DATA IN DATA OUT + * ======= ======== + * src+glb_off-> x_p dst+glb_off-> x_r + * x_p y_r + * y_p 2x(3/4/6/8)= + * y_p 6/8/12/16 dw + * a + * k + * m + * cst + * 7x(3/4/6/8)+(4/4/8/8)= + * 25/32/50/64 dw + * + * 2) Point addition R(x_r, y_r) = P(x_p, y_p) + Q(x_q, y_q) + * + * DATA IN DATA OUT + * ======= ======== + * src+glb_off-> x_p dst+glb_off-> x_r + * y_p y_r + * x_q 2x(3/4/6/8)= + * y_q 6/8/12/16 dw + * a + * m + * cst + * 7x(3/4/6/8)= + * 21/28/42/56 dw + * + * 3) Point double R(x_r, y_r) = 2 . P(x_p, y_p) + * + * DATA IN DATA OUT + * ======= ======== + * src+glb_off-> x_p dst+glb_off-> x_r + * y_p y_r + * a 2x(3/4/6/8)= + * m 6/8/12/16 dw + * cst + * 5x(3/4/6/8)= + * 15/20/30/40 dw + * + * 4) Point verification Is_On_Curve = P(x_p, y_p) on curve ? 1 : 0 + * + * DATA IN DATA OUT + * ======= ======== + * src+glb_off-> x_p dst+glb_off-> Is_On_Curve + * y_p 1 dw + * a + * b + * m + * cst + * 6x(3/4/6/8)= + * 18/24/36/48 dw + * + * 5) Modular addition c = x + y mod m + * + * DATA IN DATA OUT + * ======= ======== + * src+glb_off-> x dst+glb_off-> c + * y 3/4/6/8 dw + * m + * 3x(3/4/6/8)= + * 9/12/18/24 dw + * + * 6) Modular substraction c = x - y mod m + * + * DATA IN DATA OUT + * ======= ======== + * src+glb_off-> x dst+glb_off-> c + * y 3/4/6/8 dw + * m + * 3x(3/4/6/8)= + * 9/12/18/24 dw + * + * 7) Modular multiplication c = x * y mod m + * + * DATA IN DATA OUT + * ======= ======== + * src+glb_off-> x dst+glb_off-> c + * y 3/4/6/8 dw + * m + * cst + * 4x(3/4/6/8)= + * 12/16/24/32 dw + * + * 8) Modular division c = x / y mod m + * + * DATA IN DATA OUT + * ======= ======== + * src+glb_off-> y dst+glb_off-> c + * x 3/4/6/8 dw + * m + * 3x(3/4/6/8)= + * 9/12/18/24 dw + * + * 9) Modular inversion c = 1 / y mod m + * + * DATA IN DATA OUT + * ======= ======== + * src+glb_off-> y dst+glb_off-> c + * m 3/4/6/8 dw + * 2x(3/4/6/8)= + * 6/8/12/16 dw + * + * 10) Modular reduction c = x mod m + * + * DATA IN DATA OUT + * ======= ======== + * src+glb_off-> x dst+glb_off-> c + * m 3/4/6/8 dw + * 2x(3/4/6/8)= + * 6/8/12/16 dw + * + */ + +/********************************************************** + * * + * ECC binary data formats * + * * + ********************************************************** + * + * + * The size of all quantities below is that of the precision + * of the chosen op (163, 191, 233) ROUNDED UP to a multiple + * of 8 bytes, i.e. 3 dwords for (163, 191) and 4 dwords for + * (233), padded with zeroes as necessary. + * + * The total lengths in dwords that are read and written, + * for each operation and length group, are specified + * at the bottom of each datastructure. + * In all that follows, b is the curve parameter. + * + * 1) Point multiplication R(x_r, y_r) = k . P(x_p, y_p) + * + * DATA IN DATA OUT + * ======= ======== + * src+glb_off-> b dst+glb_off-> x_r + * k y_r + * x_p 2x(3/4) + * y_p 6/8 dw + * 4x(3/4)= + * 12/16 dw + * + * 2) Binary GF inversion C(x) = 1 / A(x) mod F(x) + * + * DATA IN DATA OUT + * ======= ======== + * src+glb_off-> A dst+glb_off-> C + * 1x(3/4)= 1x(3/4) + * 3/4 dw 3/4 dw + * + * 3) Binary GF multiplication C(x) = B(x) * A(x) mod F(x) + * + * DATA IN DATA OUT + * ======= ======== + * src+glb_off-> A dst+glb_off-> C + * B 1x(3/4) + * 2x(3/4)= 3/4 dw + * 6/8 dw + * + * 4) Binary GF addition C(x) = B(x) + A(x) mod F(x) + * + * DATA IN DATA OUT + * ======= ======== + * src+glb_off-> A dst+glb_off-> C + * B 1x(3/4) + * 2x(3/4)= 3/4 dw + * 6/8dw + * + */ + +/* + * RSA data format + */ + +/* + * IMPORTANT NOTE: + * + * As specified in the datastructures below, + * the engine assumes all data (including + * exponent and modulus) to be adjacent on + * dword boundaries, e.g., + * + * Operation length = 512 bits + * Exponent length = 16 bits + * Modulus length = 512 bits + * + * The engine expects to read: + * + * 63 0 + * ----------------------- + * | | Constant0 + * ----------------------- + * | | Constant1 + * ----------------------- + * | | Constant2 + * ----------------------- + * | | Constant3 + * ----------------------- + * | | Constant4 + * ----------------------- + * | | Constant5 + * ----------------------- + * | | Constant6 + * ----------------------- + * | | Constant7 + * ----------------------- + * | IGNORED |B1|B0| Exponent0 (Exponent length = 16 bits = 2 bytes, so only 2 least significant bytes of exponent used) + * ----------------------- + * | | Modulus0 + * ----------------------- + * | | Modulus1 + * ----------------------- + * | | Modulus2 + * ----------------------- + * | | Modulus3 + * ----------------------- + * | | Modulus4 + * ----------------------- + * | | Modulus5 + * ----------------------- + * | | Modulus6 + * ----------------------- + * | | Modulus7 + * ----------------------- + * | | Message0 + * ----------------------- + * | | Message1 + * ----------------------- + * | | Message2 + * ----------------------- + * | | Message3 + * ----------------------- + * | | Message4 + * ----------------------- + * | | Message5 + * ----------------------- + * | | Message6 + * ----------------------- + * | | Message7 + * ----------------------- + * + */ + +/* #define PUBKEY_CTL_CTL */ +#define PUBKEY_CTL_CTL_LSB 61 +#define PUBKEY_CTL_CTL_BITS THREE_BITS +#define PUBKEY_CTL_CTL_MASK (PUBKEY_CTL_CTL_BITS << PUBKEY_CTL_CTL_LSB) + +/* #define PUBKEY_CTL_OP_CLASS */ +#define PUBKEY_CTL_OP_CLASS_RSA 0 +#define PUBKEY_CTL_OP_CLASS_ECC 1 +#define PUBKEY_CTL_OP_CLASS_LSB 54 +#define PUBKEY_CTL_OP_CLASS_BITS SEVEN_BITS +#define PUBKEY_CTL_OP_CLASS_MASK (PUBKEY_CTL_OP_CLASS_BITS << PUBKEY_CTL_OP_CLASS_LSB) + +/* #define PUBKEY_CTL_VALID */ +#define PUBKEY_CTL_VALID_FALSE 0 +#define PUBKEY_CTL_VALID_TRUE 1 +#define PUBKEY_CTL_VALID_LSB 53 +#define PUBKEY_CTL_VALID_BITS ONE_BIT +#define PUBKEY_CTL_VALID_MASK \ + (PUBKEY_CTL_VALID_BITS << PUBKEY_CTL_VALID_LSB) + +/* #define PUBKEY_CTL_ECC_TYPE */ +#define PUBKEY_CTL_ECC_TYPE_PRIME_160 0 +#define PUBKEY_CTL_ECC_TYPE_PRIME_192 1 +#define PUBKEY_CTL_ECC_TYPE_PRIME_224 2 +#define PUBKEY_CTL_ECC_TYPE_PRIME_256 3 +#define PUBKEY_CTL_ECC_TYPE_PRIME_384 4 +#define PUBKEY_CTL_ECC_TYPE_PRIME_512 5 +#define PUBKEY_CTL_ECC_TYPE_BIN_163 0x20 +#define PUBKEY_CTL_ECC_TYPE_BIN_191 0x21 +#define PUBKEY_CTL_ECC_TYPE_BIN_233 0x22 +#define PUBKEY_CTL_ECC_TYPE_UC_LOAD 0x70 +#define PUBKEY_CTL_ECC_TYPE_LSB 46 +#define PUBKEY_CTL_ECC_TYPE_BITS SEVEN_BITS +#define PUBKEY_CTL_ECC_TYPE_MASK (PUBKEY_CTL_ECC_TYPE_BITS << PUBKEY_CTL_ECC_TYPE_LSB) + +/* #define PUBKEY_CTL_ECC_FUNCTION */ +#define PUBKEY_CTL_ECC_FUNCTION_NOP 0 +#define PUBKEY_CTL_ECC_FUNCTION_POINT_MUL 0 +#define PUBKEY_CTL_ECC_FUNCTION_POINT_ADD 1 +#define PUBKEY_CTL_ECC_FUNCTION_POINT_DBL 2 +#define PUBKEY_CTL_ECC_FUNCTION_POINT_VFY 3 +#define PUBKEY_CTL_ECC_FUNCTION_MODULAR_ADD 4 +#define PUBKEY_CTL_ECC_FUNCTION_MODULAR_SUB 5 +#define PUBKEY_CTL_ECC_FUNCTION_MODULAR_MUL 6 +#define PUBKEY_CTL_ECC_FUNCTION_MODULAR_DIV 7 +#define PUBKEY_CTL_ECC_FUNCTION_MODULAR_INV 8 +#define PUBKEY_CTL_ECC_FUNCTION_MODULAR_RED 9 +#define PUBKEY_CTL_ECC_FUNCTION_LSB 40 +#define PUBKEY_CTL_ECC_FUNCTION_BITS SIX_BITS +#define PUBKEY_CTL_ECC_FUNCTION_MASK (PUBKEY_CTL_ECC_FUNCTION_BITS << PUBKEY_CTL_ECC_FUNCTION_LSB) + +/* #define PUBKEY_CTL_BLKWIDTH */ +#define PUBKEY_CTL_BLKWIDTH_512 0 +#define PUBKEY_CTL_BLKWIDTH_1024 1 +#define PUBKEY_CTL_BLKWIDTH_LSB 52 +#define PUBKEY_CTL_BLKWIDTH_BITS ONE_BIT +#define PUBKEY_CTL_BLKWIDTH_MASK \ + (PUBKEY_CTL_BLKWIDTH_BITS << PUBKEY_CTL_BLKWIDTH_LSB) + +/* #define PUBKEY_CTL_LD_CONST */ +#define PUBKEY_CTL_LD_CONST_OLD 0 +#define PUBKEY_CTL_LD_CONST_NEW 1 +#define PUBKEY_CTL_LD_CONST_LSB 51 +#define PUBKEY_CTL_LD_CONST_BITS ONE_BIT +#define PUBKEY_CTL_LD_CONST_MASK \ + (PUBKEY_CTL_LD_CONST_BITS << PUBKEY_CTL_LD_CONST_LSB) + +/* #define PUBKEY_CTL_EXPWIDTH */ +#define PUBKEY_CTL_EXPWIDTH_LSB 40 +#define PUBKEY_CTL_EXPWIDTH_BITS ELEVEN_BITS +#define PUBKEY_CTL_EXPWIDTH_MASK \ + (PUBKEY_CTL_EXPWIDTH_BITS << PUBKEY_CTL_EXPWIDTH_LSB) + +/* #define PUBKEY_CTL_SRCADDR */ +#define PUBKEY_CTL_SRCADDR_LSB 0 +#define PUBKEY_CTL_SRCADDR_BITS FOURTY_BITS +#define PUBKEY_CTL_SRCADDR_MASK \ + (PUBKEY_CTL_SRCADDR_BITS << PUBKEY_CTL_SRCADDR_LSB) + +/* #define PUBKEY_CTL_SRC_OFFSET */ +#define PUBKEY_CTL_SRC_OFFSET_LSB 0 +#define PUBKEY_CTL_SRC_OFFSET_BITS THREE_BITS +#define PUBKEY_CTL_SRC_OFFSET_MASK \ + (PUBKEY_CTL_SRC_OFFSET_BITS << PUBKEY_CTL_SRC_OFFSET_LSB) + + +/* #define PUBKEY_CTL1_CTL */ +#define PUBKEY_CTL1_CTL_LSB 61 +#define PUBKEY_CTL1_CTL_BITS THREE_BITS +#define PUBKEY_CTL1_CTL_MASK (PUBKEY_CTL_CTL_BITS << PUBKEY_CTL_CTL_LSB) + +/* #define PUBKEY_CTL1_MODWIDTH */ +#define PUBKEY_CTL1_MODWIDTH_LSB 40 +#define PUBKEY_CTL1_MODWIDTH_BITS ELEVEN_BITS +#define PUBKEY_CTL1_MODWIDTH_MASK \ + (PUBKEY_CTL1_MODWIDTH_BITS << PUBKEY_CTL1_MODWIDTH_LSB) + +/* #define PUBKEY_CTL1_DSTADDR */ +#define PUBKEY_CTL1_DSTADDR_LSB 0 +#define PUBKEY_CTL1_DSTADDR_BITS FOURTY_BITS +#define PUBKEY_CTL1_DSTADDR_MASK \ + (PUBKEY_CTL1_DSTADDR_BITS << PUBKEY_CTL1_DSTADDR_LSB) + +/* #define PUBKEY_CTL1_DST_OFFSET */ +#define PUBKEY_CTL1_DST_OFFSET_LSB 0 +#define PUBKEY_CTL1_DST_OFFSET_BITS THREE_BITS +#define PUBKEY_CTL1_DST_OFFSET_MASK \ + (PUBKEY_CTL1_DST_OFFSET_BITS << PUBKEY_CTL1_DST_OFFSET_LSB) + +/* + * Upon completion of operation, the RSA block returns a 2-word free descriptor + * in the following format: + * + * 63 61 60 54 53 52 51 49 48 40 39 5 4 3 2 0 + * ------------------------------------------------------------------------------------------------------------------------- + * | Ctrl | Destination Id | 2'b00 | Desc Ctrl | Control Error | Source Address | Software Scratch0 | Global src data offset | + * ------------------------------------------------------------------------------------------------------------------------- + * | Ctrl | Destination Id | 2'b00 | Desc Ctrl | Data Error | Dest Address | Software Scratch1 | Global dst data offset | + * ------------------------------------------------------------------------------------------------------------------------- + * + * The Control and Data Error codes are enumerated below + * + * Error conditions + * ================ + * + * Control Error Code Control Error Condition + * ------------------ ----------------------- + * 9'h000 No Error + * 9'h001 Undefined Op Class + * 9'h002 Undefined ECC TYPE (ECC only) + * 9'h004 Undefined ECC FUNCTION (ECC only) + * 9'h008 ECC timeout (ECC only) + * 9'h010 UNUSED + * 9'h020 UNUSED + * 9'h040 UNUSED + * 9'h080 Data Read Error + * 9'h100 Descriptor Ctrl Field Error (D0.Ctrl != SOP || D1.Ctrl != EOP) + * + * Data Error Code Data Error Condition + * --------------- -------------------- + * 9'h000 No Error + * 9'h001 Exponent Width > Block Width (RSA Only) + * 9'h002 Modulus Width > Block Width (RSA Only) + * 9'h004 UNUSED + * 9'h008 UNUSED + * 9'h010 UNUSED + * 9'h020 UNUSED + * 9'h040 UNUSED + * 9'h080 Data Read Error + * 9'h100 UNUSED + */ + +/* + * Result Data Word for Message Ring Descriptor + */ + +/* #define PUBKEY_RSLT_CTL_CTL */ +#define PUBKEY_RSLT_CTL_CTL_LSB 61 +#define PUBKEY_RSLT_CTL_CTL_BITS THREE_BITS +#define PUBKEY_RSLT_CTL_CTL_MASK \ + (PUBKEY_RSLT_CTL_CTL_BITS << PUBKEY_RSLT_CTL_CTL_LSB) + +/* #define PUBKEY_RSLT_CTL_DST_ID */ +#define PUBKEY_RSLT_CTL_DST_ID_LSB 54 +#define PUBKEY_RSLT_CTL_DST_ID_BITS SEVEN_BITS +#define PUBKEY_RSLT_CTL_DST_ID_MASK \ + (PUBKEY_RSLT_CTL_DST_ID_BITS << PUBKEY_RSLT_CTL_DST_ID_LSB) + +/* #define PUBKEY_RSLT_CTL_DESC_CTL */ +#define PUBKEY_RSLT_CTL_DESC_CTL_LSB 49 +#define PUBKEY_RSLT_CTL_DESC_CTL_BITS THREE_BITS +#define PUBKEY_RSLT_CTL_DESC_CTL_MASK \ + (PUBKEY_RSLT_CTL_DESC_CTL_BITS << PUBKEY_RSLT_CTL_DESC_CTL_LSB) + + +/* #define PUBKEY_RSLT_CTL_ERROR */ +#define PUBKEY_RSLT_CTL_ERROR_LSB 40 +#define PUBKEY_RSLT_CTL_ERROR_BITS NINE_BITS +#define PUBKEY_RSLT_CTL_ERROR_MASK \ + (PUBKEY_RSLT_CTL_ERROR_BITS << PUBKEY_RSLT_CTL_ERROR_LSB) + +/* #define PUBKEY_RSLT_CTL_SRCADDR */ +#define PUBKEY_RSLT_CTL_SRCADDR_LSB 0 +#define PUBKEY_RSLT_CTL_SRCADDR_BITS FOURTY_BITS +#define PUBKEY_RSLT_CTL_SRCADDR_MASK \ + (PUBKEY_RSLT_CTL_SRCADDR_BITS << PUBKEY_RSLT_CTL_SRCADDR_LSB) + + +/* #define PUBKEY_RSLT_DATA_CTL */ +#define PUBKEY_RSLT_DATA_CTL_LSB 61 +#define PUBKEY_RSLT_DATA_CTL_BITS THREE_BITS +#define PUBKEY_RSLT_DATA_CTL_MASK \ + (PUBKEY_RSLT_DATA_CTL_BITS << PUBKEY_RSLT_DATA_CTL_LSB) + +/* #define PUBKEY_RSLT_DATA_DST_ID */ +#define PUBKEY_RSLT_DATA_DST_ID_LSB 54 +#define PUBKEY_RSLT_DATA_DST_ID_BITS SEVEN_BITS +#define PUBKEY_RSLT_DATA_DST_ID_MASK \ + (PUBKEY_RSLT_DATA_DST_ID_BITS << PUBKEY_RSLT_DATA_DST_ID_LSB) + +/* #define PUBKEY_RSLT_DATA_DESC_CTL */ +#define PUBKEY_RSLT_DATA_DESC_CTL_LSB 49 +#define PUBKEY_RSLT_DATA_DESC_CTL_BITS THREE_BITS +#define PUBKEY_RSLT_DATA_DESC_CTL_MASK \ + (PUBKEY_RSLT_DATA_DESC_CTL_BITS << PUBKEY_RSLT_DATA_DESC_CTL_LSB) + +/* #define PUBKEY_RSLT_DATA_ERROR */ +#define PUBKEY_RSLT_DATA_ERROR_LSB 40 +#define PUBKEY_RSLT_DATA_ERROR_BITS NINE_BITS +#define PUBKEY_RSLT_DATA_ERROR_MASK \ + (PUBKEY_RSLT_DATA_ERROR_BITS << PUBKEY_RSLT_DATA_ERROR_LSB) + +/* #define PUBKEY_RSLT_DATA_DSTADDR */ +#define PUBKEY_RSLT_DATA_DSTADDR_LSB 40 +#define PUBKEY_RSLT_DATA_DSTADDR_BITS FOURTY_BITS +#define PUBKEY_RSLT_DATA_DSTADDR_MASK \ + (PUBKEY_RSLT_DATA_DSTADDR_BITS << PUBKEY_RSLT_DATA_DSTADDR_LSB) + +/* + * ****************************************************************** + * RSA Block - Data Error Code and Conditions + * ****************************************************************** + */ + +#define PK_CTL_ERR_NONE 0x0000 /* No Error */ +#define PK_CTL_ERR_OP_CLASS 0x0001 /* Undefined Op Class */ +#define PK_CTL_ERR_ECC_TYPE 0x0002 /* Undefined ECC TYPE (ECC only) */ +#define PK_CTL_ERR_ECC_FUNCT 0x0004 /* Undefined ECC FUNCTION (ECC only) */ +#define PK_CTL_ERR_ECC_TIMEOUT 0x0008 /* ECC timeout (ECC only) */ +#define PK_CTL_ERR_READ 0x0080 /* Data Read Error */ +#define PK_CTL_ERR_DESC 0x0100 /* Descriptor Ctrl Field Error (D0.Ctrl != SOP || D1.Ctrl != EOP) */ +#define PK_CTL_ERR_TIMEOUT 0x1000 /* Message Responce Timeout */ + +#define PK_DATA_ERR_NONE 0x0000 /* No Error */ +#define PK_DATA_ERR_EXP_WIDTH 0x0001 /* Exponent Width > Block Width */ +#define PK_DATA_ERR_MOD_WIDTH 0x0002 /* Modulus Width > Block Width */ +#define PK_DATA_ERR_READ 0x0080 /* Data Read Error */ + + +/* + * This defines the RSA data format + */ +/* + * typedef struct RSAData_s { + * uint64_t Constant; + * uint64_t Exponent; + * uint64_t Modulus; + * uint64_t Message; + *} RSAData_t, *RSAData_pt; + * + * typedef RSAData_t DHData_t; + * typedef RSAData_pt DHData_pt; + */ + +typedef struct UserPubData_s { + uint8_t *source; + uint8_t *user_result; + uint32_t result_length; +} UserPubData_t, *UserPubData_pt; + +typedef struct pubkey_desc { + OperationDescriptor_t op_ctl; /* size is cacheline */ + uint8_t source[1024]; + uint8_t dest[256]; /* 1024 makes cacheline-aligned */ + uint64_t control0; + uint64_t control1; + uint64_t ctl_result; + uint64_t data_result; + struct pubkey_desc *alloc; + UserPubData_t kern; /* ptrs for temp buffers */ +// volatile atomic_t flag_complete; +// struct semaphore sem_complete; +// wait_queue_t submit_wait; +} pubkey_desc_t, *pubkey_desc_pt; + +/* + * KASUMI F8 and F9 use the IV0/IV1 fields : + * + * 63 41 40 39 37 36 32 31 0 + * ---------------------------------------------------------------------------- + * | |FX/DIRECTION| | F8/BEARER | F8/COUNT | IV0 + * ---------------------------------------------------------------------------- + * 1 5 32 + * + * 63 32 31 0 + * ---------------------------------------------------------------------------- + * | F9/FRESH | F9/COUNT | IV1 + * ---------------------------------------------------------------------------- + * 32 32 + */ +#endif /* _XLR_SEC_DESC_H_ */ diff --git a/sys/dev/rmi/sec/rmilib.c b/sys/dev/rmi/sec/rmilib.c new file mode 100644 index 00000000000..a2eda2bc959 --- /dev/null +++ b/sys/dev/rmi/sec/rmilib.c @@ -0,0 +1,3193 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + + +#include +#include +#include +#include +#include +#include +#include +#include + + +//static int msgrng_stnid_pk0 = MSGRNG_STNID_PK0; +/*#define RMI_SEC_DEBUG */ + +#define SMP_CACHE_BYTES XLR_CACHELINE_SIZE +#define NUM_CHUNKS(size, bits) ( ((size)>>(bits)) + (((size)&((1<<(bits))-1))?1:0) ) + +static const char nib2hex[] = "0123456789ABCDEF"; +symkey_desc_pt g_desc; +struct xlr_sec_command *g_cmd; + +#ifdef XLR_SEC_CMD_DEBUG +static void +decode_symkey_desc (symkey_desc_pt desc, uint32_t cfg_vector); +#endif + +void print_buf (char *desc, void *data, int len); + +static int +xlr_sec_cipher_hash_command(xlr_sec_io_pt op, symkey_desc_pt desc, uint8_t ); + +static xlr_sec_error_t +xlr_sec_setup_descriptor (xlr_sec_io_pt op, + unsigned int flags, + symkey_desc_pt desc, + uint32_t *cfg_vector); + +static +xlr_sec_error_t xlr_sec_setup_packet (xlr_sec_io_pt op, + symkey_desc_pt desc, + unsigned int flags, + uint64_t *data, + PacketDescriptor_pt pkt_desc, + ControlDescriptor_pt ctl_desc, + uint32_t vector, + PacketDescriptor_pt next_pkt_desc, + uint8_t multi_frag_flag); + +static int +xlr_sec_submit_message(symkey_desc_pt desc, uint32_t cfg_vector); + +static +xlr_sec_error_t xlr_sec_setup_cipher(xlr_sec_io_pt op, + ControlDescriptor_pt ctl_desc, + uint32_t *vector); + +static +xlr_sec_error_t xlr_sec_setup_digest(xlr_sec_io_pt op, + ControlDescriptor_pt ctl_desc, + uint32_t *vector); + +static +xlr_sec_error_t xlr_sec_setup_cksum(xlr_sec_io_pt op, + ControlDescriptor_pt ctl_desc); + +static +xlr_sec_error_t xlr_sec_control_setup (xlr_sec_io_pt op, + unsigned int flags, + uint64_t *control, + ControlDescriptor_pt ctl_desc, + xlr_sec_drv_user_t *user, + uint32_t vector); + + +xlr_sec_error_t +xlr_sec_submit_op(symkey_desc_pt desc); + +static void xlr_sec_free_desc(symkey_desc_pt desc); + +void xlr_sec_msgring_handler(int bucket, int size, int code, int stid, + struct msgrng_msg *msg, void *data); + + +void xlr_sec_init( struct xlr_sec_softc *sc) +{ + unsigned int i; + xlr_reg_t* mmio; + + + mmio = sc->mmio = xlr_io_mmio( XLR_IO_SECURITY_OFFSET ) ; + + xlr_write_reg(mmio, SEC_DMA_CREDIT, SEC_DMA_CREDIT_CONFIG); + + + xlr_write_reg(mmio, SEC_CONFIG2, SEC_CFG2_ROUND_ROBIN_ON); + + for(i = 0; i < 8; i++) + xlr_write_reg (mmio, + SEC_MSG_BUCKET0_SIZE + i, + xlr_is_xls() ? + xls_bucket_sizes.bucket[MSGRNG_STNID_SEC + i]: + bucket_sizes.bucket[MSGRNG_STNID_SEC + i]); + + for(i = 0; i < 128; i++) + xlr_write_reg (mmio, + SEC_CC_CPU0_0 + i, + xlr_is_xls() ? + xls_cc_table_sec.counters[i>>3][i&0x07]: + cc_table_sec.counters[i>>3][i&0x07]); + + + /* + * Register a bucket handler with the phoenix messaging subsystem + * For now, register handler for bucket 0->5 in msg stn 0 + */ + if (register_msgring_handler(TX_STN_SAE, xlr_sec_msgring_handler,NULL)) { + panic("Couldn't register msgring handler 0\n"); + } + + return ; +} + + + +int xlr_sec_setup( struct xlr_sec_session* ses, + struct xlr_sec_command *cmd, + symkey_desc_pt desc + ) +{ + xlr_sec_io_pt op; + int size, ret_val; + int iv_len; + + + desc->ses = ses; + op = &cmd->op ; + if(op == NULL) + return (-ENOMEM); + + + + desc->ctl_desc.instruction = 0; + memset(&desc->ctl_desc.cipherHashInfo ,0 , sizeof(CipherHashInfo_t)); + desc->control = 0; + + desc->pkt_desc[0].srcLengthIVOffUseIVNext = 0; + desc->pkt_desc[0].dstDataSettings = 0; + desc->pkt_desc[0].authDstNonceLow = 0; + desc->pkt_desc[0].ckSumDstNonceHiCFBMaskLLWMask = 0; + desc->pkt_desc[1].srcLengthIVOffUseIVNext = 0; + desc->pkt_desc[1].dstDataSettings = 0; + desc->pkt_desc[1].authDstNonceLow = 0; + desc->pkt_desc[1].ckSumDstNonceHiCFBMaskLLWMask = 0; + + desc->data = 0; + desc->ctl_result = 0; + desc->data_result = 0; + + + if (op->flags & XLR_SEC_FLAGS_HIGH_PRIORITY) + if (!xlr_is_xls()) + desc->op_ctl.stn_id++; + + desc->user.user_src = (uint8_t *)(unsigned long)op->source_buf; + desc->user.user_dest = (uint8_t *)(unsigned long)op->dest_buf; + desc->user.user_auth = (uint8_t *)(unsigned long)op->auth_dest; + + + if ((op->cipher_type == XLR_SEC_CIPHER_TYPE_ARC4) && + (!op->rc4_state && (op->rc4_loadstate || op->rc4_savestate))) { + printf(" ** Load/Save State and no State **"); + xlr_sec_free_desc(desc); + return (-EINVAL); + } + desc->user.user_state = (uint8_t *)(unsigned long)op->rc4_state; + + + switch (op->cipher_type) { + case XLR_SEC_CIPHER_TYPE_NONE: + iv_len = 0; + break; + case XLR_SEC_CIPHER_TYPE_DES: + case XLR_SEC_CIPHER_TYPE_3DES: + iv_len = XLR_SEC_DES_IV_LENGTH; + break; + case XLR_SEC_CIPHER_TYPE_AES128: + case XLR_SEC_CIPHER_TYPE_AES192: + case XLR_SEC_CIPHER_TYPE_AES256: + iv_len = XLR_SEC_AES_IV_LENGTH; + break; + case XLR_SEC_CIPHER_TYPE_ARC4: + iv_len = XLR_SEC_ARC4_IV_LENGTH; + break; + case XLR_SEC_CIPHER_TYPE_KASUMI_F8: + iv_len = XLR_SEC_KASUMI_F8_IV_LENGTH; + break; + + default: + printf(" ** Undefined Cipher Type **"); + xlr_sec_free_desc(desc); + return (-EINVAL); + } + + + + + size = op->source_buf_size + iv_len; + + /* make sure that there are enough bytes for aes based stream ciphers */ + if (op->cipher_mode == XLR_SEC_CIPHER_MODE_F8 || + op->cipher_mode == XLR_SEC_CIPHER_MODE_CTR) + size += XLR_SEC_AES_BLOCK_SIZE - 1; + + if (op->cipher_type == XLR_SEC_CIPHER_TYPE_NONE) { + if(op->source_buf_size != 0){ + memcpy(desc->user.aligned_src,(uint8_t *)(unsigned long)op->source_buf, + op->source_buf_size); + } + } + else { + if(ses->multi_frag_flag){ + /* copy IV into temporary kernel source buffer */ + memcpy (desc->user.aligned_src, &op->initial_vector[0], iv_len); + + /* copy input data to temporary kernel source buffer */ + memcpy((uint8_t *) (desc->user.aligned_src + iv_len), + (uint8_t *)(unsigned long)op->source_buf, SEC_MAX_FRAG_LEN); + + desc->next_src_len = op->source_buf_size - SEC_MAX_FRAG_LEN; + memcpy((uint8_t *) (desc->next_src_buf ), + (uint8_t *)(unsigned long)(op->source_buf + SEC_MAX_FRAG_LEN), + desc->next_src_len ); + + op->source_buf_size = SEC_MAX_FRAG_LEN ; + op->source_buf_size += iv_len; + } + else{ + /* copy IV into temporary kernel source buffer */ + memcpy (desc->user.aligned_src, &op->initial_vector[0], iv_len); + + /* copy input data to temporary kernel source buffer */ + memcpy((uint8_t *) (desc->user.aligned_src + iv_len), + (uint8_t *)(unsigned long)op->source_buf,op->source_buf_size); + op->source_buf_size += iv_len; + } + } + + + + /* Set source to new kernel space */ + op->source_buf = (uint64_t)(unsigned long)desc->user.aligned_src; + + + /* + * Build new dest buffer, for Cipher output only + */ + if (op->cipher_type == XLR_SEC_CIPHER_TYPE_NONE) { + /* + * Digest Engine *NEEDS* this, + * otherwise it will write at 0[x] + */ + op->dest_buf = (uint64_t)(unsigned long)desc->user.aligned_src; + } + else { + /* DEBUG -dpk */ + XLR_SEC_CMD_DIAG("dest_buf_size = %d \n", op->dest_buf_size); + + size = op->dest_buf_size + iv_len; + + /* make sure that there are enough bytes for aes based stream ciphers */ + if (op->cipher_mode == XLR_SEC_CIPHER_MODE_F8 || + op->cipher_mode == XLR_SEC_CIPHER_MODE_CTR) + size += XLR_SEC_AES_BLOCK_SIZE - 1; + op->dest_buf = (uint64_t)(unsigned long)desc->user.aligned_dest; + + } + + ret_val = xlr_sec_cipher_hash_command (op, desc, ses->multi_frag_flag); + + return (ret_val); + +} + +static int +xlr_sec_cipher_hash_command(xlr_sec_io_pt op, symkey_desc_pt desc, + uint8_t multi_frag_flag) +{ + xlr_sec_error_t err; + uint32_t cfg_vector; + unsigned int setup_flags = 0; + + err = XLR_SEC_ERR_NONE; + cfg_vector = 0; + + if ((op->digest_type == XLR_SEC_DIGEST_TYPE_NONE) && + (op->cipher_type != XLR_SEC_CIPHER_TYPE_ARC4) && + (op->cipher_mode != XLR_SEC_CIPHER_MODE_F8) && + (op->cipher_type != XLR_SEC_CIPHER_TYPE_KASUMI_F8) && + (op->source_buf_size & 0x7)) { + printf("Invalid Cipher Block Size, data len=%d\n", + op->source_buf_size); + return (-EINVAL); + } + + do { + + if ((op->cipher_type == XLR_SEC_CIPHER_TYPE_3DES) && + (op->cipher_op == XLR_SEC_CIPHER_OP_DECRYPT)) + setup_flags = XLR_SEC_SETUP_OP_FLIP_3DES_KEY; + + err = xlr_sec_setup_descriptor(op, + setup_flags, + desc, &cfg_vector); + if (err != XLR_SEC_ERR_NONE) + break; + + err = xlr_sec_setup_packet(op, + desc, + op->digest_type != XLR_SEC_DIGEST_TYPE_NONE ? + XLR_SEC_SETUP_OP_CIPHER_HMAC : 0, + &desc->data, + &desc->pkt_desc[0], + &desc->ctl_desc, + cfg_vector, + &desc->pkt_desc[1], + multi_frag_flag); + if (err != XLR_SEC_ERR_NONE) + break; + } while(0); + if (err != XLR_SEC_ERR_NONE) { + return (EINVAL); + } + + err = xlr_sec_submit_message(desc, cfg_vector); + return err; +} + + +static xlr_sec_error_t +xlr_sec_setup_descriptor (xlr_sec_io_pt op, + unsigned int flags, + symkey_desc_pt desc, + uint32_t *cfg_vector) +{ + xlr_sec_error_t err; + + XLR_SEC_CMD_DIAG("xlr_sec_setup_descriptor: ENTER\n"); + + + if ((err=xlr_sec_setup_cipher(op,&desc->ctl_desc,cfg_vector)) != XLR_SEC_ERR_NONE) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_descriptor: xlr_sec_setup_cipher done err %d\n", + (int)err); + return err; + } + + if (op->digest_type != XLR_SEC_DIGEST_TYPE_NONE) { + if ((err=xlr_sec_setup_digest(op,&desc->ctl_desc,cfg_vector)) != XLR_SEC_ERR_NONE) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_descriptor: xlr_sec_setup_digest done err %d\n", + (int)err); + return err; + } + } + + if ((err = xlr_sec_setup_cksum(op, &desc->ctl_desc)) != XLR_SEC_ERR_NONE) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_descriptor: xlr_sec_setup_cksum done err %d\n", + (int)err); + return err; + } + + if ((err = xlr_sec_control_setup(op, + flags, + &desc->control, + &desc->ctl_desc, + &desc->user, + *cfg_vector)) != XLR_SEC_ERR_NONE) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_descriptor: xlr_sec_control_setup done err %d\n", + (int)err); + return err; + } + + XLR_SEC_CMD_DIAG("xlr_sec_setup_descriptor: DONE\n"); + return err; +} + + + +static +xlr_sec_error_t xlr_sec_setup_packet (xlr_sec_io_pt op, + symkey_desc_pt desc, + unsigned int flags, + uint64_t *data, + PacketDescriptor_pt pkt_desc, + ControlDescriptor_pt ctl_desc, + uint32_t vector, + PacketDescriptor_pt next_pkt_desc, + uint8_t multi_frag_flag) +{ + uint32_t len, next_len = 0, len_dwords, last_u64_bytes; + uint64_t addr; + uint64_t seg_addr, next_seg_addr = 0; + uint64_t byte_offset, global_offset; + uint32_t cipher_offset_dwords; + + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ENTER vector = %04x\n", vector); + + /* physical address of the source buffer */ + addr = (uint64_t)vtophys((void*)(unsigned long)op->source_buf); + /* cache-aligned base of the source buffer */ + seg_addr = (addr & ~(SMP_CACHE_BYTES - 1)); + /* offset in bytes to the source buffer start from the segment base */ + byte_offset = addr - seg_addr; + /* global offset: 0-7 bytes */ + global_offset = byte_offset & 0x7; + + + /* + * op->source_buf_size is expected to be the Nb double words to stream + * in (Including Segment address->CP/IV/Auth/CkSum offsets) + */ + + /* adjusted length of the whole thing, accounting for the added head, + sans global_offset (per Paul S.) + */ + + len = op->source_buf_size + byte_offset - global_offset; + if(multi_frag_flag){ + next_seg_addr = (uint64_t)vtophys((void*)(unsigned long)(desc->next_src_buf) ); + next_seg_addr = (next_seg_addr & ~(SMP_CACHE_BYTES - 1)); + next_len = desc->next_src_len; + } + + /* length of the whole thing in dwords */ + len_dwords = NUM_CHUNKS(len, 3); + /* number of bytes in the last chunk (len % 8) */ + last_u64_bytes = len & 0x07; + + if (op->cipher_offset & 0x7) { + printf("** cipher_offset(%d) fails 64-bit word alignment **", + op->cipher_offset); + + return XLR_SEC_ERR_CIPHER_MODE; /* ! fix ! */ + } + + /* global_offset is only three bits, so work the number of the whole + 8-byte words into the global offset. + both offset and cipher_offset are byte counts + */ + cipher_offset_dwords = (op->iv_offset + byte_offset) >> 3; + + + if (op->cipher_mode == XLR_SEC_CIPHER_MODE_F8 || + op->cipher_mode == XLR_SEC_CIPHER_MODE_CTR) { + if(multi_frag_flag){ + int nlhmac = ((op->source_buf_size + global_offset + 7 - op->cipher_offset) >> 3) & 1; + pkt_desc->srcLengthIVOffUseIVNext = + + FIELD_VALUE(PKT_DSC_HASHBYTES, len & 7) | + FIELD_VALUE(PKT_DSC_IVOFF, cipher_offset_dwords) | + FIELD_VALUE(PKT_DSC_PKTLEN, nlhmac + ((len + 7) >> 3)) | + FIELD_VALUE(PKT_DSC_NLHMAC, nlhmac) | + FIELD_VALUE(PKT_DSC_BREAK, 0) | + FIELD_VALUE(PKT_DSC_WAIT, 1) | + FIELD_VALUE(PKT_DSC_NEXT, 1) | + FIELD_VALUE(PKT_DSC_SEGADDR, seg_addr >> (PKT_DSC_SEGADDR_LSB)) | + FIELD_VALUE(PKT_DSC_SEGOFFSET, global_offset); + } + else{ + int nlhmac = ((op->source_buf_size + global_offset + 7 - op->cipher_offset) >> 3) & 1; + pkt_desc->srcLengthIVOffUseIVNext = + FIELD_VALUE(PKT_DSC_HASHBYTES, len & 7) | + FIELD_VALUE(PKT_DSC_IVOFF, cipher_offset_dwords) | + FIELD_VALUE(PKT_DSC_PKTLEN, nlhmac + ((len + 7) >> 3)) | + FIELD_VALUE(PKT_DSC_NLHMAC, nlhmac) | + FIELD_VALUE(PKT_DSC_BREAK, 0) | + FIELD_VALUE(PKT_DSC_WAIT, 0) | + FIELD_VALUE(PKT_DSC_SEGADDR, seg_addr >> (PKT_DSC_SEGADDR_LSB)) | + FIELD_VALUE(PKT_DSC_SEGOFFSET, global_offset); + + } + } + else{ + if(multi_frag_flag){ + pkt_desc->srcLengthIVOffUseIVNext = + + FIELD_VALUE(PKT_DSC_HASHBYTES, len & 7) | + FIELD_VALUE(PKT_DSC_IVOFF, cipher_offset_dwords) | + FIELD_VALUE(PKT_DSC_PKTLEN, (len + 7) >> 3) | + FIELD_VALUE(PKT_DSC_BREAK, 0) | + FIELD_VALUE(PKT_DSC_WAIT, 0) | + FIELD_VALUE(PKT_DSC_NEXT, 1) | + FIELD_VALUE(PKT_DSC_SEGADDR, seg_addr >> (PKT_DSC_SEGADDR_LSB)) | + FIELD_VALUE(PKT_DSC_SEGOFFSET, global_offset); + + + next_pkt_desc->srcLengthIVOffUseIVNext = + FIELD_VALUE(PKT_DSC_HASHBYTES, (next_len & 7)) | + FIELD_VALUE(PKT_DSC_IVOFF, 0) | + FIELD_VALUE(PKT_DSC_PKTLEN, (next_len + 7) >> 3) | + FIELD_VALUE(PKT_DSC_BREAK, 0) | + FIELD_VALUE(PKT_DSC_WAIT, 0) | + FIELD_VALUE(PKT_DSC_NEXT, 0) | + FIELD_VALUE(PKT_DSC_SEGADDR, next_seg_addr >> (PKT_DSC_SEGADDR_LSB)) | + FIELD_VALUE(PKT_DSC_SEGOFFSET, 0); + + + } + else{ + pkt_desc->srcLengthIVOffUseIVNext = + FIELD_VALUE(PKT_DSC_HASHBYTES, len & 7) | + FIELD_VALUE(PKT_DSC_IVOFF, cipher_offset_dwords) | + FIELD_VALUE(PKT_DSC_PKTLEN, (len + 7) >> 3) | + FIELD_VALUE(PKT_DSC_BREAK, 0) | + FIELD_VALUE(PKT_DSC_WAIT, 0) | + FIELD_VALUE(PKT_DSC_SEGADDR, seg_addr >> (PKT_DSC_SEGADDR_LSB)) | + FIELD_VALUE(PKT_DSC_SEGOFFSET, global_offset); + + + } + } + + switch (op->pkt_hmac) { + case XLR_SEC_LOADHMACKEY_MODE_OLD: + CLEAR_SET_FIELD(pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_LOADHMACKEY, PKT_DSC_LOADHMACKEY_OLD); + if(multi_frag_flag){ + CLEAR_SET_FIELD(next_pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_LOADHMACKEY, PKT_DSC_LOADHMACKEY_OLD); + + } + break; + case XLR_SEC_LOADHMACKEY_MODE_LOAD: + CLEAR_SET_FIELD(pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_LOADHMACKEY, PKT_DSC_LOADHMACKEY_LOAD); + if(multi_frag_flag){ + CLEAR_SET_FIELD(next_pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_LOADHMACKEY, PKT_DSC_LOADHMACKEY_LOAD); + + } + break; + default: + if (vector & (XLR_SEC_VECTOR_HMAC | XLR_SEC_VECTOR_HMAC2 | XLR_SEC_VECTOR_GCM | XLR_SEC_VECTOR_F9)) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ERR_LOADHMACKEY_MODE EXIT\n"); + return XLR_SEC_ERR_LOADHMACKEY_MODE; + } + break; + } + + switch (op->pkt_hash) { + case XLR_SEC_PADHASH_PADDED: + CLEAR_SET_FIELD(pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_PADHASH, PKT_DSC_PADHASH_PADDED); + if(multi_frag_flag){ + CLEAR_SET_FIELD(next_pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_PADHASH, PKT_DSC_PADHASH_PADDED); + } + break; + case XLR_SEC_PADHASH_PAD: + CLEAR_SET_FIELD(pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_PADHASH, PKT_DSC_PADHASH_PAD); + if(multi_frag_flag){ + CLEAR_SET_FIELD(next_pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_PADHASH, PKT_DSC_PADHASH_PAD); + } + break; + default: + if (vector & (XLR_SEC_VECTOR_MAC | XLR_SEC_VECTOR_HMAC | XLR_SEC_VECTOR_HMAC2)) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ERR_PADHASH_MODE EXIT\n"); + return XLR_SEC_ERR_PADHASH_MODE; + } + break; + } + + switch (op->pkt_iv) { + case XLR_SEC_PKT_IV_OLD: + CLEAR_SET_FIELD(pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_IV, PKT_DSC_IV_OLD); + if(multi_frag_flag){ + CLEAR_SET_FIELD(next_pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_IV, PKT_DSC_IV_OLD); + + } + break; + case XLR_SEC_PKT_IV_NEW: + CLEAR_SET_FIELD(pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_IV, PKT_DSC_IV_NEW); + if(multi_frag_flag){ + CLEAR_SET_FIELD(next_pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_IV, PKT_DSC_IV_NEW); + + } + break; + default: + if (vector & XLR_SEC_VECTOR_CIPHER) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ERR_PKT_IV_MODE EXIT\n"); + return XLR_SEC_ERR_PKT_IV_MODE; + } + break; + } + + XLR_SEC_CMD_DIAG ("xlr_sec_setup_packet: src_buf=%llx phys_src_buf=%llx \n", + (unsigned long long)op->source_buf, (unsigned long long)addr); + + XLR_SEC_CMD_DIAG ("xlr_sec_setup_packet: seg_addr=%llx offset=%lld\n", + (unsigned long long)seg_addr, (unsigned long long)byte_offset); + + XLR_SEC_CMD_DIAG ("xlr_sec_setup_packet: global src offset: %d, iv_offset=%d\n", + cipher_offset_dwords, op->iv_offset); + + XLR_SEC_CMD_DIAG ("xlr_sec_setup_packet: src_buf_sz=%d PKT_LEN=%d\n", + op->source_buf_size, len_dwords); + + /* same operation with the destination. + cipher offset affects this, as well + */ + if(multi_frag_flag){ + next_seg_addr = (uint64_t)vtophys((void*)(unsigned long)(desc->next_dest_buf) ); + next_seg_addr = (next_seg_addr & ~(SMP_CACHE_BYTES - 1)); + } + + addr = (uint64_t)vtophys((void*)(unsigned long)op->dest_buf); + seg_addr = (addr & ~(SMP_CACHE_BYTES - 1)); + byte_offset = addr - seg_addr; + global_offset = byte_offset & 0x7; + + XLR_SEC_CMD_DIAG ("xlr_sec_setup_packet: dest_buf=%llx phys_dest_buf=%llx \n", + (unsigned long long)op->dest_buf, (unsigned long long)addr); + + XLR_SEC_CMD_DIAG ("xlr_sec_setup_packet: seg_addr=%llx offset=%lld\n", + (unsigned long long)seg_addr, (unsigned long long)byte_offset); + + /* + * Dest Address = + * (Cipher Dest Address) + (Cipher Offset) + (Global Dest Data Offset) + * + * Cipher Dest Address - Cache-line (0xffffffffe0) + * Cipher Offset - Which (64-bit) Word in Cacheline (0-3) + * Global Dest Data Offset - Number of Bytes in (64-bit) Word before data + * + * It must be set for Digest-only Ops, since + * the Digest engine will write data to this address. + */ + cipher_offset_dwords = (op->cipher_offset + byte_offset) >> 3; + + + pkt_desc->dstDataSettings = + /* SYM_OP, HASHSRC */ + FIELD_VALUE(PKT_DSC_CPHROFF, cipher_offset_dwords) | + FIELD_VALUE(PKT_DSC_HASHOFF, (op->digest_offset + byte_offset) >> 3) | + FIELD_VALUE(PKT_DSC_CPHR_DST_ADDR, seg_addr) | + FIELD_VALUE(PKT_DSC_CPHR_DST_DWOFFSET, 0) | + FIELD_VALUE(PKT_DSC_CPHR_DST_OFFSET, global_offset); + + if(multi_frag_flag){ + next_pkt_desc->dstDataSettings = + /* SYM_OP, HASHSRC */ + FIELD_VALUE(PKT_DSC_CPHROFF, cipher_offset_dwords) | + FIELD_VALUE(PKT_DSC_HASHOFF, (op->digest_offset + byte_offset) >> 3) | + FIELD_VALUE(PKT_DSC_CPHR_DST_ADDR, next_seg_addr) | + FIELD_VALUE(PKT_DSC_CPHR_DST_DWOFFSET, 0) | + FIELD_VALUE(PKT_DSC_CPHR_DST_OFFSET, global_offset); + + } + + if (op->cipher_type == XLR_SEC_CIPHER_TYPE_ARC4) + pkt_desc->dstDataSettings |= FIELD_VALUE(PKT_DSC_ARC4BYTECOUNT, last_u64_bytes); + + if (op->cipher_type != XLR_SEC_CIPHER_TYPE_NONE) { + switch (op->cipher_op) { + case XLR_SEC_CIPHER_OP_ENCRYPT: + CLEAR_SET_FIELD(pkt_desc->dstDataSettings, + PKT_DSC_SYM_OP, PKT_DSC_SYM_OP_ENCRYPT); + if(multi_frag_flag){ + CLEAR_SET_FIELD(next_pkt_desc->dstDataSettings, + PKT_DSC_SYM_OP, PKT_DSC_SYM_OP_ENCRYPT); + + } + break; + case XLR_SEC_CIPHER_OP_DECRYPT: + CLEAR_SET_FIELD(pkt_desc->dstDataSettings, + PKT_DSC_SYM_OP, PKT_DSC_SYM_OP_DECRYPT); + if(multi_frag_flag){ + CLEAR_SET_FIELD(next_pkt_desc->dstDataSettings, + PKT_DSC_SYM_OP, PKT_DSC_SYM_OP_DECRYPT); + + } + break; + default: + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ERR_CIPHER_OP EXIT\n"); + return XLR_SEC_ERR_CIPHER_OP; + } + } + if (flags & XLR_SEC_SETUP_OP_HMAC) { + switch (op->digest_src) { + case XLR_SEC_DIGEST_SRC_DMA: + CLEAR_SET_FIELD(pkt_desc->dstDataSettings, + PKT_DSC_HASHSRC, PKT_DSC_HASHSRC_DMA); + if(multi_frag_flag){ + CLEAR_SET_FIELD(next_pkt_desc->dstDataSettings, + PKT_DSC_HASHSRC, PKT_DSC_HASHSRC_DMA); + + } + break; + case XLR_SEC_DIGEST_SRC_CPHR: + CLEAR_SET_FIELD(pkt_desc->dstDataSettings, + PKT_DSC_HASHSRC, PKT_DSC_HASHSRC_CIPHER); + if(multi_frag_flag){ + CLEAR_SET_FIELD(next_pkt_desc->dstDataSettings, + PKT_DSC_HASHSRC, PKT_DSC_HASHSRC_CIPHER); + } + break; + default: + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ERR_DIGEST_SRC EXIT\n"); + return XLR_SEC_ERR_DIGEST_SRC; + } + } + if (op->cksum_type != XLR_SEC_CKSUM_TYPE_NOP) { + switch (op->cksum_src) { + case XLR_SEC_CKSUM_SRC_DMA: + CLEAR_SET_FIELD(pkt_desc->dstDataSettings, + PKT_DSC_CKSUMSRC, PKT_DSC_CKSUMSRC_DMA); + if(multi_frag_flag){ + CLEAR_SET_FIELD(next_pkt_desc->dstDataSettings, + PKT_DSC_CKSUMSRC, PKT_DSC_CKSUMSRC_DMA); + } + break; + case XLR_SEC_CKSUM_SRC_CIPHER: + CLEAR_SET_FIELD(next_pkt_desc->dstDataSettings, + PKT_DSC_CKSUMSRC, PKT_DSC_CKSUMSRC_CIPHER); + if(multi_frag_flag){ + CLEAR_SET_FIELD(next_pkt_desc->dstDataSettings, + PKT_DSC_CKSUMSRC, PKT_DSC_CKSUMSRC_CIPHER); + } + break; + default: + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ERR_CKSUM_SRC EXIT\n"); + return XLR_SEC_ERR_CKSUM_SRC; + } + } + + pkt_desc->ckSumDstNonceHiCFBMaskLLWMask = + FIELD_VALUE(PKT_DSC_HASH_BYTE_OFF, (op->digest_offset & 0x7)) | + FIELD_VALUE(PKT_DSC_PKTLEN_BYTES, 0) | + /* NONCE_HI, PKT_DSC_LASTWORD, CFB_MASK, CKSUM_DST_ADDR */ + FIELD_VALUE(PKT_DSC_IV_OFF_HI, 0); + + if(multi_frag_flag){ + next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask = + FIELD_VALUE(PKT_DSC_HASH_BYTE_OFF, (op->digest_offset & 0x7)) | + FIELD_VALUE(PKT_DSC_PKTLEN_BYTES, 0) | + /* NONCE_HI, PKT_DSC_LASTWORD, CFB_MASK, CKSUM_DST_ADDR */ + FIELD_VALUE(PKT_DSC_IV_OFF_HI, 0); + + } + switch (op->pkt_lastword) { + case XLR_SEC_LASTWORD_128: + CLEAR_SET_FIELD(pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_128); + if(multi_frag_flag){ + CLEAR_SET_FIELD(next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_128); + + } + break; + case XLR_SEC_LASTWORD_96MASK: + CLEAR_SET_FIELD(pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_96MASK); + if(multi_frag_flag){ + CLEAR_SET_FIELD(next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_96MASK); + } + break; + case XLR_SEC_LASTWORD_64MASK: + CLEAR_SET_FIELD(pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_64MASK); + if(multi_frag_flag){ + CLEAR_SET_FIELD(next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_64MASK); + } + break; + case XLR_SEC_LASTWORD_32MASK: + CLEAR_SET_FIELD(pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_32MASK); + if(multi_frag_flag){ + CLEAR_SET_FIELD(next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_32MASK); + } + break; + default: + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ERR_LASTWORD_MODE EXIT\n"); + return XLR_SEC_ERR_LASTWORD_MODE; + } + CLEAR_SET_FIELD(pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_CFB_MASK, op->cfb_mask); + CLEAR_SET_FIELD(pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_NONCE_HI, htonl(op->nonce)>>24); + CLEAR_SET_FIELD(pkt_desc->authDstNonceLow, + PKT_DSC_NONCE_LOW, htonl(op->nonce)&0xffffff); + + if(multi_frag_flag){ + CLEAR_SET_FIELD(next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_CFB_MASK, op->cfb_mask); + CLEAR_SET_FIELD(next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_NONCE_HI, htonl(op->nonce)>>24); + CLEAR_SET_FIELD(next_pkt_desc->authDstNonceLow, + PKT_DSC_NONCE_LOW, htonl(op->nonce)&0xffffff); + + + } + + /* Auth Dest Address must be Cacheline aligned on input */ + if (vector & (XLR_SEC_VECTOR_MAC | XLR_SEC_VECTOR_HMAC | XLR_SEC_VECTOR_HMAC2 | XLR_SEC_VECTOR_GCM | XLR_SEC_VECTOR_F9)){ + pkt_desc->authDstNonceLow |= + /* NONCE_LOW */ + FIELD_VALUE(PKT_DSC_AUTH_DST_ADDR, + (uint64_t) vtophys((void*)(unsigned long)op->auth_dest)) | + FIELD_VALUE(PKT_DSC_CIPH_OFF_HI, 0); + + + if(multi_frag_flag){ + next_pkt_desc->authDstNonceLow |= + /* NONCE_LOW */ + FIELD_VALUE(PKT_DSC_AUTH_DST_ADDR, + (uint64_t) vtophys((void*)(unsigned long)desc->next_auth_dest)) | + FIELD_VALUE(PKT_DSC_CIPH_OFF_HI, 0); + + + } + + + } + + + /* CkSum Dest Address must be Cacheline aligned on input */ + if (op->cksum_type == XLR_SEC_CKSUM_TYPE_IP){ + CLEAR_SET_FIELD(pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_CKSUM_DST_ADDR, + (uint64_t)vtophys((void*)(unsigned long)op->cksum_dest)); + + if(multi_frag_flag){ + CLEAR_SET_FIELD(next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_CKSUM_DST_ADDR, + (uint64_t)vtophys((void*)(unsigned long)desc->next_cksum_dest)); + + } + + } + /* + XLR_SEC_CMD_DIAG (" xlr_sec_setup_packet(): pkt_desc=%llx phys_pkt_desc=%llx \n", + (unsigned long long)pkt_desc, (unsigned long long)virt_to_phys(pkt_desc)); + (unsigned long long)pkt_desc, (unsigned long long)vtophys(pkt_desc)); + */ + XLR_SEC_CMD_DIAG (" xlr_sec_setup_packet(): pkt_desc=%p phys_pkt_desc=%llx \n", + pkt_desc, (unsigned long long)vtophys(pkt_desc)); + + + + CLEAR_SET_FIELD(*data, MSG_CMD_DATA_ADDR, ((uint64_t)vtophys(pkt_desc))); + CLEAR_SET_FIELD(*data, MSG_CMD_DATA_CTL, SEC_EOP); + CLEAR_SET_FIELD(*data, MSG_CMD_DATA_LEN, MSG_CMD_DATA_LEN_LOAD); + + + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: DONE\n"); + +#ifdef RMI_SEC_DEBUG + + { + printf("data desc\n"); + printf("srcLengthIVOffUseIVNext = 0x%llx\n",pkt_desc->srcLengthIVOffUseIVNext ); + printf("dstDataSettings = 0x%llx\n", pkt_desc->dstDataSettings); + printf("authDstNonceLow = 0x%llx\n", pkt_desc->authDstNonceLow); + printf("ckSumDstNonceHiCFBMaskLLWMask = 0x%llx\n", pkt_desc->ckSumDstNonceHiCFBMaskLLWMask); + } + + if(multi_frag_flag){ + + printf("next data desc\n"); + printf("srcLengthIVOffUseIVNext = 0x%llx\n",next_pkt_desc->srcLengthIVOffUseIVNext ); + printf("dstDataSettings = 0x%llx\n", next_pkt_desc->dstDataSettings); + printf("authDstNonceLow = 0x%llx\n", next_pkt_desc->authDstNonceLow); + printf("ckSumDstNonceHiCFBMaskLLWMask = 0x%llx\n", next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask); + } + +#endif + +#ifdef SYMBOL + if (op->cipher_type == XLR_SEC_CIPHER_TYPE_ARC4) { + op->source_buf -= 0; + op->source_buf_size += 0; + op->dest_buf -= 0; + } +#endif + return XLR_SEC_ERR_NONE; +} + + +static int identify_symkey_ctl_error(uint32_t code, xlr_sec_error_t err) +{ + int ret_val = EINVAL; + + switch(code) { + case CTL_ERR_NONE: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error: No Error\n"); + ret_val = 0; + break; + case CTL_ERR_CIPHER_OP: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error(CTL_ERR_CIPHER_OP) - Unknown Cipher Op \n"); + break; + case CTL_ERR_MODE: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error(CTL_ERR_MODE) - " + "Unknown or Not Allowed Mode \n"); + break; + case CTL_ERR_CHKSUM_SRC: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error(CTL_ERR_CHKSUM_SRC) - Unknown CkSum Src\n"); + break; + case CTL_ERR_CFB_MASK: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error(CTL_ERR_CFB_MASK) - Forbidden CFB Mask \n"); + break; + case CTL_ERR_OP: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error(CTL_ERR_OP) - Unknown Ctrl Op \n"); + break; + case CTL_ERR_DATA_READ: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error(CTL_ERR_DATA_READ) - Data Read Error\n"); + break; + case CTL_ERR_DESC_CTRL: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error(CTL_ERR_DESC_CTRL) - " + "Descriptor Ctrl Field Error \n"); + break; + case CTL_ERR_UNDEF1: + case CTL_ERR_UNDEF2: + default: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error: UNKNOWN CODE=%d \n", code); + break; + } + return ret_val; +} + +static +int identify_symkey_data_error(uint32_t code, xlr_sec_error_t err) +{ + int ret_val = -EINVAL; + + switch(code) { + case DATA_ERR_NONE: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error No Error\n"); + ret_val = 0; + break; + case DATA_ERR_LEN_CIPHER: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Not Enough Data To Cipher\n"); + break; + case DATA_ERR_IV_ADDR: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Illegal IV Loacation\n"); + break; + case DATA_ERR_WD_LEN_AES: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Illegal Nb Words To AES\n"); + break; + case DATA_ERR_BYTE_COUNT: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Illegal Pad And ByteCount Spec\n"); + break; + case DATA_ERR_LEN_CKSUM: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Not Enough Data To CkSum\n"); + break; + case DATA_ERR_OP: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Unknown Data Op \n"); + break; + case DATA_ERR_READ: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Data Read Error \n"); + break; + case DATA_ERR_WRITE: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Data Write Error \n"); + break; + case DATA_ERR_UNDEF1: + default: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error - UNKNOWN CODE=%d \n", code); + break; + } + return ret_val; +} + + +static int +xlr_sec_submit_message(symkey_desc_pt desc, uint32_t cfg_vector) +{ + xlr_sec_error_t err; + uint32_t ctl_error, data_error; + int ret_val = 0; + + XLR_SEC_CMD_DIAG("xlr_sec_submit_message: ENTER\n"); + + err = XLR_SEC_ERR_NONE; + + XLR_SEC_CMD_DIAG_SYM_DESC(desc, cfg_vector); + + do { + /* For now, send message and wait for response */ + err = xlr_sec_submit_op(desc); + + XLR_SEC_CMD_DIAG("xlr_sec_submit_message: err = %d \n", (uint32_t)err); + + if( err != XLR_SEC_ERR_NONE ) { + ret_val = (EINVAL); + break; + } + + ctl_error = desc->ctl_result; + data_error = desc->data_result; + + XLR_SEC_CMD_DIAG("xlr_sec_submit_message: ctl_error = %x data_error = %x\n", + ctl_error, data_error); + + if ((ret_val = identify_symkey_ctl_error(ctl_error, err)) == 0) + ret_val = identify_symkey_data_error(data_error, err); + + XLR_SEC_CMD_DIAG("xlr_sec_submit_message: identify error = %d \n", ret_val ); + + } while( 0 ); + + XLR_SEC_CMD_DIAG("xlr_sec_submit_message: DONE\n"); + return (ret_val); +} + + +static +xlr_sec_error_t xlr_sec_setup_cipher(xlr_sec_io_pt op, + ControlDescriptor_pt ctl_desc, + uint32_t *vector) +{ + uint32_t aes_flag = 0; + uint32_t cipher_vector = 0; + + XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ENTER vector = %04x\n", *vector); + + switch (op->cipher_type) { + case XLR_SEC_CIPHER_TYPE_NONE: + SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_BYPASS); + XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: CIPHER_TYPE_NONE EXIT\n"); + return XLR_SEC_ERR_NONE; + case XLR_SEC_CIPHER_TYPE_DES: + cipher_vector |= XLR_SEC_VECTOR_CIPHER_DES; + SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_DES); + break; + case XLR_SEC_CIPHER_TYPE_3DES: + cipher_vector |= XLR_SEC_VECTOR_CIPHER_3DES; + SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_3DES); + break; + case XLR_SEC_CIPHER_TYPE_AES128: + aes_flag = 1; + cipher_vector |= XLR_SEC_VECTOR_CIPHER_AES128; + SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_AES128); + break; + case XLR_SEC_CIPHER_TYPE_AES192: + aes_flag = 1; + cipher_vector |= XLR_SEC_VECTOR_CIPHER_AES192; + SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_AES192); + break; + case XLR_SEC_CIPHER_TYPE_AES256: + aes_flag = 1; + cipher_vector |= XLR_SEC_VECTOR_CIPHER_AES256; + SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_AES256); + break; + case XLR_SEC_CIPHER_TYPE_ARC4: + cipher_vector |= XLR_SEC_VECTOR_CIPHER_ARC4; + SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_ARC4); + SET_FIELD(ctl_desc->instruction, CTL_DSC_ARC4_KEYLEN, + op->rc4_key_len); + SET_FIELD(ctl_desc->instruction, CTL_DSC_ARC4_LOADSTATE, + op->rc4_loadstate); + SET_FIELD(ctl_desc->instruction, CTL_DSC_ARC4_SAVESTATE, + op->rc4_savestate); + if (op->rc4_loadstate || op->rc4_savestate) + cipher_vector |= XLR_SEC_VECTOR_STATE; + break; + case XLR_SEC_CIPHER_TYPE_KASUMI_F8: + aes_flag = 1; + cipher_vector |= XLR_SEC_VECTOR_CIPHER_KASUMI_F8; + SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_KASUMI_F8); + break; + default: + XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ERR_CIPHER_TYPE EXIT\n"); + return XLR_SEC_ERR_CIPHER_TYPE; + } + + switch (op->cipher_mode) { + case XLR_SEC_CIPHER_MODE_ECB: + if (aes_flag == 1) + cipher_vector |= XLR_SEC_VECTOR_MODE_ECB_CBC_OFB; + else + cipher_vector |= XLR_SEC_VECTOR_MODE_ECB_CBC; + SET_FIELD(ctl_desc->instruction, CTL_DSC_MODE, CTL_DSC_MODE_ECB); + break; + case XLR_SEC_CIPHER_MODE_CBC: + if (aes_flag == 1) + cipher_vector |= XLR_SEC_VECTOR_MODE_ECB_CBC_OFB; + else + cipher_vector |= XLR_SEC_VECTOR_MODE_ECB_CBC; + SET_FIELD(ctl_desc->instruction, CTL_DSC_MODE, CTL_DSC_MODE_CBC); + break; + case XLR_SEC_CIPHER_MODE_OFB: + if (aes_flag == 0) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ERR_CIPHER_MODE EXIT\n"); + return XLR_SEC_ERR_CIPHER_MODE; + } + cipher_vector |= XLR_SEC_VECTOR_MODE_ECB_CBC_OFB; + SET_FIELD(ctl_desc->instruction, CTL_DSC_MODE, CTL_DSC_MODE_OFB); + break; + case XLR_SEC_CIPHER_MODE_CTR: + if (aes_flag == 0) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ERR_CIPHER_MODE EXIT\n"); + return XLR_SEC_ERR_CIPHER_MODE; + } + cipher_vector |= XLR_SEC_VECTOR_MODE_CTR_CFB; + SET_FIELD(ctl_desc->instruction, CTL_DSC_MODE, CTL_DSC_MODE_CTR); + break; + case XLR_SEC_CIPHER_MODE_CFB: + if (aes_flag == 0) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ERR_CIPHER_MODE EXIT\n"); + return XLR_SEC_ERR_CIPHER_MODE; + } + cipher_vector |= XLR_SEC_VECTOR_MODE_CTR_CFB; + SET_FIELD(ctl_desc->instruction, CTL_DSC_MODE, CTL_DSC_MODE_CFB); + break; + case XLR_SEC_CIPHER_MODE_F8: + if (aes_flag == 0) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ERR_CIPHER_MODE EXIT\n"); + return XLR_SEC_ERR_CIPHER_MODE; + } + cipher_vector |= XLR_SEC_VECTOR_MODE_F8; + SET_FIELD(ctl_desc->instruction, CTL_DSC_MODE, CTL_DSC_MODE_F8); + break; + default: + if (!(cipher_vector & (XLR_SEC_VECTOR_CIPHER_ARC4 | XLR_SEC_VECTOR_CIPHER_KASUMI_F8))) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ERR_CIPHER_MODE EXIT\n"); + return XLR_SEC_ERR_CIPHER_MODE; + } + } + + switch (op->cipher_init) { + case XLR_SEC_CIPHER_INIT_OK: + SET_FIELD(ctl_desc->instruction, + CTL_DSC_ICPHR, CTL_DSC_ICPHR_OKY); + break; + + case XLR_SEC_CIPHER_INIT_NK: + SET_FIELD(ctl_desc->instruction, + CTL_DSC_ICPHR, CTL_DSC_ICPHR_NKY); + break; + default: + XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ERR_CIPHER_INIT EXIT\n"); + return XLR_SEC_ERR_CIPHER_INIT; + } + + *vector |= cipher_vector; + + XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: EXIT vector = %04x\n", *vector); + + return XLR_SEC_ERR_NONE; +} + + +static +xlr_sec_error_t xlr_sec_setup_digest(xlr_sec_io_pt op, + ControlDescriptor_pt ctl_desc, + uint32_t *vector) +{ + uint32_t hash_flag = 0; + uint32_t hmac_flag = 0; + uint32_t digest_vector = 0; + + XLR_SEC_CMD_DIAG("xlr_sec_setup_digest: ENTER vector = %04x\n", *vector); + + switch (op->digest_type) { + case XLR_SEC_DIGEST_TYPE_MD5: + digest_vector |= XLR_SEC_VECTOR_MAC; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_MD5); + break; + case XLR_SEC_DIGEST_TYPE_SHA1: + digest_vector |= XLR_SEC_VECTOR_MAC; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA1); + break; + case XLR_SEC_DIGEST_TYPE_SHA256: + digest_vector |= XLR_SEC_VECTOR_MAC; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA256); + break; + case XLR_SEC_DIGEST_TYPE_SHA384: + digest_vector |= XLR_SEC_VECTOR_MAC; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASHHI, CTL_DSC_HASH_SHA384>>2); + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA384); + break; + case XLR_SEC_DIGEST_TYPE_SHA512: + digest_vector |= XLR_SEC_VECTOR_MAC; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASHHI, CTL_DSC_HASH_SHA512>>2); + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA512); + break; + case XLR_SEC_DIGEST_TYPE_GCM: + hash_flag = 1; + digest_vector |= XLR_SEC_VECTOR_GCM; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASHHI, CTL_DSC_HASH_GCM>>2); + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_GCM); + break; + case XLR_SEC_DIGEST_TYPE_KASUMI_F9: + hash_flag = 1; + digest_vector |= XLR_SEC_VECTOR_F9; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASHHI, CTL_DSC_HASH_KASUMI_F9>>2); + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_KASUMI_F9); + break; + case XLR_SEC_DIGEST_TYPE_HMAC_MD5: + hmac_flag = 1; + digest_vector |= XLR_SEC_VECTOR_HMAC; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_MD5); + break; + case XLR_SEC_DIGEST_TYPE_HMAC_SHA1: + hmac_flag = 1; + digest_vector |= XLR_SEC_VECTOR_HMAC; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA1); + break; + case XLR_SEC_DIGEST_TYPE_HMAC_SHA256: + hmac_flag = 1; + digest_vector |= XLR_SEC_VECTOR_HMAC; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA256); + break; + case XLR_SEC_DIGEST_TYPE_HMAC_SHA384: + hmac_flag = 1; + digest_vector |= XLR_SEC_VECTOR_HMAC2; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASHHI, CTL_DSC_HASH_SHA384>>2); + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA384); + break; + case XLR_SEC_DIGEST_TYPE_HMAC_SHA512: + hmac_flag = 1; + digest_vector |= XLR_SEC_VECTOR_HMAC2; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASHHI, CTL_DSC_HASH_SHA512>>2); + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA512); + break; + default: + return XLR_SEC_ERR_DIGEST_TYPE; + } + + if (hmac_flag == 1) { + SET_FIELD(ctl_desc->instruction, CTL_DSC_HMAC, CTL_DSC_HMAC_ON); + + } + if (hmac_flag || hash_flag) { + switch (op->digest_init) { + case XLR_SEC_DIGEST_INIT_OLDKEY: + SET_FIELD(ctl_desc->instruction, CTL_DSC_IHASH, CTL_DSC_IHASH_OLD); + break; + case XLR_SEC_DIGEST_INIT_NEWKEY: + SET_FIELD(ctl_desc->instruction, CTL_DSC_IHASH, CTL_DSC_IHASH_NEW); + break; + default: + return XLR_SEC_ERR_DIGEST_INIT; + } + } /* hmac_flag */ + + *vector |= digest_vector; + + XLR_SEC_CMD_DIAG("xlr_sec_setup_digest: EXIT vector = %04x\n", *vector); + + return XLR_SEC_ERR_NONE; +} + +static +xlr_sec_error_t xlr_sec_setup_cksum(xlr_sec_io_pt op, + ControlDescriptor_pt ctl_desc) +{ + switch (op->cksum_type) { + case XLR_SEC_CKSUM_TYPE_NOP: + SET_FIELD(ctl_desc->instruction, CTL_DSC_CKSUM, CTL_DSC_CKSUM_NOP); + return XLR_SEC_ERR_NONE; + case XLR_SEC_CKSUM_TYPE_IP: + SET_FIELD(ctl_desc->instruction, CTL_DSC_CKSUM, CTL_DSC_CKSUM_IP); + break; + default: + return XLR_SEC_ERR_CKSUM_TYPE; + } + + return XLR_SEC_ERR_NONE; +} + + +static +xlr_sec_error_t xlr_sec_control_setup (xlr_sec_io_pt op, + unsigned int flags, + uint64_t *control, + ControlDescriptor_pt ctl_desc, + xlr_sec_drv_user_t *user, + uint32_t vector) +{ + uint64_t *hmac_key = NULL; + uint64_t *cipher_key = NULL; + uint64_t *cipher_state = NULL; + uint32_t ctl_size = 0; + uint64_t ctl_addr = 0; + uint32_t cipher_keylen = 0; + uint32_t hmac_keylen = 0; + uint32_t ctl_len; + +#ifdef SYM_DEBUG + XLR_SEC_CMD_DIAG(" ENTER vector = %04x\n", vector); +#endif + + + switch (vector) { + case XLR_SEC_VECTOR_MAC: + XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR_MAC \n"); + ctl_size = sizeof(HMAC_t); + break; + case XLR_SEC_VECTOR_HMAC: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_HMAC \n"); + hmac_key = &ctl_desc->cipherHashInfo.infoHMAC.hmacKey0; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(HMAC_t); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoARC4.cipherKey0; + cipher_keylen = op->rc4_key_len; + ctl_size = sizeof(ARC4_t); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__HMAC\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoARC4HMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoARC4HMAC.hmacKey0; + cipher_keylen = op->rc4_key_len; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(ARC4HMAC_t); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__STATE: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__STATE\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoARC4State.cipherKey0; + cipher_state = + &ctl_desc->cipherHashInfo.infoARC4State.Arc4SboxData0; + cipher_keylen = op->rc4_key_len; + ctl_size = sizeof(ARC4State_t); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC__STATE: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__HMAC__STATE\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoARC4StateHMAC.cipherKey0; + cipher_state = + &ctl_desc->cipherHashInfo.infoARC4StateHMAC.Arc4SboxData0; + hmac_key = &ctl_desc->cipherHashInfo.infoARC4StateHMAC.hmacKey0; + cipher_keylen = op->rc4_key_len; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(ARC4StateHMAC_t); + break; + case XLR_SEC_VECTOR_CIPHER_KASUMI_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_KASUMI_F8\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoKASUMIF8.cipherKey0; + cipher_keylen = XLR_SEC_KASUMI_F8_KEY_LENGTH; + ctl_size = sizeof(KASUMIF8_t); + break; + case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoKASUMIF8HMAC.cipherKey0; + cipher_keylen = XLR_SEC_KASUMI_F8_KEY_LENGTH; + hmac_key = &ctl_desc->cipherHashInfo.infoKASUMIF8HMAC.hmacKey0; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(KASUMIF8HMAC_t); + break; + case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC2: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC2\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoKASUMIF8HMAC2.cipherKey0; + cipher_keylen = XLR_SEC_KASUMI_F8_KEY_LENGTH; + hmac_key = &ctl_desc->cipherHashInfo.infoKASUMIF8HMAC2.hmacKey0; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(KASUMIF8HMAC2_t); + break; + case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__GCM: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__GCM\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoKASUMIF8GCM.cipherKey0; + cipher_keylen = XLR_SEC_KASUMI_F8_KEY_LENGTH; + hmac_key = &ctl_desc->cipherHashInfo.infoKASUMIF8GCM.GCMH0; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(KASUMIF8GCM_t); + break; + case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__F9: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__F9\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoKASUMIF8F9.cipherKey0; + cipher_keylen = XLR_SEC_KASUMI_F8_KEY_LENGTH; + hmac_key = &ctl_desc->cipherHashInfo.infoKASUMIF8F9.authKey0; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(KASUMIF8F9_t); + break; + case XLR_SEC_VECTOR__CIPHER_DES__HMAC__MODE_ECB_CBC: + XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_DES__HMAC__MODE_ECB_CBC \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoDESHMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoDESHMAC.hmacKey0; + hmac_keylen = sizeof(HMAC_t); + cipher_keylen = XLR_SEC_DES_KEY_LENGTH; + ctl_size = sizeof(DESHMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_DES__MODE_ECB_CBC: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_DES__MODE_ECB_CBC \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoDES.cipherKey0; + cipher_keylen = XLR_SEC_DES_KEY_LENGTH; + ctl_size = sizeof(DES_t); + break; + case XLR_SEC_VECTOR__CIPHER_3DES__HMAC__MODE_ECB_CBC: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_3DES__HMAC__MODE_ECB_CBC \n"); + cipher_key = &ctl_desc->cipherHashInfo.info3DESHMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.info3DESHMAC.hmacKey0; + cipher_keylen = XLR_SEC_3DES_KEY_LENGTH; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(DES3HMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_3DES__MODE_ECB_CBC: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_3DES__MODE_ECB_CBC \n"); + cipher_key = &ctl_desc->cipherHashInfo.info3DES.cipherKey0; + cipher_keylen = XLR_SEC_3DES_KEY_LENGTH; + ctl_size = sizeof(DES3_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128HMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128HMAC.hmacKey0; + cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(AES128HMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128.cipherKey0; + cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; + ctl_size = sizeof(AES128_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128HMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128HMAC.hmacKey0; + cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(AES128HMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128.cipherKey0; + cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; + ctl_size = sizeof(AES128_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128F8HMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128F8HMAC.hmacKey0; + cipher_keylen = XLR_SEC_AES128F8_KEY_LENGTH; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(AES128F8HMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128F8.cipherKey0; + cipher_keylen = XLR_SEC_AES128F8_KEY_LENGTH; + ctl_size = sizeof(AES128F8_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192HMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192HMAC.hmacKey0; + cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(AES192HMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192.cipherKey0; + cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; + ctl_size = sizeof(AES192_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192HMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192HMAC.hmacKey0; + cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(AES192HMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192.cipherKey0; + cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; + ctl_size = sizeof(AES192_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192F8HMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192F8HMAC.hmacKey0; + cipher_keylen = XLR_SEC_AES192F8_KEY_LENGTH; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(AES192F8HMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192F8.cipherKey0; + cipher_keylen = XLR_SEC_AES192F8_KEY_LENGTH; + ctl_size = sizeof(AES192F8_t); + break; + + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256HMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256HMAC.hmacKey0; + cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(AES256HMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256.cipherKey0; + cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; + ctl_size = sizeof(AES256_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256HMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256HMAC.hmacKey0; + cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(AES256HMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256.cipherKey0; + cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; + ctl_size = sizeof(AES256_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256F8HMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256F8HMAC.hmacKey0; + cipher_keylen = XLR_SEC_AES256F8_KEY_LENGTH; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(AES256F8HMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256F8.cipherKey0; + cipher_keylen = XLR_SEC_AES256F8_KEY_LENGTH; + ctl_size = sizeof(AES256F8_t); + break; + case XLR_SEC_VECTOR_HMAC2: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_HMAC2 \n"); + hmac_key = &ctl_desc->cipherHashInfo.infoHMAC2.hmacKey0; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(HMAC2_t); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoARC4HMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoARC4HMAC2.hmacKey0; + cipher_keylen = op->rc4_key_len; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(ARC4HMAC2_t); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2__STATE: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2__STATE\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoARC4StateHMAC2.cipherKey0; + cipher_state = + &ctl_desc->cipherHashInfo.infoARC4StateHMAC2.Arc4SboxData0; + hmac_key = &ctl_desc->cipherHashInfo.infoARC4StateHMAC2.hmacKey0; + cipher_keylen = op->rc4_key_len; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(ARC4StateHMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_DES__HMAC2__MODE_ECB_CBC: + XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_DES__HMAC2__MODE_ECB_CBC \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoDESHMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoDESHMAC2.hmacKey0; + hmac_keylen = sizeof(HMAC2_t); + cipher_keylen = XLR_SEC_DES_KEY_LENGTH; + ctl_size = sizeof(DESHMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_3DES__HMAC2__MODE_ECB_CBC: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_3DES__HMAC2__MODE_ECB_CBC \n"); + cipher_key = &ctl_desc->cipherHashInfo.info3DESHMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.info3DESHMAC2.hmacKey0; + cipher_keylen = XLR_SEC_3DES_KEY_LENGTH; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(DES3HMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128HMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128HMAC2.hmacKey0; + cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(AES128HMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128HMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128HMAC2.hmacKey0; + cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(AES128HMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128F8HMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128F8HMAC2.hmacKey0; + cipher_keylen = XLR_SEC_AES128F8_KEY_LENGTH; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(AES128F8HMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192HMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192HMAC2.hmacKey0; + cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(AES192HMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192HMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192HMAC2.hmacKey0; + cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(AES192HMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192F8HMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192F8HMAC2.hmacKey0; + cipher_keylen = XLR_SEC_AES192F8_KEY_LENGTH; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(AES192F8HMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256HMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256HMAC2.hmacKey0; + cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(AES256HMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256HMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256HMAC2.hmacKey0; + cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(AES256HMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256F8HMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256F8HMAC2.hmacKey0; + cipher_keylen = XLR_SEC_AES256F8_KEY_LENGTH; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(AES256F8HMAC2_t); + break; + case XLR_SEC_VECTOR_GCM: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_GCM \n"); + hmac_key = &ctl_desc->cipherHashInfo.infoGCM.GCMH0; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(GCM_t); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__GCM: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__GCM\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoARC4GCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoARC4GCM.GCMH0; + cipher_keylen = op->rc4_key_len; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(ARC4GCM_t); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__GCM__STATE: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__GCM__STATE\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoARC4StateGCM.cipherKey0; + cipher_state = + &ctl_desc->cipherHashInfo.infoARC4StateGCM.Arc4SboxData0; + hmac_key = &ctl_desc->cipherHashInfo.infoARC4StateGCM.GCMH0; + cipher_keylen = op->rc4_key_len; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(ARC4StateGCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_DES__GCM__MODE_ECB_CBC: + XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_DES__GCM__MODE_ECB_CBC \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoDESGCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoDESGCM.GCMH0; + hmac_keylen = sizeof(GCM_t); + cipher_keylen = XLR_SEC_DES_KEY_LENGTH; + ctl_size = sizeof(DESGCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_3DES__GCM__MODE_ECB_CBC: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_3DES__GCM__MODE_ECB_CBC \n"); + cipher_key = &ctl_desc->cipherHashInfo.info3DESGCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.info3DESGCM.GCMH0; + cipher_keylen = XLR_SEC_3DES_KEY_LENGTH; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(DES3GCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128GCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128GCM.GCMH0; + cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(AES128GCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128GCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128GCM.GCMH0; + cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(AES128GCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128F8GCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128F8GCM.GCMH0; + cipher_keylen = XLR_SEC_AES128F8_KEY_LENGTH; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(AES128F8GCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192GCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192GCM.GCMH0; + cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(AES192GCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192GCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192GCM.GCMH0; + cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(AES192GCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192F8GCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192F8GCM.GCMH0; + cipher_keylen = XLR_SEC_AES192F8_KEY_LENGTH; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(AES192F8GCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256GCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256GCM.GCMH0; + cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(AES256GCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256GCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256GCM.GCMH0; + cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(AES256GCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256F8GCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256F8GCM.GCMH0; + cipher_keylen = XLR_SEC_AES256F8_KEY_LENGTH; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(AES256F8GCM_t); + break; + case XLR_SEC_VECTOR_F9: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_F9 \n"); + hmac_key = &ctl_desc->cipherHashInfo.infoF9.authKey0; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(F9_t); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__F9: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__F9\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoARC4F9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoARC4F9.authKey0; + cipher_keylen = op->rc4_key_len; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(ARC4F9_t); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__F9__STATE: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__F9__STATE\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoARC4StateF9.cipherKey0; + cipher_state = + &ctl_desc->cipherHashInfo.infoARC4StateF9.Arc4SboxData0; + hmac_key = &ctl_desc->cipherHashInfo.infoARC4StateF9.authKey0; + cipher_keylen = op->rc4_key_len; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(ARC4StateF9_t); + break; + case XLR_SEC_VECTOR__CIPHER_DES__F9__MODE_ECB_CBC: + XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_DES__F9__MODE_ECB_CBC \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoDESF9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoDESF9.authKey0; + hmac_keylen = sizeof(F9_t); + cipher_keylen = XLR_SEC_DES_KEY_LENGTH; + ctl_size = sizeof(DESF9_t); + break; + case XLR_SEC_VECTOR__CIPHER_3DES__F9__MODE_ECB_CBC: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_3DES__F9__MODE_ECB_CBC \n"); + cipher_key = &ctl_desc->cipherHashInfo.info3DESF9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.info3DESF9.authKey0; + cipher_keylen = XLR_SEC_3DES_KEY_LENGTH; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(DES3F9_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128F9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128F9.authKey0; + cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(AES128F9_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128F9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128F9.authKey0; + cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(AES128F9_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128F8F9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128F8F9.authKey0; + cipher_keylen = XLR_SEC_AES128F8_KEY_LENGTH; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(AES128F8F9_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192F9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192F9.authKey0; + cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(AES192F9_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192F9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192F9.authKey0; + cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(AES192F9_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192F8F9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192F8F9.authKey0; + cipher_keylen = XLR_SEC_AES192F8_KEY_LENGTH; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(AES192F8F9_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256F9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256F9.authKey0; + cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(AES256F9_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256F9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256F9.authKey0; + cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(AES256F9_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256F8F9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256F8F9.authKey0; + cipher_keylen = XLR_SEC_AES256F8_KEY_LENGTH; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(AES256F8F9_t); + break; + + default: + XLR_SEC_CMD_DIAG("default \n"); + return XLR_SEC_ERR_CONTROL_VECTOR; + } + + if ((cipher_key != NULL) && !(flags & XLR_SEC_SETUP_OP_PRESERVE_CIPHER_KEY)) + memcpy(cipher_key, &op->crypt_key[0], cipher_keylen); + + if ((hmac_key != NULL) && !(flags & XLR_SEC_SETUP_OP_PRESERVE_HMAC_KEY)) + memcpy(hmac_key, &op->mac_key[0], hmac_keylen); + if (cipher_state) { + if (op->rc4_loadstate) + memcpy(cipher_state, (void *)(unsigned long)op->rc4_state, + XLR_SEC_MAX_RC4_STATE_SIZE); + if (op->rc4_savestate) + user->aligned_state = (char *)cipher_state; + } + + if (flags & XLR_SEC_SETUP_OP_FLIP_3DES_KEY) { + uint64_t temp; + + temp = ctl_desc->cipherHashInfo.info3DES.cipherKey0; + ctl_desc->cipherHashInfo.info3DES.cipherKey0 = + ctl_desc->cipherHashInfo.info3DES.cipherKey2; + ctl_desc->cipherHashInfo.info3DES.cipherKey2 = temp; + } + + /* + * Control length is the number of control cachelines to be read so + * user needs to round up the control length to closest integer + * multiple of 32 bytes. + */ + ctl_size += sizeof(ctl_desc->instruction); + ctl_len = NUM_CHUNKS(ctl_size, 5); + XLR_SEC_CMD_DIAG("ctl_size in bytes: %u, in cachelines: %u\n", ctl_size, ctl_len); + CLEAR_SET_FIELD(*control, MSG_CMD_CTL_LEN, ctl_len); + + ctl_addr = (uint64_t)vtophys(ctl_desc); + CLEAR_SET_FIELD(*control, MSG_CMD_CTL_ADDR, ctl_addr); + + XLR_SEC_CMD_DIAG(" xlr_sec_control_setup(): ctl_desc=%p ctl_addr=%llx \n", + ctl_desc, (unsigned long long)ctl_addr); + + CLEAR_SET_FIELD(*control, MSG_CMD_CTL_CTL, SEC_SOP); + + return XLR_SEC_ERR_NONE; +} + + +xlr_sec_error_t +xlr_sec_submit_op(symkey_desc_pt desc) +{ + struct msgrng_msg send_msg; + + int rsp_dest_id, cpu, hard_cpu, hard_thread; + int code, retries; + unsigned long msgrng_flags = 0; + + /* threads (0-3) are orthogonal to buckets 0-3 */ + cpu = xlr_cpu_id(); + + hard_cpu = cpu >> 2; + hard_thread = cpu & 0x3; /* thread id */ + rsp_dest_id = (hard_cpu << 3) + hard_thread; + + desc->op_ctl.cpu = hard_cpu; + desc->op_ctl.flags = 0; /* called from kernel thread */ + + XLR_SEC_CMD_DIAG("[%s]:%d: cpu=0x%x hard_cpu=0x%x hard_thrd=0x%x id=0x%x \n", + __FUNCTION__, __LINE__, cpu, hard_cpu, hard_thread, rsp_dest_id); + + /* + * Set DestId in Message Control Word. + * This tells the Security Engine which bucket to send the + * reply to for this CPU + */ + CLEAR_SET_FIELD(desc->control, MSG_CMD_CTL_ID, rsp_dest_id); + CLEAR_SET_FIELD(desc->data, MSG_CMD_CTL_ID, rsp_dest_id); + + CLEAR_SET_FIELD(desc->control, MSG_CTL_OP_TYPE, MSG0_CTL_OP_ENGINE_SYMKEY); + CLEAR_SET_FIELD(desc->data, MSG_CTL_OP_TYPE, MSG1_CTL_OP_SYMKEY_PIPE0); + + send_msg.msg0 = desc->control | (1ULL<<53); + send_msg.msg1 = desc->data | (1ULL<<53) | (1ULL<<52); + send_msg.msg2 = send_msg.msg3 = 0; + + desc->op_ctl.flags = 1; // in_interrupt(); /* ipsec softirq ? */ + + XLR_SEC_CMD_DIAG("[%s]: IN_IRQ=%d msg0=0x%llx msg1=0x%llx \n", + __FUNCTION__, desc->op_ctl.flags, send_msg.msg0, send_msg.msg1); + + + + retries = 100; + + while (retries--) { + msgrng_flags_save(msgrng_flags); + + code = message_send_retry(SEC_MSGRING_WORDSIZE, + MSGRNG_CODE_SEC, + desc->op_ctl.stn_id, + &send_msg); + + + msgrng_flags_restore(msgrng_flags); + + if (code == 0) + break; + } + + + return (XLR_SEC_ERR_NONE); +} + + + +symkey_desc_pt xlr_sec_allocate_desc(void* session_ptr) +{ + uint64_t addr; + symkey_desc_pt aligned, new; + + new = (symkey_desc_pt) malloc(sizeof(symkey_desc_t), + M_DEVBUF, M_NOWAIT | M_ZERO); + + if (new == NULL) + return (NULL); + + new->ses = session_ptr ; + + new->user.kern_src = new->user.aligned_src = + (uint8_t *) contigmalloc(256*1024+1024, + M_DEVBUF, M_NOWAIT | M_ZERO, + 0, 0xffffffff, XLR_CACHELINE_SIZE, 0); + + if(new->user.kern_src == NULL){ + printf("ERROR - malloc failed for user.kern_src\n"); + return NULL; + } + + + new->user.aligned_dest = new->user.kern_dest = + (uint8_t *) contigmalloc(257*1024, + M_DEVBUF, M_NOWAIT | M_ZERO, + 0, 0xffffffff, XLR_CACHELINE_SIZE, 0); + + if(new->user.aligned_dest == NULL){ + printf("ERROR - malloc failed for user.aligned_dest\n"); + return NULL; + } + + + new->next_src_buf = (uint8_t *) contigmalloc(256*1024+1024, + M_DEVBUF, M_NOWAIT | M_ZERO, + 0, 0xffffffff, XLR_CACHELINE_SIZE, 0); + + if(new->next_src_buf == NULL){ + printf("ERROR - malloc failed for next_src_buf\n"); + return NULL; + } + + + new->next_dest_buf = + (uint8_t *) contigmalloc(257*1024, + M_DEVBUF, M_NOWAIT | M_ZERO, + 0, 0xffffffff, XLR_CACHELINE_SIZE, 0); + + if(new->next_dest_buf == NULL){ + printf("ERROR - malloc failed for next_dest_buf\n"); + return NULL; + } + + new->user.kern_auth = new->user.user_auth = NULL; + new->user.aligned_auth = new->user.user_auth = NULL; + + + /* find cacheline alignment */ + aligned = new; + addr = (uint64_t)vtophys(new); + + /* save for free */ + aligned->alloc = new; + + /* setup common control info */ + aligned->op_ctl.phys_self = addr; + aligned->op_ctl.stn_id = MSGRNG_STNID_SEC0; + + return (aligned); +} + + +static void xlr_sec_free_desc(symkey_desc_pt desc) +{ + if ((desc == NULL) || (desc->alloc == NULL)) { + printf("%s: NULL descriptor \n", __FUNCTION__); + return; + } + + contigfree(desc,sizeof(symkey_desc_t),M_DEVBUF); + + + return; +} + +void print_buf (char *desc, void *data, int len) +{ + uint8_t *dp; + int i; + + DPRINT("%s: ", desc); /* newline done in for-loop */ + dp = data; + for (i=0; i < len; i++, dp++) { + if ((i % 16) == 0) DPRINT("\n"); + DPRINT(" %c%c", + nib2hex[(((*dp)&0xf0)>>4)], + nib2hex[((*dp)&0x0f)] ); + } + DPRINT("\n"); +} + + +#ifdef XLR_SEC_CMD_DEBUG +static void +decode_symkey_desc (symkey_desc_pt desc, uint32_t cfg_vector) +{ + + unsigned long long word; + /* uint8_t *info; */ + /* int i; */ + + DPRINT ("MSG - CTL: \n"); + DPRINT ("\t CTRL = %lld \n", + GET_FIELD(desc->control, MSG_CMD_CTL_CTL)); + DPRINT ("\t CTRL LEN = %lld \n", + GET_FIELD(desc->control, MSG_CMD_CTL_LEN)); + DPRINT ("\t CTRL ADDR = %llx \n\n", + GET_FIELD(desc->control, MSG_CMD_CTL_ADDR)); + + DPRINT ("MSG - DATA: \n"); + DPRINT ("\t CTRL = %lld \n", + GET_FIELD(desc->data, MSG_CMD_DATA_CTL)); + DPRINT ("\t DATA LEN = %lld \n", + GET_FIELD(desc->data, MSG_CMD_DATA_LEN)); + DPRINT ("\t DATA ADDR = %llx \n\n", + GET_FIELD(desc->data, MSG_CMD_DATA_ADDR)); + + DPRINT ("CONTROL DESCRIPTOR: \n"); + word = desc->ctl_desc.instruction; + DPRINT ("\tINSTRUCTION: %llx\n", word); + DPRINT("\t\tOVERRIDE CIPH = %lld \n", GET_FIELD(word, CTL_DSC_OVERRIDECIPHER)); + DPRINT("\t\tARC4 WAIT = %lld \n", GET_FIELD(word, CTL_DSC_ARC4_WAIT4SAVE)); + DPRINT("\t\tARC4 SAVE = %lld \n", GET_FIELD(word, CTL_DSC_ARC4_SAVESTATE)); + DPRINT("\t\tARC4 LOAD = %lld \n", GET_FIELD(word, CTL_DSC_ARC4_LOADSTATE)); + DPRINT("\t\tARC4 KEYLEN = %lld \n", GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + DPRINT("\t\tCIPHER = %lld \n", GET_FIELD(word, CTL_DSC_CPHR)); + DPRINT("\t\tCIPHER MODE = %lld \n", GET_FIELD(word, CTL_DSC_MODE)); + DPRINT("\t\tINIT CIPHER = %lld \n", GET_FIELD(word, CTL_DSC_ICPHR)); + DPRINT("\t\tHMAC = %lld \n", GET_FIELD(word, CTL_DSC_HMAC)); + DPRINT("\t\tHASH ALG = %lld \n", GET_FIELD(word, CTL_DSC_HASH) | (GET_FIELD(word, CTL_DSC_HASHHI)<<2)); + DPRINT("\t\tINIT HASH = %lld \n", GET_FIELD(word, CTL_DSC_IHASH)); + DPRINT("\t\tCHKSUM = %lld \n", GET_FIELD(word, CTL_DSC_CKSUM)); + DPRINT ("\tCIPHER HASH INFO: \n"); +#if 0 + info = (uint8_t *)&desc->ctl_desc->cipherHashInfo; + for (i=0; i < sizeof(CipherHashInfo_t); i++, info++) { + DPRINT(" %02x", *info); + if (i && (i % 16) == 0) DPRINT("\n"); + } + DPRINT("\n\n"); +#endif + + switch (cfg_vector) { + case XLR_SEC_VECTOR_CIPHER_ARC4: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4 \n"); + print_buf("ARC4 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4.cipherKey0, + GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__HMAC \n"); + print_buf("ARC4 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4HMAC.cipherKey0, + GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoARC4HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__STATE: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__STATE \n"); + print_buf("ARC4 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4State.cipherKey0, + GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC__STATE: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__HMAC__STATE \n"); + print_buf("ARC4 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4StateHMAC.cipherKey0, + GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoARC4StateHMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR_CIPHER_KASUMI_F8: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_KASUMI_F8 \n"); + print_buf("KASUMI_F8 Key", + &desc->ctl_desc.cipherHashInfo.infoKASUMIF8.cipherKey0, + XLR_SEC_KASUMI_F8_KEY_LENGTH); + break; + case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC: + DPRINT("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC\n"); + print_buf("KASUMI_F8 Key", + &desc->ctl_desc.cipherHashInfo.infoKASUMIF8HMAC.cipherKey0, + XLR_SEC_KASUMI_F8_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoKASUMIF8HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC2: + DPRINT("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC2\n"); + print_buf("KASUMI_F8 Key", + &desc->ctl_desc.cipherHashInfo.infoKASUMIF8HMAC2.cipherKey0, + XLR_SEC_KASUMI_F8_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoKASUMIF8HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__GCM: + DPRINT("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__GCM\n"); + print_buf("KASUMI_F8 Key", + &desc->ctl_desc.cipherHashInfo.infoKASUMIF8GCM.cipherKey0, + XLR_SEC_KASUMI_F8_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoKASUMIF8GCM.GCMH0, + sizeof(GCM_t)); + break; + case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__F9: + DPRINT("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__F9\n"); + print_buf("KASUMI_F8 Key", + &desc->ctl_desc.cipherHashInfo.infoKASUMIF8F9.cipherKey0, + XLR_SEC_KASUMI_F8_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoKASUMIF8F9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR_MAC: + DPRINT("VECTOR: XLR_SEC_VECTOR_MAC \n"); + DPRINT("MAC-ONLY - No Info\n"); + break; + case XLR_SEC_VECTOR_HMAC: + DPRINT ("VECTOR: XLR_SEC_VECTOR_HMAC \n"); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoHMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_DES__HMAC__MODE_ECB_CBC: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_DES__HMAC__MODE_ECB_CBC \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoDESHMAC.cipherKey0, + XLR_SEC_DES_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoDESHMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_DES__MODE_ECB_CBC: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_DES__MODE_ECB_CBC \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoDES.cipherKey0, + XLR_SEC_DES_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_3DES__HMAC__MODE_ECB_CBC: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_3DES__HMAC__MODE_ECB_CBC \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.info3DESHMAC.cipherKey0, + XLR_SEC_3DES_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.info3DESHMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_3DES__MODE_ECB_CBC: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_3DES__MODE_ECB_CBC \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.info3DES.cipherKey0, + XLR_SEC_3DES_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_CTR_CFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128HMAC.cipherKey0, + XLR_SEC_AES128_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoAES128HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__MODE_CTR_CFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128.cipherKey0, + XLR_SEC_AES128_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_ECB_CBC_OFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_ECB_CBC_OFB\n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128HMAC.cipherKey0, + XLR_SEC_AES128_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoAES128HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__MODE_ECB_CBC_OFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__MODE_ECB_CBC_OFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128.cipherKey0, + XLR_SEC_AES128_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_CTR_CFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192HMAC.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoAES192HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__MODE_CTR_CFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_ECB_CBC_OFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_ECB_CBC_OFB\n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192HMAC.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoAES192HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__MODE_ECB_CBC_OFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__MODE_ECB_CBC_OFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + break; + + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_CTR_CFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256HMAC.cipherKey0, + XLR_SEC_AES256_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoAES256HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__MODE_CTR_CFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256.cipherKey0, + XLR_SEC_AES256_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_ECB_CBC_OFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_ECB_CBC_OFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256HMAC.cipherKey0, + XLR_SEC_AES256_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoAES256HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__MODE_ECB_CBC_OFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__MODE_ECB_CBC_OFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256.cipherKey0, + XLR_SEC_AES256_KEY_LENGTH); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2 \n"); + print_buf("ARC4 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4HMAC2.cipherKey0, + GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2__STATE: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2__STATE \n"); + print_buf("ARC4 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4StateHMAC2.cipherKey0, + GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4StateHMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR_HMAC2: + DPRINT ("VECTOR: XLR_SEC_VECTOR_HMAC2 \n"); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoHMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR__CIPHER_DES__HMAC2__MODE_ECB_CBC: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_DES__HMAC2__MODE_ECB_CBC \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoDESHMAC2.cipherKey0, + XLR_SEC_DES_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoDESHMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR__CIPHER_3DES__HMAC2__MODE_ECB_CBC: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_3DES__HMAC2__MODE_ECB_CBC \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.info3DESHMAC2.cipherKey0, + XLR_SEC_3DES_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.info3DESHMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_CTR_CFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128HMAC2.cipherKey0, + XLR_SEC_AES128_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoAES128HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_ECB_CBC_OFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_ECB_CBC_OFB\n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128HMAC2.cipherKey0, + XLR_SEC_AES128_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoAES128HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_CTR_CFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192HMAC2.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoAES192HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_ECB_CBC_OFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_ECB_CBC_OFB\n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192HMAC2.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoAES192HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_CTR_CFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256HMAC2.cipherKey0, + XLR_SEC_AES256_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoAES256HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_ECB_CBC_OFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_ECB_CBC_OFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256HMAC2.cipherKey0, + XLR_SEC_AES256_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoAES256HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__GCM: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__GCM \n"); + print_buf("ARC4 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4GCM.cipherKey0, + GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoARC4GCM.GCMH0, + sizeof(GCM_t)); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__GCM__STATE: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__GCM__STATE \n"); + print_buf("ARC4 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4StateGCM.cipherKey0, + GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoARC4StateGCM.GCMH0, + sizeof(GCM_t)); + break; + case XLR_SEC_VECTOR_GCM: + DPRINT ("VECTOR: XLR_SEC_VECTOR_GCM \n"); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoGCM.GCMH0, + sizeof(GCM_t)); + break; + case XLR_SEC_VECTOR__CIPHER_DES__GCM__MODE_ECB_CBC: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_DES__GCM__MODE_ECB_CBC \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoDESGCM.cipherKey0, + XLR_SEC_DES_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoDESGCM.GCMH0, + sizeof(GCM_t)); + break; + case XLR_SEC_VECTOR__CIPHER_3DES__GCM__MODE_ECB_CBC: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_3DES__GCM__MODE_ECB_CBC \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.info3DESGCM.cipherKey0, + XLR_SEC_3DES_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.info3DESGCM.GCMH0, + sizeof(GCM_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_CTR_CFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128GCM.cipherKey0, + XLR_SEC_AES128_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoAES128GCM.GCMH0, + XLR_SEC_AES128_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_ECB_CBC_OFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_ECB_CBC_OFB\n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128GCM.cipherKey0, + XLR_SEC_AES128_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoAES128GCM.GCMH0, + XLR_SEC_AES128_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_CTR_CFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192GCM.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoAES192GCM.GCMH0, + XLR_SEC_AES192_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_ECB_CBC_OFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_ECB_CBC_OFB\n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192GCM.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoAES192GCM.GCMH0, + XLR_SEC_AES192_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_CTR_CFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256GCM.cipherKey0, + XLR_SEC_AES256_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoAES256GCM.GCMH0, + XLR_SEC_AES256_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_ECB_CBC_OFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_ECB_CBC_OFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256GCM.cipherKey0, + XLR_SEC_AES256_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoAES256GCM.GCMH0, + XLR_SEC_AES256_KEY_LENGTH); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__F9: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__F9 \n"); + print_buf("ARC4 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4F9.cipherKey0, + GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4F9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__F9__STATE: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__F9__STATE \n"); + print_buf("ARC4 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4StateF9.cipherKey0, + GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4StateF9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR_F9: + DPRINT ("VECTOR: XLR_SEC_VECTOR_F9 \n"); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoF9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_DES__F9__MODE_ECB_CBC: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_DES__F9__MODE_ECB_CBC \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoDESF9.cipherKey0, + XLR_SEC_DES_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoDESF9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_3DES__F9__MODE_ECB_CBC: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_3DES__F9__MODE_ECB_CBC \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.info3DESF9.cipherKey0, + XLR_SEC_3DES_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.info3DESF9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_CTR_CFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F9.cipherKey0, + XLR_SEC_AES128_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_ECB_CBC_OFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_ECB_CBC_OFB\n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F9.cipherKey0, + XLR_SEC_AES128_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_CTR_CFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F9.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_ECB_CBC_OFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_ECB_CBC_OFB\n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F9.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_CTR_CFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F9.cipherKey0, + XLR_SEC_AES256_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_ECB_CBC_OFB: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_ECB_CBC_OFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F9.cipherKey0, + XLR_SEC_AES256_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_F8: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F8HMAC.cipherKey0, + XLR_SEC_AES128F8_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F8HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__MODE_F8: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F8.cipherKey0, + XLR_SEC_AES128F8_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_F8: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F8HMAC.cipherKey0, + XLR_SEC_AES192F8_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F8HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__MODE_F8: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F8.cipherKey0, + XLR_SEC_AES192F8_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_F8: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F8HMAC.cipherKey0, + XLR_SEC_AES256F8_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoAES256HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__MODE_F8: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F8.cipherKey0, + XLR_SEC_AES256F8_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_F8: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F8HMAC2.cipherKey0, + XLR_SEC_AES128F8_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F8HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_F8: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F8HMAC2.cipherKey0, + XLR_SEC_AES192F8_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F8HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_F8: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F8HMAC2.cipherKey0, + XLR_SEC_AES256F8_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F8HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_F8: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F8GCM.cipherKey0, + XLR_SEC_AES128F8_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoAES128GCM.GCMH0, + XLR_SEC_AES128_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_F8: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F8GCM.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F8GCM.GCMH0, + XLR_SEC_AES192_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_F8: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F8GCM.cipherKey0, + XLR_SEC_AES256F8_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F8GCM.GCMH0, + XLR_SEC_AES256_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_F8: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F8F9.cipherKey0, + XLR_SEC_AES128F8_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F8F9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_F8: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F8F9.cipherKey0, + XLR_SEC_AES192F8_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F8F9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_F8: + DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F8F9.cipherKey0, + XLR_SEC_AES256F8_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F8F9.authKey0, + sizeof(F9_t)); + break; + + default: + DPRINT ("VECTOR: ???? \n"); + DPRINT(">>> WHAT THE HECK !!! <<< \n"); + break; + } + DPRINT ("PACKET DESCRIPTOR: \n"); + word = desc->pkt_desc.srcLengthIVOffUseIVNext; + DPRINT ("\tSrcLengthIVOffsetIVNext: %llx\n", word); + DPRINT ("\t\tLoad HMAC = %lld \n", + GET_FIELD(word, PKT_DSC_LOADHMACKEY)); + DPRINT ("\t\tPad Hash = %lld \n", + GET_FIELD(word, PKT_DSC_PADHASH)); + DPRINT ("\t\tHash Byte Count = %lld \n", + GET_FIELD(word, PKT_DSC_HASHBYTES)); + DPRINT ("\t\tNext = %lld \n", + GET_FIELD(word, PKT_DSC_NEXT)); + DPRINT ("\t\tUse IV = %lld \n", + GET_FIELD(word, PKT_DSC_IV)); + DPRINT ("\t\tIV Offset = %lld \n", + GET_FIELD(word, PKT_DSC_IVOFF)); + DPRINT ("\t\tPacket Length = %lld \n", + GET_FIELD(word, PKT_DSC_PKTLEN)); + DPRINT ("\t\tNLHMAC = %lld \n", GET_FIELD(word, PKT_DSC_NLHMAC)); + DPRINT ("\t\tBreak = %lld \n", GET_FIELD(word, PKT_DSC_BREAK)); + DPRINT ("\t\tWait = %lld \n", GET_FIELD(word, PKT_DSC_WAIT)); + DPRINT ("\t\tSegment Src Addr = %llx \n", + (GET_FIELD(word, PKT_DSC_SEGADDR) << 5)& 0xffffffffffULL); + DPRINT("\t\tSRTCP = %lld \n", GET_FIELD(word, PKT_DSC_SRTCP)); + DPRINT ("\t\tGlobal Src Offset = %lld \n", + GET_FIELD(word, PKT_DSC_SEGOFFSET)); + + word = desc->pkt_desc.dstDataSettings; + DPRINT("\tdstDataSettings: %llx \n", word); + DPRINT("\t\tArc4 Byte Count = %lld \n", GET_FIELD(word, + PKT_DSC_ARC4BYTECOUNT)); + DPRINT("\t\tSym Operation = %lld \n", GET_FIELD(word, PKT_DSC_SYM_OP)); + DPRINT("\t\tCipher Offset = %lld \n", GET_FIELD(word, PKT_DSC_CPHROFF)); + DPRINT("\t\tHash Offset = %lld \n", GET_FIELD(word, PKT_DSC_HASHOFF)); + DPRINT("\t\tHash Source = %lld \n", GET_FIELD(word, PKT_DSC_HASHSRC)); + DPRINT("\t\tChecksum Offset = %lld \n", GET_FIELD(word, + PKT_DSC_CKSUMOFF)); + DPRINT("\t\tChecksum Source = %lld \n", GET_FIELD(word, + PKT_DSC_CKSUMSRC)); + DPRINT("\t\tCipher Dest Addr = %llx \n", GET_FIELD(word, + PKT_DSC_CPHR_DST_ADDR)); + DPRINT("\t\tCipher Dest Dword = %lld \n", GET_FIELD(word, + PKT_DSC_CPHR_DST_DWOFFSET)); + DPRINT("\t\tCipher Dest Offset= %lld \n", GET_FIELD(word, + PKT_DSC_CPHR_DST_OFFSET)); + word = desc->pkt_desc.authDstNonceLow; + DPRINT("\tauthDstNonceLow: %llx \n", word); + DPRINT("\t\tNonce Low 24 = %lld \n", GET_FIELD(word, + PKT_DSC_NONCE_LOW)); + DPRINT("\t\tauthDst = %llx \n", GET_FIELD(word, + PKT_DSC_AUTH_DST_ADDR)); + DPRINT("\t\tCipher Offset High= %lld \n", GET_FIELD(word, + PKT_DSC_CIPH_OFF_HI)); + word = desc->pkt_desc.ckSumDstNonceHiCFBMaskLLWMask; + DPRINT("\tckSumDstNonceHiCFBMaskLLWMask: %llx \n", word); + DPRINT("\t\tHash Byte off = %lld \n", GET_FIELD(word, PKT_DSC_HASH_BYTE_OFF)); + DPRINT("\t\tPacket Len bytes = %lld \n", GET_FIELD(word, PKT_DSC_PKTLEN_BYTES)); + DPRINT("\t\tLast Long Word Mask = %lld \n", GET_FIELD(word, + PKT_DSC_LASTWORD)); + DPRINT("\t\tCipher Dst Address = %llx \n", GET_FIELD(word, + PKT_DSC_CPHR_DST_ADDR)); + DPRINT("\t\tGlobal Dst Offset = %lld \n", GET_FIELD(word, + PKT_DSC_CPHR_DST_OFFSET)); + + DPRINT ("CFG_VECTOR = %04x\n", cfg_vector); + DPRINT ("\n\n"); +} +#endif + + + +/* This function is called from an interrupt handler */ +void xlr_sec_msgring_handler(int bucket, int size, int code, int stid, + struct msgrng_msg *msg, void *data) +{ + uint64_t error; + uint64_t addr, sec_eng, sec_pipe; + xlr_sec_io_pt op = NULL; + symkey_desc_pt desc=NULL; + struct xlr_sec_session *ses =NULL; + struct xlr_sec_command* cmd=NULL; + + + if (code != MSGRNG_CODE_SEC) { + panic("xlr_sec_msgring_handler: bad code = %d," + " expected code = %d\n", + code, MSGRNG_CODE_SEC); + } + + + if ((stid < MSGRNG_STNID_SEC0) || (stid > MSGRNG_STNID_PK0)) { + panic("xlr_sec_msgring_handler: bad stn id = %d, expect %d - %d\n", + stid, MSGRNG_STNID_SEC0, MSGRNG_STNID_PK0); + } + + + /* + * The Submit() operation encodes the engine and pipe in these two + * separate fields. This allows use to verify the result type with + * the submitted operation type. + */ + sec_eng = GET_FIELD(msg->msg0, MSG_CTL_OP_TYPE); + sec_pipe = GET_FIELD(msg->msg1, MSG_CTL_OP_TYPE); + + + error = msg->msg0 >>40 & 0x1ff ; + if(error) printf("ctrl error = 0x%llx\n", error); + error = msg->msg1 >>40 & 0x1ff ; + if(error) printf("data error = 0x%llx\n", error); + + + XLR_SEC_CMD_DIAG("[%s]: eng=%lld pipe=%lld\n", + __FUNCTION__, sec_eng, sec_pipe); + + /* Symmetric Key Operation ? */ + if (sec_eng == MSG0_CTL_OP_ENGINE_SYMKEY) { + + /* + * The data descriptor address allows us to associate the response + * with the submitted operation. + * Address is 40-bit cacheline aligned address. + * We need to zero bit 0-4 since they are used for the + * engine and pipe Id. + */ + addr = GET_FIELD(msg->msg1, MSG_RSLT_DATA_DSC_ADDR); + + addr = addr & ~((1 << 5) - 1); + if (!addr) { + panic("[%s:STNID_SEC]: NULL symkey addr!\n", __FUNCTION__); + + } + + + /* + * The adddress points to the data descriptor. + * The operation descriptor is defined with the 32-byte cacheline + * size in mind. It allows the code to use this address to reference + * the symkey descriptor. (ref: xlr_sec_desc.h) + */ + addr = addr - sizeof(OperationDescriptor_t); + desc = (symkey_desc_pt) MIPS_PHYS_TO_KSEG0(addr); + + if (!desc) { + printf("\nerror : not getting desc back correctly \n"); + panic("[%s:STNID_SEC]: NULL symkey data descriptor!\n", __FUNCTION__); + } + + ses = (struct xlr_sec_session* ) desc->ses; + if (!ses) { + printf("\n error : not getting ses back correctly \n"); + panic("[%s:STNID_SEC]: NULL symkey data descriptor!\n", __FUNCTION__); + } + + cmd = &ses->cmd; + if (!cmd) { + printf("\n error : not getting cmd back correctly \n"); + panic("[%s:STNID_SEC]: NULL symkey data descriptor!\n", __FUNCTION__); + } + + op = &cmd->op; + if (!op) { + printf("\n error : not getting op back correctly \n"); + panic("[%s:STNID_SEC]: NULL symkey data descriptor!\n", __FUNCTION__); + } + + + + XLR_SEC_CMD_DIAG("[%s:STNID_SEC]: addr=0x%llx desc=%p alloc=%p \n", + __FUNCTION__, addr, desc, desc->alloc); + + XLR_SEC_CMD_DIAG("[%s:STNID_SEC]: op_ctl=%p phys_self=%llx stn_id=%d \n", + __FUNCTION__, &desc->op_ctl, desc->op_ctl.phys_self, + desc->op_ctl.stn_id); + + if (addr != desc->op_ctl.phys_self) { + XLR_SEC_CMD_DIAG("[%s:STNID_SEC]: Control Descriptor fails Self-Verify !\n", + __FUNCTION__); + printf("[%s:STNID_SEC]: Control Descriptor fails Self-Verify !\n", + __FUNCTION__); + printf("[%s:STNID_SEC]: addr=0x%llx desc=%p alloc=%p \n", + __FUNCTION__, (unsigned long long)addr, desc, desc->alloc); + printf("[%s:STNID_SEC]: op_ctl=%p phys_self=%llx stn_id=%d \n", + __FUNCTION__, &desc->op_ctl, (unsigned long long)desc->op_ctl.phys_self, + desc->op_ctl.stn_id); + + } + + if (desc->op_ctl.stn_id != MSGRNG_STNID_SEC0 && + desc->op_ctl.stn_id != MSGRNG_STNID_SEC1) { + XLR_SEC_CMD_DIAG("[%s:STNID_SEC]: Operation Type Mismatch !\n", + __FUNCTION__); + printf("[%s:STNID_SEC]: Operation Type Mismatch !\n", + __FUNCTION__); + printf("[%s:STNID_SEC]: addr=0x%llx desc=%p alloc=%p \n", + __FUNCTION__, (unsigned long long)addr, desc, desc->alloc); + printf("[%s:STNID_SEC]: op_ctl=%p phys_self=%llx stn_id=%d \n", + __FUNCTION__, &desc->op_ctl, (unsigned long long)desc->op_ctl.phys_self, + desc->op_ctl.stn_id); + } + + desc->ctl_result = GET_FIELD(msg->msg0, MSG_RSLT_CTL_INST_ERR); + desc->data_result = GET_FIELD(msg->msg1, MSG_RSLT_DATA_INST_ERR); + + XLR_SEC_CMD_DIAG("[%s:STNID_SEC]: cpu=%d ctl_result=0x%llx data_result=%llx\n", + __FUNCTION__, desc->op_ctl.cpu, + desc->ctl_result, desc->data_result); + + } +#if 0 + else if (sec_eng == MSG0_CTL_OP_ENGINE_PUBKEY) { + pubkey_desc_pt desc; + + if (sec_pipe != MSG1_CTL_OP_PUBKEY_PIPE0) { + /* response to uc load */ + /* + XLR_SEC_CMD_DIAG("[%s:STNID_SEC]: ecc cpu=%d ctl_result=0x%llx data_result=%llx\n", + __FUNCTION__, desc->op_ctl.cpu, + desc->ctl_result, desc->data_result); + */ + return; + } + /* + * The data descriptor address allows us to associate the response + * with the submitted operation. + * Address is 40-bit cacheline aligned address. + * We need to zero bit 0-4 since they are used for the + * engine and pipe Id. + */ + addr = GET_FIELD(msg->msg0, PUBKEY_RSLT_CTL_SRCADDR); + addr = addr & ~((1 << 5) - 1); + if (!addr) { + panic("[%s:STNID_SEC]: NULL pubkey ctrl desc!\n", __FUNCTION__); + } + + /* + * The adddress points to the data descriptor. + * The operation descriptor is defined with the 32-byte cacheline + * size in mind. It allows the code to use this address to reference + * the symkey descriptor. (ref: xlr_sec_desc.h) + */ + addr = addr - sizeof(OperationDescriptor_t); + + /* Get pointer to pubkey Descriptor */ + desc = (pubkey_desc_pt)(unsigned long) addr ; + if (!desc) { + panic("[%s:STNID_SEC]: NULL pubkey data descriptor!\n", __FUNCTION__); + } + + XLR_SEC_CMD_DIAG("[%s:STNID_PK0]: addr=0x%llx desc=%p alloc=%p \n", + __FUNCTION__, addr, desc, desc->alloc); + + XLR_SEC_CMD_DIAG("[%s:STNID_PK0]: op_ctl=%p phys_self=%llx stn_id=%d \n", + __FUNCTION__, &desc->op_ctl, desc->op_ctl.phys_self, + desc->op_ctl.stn_id); + + if (addr != desc->op_ctl.phys_self) { + XLR_SEC_CMD_DIAG("[%s:STNID_PK0]: Control Descriptor fails Self-Verify !\n", + __FUNCTION__); + } + + + if (desc->op_ctl.stn_id != msgrng_stnid_pk0) { + XLR_SEC_CMD_DIAG("[%s:STNID_PK0]: Operation Type Mismatch ! \n", + __FUNCTION__); + } + + desc->ctl_result = GET_FIELD(msg->msg0, PUBKEY_RSLT_CTL_ERROR); + desc->data_result = GET_FIELD(msg->msg1, PUBKEY_RSLT_DATA_ERROR); + + XLR_SEC_CMD_DIAG("[%s:STNID_PK0]: ctl_result=0x%llx data_result=%llx\n", + __FUNCTION__, desc->ctl_result, desc->data_result); + + } +#endif + else { + printf("[%s]: HANDLER bad id = %d\n", __FUNCTION__, stid); + } +#ifdef RMI_SEC_DEBUG + if(ses->multi_frag_flag){ + int i; + char *ptr; + printf("\n RETURNED DATA: \n"); + + ptr = (char*) (unsigned long)(desc->user.aligned_dest+cmd->op.cipher_offset) ; + for(i = 0; i< SEC_MAX_FRAG_LEN ; i++){ + printf("%c ",(char) *ptr++); + if((i%10) == 0) printf("\n"); + } + + printf("second desc\n"); + ptr = (char*) (unsigned long)(desc->next_dest_buf) ; + for(i = 0; i< desc->next_src_len; i++){ + printf("%c ",(char) *ptr++); + if((i%10) == 0) printf("\n"); + } + } +#endif + + + /* Copy cipher-data to User-space */ + if (op->cipher_type != XLR_SEC_CIPHER_TYPE_NONE) { + + size = op->dest_buf_size; + + /* DEBUG -dpk */ + XLR_SEC_CMD_DIAG("cipher: to_addr=%p from_addr=%p size=%d \n", + desc->user.user_dest, desc->user.aligned_dest, size); + + if(ses->multi_frag_flag){ + crypto_copyback(cmd->crp->crp_flags, cmd->crp->crp_buf, 0, + SEC_MAX_FRAG_LEN, (caddr_t)(long)desc->user.aligned_dest+op->cipher_offset); + crypto_copyback(cmd->crp->crp_flags, cmd->crp->crp_buf+SEC_MAX_FRAG_LEN, 0, + desc->next_src_len, (caddr_t)(long)desc->next_dest_buf); + crypto_done(cmd->crp); + } + else{ + crypto_copyback(cmd->crp->crp_flags, cmd->crp->crp_buf, 0, + cmd->op.dest_buf_size, (caddr_t)(long)desc->user.aligned_dest+op->cipher_offset); + crypto_done(cmd->crp); + + } + + + } + + + /* Copy digest to User-space */ + if (op->digest_type != XLR_SEC_DIGEST_TYPE_NONE) { + + int offset = 0; + switch (op->digest_type) { + case XLR_SEC_DIGEST_TYPE_MD5: + size = XLR_SEC_MD5_LENGTH; + break; + case XLR_SEC_DIGEST_TYPE_SHA1: + size = XLR_SEC_SHA1_LENGTH; + break; + case XLR_SEC_DIGEST_TYPE_SHA256: + size = XLR_SEC_SHA256_LENGTH; + break; + case XLR_SEC_DIGEST_TYPE_SHA384: + size = XLR_SEC_SHA384_LENGTH; + break; + case XLR_SEC_DIGEST_TYPE_SHA512: + size = XLR_SEC_SHA512_LENGTH; + break; + case XLR_SEC_DIGEST_TYPE_GCM: + size = XLR_SEC_GCM_LENGTH; + break; + case XLR_SEC_DIGEST_TYPE_KASUMI_F9: + offset = 4; + size = XLR_SEC_KASUMI_F9_RESULT_LENGTH; + break; + default: + size = 0; + } + + XLR_SEC_CMD_DIAG("digest: to_addr=%p from_addr=%p size=%d \n", + desc->user.user_auth, desc->user.aligned_auth, size); + memcpy(desc->user.user_auth, desc->user.aligned_auth + offset,size); + op->auth_dest = (uint64_t)(unsigned long)desc->user.user_auth; + } + + + if (op->cipher_type == XLR_SEC_CIPHER_TYPE_ARC4 && + op->rc4_savestate) { + + size = XLR_SEC_MAX_RC4_STATE_SIZE; + + XLR_SEC_CMD_DIAG("state: to_addr=%p from_addr=%p size=%d \n", + desc->user.user_state, desc->user.aligned_state, size); + op->rc4_state = (uint64_t)(unsigned long)desc->user.user_state; + } + + return; +} + diff --git a/sys/dev/rmi/sec/rmilib.h b/sys/dev/rmi/sec/rmilib.h new file mode 100644 index 00000000000..7eb7c5d9545 --- /dev/null +++ b/sys/dev/rmi/sec/rmilib.h @@ -0,0 +1,991 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ + +#ifndef _RMILIB_H_ +#define _RMILIB_H_ + +#include +#include + +/*#define XLR_SEC_CMD_DEBUG*/ + +#ifdef XLR_SEC_CMD_DEBUG +#define DPRINT printf +#define XLR_SEC_CMD_DIAG(fmt, args...) { \ + DPRINT(fmt, ##args); \ + } +#define XLR_SEC_CMD_DIAG_SYM_DESC(desc, vec) { \ + decode_symkey_desc ((desc), (vec)); \ + } +#else +#define DPRINT(fmt, args...) +#define XLR_SEC_CMD_DIAG(fmt, args...) +#define XLR_SEC_CMD_DIAG_SYM_DESC(desc, vec) +#endif + + + + + + +/* +#include + +#define OS_ALLOC_KERNEL(size) kmalloc((size), GFP_KERNEL) +#define virt_to_phys(x) vtophys((vm_offset_t)(x)) +*/ +/* + * Cryptographic parameter definitions + */ +#define XLR_SEC_DES_KEY_LENGTH 8 /* Bytes */ +#define XLR_SEC_3DES_KEY_LENGTH 24 /* Bytes */ +#define XLR_SEC_AES128_KEY_LENGTH 16 /* Bytes */ +#define XLR_SEC_AES192_KEY_LENGTH 24 /* Bytes */ +#define XLR_SEC_AES256_KEY_LENGTH 32 /* Bytes */ +#define XLR_SEC_AES128F8_KEY_LENGTH 32 /* Bytes */ +#define XLR_SEC_AES192F8_KEY_LENGTH 48 /* Bytes */ +#define XLR_SEC_AES256F8_KEY_LENGTH 64 /* Bytes */ +#define XLR_SEC_KASUMI_F8_KEY_LENGTH 16 /* Bytes */ +#define XLR_SEC_MAX_CRYPT_KEY_LENGTH XLR_SEC_AES256F8_KEY_LENGTH + + +#define XLR_SEC_DES_IV_LENGTH 8 /* Bytes */ +#define XLR_SEC_AES_IV_LENGTH 16 /* Bytes */ +#define XLR_SEC_ARC4_IV_LENGTH 0 /* Bytes */ +#define XLR_SEC_KASUMI_F8_IV_LENGTH 16 /* Bytes */ +#define XLR_SEC_MAX_IV_LENGTH 16 /* Bytes */ +#define XLR_SEC_IV_LENGTH_BYTES 8 /* Bytes */ + +#define XLR_SEC_AES_BLOCK_SIZE 16 /* Bytes */ +#define XLR_SEC_DES_BLOCK_SIZE 8 /* Bytes */ +#define XLR_SEC_3DES_BLOCK_SIZE 8 /* Bytes */ + +#define XLR_SEC_MD5_BLOCK_SIZE 64 /* Bytes */ +#define XLR_SEC_SHA1_BLOCK_SIZE 64 /* Bytes */ +#define XLR_SEC_SHA256_BLOCK_SIZE 64 /* Bytes */ +#define XLR_SEC_SHA384_BLOCK_SIZE 128/* Bytes */ +#define XLR_SEC_SHA512_BLOCK_SIZE 128/* Bytes */ +#define XLR_SEC_GCM_BLOCK_SIZE 16 /* XXX: Bytes */ +#define XLR_SEC_KASUMI_F9_BLOCK_SIZE 16 /* XXX: Bytes */ +#define XLR_SEC_MAX_BLOCK_SIZE 64 /* Max of MD5/SHA */ +#define XLR_SEC_MD5_LENGTH 16 /* Bytes */ +#define XLR_SEC_SHA1_LENGTH 20 /* Bytes */ +#define XLR_SEC_SHA256_LENGTH 32 /* Bytes */ +#define XLR_SEC_SHA384_LENGTH 64 /* Bytes */ +#define XLR_SEC_SHA512_LENGTH 64 /* Bytes */ +#define XLR_SEC_GCM_LENGTH 16 /* Bytes */ +#define XLR_SEC_KASUMI_F9_LENGTH 16 /* Bytes */ +#define XLR_SEC_KASUMI_F9_RESULT_LENGTH 4 /* Bytes */ +#define XLR_SEC_HMAC_LENGTH 64 /* Max of MD5/SHA/SHA256 */ +#define XLR_SEC_MAX_AUTH_KEY_LENGTH XLR_SEC_SHA512_BLOCK_SIZE +#define XLR_SEC_MAX_RC4_STATE_SIZE 264 /* char s[256], int i, int j */ + +/* Status code is used by the SRL to indicate status */ +typedef unsigned int xlr_sec_status_t; + +/* + * Status codes + */ +#define XLR_SEC_STATUS_SUCCESS 0 +#define XLR_SEC_STATUS_NO_DEVICE -1 +#define XLR_SEC_STATUS_TIMEOUT -2 +#define XLR_SEC_STATUS_INVALID_PARAMETER -3 +#define XLR_SEC_STATUS_DEVICE_FAILED -4 +#define XLR_SEC_STATUS_DEVICE_BUSY -5 +#define XLR_SEC_STATUS_NO_RESOURCE -6 +#define XLR_SEC_STATUS_CANCELLED -7 + +/* + * Flags + */ +#define XLR_SEC_FLAGS_HIGH_PRIORITY 1 + +/* Error code is used to indicate any errors */ +typedef int xlr_sec_error_t; + +/* + */ +#define XLR_SEC_ERR_NONE 0 +#define XLR_SEC_ERR_CIPHER_OP -1 +#define XLR_SEC_ERR_CIPHER_TYPE -2 +#define XLR_SEC_ERR_CIPHER_MODE -3 +#define XLR_SEC_ERR_CIPHER_INIT -4 +#define XLR_SEC_ERR_DIGEST_TYPE -5 +#define XLR_SEC_ERR_DIGEST_INIT -6 +#define XLR_SEC_ERR_DIGEST_SRC -7 +#define XLR_SEC_ERR_CKSUM_TYPE -8 +#define XLR_SEC_ERR_CKSUM_SRC -9 +#define XLR_SEC_ERR_ALLOC -10 +#define XLR_SEC_ERR_CONTROL_VECTOR -11 +#define XLR_SEC_ERR_LOADHMACKEY_MODE -12 +#define XLR_SEC_ERR_PADHASH_MODE -13 +#define XLR_SEC_ERR_HASHBYTES_MODE -14 +#define XLR_SEC_ERR_NEXT_MODE -15 +#define XLR_SEC_ERR_PKT_IV_MODE -16 +#define XLR_SEC_ERR_LASTWORD_MODE -17 +#define XLR_SEC_ERR_PUBKEY_OP -18 +#define XLR_SEC_ERR_SYMKEY_MSGSND -19 +#define XLR_SEC_ERR_PUBKEY_MSGSND -20 +#define XLR_SEC_ERR_SYMKEY_GETSEM -21 +#define XLR_SEC_ERR_PUBKEY_GETSEM -22 + +/* + * Descriptor Vector quantities + * (helps to identify descriptor type per operation) + */ +#define XLR_SEC_VECTOR_CIPHER_DES 0x0001 +#define XLR_SEC_VECTOR_CIPHER_3DES 0x0002 +#define XLR_SEC_VECTOR_CIPHER_AES128 0x0004 +#define XLR_SEC_VECTOR_CIPHER_AES192 0x0008 +#define XLR_SEC_VECTOR_CIPHER_AES256 0x0010 +#define XLR_SEC_VECTOR_CIPHER_ARC4 0x0020 +#define XLR_SEC_VECTOR_CIPHER_AES (XLR_SEC_VECTOR_CIPHER_AES128 | \ + XLR_SEC_VECTOR_CIPHER_AES192 | \ + XLR_SEC_VECTOR_CIPHER_AES256) +#define XLR_SEC_VECTOR_CIPHER (XLR_SEC_VECTOR_CIPHER_DES | \ + XLR_SEC_VECTOR_CIPHER_3DES | \ + XLR_SEC_VECTOR_CIPHER_AES128 | \ + XLR_SEC_VECTOR_CIPHER_AES192 | \ + XLR_SEC_VECTOR_CIPHER_AES256 | \ + XLR_SEC_VECTOR_CIPHER_ARC4) + +#define XLR_SEC_VECTOR_HMAC 0x0040 +#define XLR_SEC_VECTOR_MAC 0x0080 +#define XLR_SEC_VECTOR_MODE_CTR_CFB 0x0100 +#define XLR_SEC_VECTOR_MODE_ECB_CBC_OFB 0x0200 +#define XLR_SEC_VECTOR_MODE_ECB_CBC 0x0400 +#define XLR_SEC_VECTOR_STATE 0x0800 +#define XLR_SEC_VECTOR_CIPHER_KASUMI_F8 0x01000 +#define XLR_SEC_VECTOR_HMAC2 0x02000 +#define XLR_SEC_VECTOR_GCM 0x04000 +#define XLR_SEC_VECTOR_F9 0x08000 +#define XLR_SEC_VECTOR_MODE_F8 0x10000 + +#define XLR_SEC_VECTOR_CIPHER_ARC4__HMAC \ +(XLR_SEC_VECTOR_CIPHER_ARC4 | XLR_SEC_VECTOR_HMAC) +#define XLR_SEC_VECTOR_CIPHER_ARC4__STATE \ +(XLR_SEC_VECTOR_CIPHER_ARC4 | XLR_SEC_VECTOR_STATE) +#define XLR_SEC_VECTOR_CIPHER_ARC4__HMAC__STATE \ +(XLR_SEC_VECTOR_CIPHER_ARC4 | XLR_SEC_VECTOR_HMAC | XLR_SEC_VECTOR_STATE) + +#define XLR_SEC_VECTOR__CIPHER_DES__HMAC__MODE_ECB_CBC \ +(XLR_SEC_VECTOR_CIPHER_DES | XLR_SEC_VECTOR_HMAC | XLR_SEC_VECTOR_MODE_ECB_CBC) + +#define XLR_SEC_VECTOR__CIPHER_DES__MODE_ECB_CBC \ +(XLR_SEC_VECTOR_CIPHER_DES | XLR_SEC_VECTOR_MODE_ECB_CBC) + +#define XLR_SEC_VECTOR__CIPHER_3DES__HMAC__MODE_ECB_CBC \ +(XLR_SEC_VECTOR_CIPHER_3DES | XLR_SEC_VECTOR_HMAC | XLR_SEC_VECTOR_MODE_ECB_CBC) + +#define XLR_SEC_VECTOR__CIPHER_3DES__MODE_ECB_CBC \ +(XLR_SEC_VECTOR_CIPHER_3DES | XLR_SEC_VECTOR_MODE_ECB_CBC) + +#define XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_CTR_CFB \ +(XLR_SEC_VECTOR_CIPHER_AES128 | XLR_SEC_VECTOR_HMAC | XLR_SEC_VECTOR_MODE_CTR_CFB) + +#define XLR_SEC_VECTOR__CIPHER_AES128__MODE_CTR_CFB \ +(XLR_SEC_VECTOR_CIPHER_AES128 | XLR_SEC_VECTOR_MODE_CTR_CFB) + +#define XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_ECB_CBC_OFB \ +(XLR_SEC_VECTOR_CIPHER_AES128 | XLR_SEC_VECTOR_HMAC | XLR_SEC_VECTOR_MODE_ECB_CBC_OFB) + +#define XLR_SEC_VECTOR__CIPHER_AES128__MODE_ECB_CBC_OFB \ +(XLR_SEC_VECTOR_CIPHER_AES128 | XLR_SEC_VECTOR_MODE_ECB_CBC_OFB) + +#define XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_CTR_CFB \ +(XLR_SEC_VECTOR_CIPHER_AES192 | XLR_SEC_VECTOR_HMAC | XLR_SEC_VECTOR_MODE_CTR_CFB) + +#define XLR_SEC_VECTOR__CIPHER_AES192__MODE_CTR_CFB \ +(XLR_SEC_VECTOR_CIPHER_AES192 | XLR_SEC_VECTOR_MODE_CTR_CFB) + +#define XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_ECB_CBC_OFB \ +(XLR_SEC_VECTOR_CIPHER_AES192 | XLR_SEC_VECTOR_HMAC | XLR_SEC_VECTOR_MODE_ECB_CBC_OFB) + +#define XLR_SEC_VECTOR__CIPHER_AES192__MODE_ECB_CBC_OFB \ +(XLR_SEC_VECTOR_CIPHER_AES192 | XLR_SEC_VECTOR_MODE_ECB_CBC_OFB) + +#define XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_CTR_CFB \ +(XLR_SEC_VECTOR_CIPHER_AES256 | XLR_SEC_VECTOR_HMAC | XLR_SEC_VECTOR_MODE_CTR_CFB) + +#define XLR_SEC_VECTOR__CIPHER_AES256__MODE_CTR_CFB \ +(XLR_SEC_VECTOR_CIPHER_AES256 | XLR_SEC_VECTOR_MODE_CTR_CFB) + +#define XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_ECB_CBC_OFB \ +(XLR_SEC_VECTOR_CIPHER_AES256 | XLR_SEC_VECTOR_HMAC | XLR_SEC_VECTOR_MODE_ECB_CBC_OFB) + +#define XLR_SEC_VECTOR__CIPHER_AES256__MODE_ECB_CBC_OFB \ +(XLR_SEC_VECTOR_CIPHER_AES256 | XLR_SEC_VECTOR_MODE_ECB_CBC_OFB) + +#define XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_F8 \ +(XLR_SEC_VECTOR_CIPHER_AES128 | XLR_SEC_VECTOR_HMAC | XLR_SEC_VECTOR_MODE_F8) + +#define XLR_SEC_VECTOR__CIPHER_AES128__MODE_F8 \ +(XLR_SEC_VECTOR_CIPHER_AES128 | XLR_SEC_VECTOR_MODE_F8) + +#define XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_F8 \ +(XLR_SEC_VECTOR_CIPHER_AES192 | XLR_SEC_VECTOR_HMAC | XLR_SEC_VECTOR_MODE_F8) + +#define XLR_SEC_VECTOR__CIPHER_AES192__MODE_F8 \ +(XLR_SEC_VECTOR_CIPHER_AES192 | XLR_SEC_VECTOR_MODE_F8) + +#define XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_F8 \ +(XLR_SEC_VECTOR_CIPHER_AES256 | XLR_SEC_VECTOR_HMAC | XLR_SEC_VECTOR_MODE_F8) + +#define XLR_SEC_VECTOR__CIPHER_AES256__MODE_F8 \ +(XLR_SEC_VECTOR_CIPHER_AES256 | XLR_SEC_VECTOR_MODE_F8) + +#define XLR_SEC_VECTOR_CIPHER_KASUMI_F8__F9 \ +(XLR_SEC_VECTOR_CIPHER_KASUMI_F8 | XLR_SEC_VECTOR_F9) + +#define XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC \ +(XLR_SEC_VECTOR_CIPHER_KASUMI_F8 | XLR_SEC_VECTOR_HMAC) + +#define XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC2 \ +(XLR_SEC_VECTOR_CIPHER_KASUMI_F8 | XLR_SEC_VECTOR_HMAC2) + +#define XLR_SEC_VECTOR_CIPHER_KASUMI_F8__GCM \ +(XLR_SEC_VECTOR_CIPHER_KASUMI_F8 | XLR_SEC_VECTOR_GCM) + +#define XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2 \ +(XLR_SEC_VECTOR_CIPHER_ARC4 | XLR_SEC_VECTOR_HMAC2) + +#define XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2__STATE \ +(XLR_SEC_VECTOR_CIPHER_ARC4 | XLR_SEC_VECTOR_HMAC2 | XLR_SEC_VECTOR_STATE) + +#define XLR_SEC_VECTOR__CIPHER_DES__HMAC2__MODE_ECB_CBC \ +(XLR_SEC_VECTOR_CIPHER_DES | XLR_SEC_VECTOR_HMAC2 | XLR_SEC_VECTOR_MODE_ECB_CBC) + +#define XLR_SEC_VECTOR__CIPHER_3DES__HMAC2__MODE_ECB_CBC \ +(XLR_SEC_VECTOR_CIPHER_3DES | XLR_SEC_VECTOR_HMAC2 | XLR_SEC_VECTOR_MODE_ECB_CBC) + +#define XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_CTR_CFB \ +(XLR_SEC_VECTOR_CIPHER_AES128 | XLR_SEC_VECTOR_HMAC2 | XLR_SEC_VECTOR_MODE_CTR_CFB) + +#define XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_ECB_CBC_OFB \ +(XLR_SEC_VECTOR_CIPHER_AES128 | XLR_SEC_VECTOR_HMAC2 | XLR_SEC_VECTOR_MODE_ECB_CBC_OFB) + +#define XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_CTR_CFB \ +(XLR_SEC_VECTOR_CIPHER_AES192 | XLR_SEC_VECTOR_HMAC2 | XLR_SEC_VECTOR_MODE_CTR_CFB) + +#define XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_ECB_CBC_OFB \ +(XLR_SEC_VECTOR_CIPHER_AES192 | XLR_SEC_VECTOR_HMAC2 | XLR_SEC_VECTOR_MODE_ECB_CBC_OFB) + +#define XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_CTR_CFB \ +(XLR_SEC_VECTOR_CIPHER_AES256 | XLR_SEC_VECTOR_HMAC2 | XLR_SEC_VECTOR_MODE_CTR_CFB) + +#define XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_ECB_CBC_OFB \ +(XLR_SEC_VECTOR_CIPHER_AES256 | XLR_SEC_VECTOR_HMAC2 | XLR_SEC_VECTOR_MODE_ECB_CBC_OFB) + +#define XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_F8 \ +(XLR_SEC_VECTOR_CIPHER_AES128 | XLR_SEC_VECTOR_HMAC2 | XLR_SEC_VECTOR_MODE_F8) + +#define XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_F8 \ +(XLR_SEC_VECTOR_CIPHER_AES192 | XLR_SEC_VECTOR_HMAC2 | XLR_SEC_VECTOR_MODE_F8) + +#define XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_F8 \ +(XLR_SEC_VECTOR_CIPHER_AES256 | XLR_SEC_VECTOR_HMAC2 | XLR_SEC_VECTOR_MODE_F8) + +#define XLR_SEC_VECTOR_CIPHER_ARC4__GCM \ +(XLR_SEC_VECTOR_CIPHER_ARC4 | XLR_SEC_VECTOR_GCM) + +#define XLR_SEC_VECTOR_CIPHER_ARC4__GCM__STATE \ +(XLR_SEC_VECTOR_CIPHER_ARC4 | XLR_SEC_VECTOR_GCM | XLR_SEC_VECTOR_STATE) + +#define XLR_SEC_VECTOR__CIPHER_DES__GCM__MODE_ECB_CBC \ +(XLR_SEC_VECTOR_CIPHER_DES | XLR_SEC_VECTOR_GCM | XLR_SEC_VECTOR_MODE_ECB_CBC) + +#define XLR_SEC_VECTOR__CIPHER_3DES__GCM__MODE_ECB_CBC \ +(XLR_SEC_VECTOR_CIPHER_3DES | XLR_SEC_VECTOR_GCM | XLR_SEC_VECTOR_MODE_ECB_CBC) + +#define XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_CTR_CFB \ +(XLR_SEC_VECTOR_CIPHER_AES128 | XLR_SEC_VECTOR_GCM | XLR_SEC_VECTOR_MODE_CTR_CFB) + +#define XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_ECB_CBC_OFB \ +(XLR_SEC_VECTOR_CIPHER_AES128 | XLR_SEC_VECTOR_GCM | XLR_SEC_VECTOR_MODE_ECB_CBC_OFB) + +#define XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_CTR_CFB \ +(XLR_SEC_VECTOR_CIPHER_AES192 | XLR_SEC_VECTOR_GCM | XLR_SEC_VECTOR_MODE_CTR_CFB) + +#define XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_ECB_CBC_OFB \ +(XLR_SEC_VECTOR_CIPHER_AES192 | XLR_SEC_VECTOR_GCM | XLR_SEC_VECTOR_MODE_ECB_CBC_OFB) + +#define XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_CTR_CFB \ +(XLR_SEC_VECTOR_CIPHER_AES256 | XLR_SEC_VECTOR_GCM | XLR_SEC_VECTOR_MODE_CTR_CFB) + +#define XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_ECB_CBC_OFB \ +(XLR_SEC_VECTOR_CIPHER_AES256 | XLR_SEC_VECTOR_GCM | XLR_SEC_VECTOR_MODE_ECB_CBC_OFB) + +#define XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_F8 \ +(XLR_SEC_VECTOR_CIPHER_AES128 | XLR_SEC_VECTOR_GCM | XLR_SEC_VECTOR_MODE_F8) + +#define XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_F8 \ +(XLR_SEC_VECTOR_CIPHER_AES192 | XLR_SEC_VECTOR_GCM | XLR_SEC_VECTOR_MODE_F8) + +#define XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_F8 \ +(XLR_SEC_VECTOR_CIPHER_AES256 | XLR_SEC_VECTOR_GCM | XLR_SEC_VECTOR_MODE_F8) + +#define XLR_SEC_VECTOR_CIPHER_ARC4__F9 \ +(XLR_SEC_VECTOR_CIPHER_ARC4 | XLR_SEC_VECTOR_F9) + +#define XLR_SEC_VECTOR_CIPHER_ARC4__F9__STATE \ +(XLR_SEC_VECTOR_CIPHER_ARC4 | XLR_SEC_VECTOR_F9 | XLR_SEC_VECTOR_STATE) + +#define XLR_SEC_VECTOR__CIPHER_DES__F9__MODE_ECB_CBC \ +(XLR_SEC_VECTOR_CIPHER_DES | XLR_SEC_VECTOR_F9 | XLR_SEC_VECTOR_MODE_ECB_CBC) + +#define XLR_SEC_VECTOR__CIPHER_3DES__F9__MODE_ECB_CBC \ +(XLR_SEC_VECTOR_CIPHER_3DES | XLR_SEC_VECTOR_F9 | XLR_SEC_VECTOR_MODE_ECB_CBC) + +#define XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_CTR_CFB \ +(XLR_SEC_VECTOR_CIPHER_AES128 | XLR_SEC_VECTOR_F9 | XLR_SEC_VECTOR_MODE_CTR_CFB) + +#define XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_ECB_CBC_OFB \ +(XLR_SEC_VECTOR_CIPHER_AES128 | XLR_SEC_VECTOR_F9 | XLR_SEC_VECTOR_MODE_ECB_CBC_OFB) + +#define XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_CTR_CFB \ +(XLR_SEC_VECTOR_CIPHER_AES192 | XLR_SEC_VECTOR_F9 | XLR_SEC_VECTOR_MODE_CTR_CFB) + +#define XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_ECB_CBC_OFB \ +(XLR_SEC_VECTOR_CIPHER_AES192 | XLR_SEC_VECTOR_F9 | XLR_SEC_VECTOR_MODE_ECB_CBC_OFB) + +#define XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_CTR_CFB \ +(XLR_SEC_VECTOR_CIPHER_AES256 | XLR_SEC_VECTOR_F9 | XLR_SEC_VECTOR_MODE_CTR_CFB) + +#define XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_ECB_CBC_OFB \ +(XLR_SEC_VECTOR_CIPHER_AES256 | XLR_SEC_VECTOR_F9 | XLR_SEC_VECTOR_MODE_ECB_CBC_OFB) + +#define XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_F8 \ +(XLR_SEC_VECTOR_CIPHER_AES128 | XLR_SEC_VECTOR_F9 | XLR_SEC_VECTOR_MODE_F8) + +#define XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_F8 \ +(XLR_SEC_VECTOR_CIPHER_AES192 | XLR_SEC_VECTOR_F9 | XLR_SEC_VECTOR_MODE_F8) + +#define XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_F8 \ +(XLR_SEC_VECTOR_CIPHER_AES256 | XLR_SEC_VECTOR_F9 | XLR_SEC_VECTOR_MODE_F8) + +/* + * Cipher Modes + */ +typedef enum { + XLR_SEC_CIPHER_MODE_NONE = 0, + XLR_SEC_CIPHER_MODE_PASS = 1, + XLR_SEC_CIPHER_MODE_ECB, + XLR_SEC_CIPHER_MODE_CBC, + XLR_SEC_CIPHER_MODE_OFB, + XLR_SEC_CIPHER_MODE_CTR, + XLR_SEC_CIPHER_MODE_CFB, + XLR_SEC_CIPHER_MODE_F8 +} XLR_SEC_CIPHER_MODE; + +typedef enum { + XLR_SEC_CIPHER_OP_NONE = 0, + XLR_SEC_CIPHER_OP_ENCRYPT = 1, + XLR_SEC_CIPHER_OP_DECRYPT +} XLR_SEC_CIPHER_OP; + +typedef enum { + XLR_SEC_CIPHER_TYPE_UNSUPPORTED = -1, + XLR_SEC_CIPHER_TYPE_NONE = 0, + XLR_SEC_CIPHER_TYPE_DES, + XLR_SEC_CIPHER_TYPE_3DES, + XLR_SEC_CIPHER_TYPE_AES128, + XLR_SEC_CIPHER_TYPE_AES192, + XLR_SEC_CIPHER_TYPE_AES256, + XLR_SEC_CIPHER_TYPE_ARC4, + XLR_SEC_CIPHER_TYPE_KASUMI_F8 +} XLR_SEC_CIPHER_TYPE; + +typedef enum { + XLR_SEC_CIPHER_INIT_OK = 1, /* Preserve old Keys */ + XLR_SEC_CIPHER_INIT_NK /*Load new Keys */ +} XLR_SEC_CIPHER_INIT; + + +/* + * Hash Modes + */ +typedef enum { + XLR_SEC_DIGEST_TYPE_UNSUPPORTED = -1, + XLR_SEC_DIGEST_TYPE_NONE = 0, + XLR_SEC_DIGEST_TYPE_MD5, + XLR_SEC_DIGEST_TYPE_SHA1, + XLR_SEC_DIGEST_TYPE_SHA256, + XLR_SEC_DIGEST_TYPE_SHA384, + XLR_SEC_DIGEST_TYPE_SHA512, + XLR_SEC_DIGEST_TYPE_GCM, + XLR_SEC_DIGEST_TYPE_KASUMI_F9, + XLR_SEC_DIGEST_TYPE_HMAC_MD5, + XLR_SEC_DIGEST_TYPE_HMAC_SHA1, + XLR_SEC_DIGEST_TYPE_HMAC_SHA256, + XLR_SEC_DIGEST_TYPE_HMAC_SHA384, + XLR_SEC_DIGEST_TYPE_HMAC_SHA512, + XLR_SEC_DIGEST_TYPE_HMAC_AES_CBC, + XLR_SEC_DIGEST_TYPE_HMAC_AES_XCBC +} XLR_SEC_DIGEST_TYPE; + +typedef enum { + XLR_SEC_DIGEST_INIT_OLDKEY = 1, /* Preserve old key HMAC key stored in ID registers (moot if HASH.HMAC == 0) */ + XLR_SEC_DIGEST_INIT_NEWKEY /*Load new HMAC key from memory ctrl section to ID registers */ +} XLR_SEC_DIGEST_INIT; + +typedef enum { + XLR_SEC_DIGEST_SRC_DMA = 1, /* DMA channel */ + XLR_SEC_DIGEST_SRC_CPHR /*Cipher if word count exceeded Cipher_Offset; else DMA */ +} XLR_SEC_DIGEST_SRC; + +/* + * Checksum Modes + */ +typedef enum { + XLR_SEC_CKSUM_TYPE_NOP = 1, + XLR_SEC_CKSUM_TYPE_IP +} XLR_SEC_CKSUM_TYPE; + +typedef enum { + XLR_SEC_CKSUM_SRC_DMA = 1, + XLR_SEC_CKSUM_SRC_CIPHER +} XLR_SEC_CKSUM_SRC; + +/* + * Packet Modes + */ +typedef enum { + XLR_SEC_LOADHMACKEY_MODE_OLD = 1, + XLR_SEC_LOADHMACKEY_MODE_LOAD +} XLR_SEC_LOADHMACKEY_MODE; + +typedef enum { + XLR_SEC_PADHASH_PADDED = 1, + XLR_SEC_PADHASH_PAD +} XLR_SEC_PADHASH_MODE; + +typedef enum { + XLR_SEC_HASHBYTES_ALL8 = 1, + XLR_SEC_HASHBYTES_MSB, + XLR_SEC_HASHBYTES_MSW +} XLR_SEC_HASHBYTES_MODE; + +typedef enum { + XLR_SEC_NEXT_FINISH = 1, + XLR_SEC_NEXT_DO +} XLR_SEC_NEXT_MODE; + +typedef enum { + XLR_SEC_PKT_IV_OLD = 1, + XLR_SEC_PKT_IV_NEW +} XLR_SEC_PKT_IV_MODE; + +typedef enum { + XLR_SEC_LASTWORD_128 = 1, + XLR_SEC_LASTWORD_96MASK, + XLR_SEC_LASTWORD_64MASK, + XLR_SEC_LASTWORD_32MASK +} XLR_SEC_LASTWORD_MODE; + +typedef enum { + XLR_SEC_CFB_MASK_REGULAR_CTR = 0, + XLR_SEC_CFB_MASK_CCMP, + XLR_SEC_CFB_MASK_GCM_WITH_SCI, + XLR_SEC_CFB_MASK_GCM_WITHOUT_SCI +} XLR_SEC_CFB_MASK_MODE; + +/* + * Public Key + */ +typedef enum { + RMIPK_BLKWIDTH_512 = 1, + RMIPK_BLKWIDTH_1024 +} RMIPK_BLKWIDTH_MODE; + +typedef enum { + RMIPK_LDCONST_OLD = 1, + RMIPK_LDCONST_NEW +} RMIPK_LDCONST_MODE; + + +typedef struct xlr_sec_io_s { + unsigned int command; + unsigned int result_status; + unsigned int flags; + unsigned int session_num; + unsigned int use_callback; + unsigned int time_us; + unsigned int user_context[2];/*usable for anything by caller*/ + unsigned int command_context; /* Context (ID) of this command). */ + unsigned char initial_vector[XLR_SEC_MAX_IV_LENGTH]; + unsigned char crypt_key[XLR_SEC_MAX_CRYPT_KEY_LENGTH]; + unsigned char mac_key[XLR_SEC_MAX_AUTH_KEY_LENGTH]; + + XLR_SEC_CIPHER_OP cipher_op; + XLR_SEC_CIPHER_MODE cipher_mode; + XLR_SEC_CIPHER_TYPE cipher_type; + XLR_SEC_CIPHER_INIT cipher_init; + unsigned int cipher_offset; + + XLR_SEC_DIGEST_TYPE digest_type; + XLR_SEC_DIGEST_INIT digest_init; + XLR_SEC_DIGEST_SRC digest_src; + unsigned int digest_offset; + + XLR_SEC_CKSUM_TYPE cksum_type; + XLR_SEC_CKSUM_SRC cksum_src; + unsigned int cksum_offset; + + XLR_SEC_LOADHMACKEY_MODE pkt_hmac; + XLR_SEC_PADHASH_MODE pkt_hash; + XLR_SEC_HASHBYTES_MODE pkt_hashbytes; + XLR_SEC_NEXT_MODE pkt_next; + XLR_SEC_PKT_IV_MODE pkt_iv; + XLR_SEC_LASTWORD_MODE pkt_lastword; + + unsigned int nonce; + unsigned int cfb_mask; + + unsigned int iv_offset; + unsigned short pad_type; + unsigned short rc4_key_len; + + unsigned int num_packets; + unsigned int num_fragments; + + uint64_t source_buf; + unsigned int source_buf_size; + uint64_t dest_buf; + unsigned int dest_buf_size; + + uint64_t auth_dest; + uint64_t cksum_dest; + + unsigned short rc4_loadstate; + unsigned short rc4_savestate; + uint64_t rc4_state; + +} xlr_sec_io_t, *xlr_sec_io_pt; + + +#define XLR_SEC_SESSION(sid) ((sid) & 0x000007ff) +#define XLR_SEC_SID(crd,ses) (((crd) << 28) | ((ses) & 0x7ff)) + +/* + * Length values for cryptography + */ +/* +#define XLR_SEC_DES_KEY_LENGTH 8 +#define XLR_SEC_3DES_KEY_LENGTH 24 +#define XLR_SEC_MAX_CRYPT_KEY_LENGTH XLR_SEC_3DES_KEY_LENGTH +#define XLR_SEC_IV_LENGTH 8 +#define XLR_SEC_AES_IV_LENGTH 16 +#define XLR_SEC_MAX_IV_LENGTH XLR_SEC_AES_IV_LENGTH +*/ + +#define SEC_MAX_FRAG_LEN 16000 + +struct xlr_sec_command { + uint16_t session_num; + struct cryptop *crp; + struct cryptodesc *enccrd, *maccrd; + + xlr_sec_io_t op; +}; +struct xlr_sec_session{ + uint32_t sessionid; + int hs_used; + int hs_mlen; + struct xlr_sec_command cmd; + void* desc_ptr; + uint8_t multi_frag_flag; +}; + +/* + * Holds data specific to rmi security accelerators + */ +struct xlr_sec_softc { + device_t sc_dev; /* device backpointer */ + struct mtx sc_mtx; /* per-instance lock */ + + int32_t sc_cid; + struct xlr_sec_session *sc_sessions; + int sc_nsessions; + xlr_reg_t* mmio; +}; + + +/* + +union xlr_sec_operand_t { + struct mbuf *m; + struct uio *io; + void *buf; +}xlr_sec_operand; +*/ + + + + + +/* this is passed to packet setup to optimize */ +#define XLR_SEC_SETUP_OP_CIPHER 0x00000001 +#define XLR_SEC_SETUP_OP_HMAC 0x00000002 +#define XLR_SEC_SETUP_OP_CIPHER_HMAC (XLR_SEC_SETUP_OP_CIPHER | XLR_SEC_SETUP_OP_HMAC) +/* this is passed to control_setup to update w/preserving existing keys */ +#define XLR_SEC_SETUP_OP_PRESERVE_HMAC_KEY 0x80000000 +#define XLR_SEC_SETUP_OP_PRESERVE_CIPHER_KEY 0x40000000 +#define XLR_SEC_SETUP_OP_UPDATE_KEYS 0x00000010 +#define XLR_SEC_SETUP_OP_FLIP_3DES_KEY 0x00000020 + + + + + +/* + * Message Ring Specifics + */ + +#define SEC_MSGRING_WORDSIZE 2 + + +/* + * + * + * rwR 31 30 29 27 26 24 23 21 20 18 + * | NA | RSA0Out | Rsa0In | Pipe3Out | Pipe3In | ... + * + * 17 15 14 12 11 9 8 6 5 3 2 0 + * | Pipe2Out | Pipe2In | Pipe1In | Pipe1In | Pipe0Out | Pipe0In | + * + * DMA CREDIT REG - + * NUMBER OF CREDITS PER PIPE + */ + +#define SEC_DMA_CREDIT_RSA0_OUT_FOUR 0x20000000 +#define SEC_DMA_CREDIT_RSA0_OUT_TWO 0x10000000 +#define SEC_DMA_CREDIT_RSA0_OUT_ONE 0x08000000 + +#define SEC_DMA_CREDIT_RSA0_IN_FOUR 0x04000000 +#define SEC_DMA_CREDIT_RSA0_IN_TWO 0x02000000 +#define SEC_DMA_CREDIT_RSA0_IN_ONE 0x01000000 + +#define SEC_DMA_CREDIT_PIPE3_OUT_FOUR 0x00800000 +#define SEC_DMA_CREDIT_PIPE3_OUT_TWO 0x00400000 +#define SEC_DMA_CREDIT_PIPE3_OUT_ONE 0x00200000 + +#define SEC_DMA_CREDIT_PIPE3_IN_FOUR 0x00100000 +#define SEC_DMA_CREDIT_PIPE3_IN_TWO 0x00080000 +#define SEC_DMA_CREDIT_PIPE3_IN_ONE 0x00040000 + +#define SEC_DMA_CREDIT_PIPE2_OUT_FOUR 0x00020000 +#define SEC_DMA_CREDIT_PIPE2_OUT_TWO 0x00010000 +#define SEC_DMA_CREDIT_PIPE2_OUT_ONE 0x00008000 + +#define SEC_DMA_CREDIT_PIPE2_IN_FOUR 0x00004000 +#define SEC_DMA_CREDIT_PIPE2_IN_TWO 0x00002000 +#define SEC_DMA_CREDIT_PIPE2_IN_ONE 0x00001000 + +#define SEC_DMA_CREDIT_PIPE1_OUT_FOUR 0x00000800 +#define SEC_DMA_CREDIT_PIPE1_OUT_TWO 0x00000400 +#define SEC_DMA_CREDIT_PIPE1_OUT_ONE 0x00000200 + +#define SEC_DMA_CREDIT_PIPE1_IN_FOUR 0x00000100 +#define SEC_DMA_CREDIT_PIPE1_IN_TWO 0x00000080 +#define SEC_DMA_CREDIT_PIPE1_IN_ONE 0x00000040 + +#define SEC_DMA_CREDIT_PIPE0_OUT_FOUR 0x00000020 +#define SEC_DMA_CREDIT_PIPE0_OUT_TWO 0x00000010 +#define SEC_DMA_CREDIT_PIPE0_OUT_ONE 0x00000008 + +#define SEC_DMA_CREDIT_PIPE0_IN_FOUR 0x00000004 +#define SEC_DMA_CREDIT_PIPE0_IN_TWO 0x00000002 +#define SEC_DMA_CREDIT_PIPE0_IN_ONE 0x00000001 + + +/* + * Currently, FOUR credits per PIPE + * 0x24924924 + */ +#define SEC_DMA_CREDIT_CONFIG SEC_DMA_CREDIT_RSA0_OUT_FOUR | \ + SEC_DMA_CREDIT_RSA0_IN_FOUR | \ + SEC_DMA_CREDIT_PIPE3_OUT_FOUR | \ + SEC_DMA_CREDIT_PIPE3_IN_FOUR | \ + SEC_DMA_CREDIT_PIPE2_OUT_FOUR | \ + SEC_DMA_CREDIT_PIPE2_IN_FOUR | \ + SEC_DMA_CREDIT_PIPE1_OUT_FOUR | \ + SEC_DMA_CREDIT_PIPE1_IN_FOUR | \ + SEC_DMA_CREDIT_PIPE0_OUT_FOUR | \ + SEC_DMA_CREDIT_PIPE0_IN_FOUR + + + + +/* + * CONFIG2 + * 31 5 4 3 + * | NA | PIPE3_DEF_DBL_ISS | PIPE2_DEF_DBL_ISS | ... + * + * 2 1 0 + * ... | PIPE1_DEF_DBL_ISS | PIPE0_DEF_DBL_ISS | ROUND_ROBIN_MODE | + * + * DBL_ISS - mode for SECENG and DMA controller which slows down transfers + * (to be conservativei; 0=Disable,1=Enable). + * ROUND_ROBIN - mode where SECENG dispatches operations to PIPE0-PIPE3 + * and all messages are sent to PIPE0. + * + */ + +#define SEC_CFG2_PIPE3_DBL_ISS_ON 0x00000010 +#define SEC_CFG2_PIPE3_DBL_ISS_OFF 0x00000000 +#define SEC_CFG2_PIPE2_DBL_ISS_ON 0x00000008 +#define SEC_CFG2_PIPE2_DBL_ISS_OFF 0x00000000 +#define SEC_CFG2_PIPE1_DBL_ISS_ON 0x00000004 +#define SEC_CFG2_PIPE1_DBL_ISS_OFF 0x00000000 +#define SEC_CFG2_PIPE0_DBL_ISS_ON 0x00000002 +#define SEC_CFG2_PIPE0_DBL_ISS_OFF 0x00000000 +#define SEC_CFG2_ROUND_ROBIN_ON 0x00000001 +#define SEC_CFG2_ROUND_ROBIN_OFF 0x00000000 + + +enum sec_pipe_config { + + SEC_PIPE_CIPHER_KEY0_L0 = 0x00, + SEC_PIPE_CIPHER_KEY0_HI, + SEC_PIPE_CIPHER_KEY1_LO, + SEC_PIPE_CIPHER_KEY1_HI, + SEC_PIPE_CIPHER_KEY2_LO, + SEC_PIPE_CIPHER_KEY2_HI, + SEC_PIPE_CIPHER_KEY3_LO, + SEC_PIPE_CIPHER_KEY3_HI, + SEC_PIPE_HMAC_KEY0_LO, + SEC_PIPE_HMAC_KEY0_HI, + SEC_PIPE_HMAC_KEY1_LO, + SEC_PIPE_HMAC_KEY1_HI, + SEC_PIPE_HMAC_KEY2_LO, + SEC_PIPE_HMAC_KEY2_HI, + SEC_PIPE_HMAC_KEY3_LO, + SEC_PIPE_HMAC_KEY3_HI, + SEC_PIPE_HMAC_KEY4_LO, + SEC_PIPE_HMAC_KEY4_HI, + SEC_PIPE_HMAC_KEY5_LO, + SEC_PIPE_HMAC_KEY5_HI, + SEC_PIPE_HMAC_KEY6_LO, + SEC_PIPE_HMAC_KEY6_HI, + SEC_PIPE_HMAC_KEY7_LO, + SEC_PIPE_HMAC_KEY7_HI, + SEC_PIPE_NCFBM_LO, + SEC_PIPE_NCFBM_HI, + SEC_PIPE_INSTR_LO, + SEC_PIPE_INSTR_HI, + SEC_PIPE_RSVD0, + SEC_PIPE_RSVD1, + SEC_PIPE_RSVD2, + SEC_PIPE_RSVD3, + + SEC_PIPE_DF_PTRS0, + SEC_PIPE_DF_PTRS1, + SEC_PIPE_DF_PTRS2, + SEC_PIPE_DF_PTRS3, + SEC_PIPE_DF_PTRS4, + SEC_PIPE_DF_PTRS5, + SEC_PIPE_DF_PTRS6, + SEC_PIPE_DF_PTRS7, + + SEC_PIPE_DU_DATA_IN_LO, + SEC_PIPE_DU_DATA_IN_HI, + SEC_PIPE_DU_DATA_IN_CTRL, + SEC_PIPE_DU_DATA_OUT_LO, + SEC_PIPE_DU_DATA_OUT_HI, + SEC_PIPE_DU_DATA_OUT_CTRL, + + SEC_PIPE_STATE0, + SEC_PIPE_STATE1, + SEC_PIPE_STATE2, + SEC_PIPE_STATE3, + SEC_PIPE_STATE4, + SEC_PIPE_INCLUDE_MASK0, + SEC_PIPE_INCLUDE_MASK1, + SEC_PIPE_INCLUDE_MASK2, + SEC_PIPE_INCLUDE_MASK3, + SEC_PIPE_INCLUDE_MASK4, + SEC_PIPE_EXCLUDE_MASK0, + SEC_PIPE_EXCLUDE_MASK1, + SEC_PIPE_EXCLUDE_MASK2, + SEC_PIPE_EXCLUDE_MASK3, + SEC_PIPE_EXCLUDE_MASK4, +}; + + +enum sec_pipe_base_config { + + SEC_PIPE0_BASE = 0x00, + SEC_PIPE1_BASE = 0x40, + SEC_PIPE2_BASE = 0x80, + SEC_PIPE3_BASE = 0xc0 + +}; + +enum sec_rsa_config { + + SEC_RSA_PIPE0_DU_DATA_IN_LO = 0x100, + SEC_RSA_PIPE0_DU_DATA_IN_HI, + SEC_RSA_PIPE0_DU_DATA_IN_CTRL, + SEC_RSA_PIPE0_DU_DATA_OUT_LO, + SEC_RSA_PIPE0_DU_DATA_OUT_HI, + SEC_RSA_PIPE0_DU_DATA_OUT_CTRL, + SEC_RSA_RSVD0, + SEC_RSA_RSVD1, + + SEC_RSA_PIPE0_STATE0, + SEC_RSA_PIPE0_STATE1, + SEC_RSA_PIPE0_STATE2, + SEC_RSA_PIPE0_INCLUDE_MASK0, + SEC_RSA_PIPE0_INCLUDE_MASK1, + SEC_RSA_PIPE0_INCLUDE_MASK2, + SEC_RSA_PIPE0_EXCLUDE_MASK0, + SEC_RSA_PIPE0_EXCLUDE_MASK1, + SEC_RSA_PIPE0_EXCLUDE_MASK2, + SEC_RSA_PIPE0_EVENT_CTR + +}; + + + + +enum sec_config { + + SEC_DMA_CREDIT = 0x140, + SEC_CONFIG1, + SEC_CONFIG2, + SEC_CONFIG3, + +}; + + + +enum sec_debug_config { + + SEC_DW0_DESCRIPTOR0_LO = 0x180, + SEC_DW0_DESCRIPTOR0_HI, + SEC_DW0_DESCRIPTOR1_LO, + SEC_DW0_DESCRIPTOR1_HI, + SEC_DW1_DESCRIPTOR0_LO, + SEC_DW1_DESCRIPTOR0_HI, + SEC_DW1_DESCRIPTOR1_LO, + SEC_DW1_DESCRIPTOR1_HI, + SEC_DW2_DESCRIPTOR0_LO, + SEC_DW2_DESCRIPTOR0_HI, + SEC_DW2_DESCRIPTOR1_LO, + SEC_DW2_DESCRIPTOR1_HI, + SEC_DW3_DESCRIPTOR0_LO, + SEC_DW3_DESCRIPTOR0_HI, + SEC_DW3_DESCRIPTOR1_LO, + SEC_DW3_DESCRIPTOR1_HI, + + SEC_STATE0, + SEC_STATE1, + SEC_STATE2, + SEC_INCLUDE_MASK0, + SEC_INCLUDE_MASK1, + SEC_INCLUDE_MASK2, + SEC_EXCLUDE_MASK0, + SEC_EXCLUDE_MASK1, + SEC_EXCLUDE_MASK2, + SEC_EVENT_CTR + +}; + + +enum sec_msgring_bucket_config { + + SEC_BIU_CREDITS = 0x308, + + SEC_MSG_BUCKET0_SIZE = 0x320, + SEC_MSG_BUCKET1_SIZE, + SEC_MSG_BUCKET2_SIZE, + SEC_MSG_BUCKET3_SIZE, + SEC_MSG_BUCKET4_SIZE, + SEC_MSG_BUCKET5_SIZE, + SEC_MSG_BUCKET6_SIZE, + SEC_MSG_BUCKET7_SIZE, +}; + +enum sec_msgring_credit_config { + + SEC_CC_CPU0_0 = 0x380, + SEC_CC_CPU1_0 = 0x388, + SEC_CC_CPU2_0 = 0x390, + SEC_CC_CPU3_0 = 0x398, + SEC_CC_CPU4_0 = 0x3a0, + SEC_CC_CPU5_0 = 0x3a8, + SEC_CC_CPU6_0 = 0x3b0, + SEC_CC_CPU7_0 = 0x3b8 + +}; + +enum sec_engine_id { + SEC_PIPE0, + SEC_PIPE1, + SEC_PIPE2, + SEC_PIPE3, + SEC_RSA +}; + +enum sec_cipher { + SEC_AES256_MODE_HMAC, + SEC_AES256_MODE, + SEC_AES256_HMAC, + SEC_AES256, + SEC_AES192_MODE_HMAC, + SEC_AES192_MODE, + SEC_AES192_HMAC, + SEC_AES192, + SEC_AES128_MODE_HMAC, + SEC_AES128_MODE, + SEC_AES128_HMAC, + SEC_AES128, + SEC_DES_HMAC, + SEC_DES, + SEC_3DES, + SEC_3DES_HMAC, + SEC_HMAC +}; + +enum sec_msgrng_msg_ctrl_config { + SEC_EOP=5, + SEC_SOP=6, +}; + + + +void xlr_sec_init( struct xlr_sec_softc *sc) ; + +int xlr_sec_setup(struct xlr_sec_session* ses, + struct xlr_sec_command *cmd, symkey_desc_pt desc); + +symkey_desc_pt xlr_sec_allocate_desc(void*); + +#endif diff --git a/sys/dev/rmi/sec/rmisec.c b/sys/dev/rmi/sec/rmisec.c new file mode 100644 index 00000000000..60eb8601a32 --- /dev/null +++ b/sys/dev/rmi/sec/rmisec.c @@ -0,0 +1,617 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include + +/*#define RMI_SEC_DEBUG */ + + +void xlr_sec_print_data(struct cryptop *crp); + +static int xlr_sec_newsession(void *arg, uint32_t *sidp, struct cryptoini *cri); +static int xlr_sec_freesession(void *arg, uint64_t tid); +static int xlr_sec_process(void *arg, struct cryptop *crp, int hint); + + +static int xlr_sec_probe(device_t); +static int xlr_sec_attach(device_t); +static int xlr_sec_detach(device_t); + + +static device_method_t xlr_sec_methods[] = { + /* device interface */ + DEVMETHOD(device_probe, xlr_sec_probe), + DEVMETHOD(device_attach, xlr_sec_attach), + DEVMETHOD(device_detach, xlr_sec_detach), + + /* bus interface */ + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_driver_added, bus_generic_driver_added), + + { 0, 0 } +}; + +static driver_t xlr_sec_driver = { + "rmisec", + xlr_sec_methods, + sizeof (struct xlr_sec_softc) +}; +static devclass_t xlr_sec_devclass; + +DRIVER_MODULE(rmisec, iodi, xlr_sec_driver, xlr_sec_devclass, 0, 0); +MODULE_DEPEND(rmisec, crypto, 1, 1, 1); + + + +static int +xlr_sec_probe(device_t dev) +{ + return (BUS_PROBE_DEFAULT); + +} + + +/* + * Attach an interface that successfully probed. + */ +static int +xlr_sec_attach(device_t dev) +{ + + struct xlr_sec_softc *sc = device_get_softc(dev); + + bzero(sc, sizeof (*sc)); + sc->sc_dev = dev; + + + mtx_init(&sc->sc_mtx, device_get_nameunit(dev), "rmi crypto driver", MTX_DEF); + + sc->sc_cid = crypto_get_driverid(0); + if (sc->sc_cid < 0) { + printf("xlr_sec - error : could not get the driver id\n"); + goto error_exit; + } + + + if(crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0, + xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc)!=0) + printf("register failed for CRYPTO_DES_CBC\n"); + + if(crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0, + xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc)!=0) + printf("register failed for CRYPTO_3DES_CBC\n"); + + if(crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0, + xlr_sec_newsession, xlr_sec_freesession, + xlr_sec_process, sc)!=0) + printf("register failed for CRYPTO_AES_CBC\n"); + + if(crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0, + xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc)!=0) + printf("register failed for CRYPTO_ARC4\n"); + + + if(crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0, + xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc)!=0) + printf("register failed for CRYPTO_MD5\n"); + + if(crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0, + xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc)!=0) + printf("register failed for CRYPTO_SHA1\n"); + + if(crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0, + xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc)!=0) + printf("register failed for CRYPTO_MD5_HMAC\n"); + + if(crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0, + xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc)!=0) + printf("register failed for CRYPTO_SHA1_HMAC\n"); + + + xlr_sec_init(sc); + return (0); + + +error_exit: + return (ENXIO); + +} + + +/* + * Detach an interface that successfully probed. + */ +static int +xlr_sec_detach(device_t dev) +{ + int sesn; + struct xlr_sec_softc *sc = device_get_softc(dev); + struct xlr_sec_session *ses = NULL; + symkey_desc_pt desc ; + + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) { + ses = &sc->sc_sessions[sesn]; + desc = (symkey_desc_pt)ses->desc_ptr; + free(desc->user.kern_src, M_DEVBUF); + free(desc->user.kern_dest, M_DEVBUF); + free(desc->next_src_buf, M_DEVBUF); + free(desc->next_dest_buf, M_DEVBUF); + free(ses->desc_ptr, M_DEVBUF) ; + } + + return (0); +} + + + + +/* + * Allocate a new 'session' and return an encoded session id. 'sidp' + * contains our registration id, and should contain an encoded session + * id on successful allocation. + */ +static int +xlr_sec_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri) +{ + struct cryptoini *c; + struct xlr_sec_softc *sc = arg; + int mac = 0, cry = 0, sesn; + struct xlr_sec_session *ses = NULL; + + + if (sidp == NULL || cri == NULL || sc == NULL) + return (EINVAL); + + + if (sc->sc_sessions == NULL) { + ses = sc->sc_sessions = (struct xlr_sec_session *)malloc( + sizeof(struct xlr_sec_session), M_DEVBUF, M_NOWAIT); + if (ses == NULL) + return (ENOMEM); + + ses->desc_ptr = (void*) xlr_sec_allocate_desc((void*)ses); + if(ses->desc_ptr == NULL) + return (ENOMEM); + + sesn = 0; + ses->sessionid = sesn; + sc->sc_nsessions = 1; + } else { + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) { + if (!sc->sc_sessions[sesn].hs_used) { + ses = &sc->sc_sessions[sesn]; + break; + } + } + + if (ses == NULL) { + sesn = sc->sc_nsessions; + ses = (struct xlr_sec_session *)malloc((sesn + 1) * + sizeof(struct xlr_sec_session), M_DEVBUF, M_NOWAIT); + if (ses == NULL) + return (ENOMEM); + bcopy(sc->sc_sessions, ses, sesn * sizeof(struct xlr_sec_session)); + bzero(sc->sc_sessions, sesn * sizeof(struct xlr_sec_session)); + free(sc->sc_sessions, M_DEVBUF); + sc->sc_sessions = ses; + ses = &sc->sc_sessions[sesn]; + ses->sessionid = sesn; + ses->desc_ptr = (void*) xlr_sec_allocate_desc((void*)ses); + if(ses->desc_ptr == NULL) + return (ENOMEM); + sc->sc_nsessions++; + } + } + ses->hs_used = 1; + + + for (c = cri; c != NULL; c = c->cri_next) { + + switch (c->cri_alg) { + case CRYPTO_MD5: + case CRYPTO_SHA1: + case CRYPTO_MD5_HMAC: + case CRYPTO_SHA1_HMAC: + if (mac) + return (EINVAL); + mac = 1; + ses->hs_mlen = c->cri_mlen; + if (ses->hs_mlen == 0) { + switch (c->cri_alg) { + case CRYPTO_MD5: + case CRYPTO_MD5_HMAC: + ses->hs_mlen = 16; + break; + case CRYPTO_SHA1: + case CRYPTO_SHA1_HMAC: + ses->hs_mlen = 20; + break; + } + } + break; + case CRYPTO_DES_CBC: + case CRYPTO_3DES_CBC: + case CRYPTO_AES_CBC: + /* XXX this may read fewer, does it matter? */ + /* read_random(ses->hs_iv, + c->cri_alg == CRYPTO_AES_CBC ? +XLR_SEC_AES_IV_LENGTH : XLR_SEC_IV_LENGTH); + */ + /*FALLTHROUGH*/ + case CRYPTO_ARC4: + if (cry) + return (EINVAL); + cry = 1; + break; + default: + return (EINVAL); + } + } + if (mac == 0 && cry == 0) + return (EINVAL); + + *sidp = XLR_SEC_SID(device_get_unit(sc->sc_dev), sesn); + return (0); +} + +/* + * Deallocate a session. + * XXX this routine should run a zero'd mac/encrypt key into context ram. + * XXX to blow away any keys already stored there. + */ +static int +xlr_sec_freesession(void *arg, u_int64_t tid) +{ + struct xlr_sec_softc *sc = arg; + int session; + u_int32_t sid = CRYPTO_SESID2LID(tid); + + if (sc == NULL) + return (EINVAL); + + session = XLR_SEC_SESSION(sid); + if (session >= sc->sc_nsessions) + return (EINVAL); + + sc->sc_sessions[session].hs_used = 0; + + return (0); +} + +#ifdef RMI_SEC_DEBUG + +void xlr_sec_print_data(struct cryptop *crp) +{ + int i, key_len; + struct cryptodesc *crp_desc; + + printf("session id = 0x%llx, crp_ilen = %d, crp_olen=%d \n", + crp->crp_sid, crp->crp_ilen, crp->crp_olen); + + printf("crp_flags = 0x%x\n", crp->crp_flags); + + + printf("crp buf:\n"); + for(i=0; icrp_ilen; i++) + { + printf("%c ",crp->crp_buf[i] ); + if(i%10 == 0) printf("\n"); + } + + printf("\n"); + printf("****************** desc ****************\n"); + crp_desc = crp->crp_desc; + printf("crd_skip=%d, crd_len=%d, crd_flags=0x%x, crd_alg=%d\n", + crp_desc->crd_skip, crp_desc->crd_len, crp_desc->crd_flags, crp_desc->crd_alg); + + key_len = crp_desc->crd_klen / 8; + printf("key(%d) :\n",key_len); + for(i=0; i< key_len; i++) + printf("%d", crp_desc->crd_key[i]); + printf("\n"); + + printf(" IV : \n"); + for(i=0; i< EALG_MAX_BLOCK_LEN; i++) + printf("%d", crp_desc->crd_iv[i]); + printf("\n"); + + printf("crd_next=%p\n", crp_desc->crd_next); + return; +} + +#endif + + +static int +xlr_sec_process(void *arg, struct cryptop *crp, int hint) +{ + struct xlr_sec_softc *sc = arg; + struct xlr_sec_command *cmd = NULL; + int session, err; + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd; + struct xlr_sec_session* ses; + + if (crp == NULL || crp->crp_callback == NULL) { + return (EINVAL); + } + + session = XLR_SEC_SESSION(crp->crp_sid); + if (sc == NULL || session >= sc->sc_nsessions) { + err = EINVAL; + goto errout; + } + + ses = &sc->sc_sessions[session]; + + cmd = &ses->cmd ; + if (cmd == NULL) { + err = ENOMEM; + goto errout; + } + + + crd1 = crp->crp_desc; + if (crd1 == NULL) { + err = EINVAL; + goto errout; + } + + crd2 = crd1->crd_next; + + if (crd2 == NULL) { + if (crd1->crd_alg == CRYPTO_MD5_HMAC || + crd1->crd_alg == CRYPTO_SHA1_HMAC || + crd1->crd_alg == CRYPTO_SHA1 || + crd1->crd_alg == CRYPTO_MD5) { + maccrd = crd1; + enccrd = NULL; + } else if (crd1->crd_alg == CRYPTO_DES_CBC || + crd1->crd_alg == CRYPTO_3DES_CBC || + crd1->crd_alg == CRYPTO_AES_CBC || + crd1->crd_alg == CRYPTO_ARC4) { + maccrd = NULL; + enccrd = crd1; + } else { + err = EINVAL; + goto errout; + } + } else { + if ((crd1->crd_alg == CRYPTO_MD5_HMAC || + crd1->crd_alg == CRYPTO_SHA1_HMAC || + crd1->crd_alg == CRYPTO_MD5 || + crd1->crd_alg == CRYPTO_SHA1) && + (crd2->crd_alg == CRYPTO_DES_CBC || + crd2->crd_alg == CRYPTO_3DES_CBC || + crd2->crd_alg == CRYPTO_AES_CBC || + crd2->crd_alg == CRYPTO_ARC4)){ + maccrd = crd1; + enccrd = crd2; + } else if ((crd1->crd_alg == CRYPTO_DES_CBC || + crd1->crd_alg == CRYPTO_ARC4 || + crd1->crd_alg == CRYPTO_3DES_CBC || + crd1->crd_alg == CRYPTO_AES_CBC) && + (crd2->crd_alg == CRYPTO_MD5_HMAC || + crd2->crd_alg == CRYPTO_SHA1_HMAC || + crd2->crd_alg == CRYPTO_MD5 || + crd2->crd_alg == CRYPTO_SHA1) && + (crd1->crd_flags & CRD_F_ENCRYPT)) { + enccrd = crd1; + maccrd = crd2; + } else { + err = EINVAL; + goto errout; + } + } + + bzero(&cmd->op, sizeof(xlr_sec_io_t)); + + cmd->op.source_buf = (uint64_t)(unsigned long) crp->crp_buf; + cmd->op.source_buf_size = crp->crp_ilen; + if(crp->crp_flags & CRYPTO_F_REL){ + cmd->op.dest_buf = (uint64_t)(unsigned long)crp->crp_buf; + cmd->op.dest_buf_size = crp->crp_ilen ; + } + else{ + cmd->op.dest_buf = (uint64_t)(unsigned long)crp->crp_buf; + cmd->op.dest_buf_size = crp->crp_ilen ; + } + cmd->op.num_packets = 1; + cmd->op.num_fragments = 1; + + + if(cmd->op.source_buf_size > SEC_MAX_FRAG_LEN){ + ses->multi_frag_flag = 1; + } + else{ + ses->multi_frag_flag = 0; + } + + if(maccrd){ + cmd->maccrd = maccrd; + cmd->op.cipher_op = XLR_SEC_CIPHER_MODE_PASS ; + cmd->op.cipher_mode = XLR_SEC_CIPHER_MODE_NONE ; + cmd->op.cipher_type = XLR_SEC_CIPHER_TYPE_NONE ; + cmd->op.cipher_init = 0 ; + cmd->op.cipher_offset = 0; + + switch(maccrd->crd_alg){ + case CRYPTO_MD5: + cmd->op.digest_type = XLR_SEC_DIGEST_TYPE_MD5 ; + cmd->op.digest_init = XLR_SEC_DIGEST_INIT_NEWKEY ; + cmd->op.digest_src = XLR_SEC_DIGEST_SRC_DMA ; + cmd->op.digest_offset = 0; + + cmd->op.cksum_type = XLR_SEC_CKSUM_TYPE_NOP ; + cmd->op.cksum_src = XLR_SEC_CKSUM_SRC_CIPHER ; + cmd->op.cksum_offset = 0; + + cmd->op.pkt_hmac = XLR_SEC_LOADHMACKEY_MODE_OLD ; + cmd->op.pkt_hash = XLR_SEC_PADHASH_PAD ; + cmd->op.pkt_hashbytes = XLR_SEC_HASHBYTES_ALL8 ; + cmd->op.pkt_next = XLR_SEC_NEXT_FINISH ; + cmd->op.pkt_iv = XLR_SEC_PKT_IV_OLD ; + cmd->op.pkt_lastword = XLR_SEC_LASTWORD_128; + + + default: + printf("currently not handled\n"); + } + } + + if(enccrd){ + cmd->enccrd = enccrd; + +#ifdef RMI_SEC_DEBUG + xlr_sec_print_data(crp); +#endif + + if(enccrd->crd_flags & CRD_F_ENCRYPT){ + cmd->op.cipher_op = XLR_SEC_CIPHER_OP_ENCRYPT; + } + else + cmd->op.cipher_op = XLR_SEC_CIPHER_OP_DECRYPT; + + switch(enccrd->crd_alg){ + case CRYPTO_DES_CBC : + case CRYPTO_3DES_CBC: + if(enccrd->crd_alg == CRYPTO_DES_CBC){ + cmd->op.cipher_type = XLR_SEC_CIPHER_TYPE_DES; + memcpy(&cmd->op.crypt_key[0],enccrd->crd_key, XLR_SEC_DES_KEY_LENGTH); + } + else{ + cmd->op.cipher_type = XLR_SEC_CIPHER_TYPE_3DES; +// if(enccrd->crd_flags & CRD_F_KEY_EXPLICIT) + { + memcpy(&cmd->op.crypt_key[0],enccrd->crd_key, XLR_SEC_3DES_KEY_LENGTH); + } + } + + cmd->op.cipher_mode = XLR_SEC_CIPHER_MODE_CBC; + cmd->op.cipher_init = XLR_SEC_CIPHER_INIT_NK; + cmd->op.cipher_offset = XLR_SEC_DES_IV_LENGTH; + + cmd->op.digest_type = XLR_SEC_DIGEST_TYPE_NONE; + cmd->op.digest_init = XLR_SEC_DIGEST_INIT_OLDKEY; + cmd->op.digest_src = XLR_SEC_DIGEST_SRC_DMA; + cmd->op.digest_offset = 0; + + cmd->op.cksum_type = XLR_SEC_CKSUM_TYPE_NOP; + cmd->op.cksum_src = XLR_SEC_CKSUM_SRC_CIPHER; + cmd->op.cksum_offset = 0; + + cmd->op.pkt_hmac = XLR_SEC_LOADHMACKEY_MODE_OLD; + cmd->op.pkt_hash = XLR_SEC_PADHASH_PAD; + cmd->op.pkt_hashbytes = XLR_SEC_HASHBYTES_ALL8; + cmd->op.pkt_next = XLR_SEC_NEXT_FINISH; + cmd->op.pkt_iv = XLR_SEC_PKT_IV_NEW; + cmd->op.pkt_lastword = XLR_SEC_LASTWORD_128; + +// if((!(enccrd->crd_flags & CRD_F_IV_PRESENT)) && + if( (enccrd->crd_flags & CRD_F_IV_EXPLICIT)){ + memcpy(&cmd->op.initial_vector[0],enccrd->crd_iv, XLR_SEC_DES_IV_LENGTH); + } + break; + + case CRYPTO_AES_CBC: + if(enccrd->crd_alg == CRYPTO_AES_CBC){ + cmd->op.cipher_type = XLR_SEC_CIPHER_TYPE_AES128; +// if(enccrd->crd_flags & CRD_F_KEY_EXPLICIT) + { + memcpy(&cmd->op.crypt_key[0],enccrd->crd_key, XLR_SEC_AES128_KEY_LENGTH); + } + } + + cmd->op.cipher_mode = XLR_SEC_CIPHER_MODE_CBC; + cmd->op.cipher_init = XLR_SEC_CIPHER_INIT_NK; + cmd->op.cipher_offset = XLR_SEC_AES_BLOCK_SIZE; + + cmd->op.digest_type = XLR_SEC_DIGEST_TYPE_NONE; + cmd->op.digest_init = XLR_SEC_DIGEST_INIT_OLDKEY; + cmd->op.digest_src = XLR_SEC_DIGEST_SRC_DMA; + cmd->op.digest_offset = 0; + + cmd->op.cksum_type = XLR_SEC_CKSUM_TYPE_NOP; + cmd->op.cksum_src = XLR_SEC_CKSUM_SRC_CIPHER; + cmd->op.cksum_offset = 0; + + cmd->op.pkt_hmac = XLR_SEC_LOADHMACKEY_MODE_OLD; + cmd->op.pkt_hash = XLR_SEC_PADHASH_PAD; + cmd->op.pkt_hashbytes = XLR_SEC_HASHBYTES_ALL8; + cmd->op.pkt_next = XLR_SEC_NEXT_FINISH; + cmd->op.pkt_iv = XLR_SEC_PKT_IV_NEW; + cmd->op.pkt_lastword = XLR_SEC_LASTWORD_128; + +// if(!(enccrd->crd_flags & CRD_F_IV_PRESENT)){ + if( (enccrd->crd_flags & CRD_F_IV_EXPLICIT)){ + memcpy(&cmd->op.initial_vector[0],enccrd->crd_iv, XLR_SEC_AES_BLOCK_SIZE); + } +// } + break; + } + } + + + cmd->crp = crp; + cmd->session_num = session; + xlr_sec_setup(ses, cmd, (symkey_desc_pt)ses->desc_ptr); + + return(0); + +errout: + if (cmd != NULL) + free(cmd, M_DEVBUF); + crp->crp_etype = err; + crypto_done(crp); + return (err); +} diff --git a/sys/dev/rmi/sec/stats.h b/sys/dev/rmi/sec/stats.h new file mode 100644 index 00000000000..276f7e9b999 --- /dev/null +++ b/sys/dev/rmi/sec/stats.h @@ -0,0 +1,469 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ + +#ifndef _STATS_H_ +#define _STATS_H_ + +typedef struct hmac_stats +{ + unsigned long md5_count; + unsigned long long md5_bytes; + unsigned long sha1_count; + unsigned long long sha1_bytes; + unsigned long sha256_count; + unsigned long long sha256_bytes; + unsigned long sha384_count; + unsigned long long sha384_bytes; + unsigned long sha512_count; + unsigned long long sha512_bytes; + unsigned long gcm_count; + unsigned long long gcm_bytes; + unsigned long kasumi_f9_count; + unsigned long long kasumi_f9_bytes; + unsigned long reverts; + unsigned long long reverts_bytes; +} hmac_stats_t, *hmac_stats_pt; + +typedef struct cipher_stats +{ + unsigned long des_encrypts; + unsigned long long des_encrypt_bytes; + unsigned long des_decrypts; + unsigned long long des_decrypt_bytes; + unsigned long des3_encrypts; + unsigned long long des3_encrypt_bytes; + unsigned long des3_decrypts; + unsigned long long des3_decrypt_bytes; + unsigned long aes_encrypts; + unsigned long long aes_encrypt_bytes; + unsigned long aes_decrypts; + unsigned long long aes_decrypt_bytes; + unsigned long arc4_encrypts; + unsigned long long arc4_encrypt_bytes; + unsigned long arc4_decrypts; + unsigned long long arc4_decrypt_bytes; + unsigned long kasumi_f8_encrypts; + unsigned long long kasumi_f8_encrypt_bytes; + unsigned long kasumi_f8_decrypts; + unsigned long long kasumi_f8_decrypt_bytes; + unsigned long reverts; + unsigned long long reverts_bytes; +} cipher_stats_t, *cipher_stats_pt; + + +typedef struct modexp_stats +{ + unsigned long modexp_512s; + unsigned long modexp_1024s; +} modexp_stats_t, *modexp_stats_pt; + +typedef struct ecc_stats +{ + unsigned long ecc_mul; + unsigned long ecc_add; + unsigned long ecc_dbl; + unsigned long ecc_vfy; + unsigned long ecc_bin_mul; + unsigned long ecc_field_bin_inv; + unsigned long ecc_field_bin_mul; + unsigned long ecc_field_bin_add; + unsigned long ecc_field_add; + unsigned long ecc_field_sub; + unsigned long ecc_field_mul; + unsigned long ecc_field_inv; + unsigned long ecc_field_div; + unsigned long ecc_field_red; +} ecc_stats_t, *ecc_stats_pt; + + +typedef struct opt_stats +{ + unsigned long combined; + unsigned long unaligned_auth_dest; + unsigned long sym_failed; + unsigned long modexp_failed; + unsigned long ecc_failed; +} opt_stats_t, *opt_stats_pt; + +typedef struct rmisec_stats +{ + uint32_t sent; + uint32_t received; + uint32_t stats_mask; + uint32_t control_mask; + rwlock_t rmisec_control_lock; + rwlock_t rmisec_stats_lock; + char clear_start[0]; + uint64_t wait_time; + uint32_t max_wait_time; + uint32_t maxsnd_wait_time; + uint32_t wait_count; + hmac_stats_t hmac; + cipher_stats_t cipher; + modexp_stats_t modexp; + ecc_stats_t ecc; + opt_stats_t opt; +} rmisec_stats_t, *rmisec_stats_pt; + + +/* stats routines */ + +static void inline phxdrv_record_sent(rmisec_stats_pt stats) +{ + write_lock(&stats->rmisec_stats_lock); + stats->sent++; + write_unlock(&stats->rmisec_stats_lock); +} + +static void inline phxdrv_record_received(rmisec_stats_pt stats) +{ + write_lock(&stats->rmisec_stats_lock); + stats->received++; + write_unlock(&stats->rmisec_stats_lock); +} + + +static void inline phxdrv_record_des(rmisec_stats_pt stats, int enc, + int nbytes) +{ + if (stats->stats_mask & PHXDRV_PROFILE_DES) { + write_lock(&stats->rmisec_stats_lock); + if (enc) { + stats->cipher.des_encrypts++; + stats->cipher.des_encrypt_bytes += nbytes; + } + else { + stats->cipher.des_decrypts++; + stats->cipher.des_decrypt_bytes += nbytes; + } + write_unlock(&stats->rmisec_stats_lock); + } +} + + +static void inline phxdrv_record_3des(rmisec_stats_pt stats, int enc, + int nbytes) +{ + if (stats->stats_mask & PHXDRV_PROFILE_3DES) { + write_lock(&stats->rmisec_stats_lock); + if (enc) { + stats->cipher.des3_encrypts++; + stats->cipher.des3_encrypt_bytes += nbytes; + } + else { + stats->cipher.des3_decrypts++; + stats->cipher.des3_decrypt_bytes += nbytes; + } + write_unlock(&stats->rmisec_stats_lock); + } +} + + +static void inline phxdrv_record_aes(rmisec_stats_pt stats, int enc, + int nbytes) +{ + if (stats->stats_mask & PHXDRV_PROFILE_AES) { + write_lock(&stats->rmisec_stats_lock); + if (enc) { + stats->cipher.aes_encrypts++; + stats->cipher.aes_encrypt_bytes += nbytes; + } + else { + stats->cipher.aes_decrypts++; + stats->cipher.aes_decrypt_bytes += nbytes; + } + write_unlock(&stats->rmisec_stats_lock); + } +} + + +static void inline phxdrv_record_arc4(rmisec_stats_pt stats, int enc, + int nbytes) +{ + if (stats->stats_mask & PHXDRV_PROFILE_ARC4) { + write_lock(&stats->rmisec_stats_lock); + if (enc) { + stats->cipher.arc4_encrypts++; + stats->cipher.arc4_encrypt_bytes += nbytes; + } + else { + stats->cipher.arc4_decrypts++; + stats->cipher.arc4_decrypt_bytes += nbytes; + } + write_unlock(&stats->rmisec_stats_lock); + } +} + +static void inline phxdrv_record_kasumi_f8(rmisec_stats_pt stats, int enc, + int nbytes) +{ + if (stats->stats_mask & PHXDRV_PROFILE_KASUMI_F8) { + write_lock(&stats->rmisec_stats_lock); + if (enc) { + stats->cipher.kasumi_f8_encrypts++; + stats->cipher.kasumi_f8_encrypt_bytes += nbytes; + } + else { + stats->cipher.kasumi_f8_decrypts++; + stats->cipher.kasumi_f8_decrypt_bytes += nbytes; + } + write_unlock(&stats->rmisec_stats_lock); + } +} + + +static void inline phxdrv_record_modexp(rmisec_stats_pt stats, + int blksize) +{ + if (stats->stats_mask & PHXDRV_PROFILE_MODEXP) { + write_lock(&stats->rmisec_stats_lock); + if (blksize == 512) { + stats->modexp.modexp_512s++; + } + if (blksize == 1024) { + stats->modexp.modexp_1024s++; + } + write_unlock(&stats->rmisec_stats_lock); + } +} + + +static void inline phxdrv_record_ecc(rmisec_stats_pt stats, PHX_ECC_OP op) +{ + if (stats->stats_mask & PHXDRV_PROFILE_ECC) { + write_lock(&stats->rmisec_stats_lock); + switch (op) { + case PHX_ECC_NOP: + break; + case PHX_ECC_MUL: + stats->ecc.ecc_mul++; + break; + case PHX_ECC_BIN_MUL: + stats->ecc.ecc_bin_mul++; + break; + case PHX_ECC_ADD: + stats->ecc.ecc_add++; + break; + case PHX_ECC_DBL: + stats->ecc.ecc_dbl++; + break; + case PHX_ECC_VFY: + stats->ecc.ecc_vfy++; + break; + case PHX_ECC_FIELD_BIN_INV: + stats->ecc.ecc_field_bin_inv++; + break; + case PHX_ECC_FIELD_BIN_MUL: + stats->ecc.ecc_field_bin_mul++; + break; + case PHX_ECC_FIELD_BIN_ADD: + stats->ecc.ecc_field_bin_add++; + break; + case PHX_ECC_FIELD_ADD: + stats->ecc.ecc_field_add++; + break; + case PHX_ECC_FIELD_SUB: + stats->ecc.ecc_field_sub++; + break; + case PHX_ECC_FIELD_MUL: + stats->ecc.ecc_field_mul++; + break; + case PHX_ECC_FIELD_INV: + stats->ecc.ecc_field_inv++; + break; + case PHX_ECC_FIELD_DIV: + stats->ecc.ecc_field_div++; + break; + case PHX_ECC_FIELD_RED: + stats->ecc.ecc_field_red++; + break; + case PHX_ECC_FIELD: + case PHX_ECC_BIN: + break; + } + write_unlock(&stats->rmisec_stats_lock); + } +} + +static void inline phxdrv_record_cipher_revert(rmisec_stats_pt stats, + int nbytes) +{ + if (stats->stats_mask & PHXDRV_PROFILE_CPHR_REVERTS) { + write_lock(&stats->rmisec_stats_lock); + stats->cipher.reverts++; + stats->cipher.reverts_bytes += nbytes; + write_unlock(&stats->rmisec_stats_lock); + } +} + +static void inline phxdrv_record_hmac_revert(rmisec_stats_pt stats, + int nbytes) +{ + if (stats->stats_mask & PHXDRV_PROFILE_HMAC_REVERTS) { + write_lock(&stats->rmisec_stats_lock); + stats->hmac.reverts++; + stats->hmac.reverts_bytes += nbytes; + write_unlock(&stats->rmisec_stats_lock); + } +} + + +static void inline phxdrv_record_md5(rmisec_stats_pt stats, + int nbytes) +{ + if (stats->stats_mask & PHXDRV_PROFILE_MD5) { + write_lock(&stats->rmisec_stats_lock); + stats->hmac.md5_count++; + stats->hmac.md5_bytes += nbytes; + write_unlock(&stats->rmisec_stats_lock); + } +} + +static void inline phxdrv_record_sha1(rmisec_stats_pt stats, + int nbytes) +{ + if (stats->stats_mask & PHXDRV_PROFILE_SHA1) { + write_lock(&stats->rmisec_stats_lock); + stats->hmac.sha1_count++; + stats->hmac.sha1_bytes += nbytes; + write_unlock(&stats->rmisec_stats_lock); + } +} + + +static void inline phxdrv_record_sha256(rmisec_stats_pt stats, + int nbytes) +{ + if (stats->stats_mask & PHXDRV_PROFILE_SHA256) { + write_lock(&stats->rmisec_stats_lock); + stats->hmac.sha256_count++; + stats->hmac.sha256_bytes += nbytes; + write_unlock(&stats->rmisec_stats_lock); + } +} + +static void inline phxdrv_record_sha384(rmisec_stats_pt stats, + int nbytes) +{ + if (stats->stats_mask & PHXDRV_PROFILE_SHA384) { + write_lock(&stats->rmisec_stats_lock); + stats->hmac.sha384_count++; + stats->hmac.sha384_bytes += nbytes; + write_unlock(&stats->rmisec_stats_lock); + } +} + + +static void inline phxdrv_record_sha512(rmisec_stats_pt stats, + int nbytes) +{ + if (stats->stats_mask & PHXDRV_PROFILE_SHA512) { + write_lock(&stats->rmisec_stats_lock); + stats->hmac.sha512_count++; + stats->hmac.sha512_bytes += nbytes; + write_unlock(&stats->rmisec_stats_lock); + } +} + +static void inline phxdrv_record_gcm(rmisec_stats_pt stats, + int nbytes) +{ + if (stats->stats_mask & PHXDRV_PROFILE_GCM) { + write_lock(&stats->rmisec_stats_lock); + stats->hmac.gcm_count++; + stats->hmac.gcm_bytes += nbytes; + write_unlock(&stats->rmisec_stats_lock); + } +} + + +static void inline phxdrv_record_kasumi_f9(rmisec_stats_pt stats, + int nbytes) +{ + if (stats->stats_mask & PHXDRV_PROFILE_KASUMI_F9) { + write_lock(&stats->rmisec_stats_lock); + stats->hmac.kasumi_f9_count++; + stats->hmac.kasumi_f9_bytes += nbytes; + write_unlock(&stats->rmisec_stats_lock); + } +} + +static void inline phxdrv_record_unaligned_auth_dest(rmisec_stats_pt stats, + int nbytes) +{ + if (stats->stats_mask & PHXDRV_PROFILE_UNALIGNED_AUTH_DEST) { + write_lock(&stats->rmisec_stats_lock); + stats->opt.unaligned_auth_dest++; + write_unlock(&stats->rmisec_stats_lock); + } +} + + +static void inline phxdrv_record_combined(rmisec_stats_pt stats, + int nbytes) +{ + if (stats->stats_mask & PHXDRV_PROFILE_COMBINED) { + write_lock(&stats->rmisec_stats_lock); + stats->opt.combined++; + write_unlock(&stats->rmisec_stats_lock); + } +} + +static void inline phxdrv_record_sym_failed(rmisec_stats_pt stats, + int nbytes) +{ + if (stats->stats_mask & PHXDRV_PROFILE_COMBINED) { + write_lock(&stats->rmisec_stats_lock); + stats->opt.sym_failed++; + write_unlock(&stats->rmisec_stats_lock); + } +} + +static void inline phxdrv_record_modexp_failed(rmisec_stats_pt stats, + int nbytes) +{ + if (stats->stats_mask & PHXDRV_PROFILE_COMBINED) { + write_lock(&stats->rmisec_stats_lock); + stats->opt.modexp_failed++; + write_unlock(&stats->rmisec_stats_lock); + } +} + +static void inline phxdrv_record_ecc_failed(rmisec_stats_pt stats, + int nbytes) +{ + if (stats->stats_mask & PHXDRV_PROFILE_COMBINED) { + write_lock(&stats->rmisec_stats_lock); + stats->opt.ecc_failed++; + write_unlock(&stats->rmisec_stats_lock); + } +} + +#endif diff --git a/sys/dev/rmi/xlr/atx_cpld.h b/sys/dev/rmi/xlr/atx_cpld.h new file mode 100644 index 00000000000..157e43ed1d7 --- /dev/null +++ b/sys/dev/rmi/xlr/atx_cpld.h @@ -0,0 +1,53 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ +#ifndef _RMI_ATX_CPLD_H_ +#define _RMI_ATX_CPLD_H_ + +/* + * bit_0 : xgs0 phy reset, bit_1 : xgs1 phy reset, bit_2 : HT reset, bit_3 : + * RTC reset, bit_4 : gmac phy soft reset, bit_5 : gmac phy hard reset, bit_6 + * : board reset, bit_7 : reserved + */ +#define ATX_CPLD_RESET_1 2 + +/* + * bit_0_2 : reserved, bit_3 : turn off xpak_0 tx, bit_4 : turn off xpak_1 + * tx, bit_5 : HT stop (active low), bit_6 : flash program enable, bit_7 : + * compact flash io mode + */ +#define ATX_CPLD_MISC_CTRL 8 + +/* + * bit_0 : reset tcam, bit_1 : reset xpak_0 module, bit_2 : reset xpak_1 + * module, bit_3_7 : reserved + */ +#define ATX_CPLD_RESET_2 9 + +#endif /* _RMI_ATX_CPLD_H_ */ diff --git a/sys/dev/rmi/xlr/rge.c b/sys/dev/rmi/xlr/rge.c new file mode 100644 index 00000000000..9b4936e5317 --- /dev/null +++ b/sys/dev/rmi/xlr/rge.c @@ -0,0 +1,2815 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ + +#ifdef HAVE_KERNEL_OPTION_HEADERS +#include "opt_device_polling.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define __RMAN_RESOURCE_VISIBLE +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include /* for DELAY */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include "miidevs.h" +#include +#include "miibus_if.h" +#include + +/* #include "opt_rge.h" */ + +MODULE_DEPEND(rge, ether, 1, 1, 1); +MODULE_DEPEND(rge, miibus, 1, 1, 1); + +/* #define DEBUG */ +/*#define RX_COPY */ + +#define RGE_TX_THRESHOLD 1024 +#define RGE_TX_Q_SIZE 1024 + +#ifdef DEBUG +#undef dbg_msg +int mac_debug = 1; +#define dbg_msg(fmt, args...) \ + do {\ + if (mac_debug) {\ + printf("[%s@%d|%s]: cpu_%d: " fmt, \ + __FILE__, __LINE__, __FUNCTION__, PCPU_GET(cpuid), ##args);\ + }\ + } while(0); + +#define DUMP_PACKETS +#else +#undef dbg_msg +#define dbg_msg(fmt, args...) +int mac_debug = 0; +#endif + +#define MAC_B2B_IPG 88 + +/* frame sizes need to be cacheline aligned */ +#define MAX_FRAME_SIZE 1536 +#define MAX_FRAME_SIZE_JUMBO 9216 + +#define MAC_SKB_BACK_PTR_SIZE SMP_CACHE_BYTES +#define MAC_PREPAD 0 +#define BYTE_OFFSET 2 +#define XLR_RX_BUF_SIZE (MAX_FRAME_SIZE+BYTE_OFFSET+MAC_PREPAD+MAC_SKB_BACK_PTR_SIZE+SMP_CACHE_BYTES) +#define MAC_CRC_LEN 4 +#define MAX_NUM_MSGRNG_STN_CC 128 + +#define MAX_NUM_DESC 1024 +#define MAX_SPILL_SIZE (MAX_NUM_DESC + 128) + +#define MAC_FRIN_TO_BE_SENT_THRESHOLD 16 + +#define MAX_FRIN_SPILL (MAX_SPILL_SIZE << 2) +#define MAX_FROUT_SPILL (MAX_SPILL_SIZE << 2) +#define MAX_CLASS_0_SPILL (MAX_SPILL_SIZE << 2) +#define MAX_CLASS_1_SPILL (MAX_SPILL_SIZE << 2) +#define MAX_CLASS_2_SPILL (MAX_SPILL_SIZE << 2) +#define MAX_CLASS_3_SPILL (MAX_SPILL_SIZE << 2) + +/***************************************************************** + * Phoenix Generic Mac driver + *****************************************************************/ + +extern uint32_t cpu_ltop_map[32]; +typedef enum { + xlr_mac_speed_10, xlr_mac_speed_100, + xlr_mac_speed_1000, xlr_mac_speed_rsvd +} xlr_mac_speed_t; + +typedef enum { + xlr_mac_duplex_auto, xlr_mac_duplex_half, + xlr_mac_duplex_full +} xlr_mac_duplex_t; + +typedef enum { + xlr_mac_link_down, + xlr_mac_link_up, +} xlr_mac_link_t; + +typedef enum { + xlr_mac_fc_auto, xlr_mac_fc_disabled, xlr_mac_fc_frame, + xlr_mac_fc_collision, xlr_mac_fc_carrier +} xlr_mac_fc_t; + + +struct rge_softc_stats { + unsigned long rx_frames; + unsigned long tx_frames; + unsigned long rx_packets; + unsigned long rx_bytes; + unsigned long tx_packets; + unsigned long tx_bytes; +}; + +struct driver_data { + + /* + * Let these be the first fields in this structure the structure is + * cacheline aligned when allocated in init_etherdev + */ + struct fr_desc *frin_spill; + struct fr_desc *frout_spill; + union rx_tx_desc *class_0_spill; + union rx_tx_desc *class_1_spill; + union rx_tx_desc *class_2_spill; + union rx_tx_desc *class_3_spill; + int spill_configured; + + struct rge_softc *sc; /* pointer to freebsd device soft-pointer */ + struct rge_softc_stats stats; + struct mtx lock; + + xlr_reg_t *mmio; + xlr_reg_t *mii_mmio; + xlr_reg_t *pcs_mmio; + xlr_reg_t *serdes_mmio; + + int txbucket; + int rfrbucket; + + int phy_oldbmsr; + int phy_oldanlpar; + int phy_oldk1stsr; + int phy_oldlinkstat; + unsigned char phys_addr[2]; + + xlr_mac_speed_t speed; /* current speed */ + xlr_mac_duplex_t duplex;/* current duplex */ + xlr_mac_link_t link; /* current link */ + xlr_mac_fc_t flow_ctrl; /* current flow control setting */ + int advertising; + + int id; + int type; + int mode; + int instance; + int phy_addr; + int frin_to_be_sent[8]; + int init_frin_desc; +}; + +/* static int mac_frin_to_be_sent_thr[8]; */ + +enum { + PORT_TX, + PORT_TX_COMPLETE, + PORT_STARTQ, + PORT_STOPQ, + PORT_START_DEV_STATE, + PORT_STOP_DEV_STATE, +}; + +#ifdef ENABLED_DEBUG +static int port_counters[4][8] __aligned(XLR_CACHELINE_SIZE); +#define port_inc_counter(port, counter) atomic_add_int(&port_counters[port][(counter)], 1) +#define port_set_counter(port, counter, value) atomic_set_int(&port_counters[port][(counter)], (value)) +#else +#define port_inc_counter(port, counter) /*Nothing*/ +#define port_set_counter(port, counter, value) /*Nothing*/ +#endif + +int xlr_rge_tx_prepend[MAXCPU]; +int xlr_rge_tx_done[MAXCPU]; +int xlr_rge_get_p2d_failed[MAXCPU]; +int xlr_rge_msg_snd_failed[MAXCPU]; +int xlr_rge_tx_ok_done[MAXCPU]; +int xlr_rge_rx_done[MAXCPU]; +int xlr_rge_repl_done[MAXCPU]; + +static __inline__ unsigned int +ldadd_wu(unsigned int value, unsigned long *addr) +{ + __asm__ __volatile__( ".set push\n" + ".set noreorder\n" + "move $8, %2\n" + "move $9, %3\n" + /* "ldaddwu $8, $9\n" */ + ".word 0x71280011\n" + "move %0, $8\n" + ".set pop\n" + : "=&r"(value), "+m"(*addr) + : "0"(value), "r" ((unsigned long)addr) + : "$8", "$9"); + return value; +} + +/* #define mac_stats_add(x, val) ({(x) += (val);}) */ +#define mac_stats_add(x, val) ldadd_wu(val, &x) + +struct rge_softc { + int unit; + int irq; + unsigned char dev_addr[6]; + unsigned long base_addr; + unsigned long mem_end; + struct ifnet *rge_ifp;/* interface info */ + device_t rge_dev; + int mtu; + int flags; + struct driver_data priv; + struct mtx rge_mtx; + device_t rge_miibus; + struct mii_data rge_mii;/* MII/media information */ + bus_space_handle_t rge_bhandle; + bus_space_tag_t rge_btag; + void *rge_intrhand; + struct resource rge_irq; + struct resource *rge_res; + struct ifmedia rge_ifmedia; /* TBI media info */ + int rge_if_flags; + int rge_link; /* link state */ + int rge_link_evt; /* pending link event */ + struct callout rge_stat_ch; + void (*xmit) (struct ifnet *); + void (*stop) (struct rge_softc *); + int (*ioctl) (struct ifnet *, u_long, caddr_t); + struct rge_softc_stats *(*get_stats) (struct rge_softc *); + int active; + int link_up; +}; + +#define XLR_MAX_CORE 8 +#define RGE_LOCK_INIT(_sc, _name) \ + mtx_init(&(_sc)->rge_mtx, _name, MTX_NETWORK_LOCK, MTX_DEF) +#define RGE_LOCK(_sc) mtx_lock(&(_sc)->rge_mtx) +#define RGE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->rge_mtx, MA_OWNED) +#define RGE_UNLOCK(_sc) mtx_unlock(&(_sc)->rge_mtx) +#define RGE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->rge_mtx) + +#define XLR_MAX_MACS 8 +#define XLR_MAX_TX_FRAGS 14 +#define MAX_P2D_DESC_PER_PORT 512 +struct p2d_tx_desc { + uint64_t frag [XLR_MAX_TX_FRAGS + 2]; +}; +#define MAX_TX_RING_SIZE (XLR_MAX_MACS * MAX_P2D_DESC_PER_PORT * sizeof(struct p2d_tx_desc)) + +struct rge_softc *dev_mac[XLR_MAX_MACS]; +static int dev_mac_xgs0; +static int dev_mac_gmac0; + +static int gmac_common_init_done; + + +static int rge_probe(device_t); +static int rge_attach(device_t); +static int rge_detach(device_t); +static int rge_suspend(device_t); +static int rge_resume(device_t); +static void rge_release_resources(struct rge_softc *); +static void rge_rx(struct rge_softc *, vm_paddr_t paddr, int); +static void rge_intr(void *); +static void rge_start_locked(struct ifnet *, int); +static void rge_start(struct ifnet *); +static int rge_ioctl(struct ifnet *, u_long, caddr_t); +static void rge_init(void *); +static void rge_stop(struct rge_softc *); +static void rge_watchdog(struct ifnet *); +static void rge_shutdown(device_t); +static void rge_reset(struct rge_softc *); + +static struct mbuf *get_mbuf(void); +static void free_buf(vm_paddr_t paddr); +static void *get_buf(void); + +static void xlr_mac_get_hwaddr(struct rge_softc *); +static void xlr_mac_setup_hwaddr(struct driver_data *); +static void rmi_xlr_mac_set_enable(struct driver_data *priv, int flag); +static void rmi_xlr_xgmac_init(struct driver_data *priv); +static void rmi_xlr_gmac_init(struct driver_data *priv); +static void mac_common_init(void); +static void rge_mii_write(struct device *, int, int, int); +static int rge_mii_read(struct device *, int, int); +static void rmi_xlr_mac_mii_statchg(device_t); +static int rmi_xlr_mac_mediachange(struct ifnet *); +static void rmi_xlr_mac_mediastatus(struct ifnet *, struct ifmediareq *); +static void xlr_mac_set_rx_mode(struct rge_softc *sc); +void +rmi_xlr_mac_msgring_handler(int bucket, int size, int code, + int stid, struct msgrng_msg *msg, + void *data); +static void mac_frin_replenish(void *); +static int rmi_xlr_mac_open(struct rge_softc *); +static int rmi_xlr_mac_close(struct rge_softc *); +static int +mac_xmit(struct mbuf *, struct rge_softc *, + struct driver_data *, int, struct p2d_tx_desc *); +static int rmi_xlr_mac_xmit(struct mbuf *, struct rge_softc *, int, struct p2d_tx_desc *); +static struct rge_softc_stats *rmi_xlr_mac_get_stats(struct rge_softc *sc); +static void rmi_xlr_mac_set_multicast_list(struct rge_softc *sc); +static int rmi_xlr_mac_change_mtu(struct rge_softc *sc, int new_mtu); +static int rmi_xlr_mac_fill_rxfr(struct rge_softc *sc); +static void rmi_xlr_config_spill_area(struct driver_data *priv); +static int rmi_xlr_mac_set_speed(struct driver_data *s, xlr_mac_speed_t speed); +static int +rmi_xlr_mac_set_duplex(struct driver_data *s, + xlr_mac_duplex_t duplex, xlr_mac_fc_t fc); +static void serdes_regs_init(struct driver_data *priv); +static int rmi_xlr_gmac_reset(struct driver_data *priv); + +/*Statistics...*/ +static int get_p2d_desc_failed = 0; +static int msg_snd_failed =0; + +SYSCTL_INT(_hw, OID_AUTO, get_p2d_failed, CTLFLAG_RW, + &get_p2d_desc_failed, 0, "p2d desc failed"); +SYSCTL_INT(_hw, OID_AUTO, msg_snd_failed, CTLFLAG_RW, + &msg_snd_failed, 0, "msg snd failed"); + +struct callout xlr_tx_stop_bkp; + +static device_method_t rge_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, rge_probe), + DEVMETHOD(device_attach, rge_attach), + DEVMETHOD(device_detach, rge_detach), + DEVMETHOD(device_shutdown, rge_shutdown), + DEVMETHOD(device_suspend, rge_suspend), + DEVMETHOD(device_resume, rge_resume), + + /* MII interface */ + DEVMETHOD(miibus_readreg, rge_mii_read), + DEVMETHOD(miibus_writereg, rge_mii_write), + DEVMETHOD(miibus_statchg, rmi_xlr_mac_mii_statchg), + {0, 0} +}; + +static driver_t rge_driver = { + "rge", + rge_methods, + sizeof(struct rge_softc) +}; + +static devclass_t rge_devclass; + +DRIVER_MODULE(rge, iodi, rge_driver, rge_devclass, 0, 0); +DRIVER_MODULE(miibus, rge, miibus_driver, miibus_devclass, 0, 0); + +#ifndef __STR +#define __STR(x) #x +#endif +#ifndef STR +#define STR(x) __STR(x) +#endif + +#define XKPHYS 0x8000000000000000 + +static __inline__ uint32_t +lw_40bit_phys(uint64_t phys, int cca) +{ + uint64_t addr; + uint32_t value = 0; + unsigned long flags; + + addr = XKPHYS | ((uint64_t)cca << 59) | (phys & 0xfffffffffcULL); + + enable_KX(flags); + __asm__ __volatile__( + ".set push\n" + ".set noreorder\n" + ".set mips64\n" + "lw %0, 0(%1) \n" + ".set pop\n" + : "=r" (value) + : "r" (addr) ); + + disable_KX(flags); + return value; +} + + +static __inline__ uint64_t +ld_40bit_phys(uint64_t phys, int cca) +{ + uint64_t addr; + uint64_t value = 0; + unsigned long flags; + + + addr = XKPHYS | ((uint64_t)cca << 59) | (phys & 0xfffffffffcULL); + enable_KX(flags); + __asm__ __volatile__( + ".set push\n" + ".set noreorder\n" + ".set mips64\n" + "ld %0, 0(%1) \n" + ".set pop\n" + : "=r" (value) + : "r" (addr)); + + disable_KX(flags); + return value; +} + + +void *xlr_tx_ring_mem; + +struct tx_desc_node { + struct p2d_tx_desc *ptr; + TAILQ_ENTRY (tx_desc_node) list; +}; +#define XLR_MAX_TX_DESC_NODES (XLR_MAX_MACS * MAX_P2D_DESC_PER_PORT) +struct tx_desc_node tx_desc_nodes[XLR_MAX_TX_DESC_NODES]; +static volatile int xlr_tot_avail_p2d[XLR_MAX_CORE]; +static int xlr_total_active_core = 0; + +/* + * This should contain the list of all free tx frag desc nodes pointing to tx + * p2d arrays + */ +static +TAILQ_HEAD(, tx_desc_node) tx_frag_desc[XLR_MAX_CORE] = + { + TAILQ_HEAD_INITIALIZER(tx_frag_desc[0]), + TAILQ_HEAD_INITIALIZER(tx_frag_desc[1]), + TAILQ_HEAD_INITIALIZER(tx_frag_desc[2]), + TAILQ_HEAD_INITIALIZER(tx_frag_desc[3]), + TAILQ_HEAD_INITIALIZER(tx_frag_desc[4]), + TAILQ_HEAD_INITIALIZER(tx_frag_desc[5]), + TAILQ_HEAD_INITIALIZER(tx_frag_desc[6]), + TAILQ_HEAD_INITIALIZER(tx_frag_desc[7]), + }; + +/* This contains a list of free tx frag node descriptors */ +static TAILQ_HEAD(, tx_desc_node) free_tx_frag_desc[XLR_MAX_CORE] = + { + TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[0]), + TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[1]), + TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[2]), + TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[3]), + TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[4]), + TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[5]), + TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[6]), + TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[7]), + }; + +static struct mtx tx_desc_lock[XLR_MAX_CORE]; + +static inline void +mac_make_desc_rfr(struct msgrng_msg *msg, + vm_paddr_t addr) +{ + msg->msg0 = (uint64_t) addr & 0xffffffffe0ULL; + msg->msg1 = msg->msg2 = msg->msg3 = 0; +} + +#define MAC_TX_DESC_ALIGNMENT (XLR_CACHELINE_SIZE - 1) + +static void +init_p2d_allocation(void) +{ + int active_core[8]= {0}; + int i=0; + uint32_t cpumask; + int cpu; + + cpumask = PCPU_GET(cpumask) | PCPU_GET(other_cpus); + + for (i = 0; i < 32; i++) { + if (cpumask & (1 << i)) { + cpu = cpu_ltop_map[i]; + if(!active_core[cpu/4]){ + active_core[cpu/4] = 1; + xlr_total_active_core++; + } + } + } + for(i=0; iptr = tx_desc; + tx_desc++; + TAILQ_INSERT_HEAD(&tx_frag_desc[j], node, list); + j = (i / (XLR_MAX_TX_DESC_NODES/xlr_total_active_core)); + } +} + +static inline struct p2d_tx_desc * +get_p2d_desc(void) +{ + struct tx_desc_node *node; + struct p2d_tx_desc *tx_desc = NULL; + int cpu = xlr_cpu_id(); + + mtx_lock_spin(&tx_desc_lock[cpu]); + node = TAILQ_FIRST(&tx_frag_desc[cpu]); + if (node) { + xlr_tot_avail_p2d[cpu]--; + TAILQ_REMOVE(&tx_frag_desc[cpu], node, list); + tx_desc = node->ptr; + TAILQ_INSERT_HEAD(&free_tx_frag_desc[cpu], node, list); + }else{ + /*Increment p2d desc fail count*/ + get_p2d_desc_failed++; + } + mtx_unlock_spin(&tx_desc_lock[cpu]); + return tx_desc; +} +static void +free_p2d_desc(struct p2d_tx_desc *tx_desc) +{ + struct tx_desc_node *node; + int cpu = xlr_cpu_id(); + + mtx_lock_spin(&tx_desc_lock[cpu]); + node = TAILQ_FIRST(&free_tx_frag_desc[cpu]); + KASSERT((node != NULL), ("Free TX frag node list is empty\n")); + + TAILQ_REMOVE(&free_tx_frag_desc[cpu], node, list); + node->ptr = tx_desc; + TAILQ_INSERT_HEAD(&tx_frag_desc[cpu], node, list); + xlr_tot_avail_p2d[cpu]++; + mtx_unlock_spin(&tx_desc_lock[cpu]); + +} + +static int +build_frag_list(struct mbuf *m_head, struct msgrng_msg *p2p_msg, struct p2d_tx_desc *tx_desc) +{ + struct mbuf *m; + vm_paddr_t paddr; + uint64_t p2d_len; + int nfrag; + vm_paddr_t p1 , p2; + uint32_t len1 , len2; + vm_offset_t taddr; + uint64_t fr_stid; + fr_stid = (xlr_cpu_id() << 3) + xlr_thr_id() + 4; + + if (tx_desc == NULL) + return 1; + + nfrag = 0; + for (m = m_head; m != NULL; m = m->m_next) { + if ((nfrag + 1) >= XLR_MAX_TX_FRAGS) { + free_p2d_desc(tx_desc); + return 1; + } + if (m->m_len != 0) { + paddr = vtophys(mtod(m, vm_offset_t)); + p1 = paddr + m->m_len; + p2 = vtophys(((vm_offset_t) m->m_data + m->m_len)); + if (p1 != p2) { + len1 = (uint32_t) + (PAGE_SIZE - (paddr & PAGE_MASK)); + tx_desc->frag[nfrag] = (127ULL << 54) | + ((uint64_t) len1 << 40) | paddr; + nfrag++; + taddr = (vm_offset_t) m->m_data + len1; + p2 = vtophys(taddr); + len2 = m->m_len - len1; + if (nfrag >= XLR_MAX_TX_FRAGS) + panic("TX frags exceeded"); + + tx_desc->frag[nfrag] = (127ULL << 54) | + ((uint64_t) len2 << 40) | p2; + + taddr += len2; + p1 = vtophys(taddr); + + if ((p2 + len2) != p1) { + printf("p1 = %llx p2 = %llx\n", p1, p2); + printf("len1 = %x len2 = %x\n", len1, + len2); + printf("m_data %p\n", m->m_data); + DELAY(1000000); + panic("Multiple Mbuf segment discontiguous\n"); + } + } else { + tx_desc->frag[nfrag] = (127ULL << 54) | + ((uint64_t) m->m_len << 40) | paddr; + } + nfrag++; + } + } + /* set eop in the last tx p2d desc */ + tx_desc->frag[nfrag - 1] |= (1ULL << 63); + paddr = vtophys((vm_offset_t) tx_desc); + tx_desc->frag[nfrag] = (1ULL << 63) | (fr_stid << 54) | paddr; + nfrag++; + tx_desc->frag[XLR_MAX_TX_FRAGS] = (uint64_t) (vm_offset_t) tx_desc; + tx_desc->frag[XLR_MAX_TX_FRAGS + 1] = (uint64_t) (vm_offset_t) m_head; + + p2d_len = (nfrag * 8); + p2p_msg->msg0 = (1ULL << 63) | (1ULL << 62) | (127ULL << 54) | + (p2d_len << 40) | paddr; + + return 0; +} +static void +release_tx_desc(struct msgrng_msg *msg, int rel_buf) +{ + vm_paddr_t paddr = msg->msg0 & 0xffffffffffULL; + uint64_t temp; + struct p2d_tx_desc *tx_desc; + struct mbuf *m; + + paddr += (XLR_MAX_TX_FRAGS * sizeof(uint64_t)); + + temp = ld_40bit_phys(paddr, 3); + + tx_desc = (struct p2d_tx_desc *)((vm_offset_t) temp); + + if (rel_buf) { + paddr += sizeof(uint64_t); + + temp = ld_40bit_phys(paddr, 3); + + m = (struct mbuf *)((vm_offset_t) temp); + m_freem(m); + } + + free_p2d_desc(tx_desc); +} + +#ifdef RX_COPY +#define RGE_MAX_NUM_DESC (6 * MAX_NUM_DESC) +uint8_t *rge_rx_buffers[RGE_MAX_NUM_DESC]; +static struct mtx rge_rx_mtx; +int g_rx_buf_head; + +static void +init_rx_buf(void) +{ + int i; + uint8_t *buf, *start; + uint32_t size , *ptr; + mtx_init(&rge_rx_mtx, "xlr rx_desc", NULL, MTX_SPIN); + + size = (RGE_MAX_NUM_DESC * (MAX_FRAME_SIZE + XLR_CACHELINE_SIZE)); + + start = (uint8_t *) contigmalloc(size, M_DEVBUF, M_NOWAIT | M_ZERO, + 0, 0xffffffff, XLR_CACHELINE_SIZE, 0); + if (start == NULL) + panic("NO RX BUFFERS"); + buf = start; + size = (MAX_FRAME_SIZE + XLR_CACHELINE_SIZE); + for (i = 0; i < RGE_MAX_NUM_DESC; i++) { + buf = start + (i * size); + ptr = (uint32_t *) buf; + *ptr = (uint32_t) buf; + rge_rx_buffers[i] = buf + XLR_CACHELINE_SIZE; + } +} + +static void * +get_rx_buf(void) +{ + void *ptr = NULL; + mtx_lock_spin(&rge_rx_mtx); + if (g_rx_buf_head < RGE_MAX_NUM_DESC) { + ptr = (void *)rge_rx_buffers[g_rx_buf_head]; + g_rx_buf_head++; + } + mtx_unlock_spin(&rge_rx_mtx); + return ptr; +} +#endif + +static struct mbuf * +get_mbuf(void) +{ + struct mbuf *m_new = NULL; + + if ((m_new = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR)) == NULL) + return NULL; + + m_new->m_len = MCLBYTES; + m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; + return m_new; +} + +static void +free_buf(vm_paddr_t paddr) +{ + struct mbuf *m; + vm_offset_t temp; + + temp = lw_40bit_phys((paddr - XLR_CACHELINE_SIZE), 3); + m = (struct mbuf *)temp; + if (m != NULL) + m_freem(m); +} + +static void * +get_buf(void) +{ +#ifdef RX_COPY + return get_rx_buf(); +#else + struct mbuf *m_new = NULL; +#ifdef INVARIANTS + vm_paddr_t temp1, temp2; +#endif + unsigned int *md; + + m_new = get_mbuf(); + + if (m_new == NULL) + return NULL; + + m_adj(m_new, XLR_CACHELINE_SIZE - ((unsigned int)m_new->m_data & 0x1f)); + md = (unsigned int *)m_new->m_data; + md[0] = (unsigned int)m_new; /* Back Ptr */ + md[1] = 0xf00bad; + m_adj(m_new, XLR_CACHELINE_SIZE); + + + /* return (void *)m_new; */ +#ifdef INVARIANTS + temp1 = vtophys((vm_offset_t) m_new->m_data); + temp2 = vtophys((vm_offset_t) m_new->m_data + 1536); + if ((temp1 + 1536) != temp2) + panic("ALLOCED BUFFER IS NOT CONTIGUOUS\n"); +#endif + return (void *)m_new->m_data; +#endif +} + +/********************************************************************** + **********************************************************************/ +static void +rmi_xlr_mac_set_enable(struct driver_data *priv, int flag) +{ + uint32_t regval; + int tx_threshold = 1518; + + if (flag) { + regval = xlr_read_reg(priv->mmio, R_TX_CONTROL); + regval |= (1 << O_TX_CONTROL__TxEnable) | + (tx_threshold << O_TX_CONTROL__TxThreshold); + + xlr_write_reg(priv->mmio, R_TX_CONTROL, regval); + + regval = xlr_read_reg(priv->mmio, R_RX_CONTROL); + regval |= 1 << O_RX_CONTROL__RxEnable; + if (priv->mode == XLR_PORT0_RGMII) + regval |= 1 << O_RX_CONTROL__RGMII; + xlr_write_reg(priv->mmio, R_RX_CONTROL, regval); + + regval = xlr_read_reg(priv->mmio, R_MAC_CONFIG_1); + regval |= (O_MAC_CONFIG_1__txen | O_MAC_CONFIG_1__rxen); + xlr_write_reg(priv->mmio, R_MAC_CONFIG_1, regval); + } else { + regval = xlr_read_reg(priv->mmio, R_TX_CONTROL); + regval &= ~((1 << O_TX_CONTROL__TxEnable) | + (tx_threshold << O_TX_CONTROL__TxThreshold)); + + xlr_write_reg(priv->mmio, R_TX_CONTROL, regval); + + regval = xlr_read_reg(priv->mmio, R_RX_CONTROL); + regval &= ~(1 << O_RX_CONTROL__RxEnable); + xlr_write_reg(priv->mmio, R_RX_CONTROL, regval); + + regval = xlr_read_reg(priv->mmio, R_MAC_CONFIG_1); + regval &= ~(O_MAC_CONFIG_1__txen | O_MAC_CONFIG_1__rxen); + xlr_write_reg(priv->mmio, R_MAC_CONFIG_1, regval); + } +} + +/********************************************************************** + **********************************************************************/ +static __inline__ int +xlr_mac_send_fr(struct driver_data *priv, + vm_paddr_t addr, int len) +{ + int stid = priv->rfrbucket; + struct msgrng_msg msg; + int vcpu = (xlr_cpu_id()<<2)+xlr_thr_id(); + + mac_make_desc_rfr(&msg, addr); + + /* Send the packet to MAC */ + dbg_msg("mac_%d: Sending free packet %llx to stid %d\n", + priv->instance, addr, stid); + if (priv->type == XLR_XGMAC) { + while (message_send(1, MSGRNG_CODE_XGMAC, stid, &msg)); + } else { + while (message_send(1, MSGRNG_CODE_MAC, stid, &msg)); + xlr_rge_repl_done[vcpu]++; + } + + return 0; +} + +/**************************************************************/ + +static void +xgmac_mdio_setup(volatile unsigned int *_mmio) +{ + int i; + uint32_t rd_data; + for (i = 0; i < 4; i++) { + rd_data = xmdio_read(_mmio, 1, 0x8000 + i); + rd_data = rd_data & 0xffffdfff; /* clear isolate bit */ + xmdio_write(_mmio, 1, 0x8000 + i, rd_data); + } +} + +/********************************************************************** + * Init MII interface + * + * Input parameters: + * s - priv structure + ********************************************************************* */ +#define PHY_STATUS_RETRIES 25000 + +static void +rmi_xlr_mac_mii_init(struct driver_data *priv) +{ + xlr_reg_t *mii_mmio = priv->mii_mmio; + + /* use the lowest clock divisor - divisor 28 */ + xlr_write_reg(mii_mmio, R_MII_MGMT_CONFIG, 0x07); +} + +/********************************************************************** + * Read a PHY register. + * + * Input parameters: + * s - priv structure + * phyaddr - PHY's address + * regidx = index of register to read + * + * Return value: + * value read, or 0 if an error occurred. + ********************************************************************* */ + +static int +rge_mii_read_internal(xlr_reg_t *mii_mmio, int phyaddr, int regidx) +{ + int i = 0; + + /* setup the phy reg to be used */ + xlr_write_reg(mii_mmio, R_MII_MGMT_ADDRESS, + (phyaddr << 8) | (regidx << 0)); + /* Issue the read command */ + xlr_write_reg(mii_mmio, R_MII_MGMT_COMMAND, + (1 << O_MII_MGMT_COMMAND__rstat)); + + /* poll for the read cycle to complete */ + for (i = 0; i < PHY_STATUS_RETRIES; i++) { + if (xlr_read_reg(mii_mmio, R_MII_MGMT_INDICATORS) == 0) + break; + } + + /* clear the read cycle */ + xlr_write_reg(mii_mmio, R_MII_MGMT_COMMAND, 0); + + if (i == PHY_STATUS_RETRIES) { + return 0xffffffff; + } + /* Read the data back */ + return xlr_read_reg(mii_mmio, R_MII_MGMT_STATUS); +} + +static int +rge_mii_read(struct device *dev, int phyaddr, int regidx) +{ + struct rge_softc *sc = device_get_softc(dev); + return rge_mii_read_internal(sc->priv.mii_mmio, phyaddr, regidx); +} + +/********************************************************************** + * Set MII hooks to newly selected media + * + * Input parameters: + * ifp - Interface Pointer + * + * Return value: + * nothing + ********************************************************************* */ +static int +rmi_xlr_mac_mediachange(struct ifnet *ifp) +{ + struct rge_softc *sc = ifp->if_softc; + + if (ifp->if_flags & IFF_UP) + mii_mediachg(&sc->rge_mii); + + return 0; +} + +/********************************************************************** + * Get the current interface media status + * + * Input parameters: + * ifp - Interface Pointer + * ifmr - Interface media request ptr + * + * Return value: + * nothing + ********************************************************************* */ +static void +rmi_xlr_mac_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) +{ + struct rge_softc *sc = ifp->if_softc; + + /*Check whether this is interface is active or not.*/ + ifmr->ifm_status = IFM_AVALID; + if(sc->link_up){ + ifmr->ifm_status |= IFM_ACTIVE; + }else{ + ifmr->ifm_active = IFM_ETHER; + } +} + +/********************************************************************** + * Write a value to a PHY register. + * + * Input parameters: + * s - priv structure + * phyaddr - PHY to use + * regidx - register within the PHY + * regval - data to write to register + * + * Return value: + * nothing + ********************************************************************* */ +static void +rge_mii_write_internal(xlr_reg_t *mii_mmio, int phyaddr, int regidx, int regval) +{ + int i = 0; + + xlr_write_reg(mii_mmio, R_MII_MGMT_ADDRESS, + (phyaddr << 8) | (regidx << 0)); + + /* Write the data which starts the write cycle */ + xlr_write_reg(mii_mmio, R_MII_MGMT_WRITE_DATA, regval); + + /* poll for the write cycle to complete */ + for (i = 0; i < PHY_STATUS_RETRIES; i++) { + if (xlr_read_reg(mii_mmio, R_MII_MGMT_INDICATORS) == 0) + break; + } + + return; +} + +static void +rge_mii_write(struct device *dev, int phyaddr, int regidx, int regval) +{ + struct rge_softc *sc = device_get_softc(dev); + + rge_mii_write_internal(sc->priv.mii_mmio, phyaddr, regidx, regval); +} + +static void +rmi_xlr_mac_mii_statchg(device_t dev) +{ +} + +static void +serdes_regs_init(struct driver_data *priv) +{ + xlr_reg_t *mmio_gpio = (xlr_reg_t *)(xlr_io_base + XLR_IO_GPIO_OFFSET); + int i; + + /* Initialize SERDES CONTROL Registers */ + rge_mii_write_internal(priv->serdes_mmio, 26, 0, 0x6DB0); + rge_mii_write_internal(priv->serdes_mmio, 26, 1, 0xFFFF); + rge_mii_write_internal(priv->serdes_mmio, 26, 2, 0xB6D0); + rge_mii_write_internal(priv->serdes_mmio, 26, 3, 0x00FF); + rge_mii_write_internal(priv->serdes_mmio, 26, 4, 0x0000); + rge_mii_write_internal(priv->serdes_mmio, 26, 5, 0x0000); + rge_mii_write_internal(priv->serdes_mmio, 26, 6, 0x0005); + rge_mii_write_internal(priv->serdes_mmio, 26, 7, 0x0001); + rge_mii_write_internal(priv->serdes_mmio, 26, 8, 0x0000); + rge_mii_write_internal(priv->serdes_mmio, 26, 9, 0x0000); + rge_mii_write_internal(priv->serdes_mmio, 26,10, 0x0000); + + /* + * For loop delay and GPIO programming crud from Linux driver, + */ + for(i=0;i<10000000;i++){} + mmio_gpio[0x20] = 0x7e6802; + mmio_gpio[0x10] = 0x7104; + for(i=0;i<100000000;i++){} + return; +} + +static void serdes_autoconfig(struct driver_data *priv) +{ + int delay = 100000; + + /* Enable Auto negotiation in the PCS Layer*/ + rge_mii_write_internal(priv->pcs_mmio, 27, 0, 0x1000); + DELAY(delay); + rge_mii_write_internal(priv->pcs_mmio, 27, 0, 0x0200); + DELAY(delay); + + rge_mii_write_internal(priv->pcs_mmio, 28, 0, 0x1000); + DELAY(delay); + rge_mii_write_internal(priv->pcs_mmio, 28, 0, 0x0200); + DELAY(delay); + + rge_mii_write_internal(priv->pcs_mmio, 29, 0, 0x1000); + DELAY(delay); + rge_mii_write_internal(priv->pcs_mmio, 29, 0, 0x0200); + DELAY(delay); + + rge_mii_write_internal(priv->pcs_mmio, 30, 0, 0x1000); + DELAY(delay); + rge_mii_write_internal(priv->pcs_mmio, 30, 0, 0x0200); + DELAY(delay); + +} + +/***************************************************************** + * Initialize GMAC + *****************************************************************/ +static void +rmi_xlr_config_pde(struct driver_data *priv) +{ + int i = 0, cpu = 0, bucket = 0; + uint64_t bucket_map = 0; + /* uint32_t desc_pack_ctrl = 0; */ + uint32_t cpumask; + + cpumask = PCPU_GET(cpumask) | PCPU_GET(other_cpus); + + for (i = 0; i < 32; i++) { + if (cpumask & (1 << i)) { + cpu = cpu_ltop_map[i]; + bucket = ((cpu >> 2) << 3);//| (cpu & 0x03); + bucket_map |= (1ULL << bucket); + dbg_msg("i=%d, cpu=%d, bucket = %d, bucket_map=%llx\n", + i, cpu, bucket, bucket_map); + } + } + + /* bucket_map = 0x1; */ + xlr_write_reg(priv->mmio, R_PDE_CLASS_0, (bucket_map & 0xffffffff)); + xlr_write_reg(priv->mmio, R_PDE_CLASS_0 + 1, + ((bucket_map >> 32) & 0xffffffff)); + + xlr_write_reg(priv->mmio, R_PDE_CLASS_1, (bucket_map & 0xffffffff)); + xlr_write_reg(priv->mmio, R_PDE_CLASS_1 + 1, + ((bucket_map >> 32) & 0xffffffff)); + + xlr_write_reg(priv->mmio, R_PDE_CLASS_2, (bucket_map & 0xffffffff)); + xlr_write_reg(priv->mmio, R_PDE_CLASS_2 + 1, + ((bucket_map >> 32) & 0xffffffff)); + + xlr_write_reg(priv->mmio, R_PDE_CLASS_3, (bucket_map & 0xffffffff)); + xlr_write_reg(priv->mmio, R_PDE_CLASS_3 + 1, + ((bucket_map >> 32) & 0xffffffff)); +} + +static void +rmi_xlr_config_parser(struct driver_data *priv) +{ + /* + * Mark it as no classification The parser extract is gauranteed to + * be zero with no classfication + */ + xlr_write_reg(priv->mmio, R_L2TYPE_0, 0x00); + + xlr_write_reg(priv->mmio, R_L2TYPE_0, 0x01); + + /* configure the parser : L2 Type is configured in the bootloader */ + /* extract IP: src, dest protocol */ + xlr_write_reg(priv->mmio, R_L3CTABLE, + (9 << 20) | (1 << 19) | (1 << 18) | (0x01 << 16) | + (0x0800 << 0)); + xlr_write_reg(priv->mmio, R_L3CTABLE + 1, + (12 << 25) | (4 << 21) | (16 << 14) | (4 << 10)); + +} + +static void +rmi_xlr_config_classifier(struct driver_data *priv) +{ + int i = 0; + + if (priv->type == XLR_XGMAC) { + /* xgmac translation table doesn't have sane values on reset */ + for (i = 0; i < 64; i++) + xlr_write_reg(priv->mmio, R_TRANSLATETABLE + i, 0x0); + + /* + * use upper 7 bits of the parser extract to index the + * translate table + */ + xlr_write_reg(priv->mmio, R_PARSERCONFIGREG, 0x0); + } +} + +enum { + SGMII_SPEED_10 = 0x00000000, + SGMII_SPEED_100 = 0x02000000, + SGMII_SPEED_1000 = 0x04000000, +}; + +static void +rmi_xlr_gmac_config_speed(struct driver_data *priv) +{ + int phy_addr = priv->phy_addr; + xlr_reg_t *mmio = priv->mmio; + struct rge_softc *sc = priv->sc; + + priv->speed = rge_mii_read_internal(priv->mii_mmio, phy_addr, 28); + priv->link = rge_mii_read_internal(priv->mii_mmio, phy_addr, 1) & 0x4; + priv->speed = (priv->speed >> 3) & 0x03; + + if (priv->speed == xlr_mac_speed_10) { + if (priv->mode != XLR_RGMII) + xlr_write_reg(mmio, R_INTERFACE_CONTROL, SGMII_SPEED_10); + xlr_write_reg(mmio, R_MAC_CONFIG_2, 0x7137); + xlr_write_reg(mmio, R_CORECONTROL, 0x02); + printf("%s: [10Mbps]\n", device_get_nameunit(sc->rge_dev)); + sc->rge_mii.mii_media.ifm_media = IFM_ETHER | IFM_AUTO | IFM_10_T | IFM_FDX; + sc->rge_mii.mii_media.ifm_cur->ifm_media = IFM_ETHER | IFM_AUTO | IFM_10_T | IFM_FDX; + sc->rge_mii.mii_media_active = IFM_ETHER | IFM_AUTO | IFM_10_T | IFM_FDX; + } else if (priv->speed == xlr_mac_speed_100) { + if (priv->mode != XLR_RGMII) + xlr_write_reg(mmio, R_INTERFACE_CONTROL, SGMII_SPEED_100); + xlr_write_reg(mmio, R_MAC_CONFIG_2, 0x7137); + xlr_write_reg(mmio, R_CORECONTROL, 0x01); + printf("%s: [100Mbps]\n", device_get_nameunit(sc->rge_dev)); + sc->rge_mii.mii_media.ifm_media = IFM_ETHER | IFM_AUTO | IFM_100_TX | IFM_FDX; + sc->rge_mii.mii_media.ifm_cur->ifm_media = IFM_ETHER | IFM_AUTO | IFM_100_TX | IFM_FDX; + sc->rge_mii.mii_media_active = IFM_ETHER | IFM_AUTO | IFM_100_TX | IFM_FDX; + } else { + if (priv->speed != xlr_mac_speed_1000) { + if (priv->mode != XLR_RGMII) + xlr_write_reg(mmio, R_INTERFACE_CONTROL, SGMII_SPEED_100); + printf("PHY reported unknown MAC speed, defaulting to 100Mbps\n"); + xlr_write_reg(mmio, R_MAC_CONFIG_2, 0x7137); + xlr_write_reg(mmio, R_CORECONTROL, 0x01); + sc->rge_mii.mii_media.ifm_media = IFM_ETHER | IFM_AUTO | IFM_100_TX | IFM_FDX; + sc->rge_mii.mii_media.ifm_cur->ifm_media = IFM_ETHER | IFM_AUTO | IFM_100_TX | IFM_FDX; + sc->rge_mii.mii_media_active = IFM_ETHER | IFM_AUTO | IFM_100_TX | IFM_FDX; + } else { + if (priv->mode != XLR_RGMII) + xlr_write_reg(mmio, R_INTERFACE_CONTROL, SGMII_SPEED_1000); + xlr_write_reg(mmio, R_MAC_CONFIG_2, 0x7237); + xlr_write_reg(mmio, R_CORECONTROL, 0x00); + printf("%s: [1000Mbps]\n", device_get_nameunit(sc->rge_dev)); + sc->rge_mii.mii_media.ifm_media = IFM_ETHER | IFM_AUTO | IFM_1000_T | IFM_FDX; + sc->rge_mii.mii_media.ifm_cur->ifm_media = IFM_ETHER | IFM_AUTO | IFM_1000_T | IFM_FDX; + sc->rge_mii.mii_media_active = IFM_ETHER | IFM_AUTO | IFM_1000_T | IFM_FDX; + } + } + + if (!priv->link) { + sc->rge_mii.mii_media.ifm_cur->ifm_media = IFM_ETHER; + sc->link_up = 0; + } else { + sc->link_up = 1; + } +} + +/***************************************************************** + * Initialize XGMAC + *****************************************************************/ +static void +rmi_xlr_xgmac_init(struct driver_data *priv) +{ + int i = 0; + xlr_reg_t *mmio = priv->mmio; + int id = priv->instance; + struct rge_softc *sc = priv->sc; + volatile unsigned short *cpld; + + cpld = (volatile unsigned short *)0xBD840000; + + xlr_write_reg(priv->mmio, R_DESC_PACK_CTRL, + (MAX_FRAME_SIZE << O_DESC_PACK_CTRL__RegularSize) | (4 << 20)); + xlr_write_reg(priv->mmio, R_BYTEOFFSET0, BYTE_OFFSET); + rmi_xlr_config_pde(priv); + rmi_xlr_config_parser(priv); + rmi_xlr_config_classifier(priv); + + xlr_write_reg(priv->mmio, R_MSG_TX_THRESHOLD, 1); + + /* configure the XGMAC Registers */ + xlr_write_reg(mmio, R_XGMAC_CONFIG_1, 0x50000026); + + /* configure the XGMAC_GLUE Registers */ + xlr_write_reg(mmio, R_DMACR0, 0xffffffff); + xlr_write_reg(mmio, R_DMACR1, 0xffffffff); + xlr_write_reg(mmio, R_DMACR2, 0xffffffff); + xlr_write_reg(mmio, R_DMACR3, 0xffffffff); + xlr_write_reg(mmio, R_STATCTRL, 0x04); + xlr_write_reg(mmio, R_L2ALLOCCTRL, 0xffffffff); + + xlr_write_reg(mmio, R_XGMACPADCALIBRATION, 0x030); + xlr_write_reg(mmio, R_EGRESSFIFOCARVINGSLOTS, 0x0f); + xlr_write_reg(mmio, R_L2ALLOCCTRL, 0xffffffff); + xlr_write_reg(mmio, R_XGMAC_MIIM_CONFIG, 0x3e); + + /* + * take XGMII phy out of reset + */ + /* + * we are pulling everything out of reset because writing a 0 would + * reset other devices on the chip + */ + cpld[ATX_CPLD_RESET_1] = 0xffff; + cpld[ATX_CPLD_MISC_CTRL] = 0xffff; + cpld[ATX_CPLD_RESET_2] = 0xffff; + + xgmac_mdio_setup(mmio); + + rmi_xlr_config_spill_area(priv); + + if (id == 0) { + for (i = 0; i < 16; i++) { + xlr_write_reg(mmio, R_XGS_TX0_BUCKET_SIZE + i, + bucket_sizes. + bucket[MSGRNG_STNID_XGS0_TX + i]); + } + + xlr_write_reg(mmio, R_XGS_JFR_BUCKET_SIZE, + bucket_sizes.bucket[MSGRNG_STNID_XMAC0JFR]); + xlr_write_reg(mmio, R_XGS_RFR_BUCKET_SIZE, + bucket_sizes.bucket[MSGRNG_STNID_XMAC0RFR]); + + for (i = 0; i < MAX_NUM_MSGRNG_STN_CC; i++) { + xlr_write_reg(mmio, R_CC_CPU0_0 + i, + cc_table_xgs_0. + counters[i >> 3][i & 0x07]); + } + } else if (id == 1) { + for (i = 0; i < 16; i++) { + xlr_write_reg(mmio, R_XGS_TX0_BUCKET_SIZE + i, + bucket_sizes. + bucket[MSGRNG_STNID_XGS1_TX + i]); + } + + xlr_write_reg(mmio, R_XGS_JFR_BUCKET_SIZE, + bucket_sizes.bucket[MSGRNG_STNID_XMAC1JFR]); + xlr_write_reg(mmio, R_XGS_RFR_BUCKET_SIZE, + bucket_sizes.bucket[MSGRNG_STNID_XMAC1RFR]); + + for (i = 0; i < MAX_NUM_MSGRNG_STN_CC; i++) { + xlr_write_reg(mmio, R_CC_CPU0_0 + i, + cc_table_xgs_1. + counters[i >> 3][i & 0x07]); + } + } + sc->rge_mii.mii_media.ifm_media = IFM_ETHER | IFM_AUTO | IFM_10G_SR | IFM_FDX; + sc->rge_mii.mii_media.ifm_media |= (IFM_AVALID | IFM_ACTIVE); + sc->rge_mii.mii_media.ifm_cur->ifm_media = IFM_ETHER | IFM_AUTO | IFM_10G_SR | IFM_FDX; + sc->rge_mii.mii_media_active = IFM_ETHER | IFM_AUTO | IFM_10G_SR | IFM_FDX; + sc->rge_mii.mii_media.ifm_cur->ifm_media |= (IFM_AVALID | IFM_ACTIVE); + + priv->init_frin_desc = 1; +} + +/******************************************************* + * Initialization gmac + *******************************************************/ +static int +rmi_xlr_gmac_reset(struct driver_data *priv) +{ + volatile uint32_t val; + xlr_reg_t *mmio = priv->mmio; + int i, maxloops = 100; + + /* Disable MAC RX */ + val = xlr_read_reg(mmio, R_MAC_CONFIG_1); + val &= ~0x4; + xlr_write_reg(mmio, R_MAC_CONFIG_1, val); + + /* Disable Core RX */ + val = xlr_read_reg(mmio, R_RX_CONTROL); + val &= ~0x1; + xlr_write_reg(mmio, R_RX_CONTROL, val); + + /* wait for rx to halt */ + for (i=0; immio; + int id = priv->instance; + struct stn_cc *gmac_cc_config; + uint32_t value = 0; + int blk = id/4, port = id % 4; + + rmi_xlr_mac_set_enable(priv, 0); + + rmi_xlr_config_spill_area(priv); + + xlr_write_reg(mmio, R_DESC_PACK_CTRL, + (BYTE_OFFSET << O_DESC_PACK_CTRL__ByteOffset) | + (1 << O_DESC_PACK_CTRL__MaxEntry) | + (MAX_FRAME_SIZE << O_DESC_PACK_CTRL__RegularSize)); + + rmi_xlr_config_pde(priv); + rmi_xlr_config_parser(priv); + rmi_xlr_config_classifier(priv); + + xlr_write_reg(mmio, R_MSG_TX_THRESHOLD, 3); + xlr_write_reg(mmio, R_MAC_CONFIG_1, 0x35); + xlr_write_reg(mmio, R_RX_CONTROL, (0x7<<6)); + + if(priv->mode == XLR_PORT0_RGMII) { + printf("Port 0 set in RGMII mode\n"); + value = xlr_read_reg(mmio, R_RX_CONTROL); + value |= 1 << O_RX_CONTROL__RGMII; + xlr_write_reg(mmio, R_RX_CONTROL, value); + } + + rmi_xlr_mac_mii_init(priv); + + +#if 0 + priv->advertising = ADVERTISED_10baseT_Full | ADVERTISED_10baseT_Half | + ADVERTISED_100baseT_Full | ADVERTISED_100baseT_Half | + ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg | + ADVERTISED_MII; +#endif + + /* + * Enable all MDIO interrupts in the phy RX_ER bit seems to be get + * set about every 1 sec in GigE mode, ignore it for now... + */ + rge_mii_write_internal(priv->mii_mmio, priv->phy_addr, 25, 0xfffffffe); + + if (priv->mode != XLR_RGMII){ + serdes_regs_init(priv); + serdes_autoconfig(priv); + } + + rmi_xlr_gmac_config_speed(priv); + + value = xlr_read_reg(mmio, R_IPG_IFG); + xlr_write_reg(mmio, R_IPG_IFG, ((value & ~0x7f) | MAC_B2B_IPG)); + xlr_write_reg(mmio, R_DMACR0, 0xffffffff); + xlr_write_reg(mmio, R_DMACR1, 0xffffffff); + xlr_write_reg(mmio, R_DMACR2, 0xffffffff); + xlr_write_reg(mmio, R_DMACR3, 0xffffffff); + xlr_write_reg(mmio, R_STATCTRL, 0x04); + xlr_write_reg(mmio, R_L2ALLOCCTRL, 0xffffffff); + xlr_write_reg(mmio, R_INTMASK, 0); + xlr_write_reg(mmio, R_FREEQCARVE, 0); + + xlr_write_reg(mmio, R_GMAC_TX0_BUCKET_SIZE + port, + xlr_board_info.bucket_sizes->bucket[priv->txbucket]); + xlr_write_reg(mmio, R_GMAC_JFR0_BUCKET_SIZE, + xlr_board_info.bucket_sizes->bucket[MSGRNG_STNID_GMACJFR_0]); + xlr_write_reg(mmio, R_GMAC_RFR0_BUCKET_SIZE, + xlr_board_info.bucket_sizes->bucket[MSGRNG_STNID_GMACRFR_0]); + xlr_write_reg(mmio, R_GMAC_JFR1_BUCKET_SIZE, + xlr_board_info.bucket_sizes->bucket[MSGRNG_STNID_GMACJFR_1]); + xlr_write_reg(mmio, R_GMAC_RFR1_BUCKET_SIZE, + xlr_board_info.bucket_sizes->bucket[MSGRNG_STNID_GMACRFR_1]); + + dbg_msg("Programming credit counter %d : %d -> %d\n", blk, R_GMAC_TX0_BUCKET_SIZE + port, + xlr_board_info.bucket_sizes->bucket[priv->txbucket]); + + gmac_cc_config = xlr_board_info.gmac_block[blk].credit_config; + for (i = 0; i < MAX_NUM_MSGRNG_STN_CC; i++) { + xlr_write_reg(mmio, R_CC_CPU0_0 + i, + gmac_cc_config->counters[i >> 3][i & 0x07]); + dbg_msg("%d: %d -> %d\n", priv->instance, + R_CC_CPU0_0 + i, gmac_cc_config->counters[i >> 3][i & 0x07]); + } + priv->init_frin_desc = 1; +} + +/********************************************************************** + * Set promiscuous mode + **********************************************************************/ +static void +xlr_mac_set_rx_mode(struct rge_softc *sc) +{ + struct driver_data *priv = &(sc->priv); + uint32_t regval; + + regval = xlr_read_reg(priv->mmio, R_MAC_FILTER_CONFIG); + + if (sc->flags & IFF_PROMISC) { + regval |= (1 << O_MAC_FILTER_CONFIG__BROADCAST_EN) | + (1 << O_MAC_FILTER_CONFIG__PAUSE_FRAME_EN) | + (1 << O_MAC_FILTER_CONFIG__ALL_MCAST_EN) | + (1 << O_MAC_FILTER_CONFIG__ALL_UCAST_EN); + } else { + regval &= ~((1 << O_MAC_FILTER_CONFIG__PAUSE_FRAME_EN) | + (1 << O_MAC_FILTER_CONFIG__ALL_UCAST_EN)); + } + + xlr_write_reg(priv->mmio, R_MAC_FILTER_CONFIG, regval); +} + +/********************************************************************** + * Configure LAN speed for the specified MAC. + ********************************************************************* */ +static int +rmi_xlr_mac_set_speed(struct driver_data *s, xlr_mac_speed_t speed) +{ + return 0; +} + +/********************************************************************** + * Set Ethernet duplex and flow control options for this MAC + ********************************************************************* */ +static int +rmi_xlr_mac_set_duplex(struct driver_data *s, + xlr_mac_duplex_t duplex, xlr_mac_fc_t fc) +{ + return 0; +} + +/***************************************************************** + * Kernel Net Stack <-> MAC Driver Interface + *****************************************************************/ +/********************************************************************** + **********************************************************************/ +#define MAC_TX_FAIL 2 +#define MAC_TX_PASS 0 +#define MAC_TX_RETRY 1 + +static __inline__ void +message_send_block(unsigned int size, unsigned int code, + unsigned int stid, struct msgrng_msg *msg) +{ + unsigned int dest = 0; + unsigned long long status = 0; + + msgrng_load_tx_msg0(msg->msg0); + msgrng_load_tx_msg1(msg->msg1); + msgrng_load_tx_msg2(msg->msg2); + msgrng_load_tx_msg3(msg->msg3); + + dest = ((size - 1) << 16) | (code << 8) | (stid); + + do { + msgrng_send(dest); + status = msgrng_read_status(); + } while (status & 0x6); + +} + +int xlr_dev_queue_xmit_hack = 0; + +static int +mac_xmit(struct mbuf *m, struct rge_softc *sc, + struct driver_data *priv, int len, struct p2d_tx_desc *tx_desc) +{ + struct msgrng_msg msg; + int stid = priv->txbucket; + uint32_t tx_cycles = 0; + unsigned long mflags = 0; + int vcpu = PCPU_GET(cpuid); + int rv; + + tx_cycles = mips_rd_count(); + + if (build_frag_list(m, &msg, tx_desc) != 0) + return MAC_TX_FAIL; + + else { + msgrng_access_enable(mflags); + if ((rv = message_send_retry(1, MSGRNG_CODE_MAC, stid, &msg)) != 0) { + msg_snd_failed++; + msgrng_access_disable(mflags); + release_tx_desc(&msg, 0); + xlr_rge_msg_snd_failed[vcpu]++; + dbg_msg("Failed packet to cpu %d, rv = %d, stid %d, msg0=%llx\n", + vcpu, rv, stid, msg.msg0); + return MAC_TX_FAIL; + } + msgrng_access_disable(mflags); + port_inc_counter(priv->instance, PORT_TX); + } + + /* Send the packet to MAC */ + dbg_msg("Sent tx packet to stid %d, msg0=%llx, msg1=%llx \n", stid, msg.msg0, msg.msg1); +#ifdef DUMP_PACKETS + { + int i = 0; + unsigned char *buf = (char *)m->m_data; + printf("Tx Packet: length=%d\n", len); + for (i = 0; i < 64; i++) { + if (i && (i % 16) == 0) + printf("\n"); + printf("%02x ", buf[i]); + } + printf("\n"); + } +#endif + xlr_inc_counter(NETIF_TX); + return MAC_TX_PASS; +} + +static int +rmi_xlr_mac_xmit(struct mbuf *m, struct rge_softc *sc, int len, struct p2d_tx_desc *tx_desc) +{ + struct driver_data *priv = &(sc->priv); + int ret = -ENOSPC; + + dbg_msg("IN\n"); + + xlr_inc_counter(NETIF_STACK_TX); + +retry: + ret = mac_xmit(m, sc, priv, len, tx_desc); + + if (ret == MAC_TX_RETRY) + goto retry; + + dbg_msg("OUT, ret = %d\n", ret); + if (ret == MAC_TX_FAIL) { + /* FULL */ + dbg_msg("Msg Ring Full. Stopping upper layer Q\n"); + port_inc_counter(priv->instance, PORT_STOPQ); + } + return ret; +} + +static void +mac_frin_replenish(void *args /* ignored */ ) +{ +#ifdef RX_COPY + return; +#else + int cpu = xlr_cpu_id(); + int done = 0; + int i = 0; + + xlr_inc_counter(REPLENISH_ENTER); + /* + * xlr_set_counter(REPLENISH_ENTER_COUNT, + * atomic_read(frin_to_be_sent)); + */ + xlr_set_counter(REPLENISH_CPU, PCPU_GET(cpuid)); + + for (;;) { + + done = 0; + + for (i = 0; i < XLR_MAX_MACS; i++) { + /* int offset = 0; */ + unsigned long msgrng_flags; + void *m; + uint32_t cycles; + struct rge_softc *sc; + struct driver_data *priv; + int frin_to_be_sent; + + sc = dev_mac[i]; + if (!sc) + goto skip; + + priv = &(sc->priv); + frin_to_be_sent = priv->frin_to_be_sent[cpu]; + + /* if (atomic_read(frin_to_be_sent) < 0) */ + if (frin_to_be_sent < 0) { + panic ("BUG?: [%s]: gmac_%d illegal value for frin_to_be_sent=%d\n", + __FUNCTION__, i, + frin_to_be_sent); + } + /* if (!atomic_read(frin_to_be_sent)) */ + if (!frin_to_be_sent) + goto skip; + + cycles = mips_rd_count(); + { + m = get_buf(); + if (!m) { + device_printf(sc->rge_dev, "No buffer\n"); + goto skip; + } + } + xlr_inc_counter(REPLENISH_FRIN); + msgrng_access_enable(msgrng_flags); + if (xlr_mac_send_fr(priv, vtophys(m), MAX_FRAME_SIZE)) { + free_buf(vtophys(m)); + printf("[%s]: rx free message_send failed!\n", __FUNCTION__); + msgrng_access_disable(msgrng_flags); + break; + } + msgrng_access_disable(msgrng_flags); + xlr_set_counter(REPLENISH_CYCLES, + (read_c0_count() - cycles)); + atomic_subtract_int((&priv->frin_to_be_sent[cpu]), 1); + + continue; + skip: + done++; + } + if (done == XLR_MAX_MACS) + break; + } +#endif +} + +static volatile uint32_t g_tx_frm_tx_ok; + +static void +rge_tx_bkp_func(void *arg, int npending) +{ + int i=0; + for(i=0; iactive) + continue; + rge_start_locked(dev_mac[i]->rge_ifp, RGE_TX_THRESHOLD); + } + atomic_subtract_int(&g_tx_frm_tx_ok, 1); +} + +/* This function is called from an interrupt handler */ +void +rmi_xlr_mac_msgring_handler(int bucket, int size, int code, + int stid, struct msgrng_msg *msg, + void *data /* ignored */ ) +{ + uint64_t phys_addr = 0; + unsigned long addr = 0; + uint32_t length = 0; + int ctrl = 0, port = 0; + struct rge_softc *sc = NULL; + struct driver_data *priv = 0; + struct ifnet *ifp; + int cpu = xlr_cpu_id(); + int vcpu=(cpu<<2)+xlr_thr_id(); + + dbg_msg("mac: bucket=%d, size=%d, code=%d, stid=%d, msg0=%llx msg1=%llx\n", + bucket, size, code, stid, msg->msg0, msg->msg1); + + phys_addr = (uint64_t) (msg->msg0 & 0xffffffffe0ULL); + length = (msg->msg0 >> 40) & 0x3fff; + if (length == 0) { + ctrl = CTRL_REG_FREE; + port = (msg->msg0 >> 54) & 0x0f; + addr = 0; + } else { + ctrl = CTRL_SNGL; + length = length - BYTE_OFFSET - MAC_CRC_LEN; + port = msg->msg0 & 0x0f; + addr = 0; + } + + if (xlr_board_info.is_xls) { + if (stid == MSGRNG_STNID_GMAC1) + port += 4; + sc = dev_mac[dev_mac_gmac0 + port]; + } else { + if (stid == MSGRNG_STNID_XGS0FR) + sc = dev_mac[dev_mac_xgs0]; + else if (stid == MSGRNG_STNID_XGS1FR) + sc = dev_mac[dev_mac_xgs0 + 1]; + else + sc = dev_mac[dev_mac_gmac0 + port]; + } + if (sc == NULL) + return; + priv = &(sc->priv); + + dbg_msg("msg0 = %llx, stid = %d, port = %d, addr=%lx, length=%d, ctrl=%d\n", + msg->msg0, stid, port, addr, length, ctrl); + + if (ctrl == CTRL_REG_FREE || ctrl == CTRL_JUMBO_FREE) { + xlr_rge_tx_ok_done[vcpu]++; + release_tx_desc(msg, 1); + ifp = sc->rge_ifp; + if (ifp->if_drv_flags & IFF_DRV_OACTIVE){ + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + } + if(atomic_cmpset_int(&g_tx_frm_tx_ok, 0,1)) + rge_tx_bkp_func(NULL,0); + xlr_set_counter(NETIF_TX_COMPLETE_CYCLES, + (read_c0_count() - msgrng_msg_cycles)); + } else if (ctrl == CTRL_SNGL || ctrl == CTRL_START) { + /* Rx Packet */ + /* struct mbuf *m = 0; */ + /* int logical_cpu = 0; */ + + dbg_msg("Received packet, port = %d\n", port); + + /* + * if num frins to be sent exceeds threshold, wake up the + * helper thread + */ + atomic_add_int(&(priv->frin_to_be_sent[cpu]), 1); + if ((priv->frin_to_be_sent[cpu]) > MAC_FRIN_TO_BE_SENT_THRESHOLD) { + mac_frin_replenish(NULL); + } + + dbg_msg("gmac_%d: rx packet: phys_addr = %llx, length = %x\n", + priv->instance, phys_addr, length); + + mac_stats_add(priv->stats.rx_packets, 1); + mac_stats_add(priv->stats.rx_bytes, length); + xlr_inc_counter(NETIF_RX); + xlr_set_counter(NETIF_RX_CYCLES, + (read_c0_count() - msgrng_msg_cycles)); + rge_rx(sc, phys_addr, length); + xlr_rge_rx_done[vcpu]++; + } else { + printf("[%s]: unrecognized ctrl=%d!\n", __FUNCTION__, ctrl); + } + +} + +/********************************************************************** + **********************************************************************/ +static int +rge_probe(dev) + device_t dev; +{ + /* Always return 0 */ + return 0; +} + +volatile unsigned long xlr_debug_enabled; +struct callout rge_dbg_count; +static void xlr_debug_count(void *addr) +{ + struct driver_data *priv = &dev_mac[0]->priv; + /*uint32_t crdt;*/ + if(xlr_debug_enabled){ + printf("\nAvailRxIn %#x\n",xlr_read_reg(priv->mmio,0x23e)); + } + callout_reset(&rge_dbg_count, hz, xlr_debug_count, NULL); +} + + +static void xlr_tx_q_wakeup(void *addr) +{ + int i=0; + int j=0; + for(i=0; iactive) + continue; + if((dev_mac[i]->rge_ifp->if_drv_flags) & IFF_DRV_OACTIVE){ + for(j=0; jrge_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + break; + } + } + } + } + callout_reset(&xlr_tx_stop_bkp, 5*hz, xlr_tx_q_wakeup, NULL); +} + +static int +rge_attach(dev) + device_t dev; +{ + struct ifnet *ifp; + struct rge_softc *sc; + struct driver_data *priv = 0; + int ret = 0; + struct xlr_gmac_block_t *gmac_conf = device_get_ivars(dev); + + sc = device_get_softc(dev); + sc->rge_dev = dev; + + /* Initialize mac's */ + sc->unit = device_get_unit(dev); + + if (sc->unit > XLR_MAX_MACS) { + ret = ENXIO; + goto out; + } + RGE_LOCK_INIT(sc, device_get_nameunit(dev)); + + priv = &(sc->priv); + priv->sc = sc; + + sc->flags = 0; /* TODO : fix me up later */ + + priv->id = sc->unit; + if (gmac_conf->type == XLR_GMAC) { + priv->instance = priv->id; + priv->mmio = (xlr_reg_t *)(xlr_io_base + gmac_conf->baseaddr + + 0x1000 * (sc->unit % 4)); + if ((ret = rmi_xlr_gmac_reset(priv)) == -1) + goto out; + } else if (gmac_conf->type == XLR_XGMAC) { + priv->instance = priv->id - xlr_board_info.gmacports; + priv->mmio = (xlr_reg_t *) (xlr_io_base + gmac_conf->baseaddr); + } + + if (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_VI) { + dbg_msg("Arizona board - offset 4 \n"); + priv->mii_mmio = (xlr_reg_t *)(xlr_io_base + XLR_IO_GMAC_4_OFFSET); + } else + priv->mii_mmio = (xlr_reg_t *)(xlr_io_base + XLR_IO_GMAC_0_OFFSET); + + priv->pcs_mmio = (xlr_reg_t *)(xlr_io_base + gmac_conf->baseaddr); + priv->serdes_mmio = (xlr_reg_t *)(xlr_io_base + XLR_IO_GMAC_0_OFFSET); + + sc->base_addr = (unsigned long) priv->mmio; + sc->mem_end = (unsigned long) priv->mmio + XLR_IO_SIZE - 1; + + sc->xmit = rge_start; + sc->stop = rge_stop; + sc->get_stats = rmi_xlr_mac_get_stats; + sc->ioctl = rge_ioctl; + + /* Initialize the device specific driver data */ + mtx_init(&priv->lock, "rge", NULL, MTX_SPIN); + + priv->type = gmac_conf->type; + + priv->mode = gmac_conf->mode; + if (xlr_board_info.is_xls == 0) { + if (xlr_board_atx_ii() && !xlr_board_atx_ii_b()) + priv->phy_addr = priv->instance - 2; + else + priv->phy_addr = priv->instance; + priv->mode = XLR_RGMII; + } else { + if (gmac_conf->mode == XLR_PORT0_RGMII && + priv->instance == 0) { + priv->mode = XLR_PORT0_RGMII; + priv->phy_addr = 0; + } else { + priv->mode = XLR_SGMII; + priv->phy_addr = priv->instance + 16; + } + } + + priv->txbucket = gmac_conf->station_txbase + priv->instance % 4; + priv->rfrbucket = gmac_conf->station_rfr; + priv->spill_configured = 0; + + dbg_msg("priv->mmio=%p\n", priv->mmio); + + /* Set up ifnet structure */ + ifp = sc->rge_ifp = if_alloc(IFT_ETHER); + if (ifp == NULL) { + device_printf(sc->rge_dev, "failed to if_alloc()\n"); + rge_release_resources(sc); + ret = ENXIO; + RGE_LOCK_DESTROY(sc); + goto out; + } + ifp->if_softc = sc; + if_initname(ifp, device_get_name(dev), device_get_unit(dev)); + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_ioctl = rge_ioctl; + ifp->if_start = rge_start; + ifp->if_watchdog = rge_watchdog; + ifp->if_init = rge_init; + ifp->if_mtu = ETHERMTU; + ifp->if_snd.ifq_drv_maxlen = RGE_TX_Q_SIZE; + IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen); + IFQ_SET_READY(&ifp->if_snd); + sc->active = 1; + ifp->if_hwassist = 0; + ifp->if_capabilities = IFCAP_TXCSUM | IFCAP_VLAN_HWTAGGING; + ifp->if_capenable = ifp->if_capabilities; + + /* Initialize the rge_softc */ + sc->irq = gmac_conf->baseirq + priv->instance % 4; + sc->rge_irq.r_flags = (u_int) sc->irq; /* We will use r_flags for + * storing irq which + * iodi_setup_intr can check */ + + ret = bus_setup_intr(dev, &sc->rge_irq, INTR_FAST | INTR_TYPE_NET | INTR_MPSAFE, + rge_intr, sc, &sc->rge_intrhand); + + if (ret) { + rge_detach(dev); + device_printf(sc->rge_dev, "couldn't set up irq\n"); + RGE_LOCK_DESTROY(sc); + goto out; + } + xlr_mac_get_hwaddr(sc); + xlr_mac_setup_hwaddr(priv); + + dbg_msg("MMIO %08lx, MII %08lx, PCS %08lx, base %08lx PHY %d IRQ %d\n", + (u_long) priv->mmio, (u_long) priv->mii_mmio, (u_long) priv->pcs_mmio, + (u_long) sc->base_addr, priv->phy_addr, sc->irq); + dbg_msg("HWADDR %02x:%02x tx %d rfr %d\n", (u_int)sc->dev_addr[4], + (u_int)sc->dev_addr[5], priv->txbucket, priv->rfrbucket); + + /* + * Set up ifmedia support. + */ + /* + * Initialize MII/media info. + */ + sc->rge_mii.mii_ifp = ifp; + sc->rge_mii.mii_readreg = rge_mii_read; + sc->rge_mii.mii_writereg = rge_mii_write; + sc->rge_mii.mii_statchg = rmi_xlr_mac_mii_statchg; + ifmedia_init(&sc->rge_mii.mii_media, 0, rmi_xlr_mac_mediachange, + rmi_xlr_mac_mediastatus); + ifmedia_add(&sc->rge_mii.mii_media, IFM_ETHER | IFM_AUTO, 0, NULL); + ifmedia_set(&sc->rge_mii.mii_media, IFM_ETHER | IFM_AUTO); + sc->rge_mii.mii_media.ifm_media = sc->rge_mii.mii_media.ifm_cur->ifm_media; + + /* + * Call MI attach routine. + */ + ether_ifattach(ifp, sc->dev_addr); + + if (priv->type == XLR_GMAC) { + rmi_xlr_gmac_init(priv); + } else if (priv->type == XLR_XGMAC) { + rmi_xlr_xgmac_init(priv); + } + dbg_msg("rge_%d: Phoenix Mac at 0x%p (mtu=%d)\n", + sc->unit, priv->mmio, sc->mtu); + dev_mac[sc->unit] = sc; + if (priv->type == XLR_XGMAC && priv->instance == 0) + dev_mac_xgs0 = sc->unit; + if (priv->type == XLR_GMAC && priv->instance == 0) + dev_mac_gmac0 = sc->unit; + + if (!gmac_common_init_done){ + mac_common_init(); + gmac_common_init_done = 1; + callout_init(&xlr_tx_stop_bkp, CALLOUT_MPSAFE); + callout_reset(&xlr_tx_stop_bkp, hz, xlr_tx_q_wakeup, NULL); + callout_init(&rge_dbg_count, CALLOUT_MPSAFE); +// callout_reset(&rge_dbg_count, hz, xlr_debug_count, NULL); + } + if ((ret = rmi_xlr_mac_open(sc)) == -1) { + RGE_LOCK_DESTROY(sc); + goto out; + } + +out: + if (ret < 0) { + device_printf(dev, "error - skipping\n"); + } + return ret; +} + +static void +rge_reset(struct rge_softc *sc) +{ +} + +static int +rge_detach(dev) + device_t dev; +{ +#ifdef FREEBSD_MAC_NOT_YET + struct rge_softc *sc; + struct ifnet *ifp; + + sc = device_get_softc(dev); + ifp = sc->rge_ifp; + + RGE_LOCK(sc); + rge_stop(sc); + rge_reset(sc); + RGE_UNLOCK(sc); + + ether_ifdetach(ifp); + + if (sc->rge_tbi) { + ifmedia_removeall(&sc->rge_ifmedia); + } else { + bus_generic_detach(dev); + device_delete_child(dev, sc->rge_miibus); + } + + rge_release_resources(sc); + +#endif /* FREEBSD_MAC_NOT_YET */ + return (0); +} +static int +rge_suspend(device_t dev) +{ + struct rge_softc *sc; + + sc = device_get_softc(dev); + RGE_LOCK(sc); + rge_stop(sc); + RGE_UNLOCK(sc); + + return 0; +} + +static int +rge_resume(device_t dev) +{ + panic("rge_resume(): unimplemented\n"); + return 0; +} + +static void +rge_release_resources(struct rge_softc *sc) +{ + + if (sc->rge_ifp != NULL) + if_free(sc->rge_ifp); + + if (mtx_initialized(&sc->rge_mtx)) /* XXX */ + RGE_LOCK_DESTROY(sc); +} +uint32_t gmac_rx_fail[32]; +uint32_t gmac_rx_pass[32]; + +#ifdef RX_COPY +static void +rge_rx(struct rge_softc *sc, vm_paddr_t paddr, int len) +{ + /* + * struct mbuf *m = (struct mbuf *)*(unsigned int *)((char *)addr - + * XLR_CACHELINE_SIZE); + */ + struct mbuf *m; + void *ptr; + vm_offset_t temp; + struct ifnet *ifp = sc->rge_ifp; + unsigned long msgrng_flags; + int cpu = PCPU_GET(cpuid); + + + temp = lw_40bit_phys((paddr - XLR_CACHELINE_SIZE), 3); + ptr = (void *)(temp + XLR_CACHELINE_SIZE); + m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); + if (m != NULL) { + m->m_len = m->m_pkthdr.len = MCLBYTES; + m_copyback(m, 0, len + BYTE_OFFSET, ptr); + /* align the data */ + m->m_data += BYTE_OFFSET; + m->m_pkthdr.len = m->m_len = len; + m->m_pkthdr.rcvif = ifp; + gmac_rx_pass[cpu]++; + } else { + gmac_rx_fail[cpu]++; + } + msgrng_access_enable(msgrng_flags); + xlr_mac_send_fr(&sc->priv, paddr, MAX_FRAME_SIZE); + msgrng_access_disable(msgrng_flags); + +#ifdef DUMP_PACKETS + { + int i = 0; + unsigned char *buf = (char *)m->m_data; + printf("Rx Packet: length=%d\n", len); + for (i = 0; i < 64; i++) { + if (i && (i % 16) == 0) + printf("\n"); + printf("%02x ", buf[i]); + } + printf("\n"); + } +#endif + + + if (m) { + ifp->if_ipackets++; + (*ifp->if_input) (ifp, m); + } +} +#else +static void +rge_rx(struct rge_softc *sc, vm_paddr_t paddr, int len) +{ + /* + * struct mbuf *m = (struct mbuf *)*(unsigned int *)((char *)addr - + * XLR_CACHELINE_SIZE); + */ + struct mbuf *m; + vm_offset_t temp; + unsigned int mag; + struct ifnet *ifp = sc->rge_ifp; + + temp = lw_40bit_phys((paddr - XLR_CACHELINE_SIZE), 3); + mag = lw_40bit_phys((paddr - XLR_CACHELINE_SIZE+4), 3); + + m = (struct mbuf *)temp; + + if (mag != 0xf00bad) { + /* somebody else packet Error - FIXME in intialization */ + printf("cpu %d: *ERROR* Not my packet paddr %llx\n", xlr_cpu_id(), paddr); + return; + } + + /* align the data */ + m->m_data += BYTE_OFFSET; + m->m_pkthdr.len = m->m_len = len; + m->m_pkthdr.rcvif = ifp; + +#ifdef DUMP_PACKETS + { + int i = 0; + unsigned char *buf = (char *)m->m_data; + printf("Rx Packet: length=%d\n", len); + for (i = 0; i < 64; i++) { + if (i && (i % 16) == 0) + printf("\n"); + printf("%02x ", buf[i]); + } + printf("\n"); + } +#endif + ifp->if_ipackets++; + (*ifp->if_input) (ifp, m); +} +#endif + +static void +rge_intr(void *arg) +{ + struct rge_softc *sc = (struct rge_softc *)arg; + struct driver_data *priv = &(sc->priv); + xlr_reg_t *mmio = priv->mmio; + uint32_t intreg = xlr_read_reg(mmio, R_INTREG); + + if (intreg & (1 << O_INTREG__MDInt)) { + uint32_t phy_int_status = 0; + int i = 0; + + for (i = 0; i < XLR_MAX_MACS; i++) { + struct rge_softc *phy_dev = 0; + struct driver_data *phy_priv = 0; + + phy_dev = dev_mac[i]; + if (phy_dev == NULL) + continue; + + phy_priv = &phy_dev->priv; + + if (phy_priv->type == XLR_XGMAC) + continue; + + phy_int_status = rge_mii_read_internal(phy_priv->mii_mmio, + phy_priv->phy_addr, 26); + printf("rge%d: Phy addr %d, MII MMIO %lx status %x\n", phy_priv->instance, + (int) phy_priv->phy_addr, (u_long)phy_priv->mii_mmio, phy_int_status); + rmi_xlr_gmac_config_speed(phy_priv); + } + } else { + printf("[%s]: mac type = %d, instance %d error " + "interrupt: INTREG = 0x%08x\n", + __FUNCTION__, priv->type, priv->instance, intreg); + } + + /* clear all interrupts and hope to make progress */ + xlr_write_reg(mmio, R_INTREG, 0xffffffff); + + /* on A0 and B0, xgmac interrupts are routed only to xgs_1 irq */ + if ((xlr_revision_b0()) && (priv->type == XLR_XGMAC)) { + struct rge_softc *xgs0_dev = dev_mac[dev_mac_xgs0]; + struct driver_data *xgs0_priv = &xgs0_dev->priv; + xlr_reg_t *xgs0_mmio = xgs0_priv->mmio; + uint32_t xgs0_intreg = xlr_read_reg(xgs0_mmio, R_INTREG); + + if (xgs0_intreg) { + printf("[%s]: mac type = %d, instance %d error " + "interrupt: INTREG = 0x%08x\n", + __FUNCTION__, xgs0_priv->type, xgs0_priv->instance, xgs0_intreg); + + xlr_write_reg(xgs0_mmio, R_INTREG, 0xffffffff); + } + } +} + +static void +rge_start_locked(struct ifnet *ifp, int threshold) +{ + struct rge_softc *sc = ifp->if_softc; + struct mbuf *m = NULL; + int prepend_pkt = 0; + int i=0; + struct p2d_tx_desc *tx_desc=NULL; + int cpu = xlr_cpu_id(); + uint32_t vcpu = (cpu<<2)+xlr_thr_id(); + + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) + return; + + for (i=0; iif_snd)) + return; + tx_desc = get_p2d_desc(); + if(!tx_desc){ + xlr_rge_get_p2d_failed[vcpu]++; + return; + } + /* Grab a packet off the queue. */ + IFQ_DEQUEUE(&ifp->if_snd, m); + if (m == NULL){ + free_p2d_desc(tx_desc); + return; + } + prepend_pkt = rmi_xlr_mac_xmit(m, sc, 0, tx_desc); + + if (prepend_pkt) { + xlr_rge_tx_prepend[vcpu]++; + IF_PREPEND(&ifp->if_snd, m); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + return; + } else { + ifp->if_opackets++; + xlr_rge_tx_done[vcpu]++; + } + } +} + +static void +rge_start(struct ifnet *ifp) +{ + rge_start_locked(ifp, RGE_TX_Q_SIZE); +} + +static int +rge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) +{ + struct rge_softc *sc = ifp->if_softc; + struct ifreq *ifr = (struct ifreq *)data; + int mask , error = 0; + /* struct mii_data *mii; */ + switch (command) { + case SIOCSIFMTU: + ifp->if_mtu = ifr->ifr_mtu; + error = rmi_xlr_mac_change_mtu(sc, ifr->ifr_mtu); + break; + case SIOCSIFFLAGS: + + RGE_LOCK(sc); + if (ifp->if_flags & IFF_UP) { + /* + * If only the state of the PROMISC flag changed, + * then just use the 'set promisc mode' command + * instead of reinitializing the entire NIC. Doing a + * full re-init means reloading the firmware and + * waiting for it to start up, which may take a + * second or two. Similarly for ALLMULTI. + */ + if (ifp->if_drv_flags & IFF_DRV_RUNNING && + ifp->if_flags & IFF_PROMISC && + !(sc->flags & IFF_PROMISC)) { + sc->flags |= IFF_PROMISC; + xlr_mac_set_rx_mode(sc); + } else if (ifp->if_drv_flags & IFF_DRV_RUNNING && + !(ifp->if_flags & IFF_PROMISC) && + sc->flags & IFF_PROMISC) { + sc->flags &= IFF_PROMISC; + xlr_mac_set_rx_mode(sc); + } else if (ifp->if_drv_flags & IFF_DRV_RUNNING && + (ifp->if_flags ^ sc->flags) & IFF_ALLMULTI) { + rmi_xlr_mac_set_multicast_list(sc); + } else + xlr_mac_set_rx_mode(sc); + } else { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + xlr_mac_set_rx_mode(sc); + } + } + sc->flags = ifp->if_flags; + RGE_UNLOCK(sc); + error = 0; + break; + case SIOCADDMULTI: + case SIOCDELMULTI: + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + RGE_LOCK(sc); + rmi_xlr_mac_set_multicast_list(sc); + RGE_UNLOCK(sc); + error = 0; + } + break; + case SIOCSIFMEDIA: + case SIOCGIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, + &sc->rge_mii.mii_media, command); + break; + case SIOCSIFCAP: + mask = ifr->ifr_reqcap ^ ifp->if_capenable; + ifp->if_hwassist = 0; + break; + default: + error = ether_ioctl(ifp, command, data); + break; + } + + return (error); +} + +static void +rge_init(void *addr) +{ + struct rge_softc *sc = (struct rge_softc *)addr; + struct ifnet *ifp; + struct driver_data *priv = &(sc->priv); + + ifp = sc->rge_ifp; + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + return; + ifp->if_drv_flags |= IFF_DRV_RUNNING; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + + rmi_xlr_mac_set_enable(priv, 1); +} + +static void +rge_stop(struct rge_softc *sc) +{ + rmi_xlr_mac_close(sc); +} + +static void +rge_watchdog(struct ifnet *sc) +{ +} + +static void +rge_shutdown(device_t dev) +{ + struct rge_softc *sc; + sc = device_get_softc(dev); + + RGE_LOCK(sc); + rge_stop(sc); + rge_reset(sc); + RGE_UNLOCK(sc); + + return; +} + +static int +rmi_xlr_mac_open(struct rge_softc *sc) +{ + struct driver_data *priv = &(sc->priv); + int i; + + dbg_msg("IN\n"); + + if (rmi_xlr_mac_fill_rxfr(sc)) { + return -1; + } + + mtx_lock_spin(&priv->lock); + + xlr_mac_set_rx_mode(sc); + + if (sc->unit == xlr_board_info.gmacports - 1) { + printf("Enabling MDIO interrupts\n"); + struct rge_softc *tmp = NULL; + for (i = 0; i < xlr_board_info.gmacports; i++) { + tmp = dev_mac[i]; + if (tmp) + xlr_write_reg(tmp->priv.mmio, R_INTMASK, + ((tmp->priv.instance == 0) << O_INTMASK__MDInt)); + } + } + + /* + * Configure the speed, duplex, and flow control + */ + rmi_xlr_mac_set_speed(priv, priv->speed); + rmi_xlr_mac_set_duplex(priv, priv->duplex, priv->flow_ctrl); + rmi_xlr_mac_set_enable(priv, 0); + + mtx_unlock_spin(&priv->lock); + + for (i = 0; i < 8; i++) { + atomic_set_int(&(priv->frin_to_be_sent[i]), 0); + } + + return 0; +} + +/********************************************************************** + **********************************************************************/ +static int +rmi_xlr_mac_close(struct rge_softc *sc) +{ + struct driver_data *priv = &(sc->priv); + + mtx_lock_spin(&priv->lock); + + /* + * There may have left over mbufs in the ring as well as in free in + * they will be reused next time open is called + */ + + rmi_xlr_mac_set_enable(priv, 0); + + xlr_inc_counter(NETIF_STOP_Q); + port_inc_counter(priv->instance, PORT_STOPQ); + + mtx_unlock_spin(&priv->lock); + + return 0; +} + +/********************************************************************** + **********************************************************************/ +static struct rge_softc_stats * +rmi_xlr_mac_get_stats(struct rge_softc *sc) +{ + struct driver_data *priv = &(sc->priv); + /* unsigned long flags; */ + + mtx_lock_spin(&priv->lock); + + /* XXX update other stats here */ + + mtx_unlock_spin(&priv->lock); + + return &priv->stats; +} + +/********************************************************************** + **********************************************************************/ +static void +rmi_xlr_mac_set_multicast_list(struct rge_softc *sc) +{ +} + +/********************************************************************** + **********************************************************************/ +static int +rmi_xlr_mac_change_mtu(struct rge_softc *sc, int new_mtu) +{ + struct driver_data *priv = &(sc->priv); + + if ((new_mtu > 9500) || (new_mtu < 64)) { + return -EINVAL; + } + mtx_lock_spin(&priv->lock); + + sc->mtu = new_mtu; + + /* Disable MAC TX/RX */ + rmi_xlr_mac_set_enable(priv, 0); + + /* Flush RX FR IN */ + /* Flush TX IN */ + rmi_xlr_mac_set_enable(priv, 1); + + mtx_unlock_spin(&priv->lock); + return 0; +} + +/********************************************************************** + **********************************************************************/ +static int +rmi_xlr_mac_fill_rxfr(struct rge_softc *sc) +{ + struct driver_data *priv = &(sc->priv); + unsigned long msgrng_flags; + int i; + int ret = 0; + void *ptr; + + dbg_msg("\n"); + if (!priv->init_frin_desc) + return ret; + priv->init_frin_desc = 0; + + dbg_msg("\n"); + for (i = 0; i < MAX_NUM_DESC; i++) { + ptr = get_buf(); + if (!ptr) { + ret = -ENOMEM; + break; + } + + /* Send the free Rx desc to the MAC */ + msgrng_access_enable(msgrng_flags); + xlr_mac_send_fr(priv, vtophys(ptr), MAX_FRAME_SIZE); + msgrng_access_disable(msgrng_flags); + } + + return ret; +} + +/********************************************************************** + **********************************************************************/ +static __inline__ void * +rmi_xlr_config_spill(xlr_reg_t * mmio, + int reg_start_0, int reg_start_1, + int reg_size, int size) +{ + uint32_t spill_size = size; + void *spill = NULL; + uint64_t phys_addr = 0; + + + spill = contigmalloc((spill_size + XLR_CACHELINE_SIZE), M_DEVBUF, + M_NOWAIT | M_ZERO, 0, 0xffffffff, XLR_CACHELINE_SIZE, 0); + if (!spill || ((vm_offset_t) spill & (XLR_CACHELINE_SIZE - 1))) { + panic("Unable to allocate memory for spill area!\n"); + } + phys_addr = vtophys(spill); + dbg_msg("Allocate spill %d bytes at %llx\n", size, phys_addr); + xlr_write_reg(mmio, reg_start_0, (phys_addr >> 5) & 0xffffffff); + xlr_write_reg(mmio, reg_start_1, (phys_addr >> 37) & 0x07); + xlr_write_reg(mmio, reg_size, spill_size); + + return spill; +} + +static void +rmi_xlr_config_spill_area(struct driver_data *priv) +{ + /* + * if driver initialization is done parallely on multiple cpus + * spill_configured needs synchronization + */ + if (priv->spill_configured) + return; + + if (priv->type == XLR_GMAC && priv->instance % 4 != 0) { + priv->spill_configured = 1; + return; + } + + priv->spill_configured = 1; + + priv->frin_spill = + rmi_xlr_config_spill(priv->mmio, + R_REG_FRIN_SPILL_MEM_START_0, + R_REG_FRIN_SPILL_MEM_START_1, + R_REG_FRIN_SPILL_MEM_SIZE, + MAX_FRIN_SPILL * + sizeof(struct fr_desc)); + + priv->class_0_spill = + rmi_xlr_config_spill(priv->mmio, + R_CLASS0_SPILL_MEM_START_0, + R_CLASS0_SPILL_MEM_START_1, + R_CLASS0_SPILL_MEM_SIZE, + MAX_CLASS_0_SPILL * + sizeof(union rx_tx_desc)); + priv->class_1_spill = + rmi_xlr_config_spill(priv->mmio, + R_CLASS1_SPILL_MEM_START_0, + R_CLASS1_SPILL_MEM_START_1, + R_CLASS1_SPILL_MEM_SIZE, + MAX_CLASS_1_SPILL * + sizeof(union rx_tx_desc)); + + priv->frout_spill = + rmi_xlr_config_spill(priv->mmio, R_FROUT_SPILL_MEM_START_0, + R_FROUT_SPILL_MEM_START_1, + R_FROUT_SPILL_MEM_SIZE, + MAX_FROUT_SPILL * + sizeof(struct fr_desc)); + + priv->class_2_spill = + rmi_xlr_config_spill(priv->mmio, + R_CLASS2_SPILL_MEM_START_0, + R_CLASS2_SPILL_MEM_START_1, + R_CLASS2_SPILL_MEM_SIZE, + MAX_CLASS_2_SPILL * + sizeof(union rx_tx_desc)); + priv->class_3_spill = + rmi_xlr_config_spill(priv->mmio, + R_CLASS3_SPILL_MEM_START_0, + R_CLASS3_SPILL_MEM_START_1, + R_CLASS3_SPILL_MEM_SIZE, + MAX_CLASS_3_SPILL * + sizeof(union rx_tx_desc)); + priv->spill_configured = 1; +} + +/***************************************************************** + * Write the MAC address to the XLR registers + * All 4 addresses are the same for now + *****************************************************************/ +static void +xlr_mac_setup_hwaddr(struct driver_data *priv) +{ + struct rge_softc *sc = priv->sc; + + xlr_write_reg(priv->mmio, R_MAC_ADDR0, + ((sc->dev_addr[5] << 24) | (sc->dev_addr[4] << 16) + | (sc->dev_addr[3] << 8) | (sc->dev_addr[2])) + ); + + xlr_write_reg(priv->mmio, R_MAC_ADDR0 + 1, + ((sc->dev_addr[1] << 24) | (sc-> + dev_addr[0] << 16))); + + xlr_write_reg(priv->mmio, R_MAC_ADDR_MASK2, 0xffffffff); + + xlr_write_reg(priv->mmio, R_MAC_ADDR_MASK2 + 1, 0xffffffff); + + xlr_write_reg(priv->mmio, R_MAC_ADDR_MASK3, 0xffffffff); + + xlr_write_reg(priv->mmio, R_MAC_ADDR_MASK3 + 1, 0xffffffff); + + xlr_write_reg(priv->mmio, R_MAC_FILTER_CONFIG, + (1 << O_MAC_FILTER_CONFIG__BROADCAST_EN) | + (1 << O_MAC_FILTER_CONFIG__ALL_MCAST_EN) | + (1 << O_MAC_FILTER_CONFIG__MAC_ADDR0_VALID) + ); +} + +/***************************************************************** + * Read the MAC address from the XLR registers + * All 4 addresses are the same for now + *****************************************************************/ +static void +xlr_mac_get_hwaddr(struct rge_softc *sc) +{ + struct driver_data *priv = &(sc->priv); + + sc->dev_addr[0] = (xlr_boot1_info.mac_addr >> 40) & 0xff; + sc->dev_addr[1] = (xlr_boot1_info.mac_addr >> 32) & 0xff; + sc->dev_addr[2] = (xlr_boot1_info.mac_addr >> 24) & 0xff; + sc->dev_addr[3] = (xlr_boot1_info.mac_addr >> 16) & 0xff; + sc->dev_addr[4] = (xlr_boot1_info.mac_addr >> 8) & 0xff; + sc->dev_addr[5] = ((xlr_boot1_info.mac_addr >> 0) & 0xff) + priv->instance; +} + +/***************************************************************** + * Mac Module Initialization + *****************************************************************/ +static void +mac_common_init(void) +{ + init_p2d_allocation(); + init_tx_ring(); +#ifdef RX_COPY + init_rx_buf(); +#endif + + if (xlr_board_info.is_xls) { + if (register_msgring_handler (TX_STN_GMAC0, + rmi_xlr_mac_msgring_handler, NULL)) { + panic("Couldn't register msgring handler\n"); + } + if (register_msgring_handler (TX_STN_GMAC1, + rmi_xlr_mac_msgring_handler, NULL)) { + panic("Couldn't register msgring handler\n"); + } + } else { + if (register_msgring_handler (TX_STN_GMAC, + rmi_xlr_mac_msgring_handler, NULL)) { + panic("Couldn't register msgring handler\n"); + } + } + +#if notyet + if (xlr_board_atx_ii()) { + if (register_msgring_handler + (TX_STN_XGS_0, rmi_xlr_mac_msgring_handler, NULL)) { + panic("Couldn't register msgring handler for TX_STN_XGS_0\n"); + } + if (register_msgring_handler + (TX_STN_XGS_1, rmi_xlr_mac_msgring_handler, NULL)) { + panic("Couldn't register msgring handler for TX_STN_XGS_1\n"); + } + } +#endif +} diff --git a/sys/dev/rmi/xlr/rge.h b/sys/dev/rmi/xlr/rge.h new file mode 100644 index 00000000000..1ece628264e --- /dev/null +++ b/sys/dev/rmi/xlr/rge.h @@ -0,0 +1,978 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ +#ifndef _RMI_RGE_H_ +#define _RMI_RGE_H_ + +/* #define MAC_SPLIT_MODE */ + +#define MAC_SPACING 0x400 +#define XGMAC_SPACING 0x400 + +/* PE-MCXMAC register and bit field definitions */ +#define R_MAC_CONFIG_1 0x00 +#define O_MAC_CONFIG_1__srst 31 +#define O_MAC_CONFIG_1__simr 30 +#define O_MAC_CONFIG_1__hrrmc 18 +#define W_MAC_CONFIG_1__hrtmc 2 +#define O_MAC_CONFIG_1__hrrfn 16 +#define W_MAC_CONFIG_1__hrtfn 2 +#define O_MAC_CONFIG_1__intlb 8 +#define O_MAC_CONFIG_1__rxfc 5 +#define O_MAC_CONFIG_1__txfc 4 +#define O_MAC_CONFIG_1__srxen 3 +#define O_MAC_CONFIG_1__rxen 2 +#define O_MAC_CONFIG_1__stxen 1 +#define O_MAC_CONFIG_1__txen 0 +#define R_MAC_CONFIG_2 0x01 +#define O_MAC_CONFIG_2__prlen 12 +#define W_MAC_CONFIG_2__prlen 4 +#define O_MAC_CONFIG_2__speed 8 +#define W_MAC_CONFIG_2__speed 2 +#define O_MAC_CONFIG_2__hugen 5 +#define O_MAC_CONFIG_2__flchk 4 +#define O_MAC_CONFIG_2__crce 1 +#define O_MAC_CONFIG_2__fulld 0 +#define R_IPG_IFG 0x02 +#define O_IPG_IFG__ipgr1 24 +#define W_IPG_IFG__ipgr1 7 +#define O_IPG_IFG__ipgr2 16 +#define W_IPG_IFG__ipgr2 7 +#define O_IPG_IFG__mifg 8 +#define W_IPG_IFG__mifg 8 +#define O_IPG_IFG__ipgt 0 +#define W_IPG_IFG__ipgt 7 +#define R_HALF_DUPLEX 0x03 +#define O_HALF_DUPLEX__abebt 24 +#define W_HALF_DUPLEX__abebt 4 +#define O_HALF_DUPLEX__abebe 19 +#define O_HALF_DUPLEX__bpnb 18 +#define O_HALF_DUPLEX__nobo 17 +#define O_HALF_DUPLEX__edxsdfr 16 +#define O_HALF_DUPLEX__retry 12 +#define W_HALF_DUPLEX__retry 4 +#define O_HALF_DUPLEX__lcol 0 +#define W_HALF_DUPLEX__lcol 10 +#define R_MAXIMUM_FRAME_LENGTH 0x04 +#define O_MAXIMUM_FRAME_LENGTH__maxf 0 +#define W_MAXIMUM_FRAME_LENGTH__maxf 16 +#define R_TEST 0x07 +#define O_TEST__mbof 3 +#define O_TEST__rthdf 2 +#define O_TEST__tpause 1 +#define O_TEST__sstct 0 +#define R_MII_MGMT_CONFIG 0x08 +#define O_MII_MGMT_CONFIG__scinc 5 +#define O_MII_MGMT_CONFIG__spre 4 +#define O_MII_MGMT_CONFIG__clks 3 +#define W_MII_MGMT_CONFIG__clks 3 +#define R_MII_MGMT_COMMAND 0x09 +#define O_MII_MGMT_COMMAND__scan 1 +#define O_MII_MGMT_COMMAND__rstat 0 +#define R_MII_MGMT_ADDRESS 0x0A +#define O_MII_MGMT_ADDRESS__fiad 8 +#define W_MII_MGMT_ADDRESS__fiad 5 +#define O_MII_MGMT_ADDRESS__fgad 5 +#define W_MII_MGMT_ADDRESS__fgad 0 +#define R_MII_MGMT_WRITE_DATA 0x0B +#define O_MII_MGMT_WRITE_DATA__ctld 0 +#define W_MII_MGMT_WRITE_DATA__ctld 16 +#define R_MII_MGMT_STATUS 0x0C +#define R_MII_MGMT_INDICATORS 0x0D +#define O_MII_MGMT_INDICATORS__nvalid 2 +#define O_MII_MGMT_INDICATORS__scan 1 +#define O_MII_MGMT_INDICATORS__busy 0 +#define R_INTERFACE_CONTROL 0x0E +#define O_INTERFACE_CONTROL__hrstint 31 +#define O_INTERFACE_CONTROL__tbimode 27 +#define O_INTERFACE_CONTROL__ghdmode 26 +#define O_INTERFACE_CONTROL__lhdmode 25 +#define O_INTERFACE_CONTROL__phymod 24 +#define O_INTERFACE_CONTROL__hrrmi 23 +#define O_INTERFACE_CONTROL__rspd 16 +#define O_INTERFACE_CONTROL__hr100 15 +#define O_INTERFACE_CONTROL__frcq 10 +#define O_INTERFACE_CONTROL__nocfr 9 +#define O_INTERFACE_CONTROL__dlfct 8 +#define O_INTERFACE_CONTROL__enjab 0 +#define R_INTERFACE_STATUS 0x0F +#define O_INTERFACE_STATUS__xsdfr 9 +#define O_INTERFACE_STATUS__ssrr 8 +#define W_INTERFACE_STATUS__ssrr 5 +#define O_INTERFACE_STATUS__miilf 3 +#define O_INTERFACE_STATUS__locar 2 +#define O_INTERFACE_STATUS__sqerr 1 +#define O_INTERFACE_STATUS__jabber 0 +#define R_STATION_ADDRESS_LS 0x10 +#define R_STATION_ADDRESS_MS 0x11 + +/* A-XGMAC register and bit field definitions */ +#define R_XGMAC_CONFIG_0 0x00 +#define O_XGMAC_CONFIG_0__hstmacrst 31 +#define O_XGMAC_CONFIG_0__hstrstrctl 23 +#define O_XGMAC_CONFIG_0__hstrstrfn 22 +#define O_XGMAC_CONFIG_0__hstrsttctl 18 +#define O_XGMAC_CONFIG_0__hstrsttfn 17 +#define O_XGMAC_CONFIG_0__hstrstmiim 16 +#define O_XGMAC_CONFIG_0__hstloopback 8 +#define R_XGMAC_CONFIG_1 0x01 +#define O_XGMAC_CONFIG_1__hsttctlen 31 +#define O_XGMAC_CONFIG_1__hsttfen 30 +#define O_XGMAC_CONFIG_1__hstrctlen 29 +#define O_XGMAC_CONFIG_1__hstrfen 28 +#define O_XGMAC_CONFIG_1__tfen 26 +#define O_XGMAC_CONFIG_1__rfen 24 +#define O_XGMAC_CONFIG_1__hstrctlshrtp 12 +#define O_XGMAC_CONFIG_1__hstdlyfcstx 10 +#define W_XGMAC_CONFIG_1__hstdlyfcstx 2 +#define O_XGMAC_CONFIG_1__hstdlyfcsrx 8 +#define W_XGMAC_CONFIG_1__hstdlyfcsrx 2 +#define O_XGMAC_CONFIG_1__hstppen 7 +#define O_XGMAC_CONFIG_1__hstbytswp 6 +#define O_XGMAC_CONFIG_1__hstdrplt64 5 +#define O_XGMAC_CONFIG_1__hstprmscrx 4 +#define O_XGMAC_CONFIG_1__hstlenchk 3 +#define O_XGMAC_CONFIG_1__hstgenfcs 2 +#define O_XGMAC_CONFIG_1__hstpadmode 0 +#define W_XGMAC_CONFIG_1__hstpadmode 2 +#define R_XGMAC_CONFIG_2 0x02 +#define O_XGMAC_CONFIG_2__hsttctlfrcp 31 +#define O_XGMAC_CONFIG_2__hstmlnkflth 27 +#define O_XGMAC_CONFIG_2__hstalnkflth 26 +#define O_XGMAC_CONFIG_2__rflnkflt 24 +#define W_XGMAC_CONFIG_2__rflnkflt 2 +#define O_XGMAC_CONFIG_2__hstipgextmod 16 +#define W_XGMAC_CONFIG_2__hstipgextmod 5 +#define O_XGMAC_CONFIG_2__hstrctlfrcp 15 +#define O_XGMAC_CONFIG_2__hstipgexten 5 +#define O_XGMAC_CONFIG_2__hstmipgext 0 +#define W_XGMAC_CONFIG_2__hstmipgext 5 +#define R_XGMAC_CONFIG_3 0x03 +#define O_XGMAC_CONFIG_3__hstfltrfrm 31 +#define W_XGMAC_CONFIG_3__hstfltrfrm 16 +#define O_XGMAC_CONFIG_3__hstfltrfrmdc 15 +#define W_XGMAC_CONFIG_3__hstfltrfrmdc 16 +#define R_XGMAC_STATION_ADDRESS_LS 0x04 +#define O_XGMAC_STATION_ADDRESS_LS__hstmacadr0 0 +#define W_XGMAC_STATION_ADDRESS_LS__hstmacadr0 32 +#define R_XGMAC_STATION_ADDRESS_MS 0x05 +#define R_XGMAC_MAX_FRAME_LEN 0x08 +#define O_XGMAC_MAX_FRAME_LEN__hstmxfrmwctx 16 +#define W_XGMAC_MAX_FRAME_LEN__hstmxfrmwctx 14 +#define O_XGMAC_MAX_FRAME_LEN__hstmxfrmbcrx 0 +#define W_XGMAC_MAX_FRAME_LEN__hstmxfrmbcrx 16 +#define R_XGMAC_REV_LEVEL 0x0B +#define O_XGMAC_REV_LEVEL__revlvl 0 +#define W_XGMAC_REV_LEVEL__revlvl 15 +#define R_XGMAC_MIIM_COMMAND 0x10 +#define O_XGMAC_MIIM_COMMAND__hstldcmd 3 +#define O_XGMAC_MIIM_COMMAND__hstmiimcmd 0 +#define W_XGMAC_MIIM_COMMAND__hstmiimcmd 3 +#define R_XGMAC_MIIM_FILED 0x11 +#define O_XGMAC_MIIM_FILED__hststfield 30 +#define W_XGMAC_MIIM_FILED__hststfield 2 +#define O_XGMAC_MIIM_FILED__hstopfield 28 +#define W_XGMAC_MIIM_FILED__hstopfield 2 +#define O_XGMAC_MIIM_FILED__hstphyadx 23 +#define W_XGMAC_MIIM_FILED__hstphyadx 5 +#define O_XGMAC_MIIM_FILED__hstregadx 18 +#define W_XGMAC_MIIM_FILED__hstregadx 5 +#define O_XGMAC_MIIM_FILED__hsttafield 16 +#define W_XGMAC_MIIM_FILED__hsttafield 2 +#define O_XGMAC_MIIM_FILED__miimrddat 0 +#define W_XGMAC_MIIM_FILED__miimrddat 16 +#define R_XGMAC_MIIM_CONFIG 0x12 +#define O_XGMAC_MIIM_CONFIG__hstnopram 7 +#define O_XGMAC_MIIM_CONFIG__hstclkdiv 0 +#define W_XGMAC_MIIM_CONFIG__hstclkdiv 7 +#define R_XGMAC_MIIM_LINK_FAIL_VECTOR 0x13 +#define O_XGMAC_MIIM_LINK_FAIL_VECTOR__miimlfvec 0 +#define W_XGMAC_MIIM_LINK_FAIL_VECTOR__miimlfvec 32 +#define R_XGMAC_MIIM_INDICATOR 0x14 +#define O_XGMAC_MIIM_INDICATOR__miimphylf 4 +#define O_XGMAC_MIIM_INDICATOR__miimmoncplt 3 +#define O_XGMAC_MIIM_INDICATOR__miimmonvld 2 +#define O_XGMAC_MIIM_INDICATOR__miimmon 1 +#define O_XGMAC_MIIM_INDICATOR__miimbusy 0 + +/* Glue logic register and bit field definitions */ +#define R_MAC_ADDR0 0x50 +#define R_MAC_ADDR1 0x52 +#define R_MAC_ADDR2 0x54 +#define R_MAC_ADDR3 0x56 +#define R_MAC_ADDR_MASK2 0x58 +#define R_MAC_ADDR_MASK3 0x5A +#define R_MAC_FILTER_CONFIG 0x5C +#define O_MAC_FILTER_CONFIG__BROADCAST_EN 10 +#define O_MAC_FILTER_CONFIG__PAUSE_FRAME_EN 9 +#define O_MAC_FILTER_CONFIG__ALL_MCAST_EN 8 +#define O_MAC_FILTER_CONFIG__ALL_UCAST_EN 7 +#define O_MAC_FILTER_CONFIG__HASH_MCAST_EN 6 +#define O_MAC_FILTER_CONFIG__HASH_UCAST_EN 5 +#define O_MAC_FILTER_CONFIG__ADDR_MATCH_DISC 4 +#define O_MAC_FILTER_CONFIG__MAC_ADDR3_VALID 3 +#define O_MAC_FILTER_CONFIG__MAC_ADDR2_VALID 2 +#define O_MAC_FILTER_CONFIG__MAC_ADDR1_VALID 1 +#define O_MAC_FILTER_CONFIG__MAC_ADDR0_VALID 0 +#define R_HASH_TABLE_VECTOR 0x30 +#define R_TX_CONTROL 0x0A0 +#define O_TX_CONTROL__Tx15Halt 31 +#define O_TX_CONTROL__Tx14Halt 30 +#define O_TX_CONTROL__Tx13Halt 29 +#define O_TX_CONTROL__Tx12Halt 28 +#define O_TX_CONTROL__Tx11Halt 27 +#define O_TX_CONTROL__Tx10Halt 26 +#define O_TX_CONTROL__Tx9Halt 25 +#define O_TX_CONTROL__Tx8Halt 24 +#define O_TX_CONTROL__Tx7Halt 23 +#define O_TX_CONTROL__Tx6Halt 22 +#define O_TX_CONTROL__Tx5Halt 21 +#define O_TX_CONTROL__Tx4Halt 20 +#define O_TX_CONTROL__Tx3Halt 19 +#define O_TX_CONTROL__Tx2Halt 18 +#define O_TX_CONTROL__Tx1Halt 17 +#define O_TX_CONTROL__Tx0Halt 16 +#define O_TX_CONTROL__TxIdle 15 +#define O_TX_CONTROL__TxEnable 14 +#define O_TX_CONTROL__TxThreshold 0 +#define W_TX_CONTROL__TxThreshold 14 +#define R_RX_CONTROL 0x0A1 +#define O_RX_CONTROL__RGMII 10 +#define O_RX_CONTROL__RxHalt 1 +#define O_RX_CONTROL__RxEnable 0 +#define R_DESC_PACK_CTRL 0x0A2 +#define O_DESC_PACK_CTRL__ByteOffset 17 +#define W_DESC_PACK_CTRL__ByteOffset 3 +#define O_DESC_PACK_CTRL__PrePadEnable 16 +#define O_DESC_PACK_CTRL__MaxEntry 14 +#define W_DESC_PACK_CTRL__MaxEntry 2 +#define O_DESC_PACK_CTRL__RegularSize 0 +#define W_DESC_PACK_CTRL__RegularSize 14 +#define R_STATCTRL 0x0A3 +#define O_STATCTRL__OverFlowEn 4 +#define O_STATCTRL__GIG 3 +#define O_STATCTRL__Sten 2 +#define O_STATCTRL__ClrCnt 1 +#define O_STATCTRL__AutoZ 0 +#define R_L2ALLOCCTRL 0x0A4 +#define O_L2ALLOCCTRL__TxL2Allocate 9 +#define W_L2ALLOCCTRL__TxL2Allocate 9 +#define O_L2ALLOCCTRL__RxL2Allocate 0 +#define W_L2ALLOCCTRL__RxL2Allocate 9 +#define R_INTMASK 0x0A5 +#define O_INTMASK__Spi4TxError 28 +#define O_INTMASK__Spi4RxError 27 +#define O_INTMASK__RGMIIHalfDupCollision 27 +#define O_INTMASK__Abort 26 +#define O_INTMASK__Underrun 25 +#define O_INTMASK__DiscardPacket 24 +#define O_INTMASK__AsyncFifoFull 23 +#define O_INTMASK__TagFull 22 +#define O_INTMASK__Class3Full 21 +#define O_INTMASK__C3EarlyFull 20 +#define O_INTMASK__Class2Full 19 +#define O_INTMASK__C2EarlyFull 18 +#define O_INTMASK__Class1Full 17 +#define O_INTMASK__C1EarlyFull 16 +#define O_INTMASK__Class0Full 15 +#define O_INTMASK__C0EarlyFull 14 +#define O_INTMASK__RxDataFull 13 +#define O_INTMASK__RxEarlyFull 12 +#define O_INTMASK__RFreeEmpty 9 +#define O_INTMASK__RFEarlyEmpty 8 +#define O_INTMASK__P2PSpillEcc 7 +#define O_INTMASK__FreeDescFull 5 +#define O_INTMASK__FreeEarlyFull 4 +#define O_INTMASK__TxFetchError 3 +#define O_INTMASK__StatCarry 2 +#define O_INTMASK__MDInt 1 +#define O_INTMASK__TxIllegal 0 +#define R_INTREG 0x0A6 +#define O_INTREG__Spi4TxError 28 +#define O_INTREG__Spi4RxError 27 +#define O_INTREG__RGMIIHalfDupCollision 27 +#define O_INTREG__Abort 26 +#define O_INTREG__Underrun 25 +#define O_INTREG__DiscardPacket 24 +#define O_INTREG__AsyncFifoFull 23 +#define O_INTREG__TagFull 22 +#define O_INTREG__Class3Full 21 +#define O_INTREG__C3EarlyFull 20 +#define O_INTREG__Class2Full 19 +#define O_INTREG__C2EarlyFull 18 +#define O_INTREG__Class1Full 17 +#define O_INTREG__C1EarlyFull 16 +#define O_INTREG__Class0Full 15 +#define O_INTREG__C0EarlyFull 14 +#define O_INTREG__RxDataFull 13 +#define O_INTREG__RxEarlyFull 12 +#define O_INTREG__RFreeEmpty 9 +#define O_INTREG__RFEarlyEmpty 8 +#define O_INTREG__P2PSpillEcc 7 +#define O_INTREG__FreeDescFull 5 +#define O_INTREG__FreeEarlyFull 4 +#define O_INTREG__TxFetchError 3 +#define O_INTREG__StatCarry 2 +#define O_INTREG__MDInt 1 +#define O_INTREG__TxIllegal 0 +#define R_TXRETRY 0x0A7 +#define O_TXRETRY__CollisionRetry 6 +#define O_TXRETRY__BusErrorRetry 5 +#define O_TXRETRY__UnderRunRetry 4 +#define O_TXRETRY__Retries 0 +#define W_TXRETRY__Retries 4 +#define R_CORECONTROL 0x0A8 +#define O_CORECONTROL__ErrorThread 4 +#define W_CORECONTROL__ErrorThread 7 +#define O_CORECONTROL__Shutdown 2 +#define O_CORECONTROL__Speed 0 +#define W_CORECONTROL__Speed 2 +#define R_BYTEOFFSET0 0x0A9 +#define R_BYTEOFFSET1 0x0AA +#define R_L2TYPE_0 0x0F0 +#define O_L2TYPE__ExtraHdrProtoSize 26 +#define W_L2TYPE__ExtraHdrProtoSize 5 +#define O_L2TYPE__ExtraHdrProtoOffset 20 +#define W_L2TYPE__ExtraHdrProtoOffset 6 +#define O_L2TYPE__ExtraHeaderSize 14 +#define W_L2TYPE__ExtraHeaderSize 6 +#define O_L2TYPE__ProtoOffset 8 +#define W_L2TYPE__ProtoOffset 6 +#define O_L2TYPE__L2HdrOffset 2 +#define W_L2TYPE__L2HdrOffset 6 +#define O_L2TYPE__L2Proto 0 +#define W_L2TYPE__L2Proto 2 +#define R_L2TYPE_1 0xF0 +#define R_L2TYPE_2 0xF0 +#define R_L2TYPE_3 0xF0 +#define R_PARSERCONFIGREG 0x100 +#define O_PARSERCONFIGREG__CRCHashPoly 8 +#define W_PARSERCONFIGREG__CRCHashPoly 7 +#define O_PARSERCONFIGREG__PrePadOffset 4 +#define W_PARSERCONFIGREG__PrePadOffset 4 +#define O_PARSERCONFIGREG__UseCAM 2 +#define O_PARSERCONFIGREG__UseHASH 1 +#define O_PARSERCONFIGREG__UseProto 0 +#define R_L3CTABLE 0x140 +#define O_L3CTABLE__Offset0 25 +#define W_L3CTABLE__Offset0 7 +#define O_L3CTABLE__Len0 21 +#define W_L3CTABLE__Len0 4 +#define O_L3CTABLE__Offset1 14 +#define W_L3CTABLE__Offset1 7 +#define O_L3CTABLE__Len1 10 +#define W_L3CTABLE__Len1 4 +#define O_L3CTABLE__Offset2 4 +#define W_L3CTABLE__Offset2 6 +#define O_L3CTABLE__Len2 0 +#define W_L3CTABLE__Len2 4 +#define O_L3CTABLE__L3HdrOffset 26 +#define W_L3CTABLE__L3HdrOffset 6 +#define O_L3CTABLE__L4ProtoOffset 20 +#define W_L3CTABLE__L4ProtoOffset 6 +#define O_L3CTABLE__IPChksumCompute 19 +#define O_L3CTABLE__L4Classify 18 +#define O_L3CTABLE__L2Proto 16 +#define W_L3CTABLE__L2Proto 2 +#define O_L3CTABLE__L3ProtoKey 0 +#define W_L3CTABLE__L3ProtoKey 16 +#define R_L4CTABLE 0x160 +#define O_L4CTABLE__Offset0 21 +#define W_L4CTABLE__Offset0 6 +#define O_L4CTABLE__Len0 17 +#define W_L4CTABLE__Len0 4 +#define O_L4CTABLE__Offset1 11 +#define W_L4CTABLE__Offset1 6 +#define O_L4CTABLE__Len1 7 +#define W_L4CTABLE__Len1 4 +#define O_L4CTABLE__TCPChksumEnable 0 +#define R_CAM4X128TABLE 0x172 +#define O_CAM4X128TABLE__ClassId 7 +#define W_CAM4X128TABLE__ClassId 2 +#define O_CAM4X128TABLE__BucketId 1 +#define W_CAM4X128TABLE__BucketId 6 +#define O_CAM4X128TABLE__UseBucket 0 +#define R_CAM4X128KEY 0x180 +#define R_TRANSLATETABLE 0x1A0 +#define R_DMACR0 0x200 +#define O_DMACR0__Data0WrMaxCr 27 +#define W_DMACR0__Data0WrMaxCr 3 +#define O_DMACR0__Data0RdMaxCr 24 +#define W_DMACR0__Data0RdMaxCr 3 +#define O_DMACR0__Data1WrMaxCr 21 +#define W_DMACR0__Data1WrMaxCr 3 +#define O_DMACR0__Data1RdMaxCr 18 +#define W_DMACR0__Data1RdMaxCr 3 +#define O_DMACR0__Data2WrMaxCr 15 +#define W_DMACR0__Data2WrMaxCr 3 +#define O_DMACR0__Data2RdMaxCr 12 +#define W_DMACR0__Data2RdMaxCr 3 +#define O_DMACR0__Data3WrMaxCr 9 +#define W_DMACR0__Data3WrMaxCr 3 +#define O_DMACR0__Data3RdMaxCr 6 +#define W_DMACR0__Data3RdMaxCr 3 +#define O_DMACR0__Data4WrMaxCr 3 +#define W_DMACR0__Data4WrMaxCr 3 +#define O_DMACR0__Data4RdMaxCr 0 +#define W_DMACR0__Data4RdMaxCr 3 +#define R_DMACR1 0x201 +#define O_DMACR1__Data5WrMaxCr 27 +#define W_DMACR1__Data5WrMaxCr 3 +#define O_DMACR1__Data5RdMaxCr 24 +#define W_DMACR1__Data5RdMaxCr 3 +#define O_DMACR1__Data6WrMaxCr 21 +#define W_DMACR1__Data6WrMaxCr 3 +#define O_DMACR1__Data6RdMaxCr 18 +#define W_DMACR1__Data6RdMaxCr 3 +#define O_DMACR1__Data7WrMaxCr 15 +#define W_DMACR1__Data7WrMaxCr 3 +#define O_DMACR1__Data7RdMaxCr 12 +#define W_DMACR1__Data7RdMaxCr 3 +#define O_DMACR1__Data8WrMaxCr 9 +#define W_DMACR1__Data8WrMaxCr 3 +#define O_DMACR1__Data8RdMaxCr 6 +#define W_DMACR1__Data8RdMaxCr 3 +#define O_DMACR1__Data9WrMaxCr 3 +#define W_DMACR1__Data9WrMaxCr 3 +#define O_DMACR1__Data9RdMaxCr 0 +#define W_DMACR1__Data9RdMaxCr 3 +#define R_DMACR2 0x202 +#define O_DMACR2__Data10WrMaxCr 27 +#define W_DMACR2__Data10WrMaxCr 3 +#define O_DMACR2__Data10RdMaxCr 24 +#define W_DMACR2__Data10RdMaxCr 3 +#define O_DMACR2__Data11WrMaxCr 21 +#define W_DMACR2__Data11WrMaxCr 3 +#define O_DMACR2__Data11RdMaxCr 18 +#define W_DMACR2__Data11RdMaxCr 3 +#define O_DMACR2__Data12WrMaxCr 15 +#define W_DMACR2__Data12WrMaxCr 3 +#define O_DMACR2__Data12RdMaxCr 12 +#define W_DMACR2__Data12RdMaxCr 3 +#define O_DMACR2__Data13WrMaxCr 9 +#define W_DMACR2__Data13WrMaxCr 3 +#define O_DMACR2__Data13RdMaxCr 6 +#define W_DMACR2__Data13RdMaxCr 3 +#define O_DMACR2__Data14WrMaxCr 3 +#define W_DMACR2__Data14WrMaxCr 3 +#define O_DMACR2__Data14RdMaxCr 0 +#define W_DMACR2__Data14RdMaxCr 3 +#define R_DMACR3 0x203 +#define O_DMACR3__Data15WrMaxCr 27 +#define W_DMACR3__Data15WrMaxCr 3 +#define O_DMACR3__Data15RdMaxCr 24 +#define W_DMACR3__Data15RdMaxCr 3 +#define O_DMACR3__SpClassWrMaxCr 21 +#define W_DMACR3__SpClassWrMaxCr 3 +#define O_DMACR3__SpClassRdMaxCr 18 +#define W_DMACR3__SpClassRdMaxCr 3 +#define O_DMACR3__JumFrInWrMaxCr 15 +#define W_DMACR3__JumFrInWrMaxCr 3 +#define O_DMACR3__JumFrInRdMaxCr 12 +#define W_DMACR3__JumFrInRdMaxCr 3 +#define O_DMACR3__RegFrInWrMaxCr 9 +#define W_DMACR3__RegFrInWrMaxCr 3 +#define O_DMACR3__RegFrInRdMaxCr 6 +#define W_DMACR3__RegFrInRdMaxCr 3 +#define O_DMACR3__FrOutWrMaxCr 3 +#define W_DMACR3__FrOutWrMaxCr 3 +#define O_DMACR3__FrOutRdMaxCr 0 +#define W_DMACR3__FrOutRdMaxCr 3 +#define R_REG_FRIN_SPILL_MEM_START_0 0x204 +#define O_REG_FRIN_SPILL_MEM_START_0__RegFrInSpillMemStart0 0 +#define W_REG_FRIN_SPILL_MEM_START_0__RegFrInSpillMemStart0 32 +#define R_REG_FRIN_SPILL_MEM_START_1 0x205 +#define O_REG_FRIN_SPILL_MEM_START_1__RegFrInSpillMemStart1 0 +#define W_REG_FRIN_SPILL_MEM_START_1__RegFrInSpillMemStart1 3 +#define R_REG_FRIN_SPILL_MEM_SIZE 0x206 +#define O_REG_FRIN_SPILL_MEM_SIZE__RegFrInSpillMemSize 0 +#define W_REG_FRIN_SPILL_MEM_SIZE__RegFrInSpillMemSize 32 +#define R_FROUT_SPILL_MEM_START_0 0x207 +#define O_FROUT_SPILL_MEM_START_0__FrOutSpillMemStart0 0 +#define W_FROUT_SPILL_MEM_START_0__FrOutSpillMemStart0 32 +#define R_FROUT_SPILL_MEM_START_1 0x208 +#define O_FROUT_SPILL_MEM_START_1__FrOutSpillMemStart1 0 +#define W_FROUT_SPILL_MEM_START_1__FrOutSpillMemStart1 3 +#define R_FROUT_SPILL_MEM_SIZE 0x209 +#define O_FROUT_SPILL_MEM_SIZE__FrOutSpillMemSize 0 +#define W_FROUT_SPILL_MEM_SIZE__FrOutSpillMemSize 32 +#define R_CLASS0_SPILL_MEM_START_0 0x20A +#define O_CLASS0_SPILL_MEM_START_0__Class0SpillMemStart0 0 +#define W_CLASS0_SPILL_MEM_START_0__Class0SpillMemStart0 32 +#define R_CLASS0_SPILL_MEM_START_1 0x20B +#define O_CLASS0_SPILL_MEM_START_1__Class0SpillMemStart1 0 +#define W_CLASS0_SPILL_MEM_START_1__Class0SpillMemStart1 3 +#define R_CLASS0_SPILL_MEM_SIZE 0x20C +#define O_CLASS0_SPILL_MEM_SIZE__Class0SpillMemSize 0 +#define W_CLASS0_SPILL_MEM_SIZE__Class0SpillMemSize 32 +#define R_JUMFRIN_SPILL_MEM_START_0 0x20D +#define O_JUMFRIN_SPILL_MEM_START_0__JumFrInSpillMemStar0 0 +#define W_JUMFRIN_SPILL_MEM_START_0__JumFrInSpillMemStar0 32 +#define R_JUMFRIN_SPILL_MEM_START_1 0x20E +#define O_JUMFRIN_SPILL_MEM_START_1__JumFrInSpillMemStart1 0 +#define W_JUMFRIN_SPILL_MEM_START_1__JumFrInSpillMemStart1 3 +#define R_JUMFRIN_SPILL_MEM_SIZE 0x20F +#define O_JUMFRIN_SPILL_MEM_SIZE__JumFrInSpillMemSize 0 +#define W_JUMFRIN_SPILL_MEM_SIZE__JumFrInSpillMemSize 32 +#define R_CLASS1_SPILL_MEM_START_0 0x210 +#define O_CLASS1_SPILL_MEM_START_0__Class1SpillMemStart0 0 +#define W_CLASS1_SPILL_MEM_START_0__Class1SpillMemStart0 32 +#define R_CLASS1_SPILL_MEM_START_1 0x211 +#define O_CLASS1_SPILL_MEM_START_1__Class1SpillMemStart1 0 +#define W_CLASS1_SPILL_MEM_START_1__Class1SpillMemStart1 3 +#define R_CLASS1_SPILL_MEM_SIZE 0x212 +#define O_CLASS1_SPILL_MEM_SIZE__Class1SpillMemSize 0 +#define W_CLASS1_SPILL_MEM_SIZE__Class1SpillMemSize 32 +#define R_CLASS2_SPILL_MEM_START_0 0x213 +#define O_CLASS2_SPILL_MEM_START_0__Class2SpillMemStart0 0 +#define W_CLASS2_SPILL_MEM_START_0__Class2SpillMemStart0 32 +#define R_CLASS2_SPILL_MEM_START_1 0x214 +#define O_CLASS2_SPILL_MEM_START_1__Class2SpillMemStart1 0 +#define W_CLASS2_SPILL_MEM_START_1__Class2SpillMemStart1 3 +#define R_CLASS2_SPILL_MEM_SIZE 0x215 +#define O_CLASS2_SPILL_MEM_SIZE__Class2SpillMemSize 0 +#define W_CLASS2_SPILL_MEM_SIZE__Class2SpillMemSize 32 +#define R_CLASS3_SPILL_MEM_START_0 0x216 +#define O_CLASS3_SPILL_MEM_START_0__Class3SpillMemStart0 0 +#define W_CLASS3_SPILL_MEM_START_0__Class3SpillMemStart0 32 +#define R_CLASS3_SPILL_MEM_START_1 0x217 +#define O_CLASS3_SPILL_MEM_START_1__Class3SpillMemStart1 0 +#define W_CLASS3_SPILL_MEM_START_1__Class3SpillMemStart1 3 +#define R_CLASS3_SPILL_MEM_SIZE 0x218 +#define O_CLASS3_SPILL_MEM_SIZE__Class3SpillMemSize 0 +#define W_CLASS3_SPILL_MEM_SIZE__Class3SpillMemSize 32 +#define R_REG_FRIN1_SPILL_MEM_START_0 0x219 +#define R_REG_FRIN1_SPILL_MEM_START_1 0x21a +#define R_REG_FRIN1_SPILL_MEM_SIZE 0x21b +#define R_SPIHNGY0 0x219 +#define O_SPIHNGY0__EG_HNGY_THRESH_0 24 +#define W_SPIHNGY0__EG_HNGY_THRESH_0 7 +#define O_SPIHNGY0__EG_HNGY_THRESH_1 16 +#define W_SPIHNGY0__EG_HNGY_THRESH_1 7 +#define O_SPIHNGY0__EG_HNGY_THRESH_2 8 +#define W_SPIHNGY0__EG_HNGY_THRESH_2 7 +#define O_SPIHNGY0__EG_HNGY_THRESH_3 0 +#define W_SPIHNGY0__EG_HNGY_THRESH_3 7 +#define R_SPIHNGY1 0x21A +#define O_SPIHNGY1__EG_HNGY_THRESH_4 24 +#define W_SPIHNGY1__EG_HNGY_THRESH_4 7 +#define O_SPIHNGY1__EG_HNGY_THRESH_5 16 +#define W_SPIHNGY1__EG_HNGY_THRESH_5 7 +#define O_SPIHNGY1__EG_HNGY_THRESH_6 8 +#define W_SPIHNGY1__EG_HNGY_THRESH_6 7 +#define O_SPIHNGY1__EG_HNGY_THRESH_7 0 +#define W_SPIHNGY1__EG_HNGY_THRESH_7 7 +#define R_SPIHNGY2 0x21B +#define O_SPIHNGY2__EG_HNGY_THRESH_8 24 +#define W_SPIHNGY2__EG_HNGY_THRESH_8 7 +#define O_SPIHNGY2__EG_HNGY_THRESH_9 16 +#define W_SPIHNGY2__EG_HNGY_THRESH_9 7 +#define O_SPIHNGY2__EG_HNGY_THRESH_10 8 +#define W_SPIHNGY2__EG_HNGY_THRESH_10 7 +#define O_SPIHNGY2__EG_HNGY_THRESH_11 0 +#define W_SPIHNGY2__EG_HNGY_THRESH_11 7 +#define R_SPIHNGY3 0x21C +#define O_SPIHNGY3__EG_HNGY_THRESH_12 24 +#define W_SPIHNGY3__EG_HNGY_THRESH_12 7 +#define O_SPIHNGY3__EG_HNGY_THRESH_13 16 +#define W_SPIHNGY3__EG_HNGY_THRESH_13 7 +#define O_SPIHNGY3__EG_HNGY_THRESH_14 8 +#define W_SPIHNGY3__EG_HNGY_THRESH_14 7 +#define O_SPIHNGY3__EG_HNGY_THRESH_15 0 +#define W_SPIHNGY3__EG_HNGY_THRESH_15 7 +#define R_SPISTRV0 0x21D +#define O_SPISTRV0__EG_STRV_THRESH_0 24 +#define W_SPISTRV0__EG_STRV_THRESH_0 7 +#define O_SPISTRV0__EG_STRV_THRESH_1 16 +#define W_SPISTRV0__EG_STRV_THRESH_1 7 +#define O_SPISTRV0__EG_STRV_THRESH_2 8 +#define W_SPISTRV0__EG_STRV_THRESH_2 7 +#define O_SPISTRV0__EG_STRV_THRESH_3 0 +#define W_SPISTRV0__EG_STRV_THRESH_3 7 +#define R_SPISTRV1 0x21E +#define O_SPISTRV1__EG_STRV_THRESH_4 24 +#define W_SPISTRV1__EG_STRV_THRESH_4 7 +#define O_SPISTRV1__EG_STRV_THRESH_5 16 +#define W_SPISTRV1__EG_STRV_THRESH_5 7 +#define O_SPISTRV1__EG_STRV_THRESH_6 8 +#define W_SPISTRV1__EG_STRV_THRESH_6 7 +#define O_SPISTRV1__EG_STRV_THRESH_7 0 +#define W_SPISTRV1__EG_STRV_THRESH_7 7 +#define R_SPISTRV2 0x21F +#define O_SPISTRV2__EG_STRV_THRESH_8 24 +#define W_SPISTRV2__EG_STRV_THRESH_8 7 +#define O_SPISTRV2__EG_STRV_THRESH_9 16 +#define W_SPISTRV2__EG_STRV_THRESH_9 7 +#define O_SPISTRV2__EG_STRV_THRESH_10 8 +#define W_SPISTRV2__EG_STRV_THRESH_10 7 +#define O_SPISTRV2__EG_STRV_THRESH_11 0 +#define W_SPISTRV2__EG_STRV_THRESH_11 7 +#define R_SPISTRV3 0x220 +#define O_SPISTRV3__EG_STRV_THRESH_12 24 +#define W_SPISTRV3__EG_STRV_THRESH_12 7 +#define O_SPISTRV3__EG_STRV_THRESH_13 16 +#define W_SPISTRV3__EG_STRV_THRESH_13 7 +#define O_SPISTRV3__EG_STRV_THRESH_14 8 +#define W_SPISTRV3__EG_STRV_THRESH_14 7 +#define O_SPISTRV3__EG_STRV_THRESH_15 0 +#define W_SPISTRV3__EG_STRV_THRESH_15 7 +#define R_TXDATAFIFO0 0x221 +#define O_TXDATAFIFO0__Tx0DataFifoStart 24 +#define W_TXDATAFIFO0__Tx0DataFifoStart 7 +#define O_TXDATAFIFO0__Tx0DataFifoSize 16 +#define W_TXDATAFIFO0__Tx0DataFifoSize 7 +#define O_TXDATAFIFO0__Tx1DataFifoStart 8 +#define W_TXDATAFIFO0__Tx1DataFifoStart 7 +#define O_TXDATAFIFO0__Tx1DataFifoSize 0 +#define W_TXDATAFIFO0__Tx1DataFifoSize 7 +#define R_TXDATAFIFO1 0x222 +#define O_TXDATAFIFO1__Tx2DataFifoStart 24 +#define W_TXDATAFIFO1__Tx2DataFifoStart 7 +#define O_TXDATAFIFO1__Tx2DataFifoSize 16 +#define W_TXDATAFIFO1__Tx2DataFifoSize 7 +#define O_TXDATAFIFO1__Tx3DataFifoStart 8 +#define W_TXDATAFIFO1__Tx3DataFifoStart 7 +#define O_TXDATAFIFO1__Tx3DataFifoSize 0 +#define W_TXDATAFIFO1__Tx3DataFifoSize 7 +#define R_TXDATAFIFO2 0x223 +#define O_TXDATAFIFO2__Tx4DataFifoStart 24 +#define W_TXDATAFIFO2__Tx4DataFifoStart 7 +#define O_TXDATAFIFO2__Tx4DataFifoSize 16 +#define W_TXDATAFIFO2__Tx4DataFifoSize 7 +#define O_TXDATAFIFO2__Tx5DataFifoStart 8 +#define W_TXDATAFIFO2__Tx5DataFifoStart 7 +#define O_TXDATAFIFO2__Tx5DataFifoSize 0 +#define W_TXDATAFIFO2__Tx5DataFifoSize 7 +#define R_TXDATAFIFO3 0x224 +#define O_TXDATAFIFO3__Tx6DataFifoStart 24 +#define W_TXDATAFIFO3__Tx6DataFifoStart 7 +#define O_TXDATAFIFO3__Tx6DataFifoSize 16 +#define W_TXDATAFIFO3__Tx6DataFifoSize 7 +#define O_TXDATAFIFO3__Tx7DataFifoStart 8 +#define W_TXDATAFIFO3__Tx7DataFifoStart 7 +#define O_TXDATAFIFO3__Tx7DataFifoSize 0 +#define W_TXDATAFIFO3__Tx7DataFifoSize 7 +#define R_TXDATAFIFO4 0x225 +#define O_TXDATAFIFO4__Tx8DataFifoStart 24 +#define W_TXDATAFIFO4__Tx8DataFifoStart 7 +#define O_TXDATAFIFO4__Tx8DataFifoSize 16 +#define W_TXDATAFIFO4__Tx8DataFifoSize 7 +#define O_TXDATAFIFO4__Tx9DataFifoStart 8 +#define W_TXDATAFIFO4__Tx9DataFifoStart 7 +#define O_TXDATAFIFO4__Tx9DataFifoSize 0 +#define W_TXDATAFIFO4__Tx9DataFifoSize 7 +#define R_TXDATAFIFO5 0x226 +#define O_TXDATAFIFO5__Tx10DataFifoStart 24 +#define W_TXDATAFIFO5__Tx10DataFifoStart 7 +#define O_TXDATAFIFO5__Tx10DataFifoSize 16 +#define W_TXDATAFIFO5__Tx10DataFifoSize 7 +#define O_TXDATAFIFO5__Tx11DataFifoStart 8 +#define W_TXDATAFIFO5__Tx11DataFifoStart 7 +#define O_TXDATAFIFO5__Tx11DataFifoSize 0 +#define W_TXDATAFIFO5__Tx11DataFifoSize 7 +#define R_TXDATAFIFO6 0x227 +#define O_TXDATAFIFO6__Tx12DataFifoStart 24 +#define W_TXDATAFIFO6__Tx12DataFifoStart 7 +#define O_TXDATAFIFO6__Tx12DataFifoSize 16 +#define W_TXDATAFIFO6__Tx12DataFifoSize 7 +#define O_TXDATAFIFO6__Tx13DataFifoStart 8 +#define W_TXDATAFIFO6__Tx13DataFifoStart 7 +#define O_TXDATAFIFO6__Tx13DataFifoSize 0 +#define W_TXDATAFIFO6__Tx13DataFifoSize 7 +#define R_TXDATAFIFO7 0x228 +#define O_TXDATAFIFO7__Tx14DataFifoStart 24 +#define W_TXDATAFIFO7__Tx14DataFifoStart 7 +#define O_TXDATAFIFO7__Tx14DataFifoSize 16 +#define W_TXDATAFIFO7__Tx14DataFifoSize 7 +#define O_TXDATAFIFO7__Tx15DataFifoStart 8 +#define W_TXDATAFIFO7__Tx15DataFifoStart 7 +#define O_TXDATAFIFO7__Tx15DataFifoSize 0 +#define W_TXDATAFIFO7__Tx15DataFifoSize 7 +#define R_RXDATAFIFO0 0x229 +#define O_RXDATAFIFO0__Rx0DataFifoStart 24 +#define W_RXDATAFIFO0__Rx0DataFifoStart 7 +#define O_RXDATAFIFO0__Rx0DataFifoSize 16 +#define W_RXDATAFIFO0__Rx0DataFifoSize 7 +#define O_RXDATAFIFO0__Rx1DataFifoStart 8 +#define W_RXDATAFIFO0__Rx1DataFifoStart 7 +#define O_RXDATAFIFO0__Rx1DataFifoSize 0 +#define W_RXDATAFIFO0__Rx1DataFifoSize 7 +#define R_RXDATAFIFO1 0x22A +#define O_RXDATAFIFO1__Rx2DataFifoStart 24 +#define W_RXDATAFIFO1__Rx2DataFifoStart 7 +#define O_RXDATAFIFO1__Rx2DataFifoSize 16 +#define W_RXDATAFIFO1__Rx2DataFifoSize 7 +#define O_RXDATAFIFO1__Rx3DataFifoStart 8 +#define W_RXDATAFIFO1__Rx3DataFifoStart 7 +#define O_RXDATAFIFO1__Rx3DataFifoSize 0 +#define W_RXDATAFIFO1__Rx3DataFifoSize 7 +#define R_RXDATAFIFO2 0x22B +#define O_RXDATAFIFO2__Rx4DataFifoStart 24 +#define W_RXDATAFIFO2__Rx4DataFifoStart 7 +#define O_RXDATAFIFO2__Rx4DataFifoSize 16 +#define W_RXDATAFIFO2__Rx4DataFifoSize 7 +#define O_RXDATAFIFO2__Rx5DataFifoStart 8 +#define W_RXDATAFIFO2__Rx5DataFifoStart 7 +#define O_RXDATAFIFO2__Rx5DataFifoSize 0 +#define W_RXDATAFIFO2__Rx5DataFifoSize 7 +#define R_RXDATAFIFO3 0x22C +#define O_RXDATAFIFO3__Rx6DataFifoStart 24 +#define W_RXDATAFIFO3__Rx6DataFifoStart 7 +#define O_RXDATAFIFO3__Rx6DataFifoSize 16 +#define W_RXDATAFIFO3__Rx6DataFifoSize 7 +#define O_RXDATAFIFO3__Rx7DataFifoStart 8 +#define W_RXDATAFIFO3__Rx7DataFifoStart 7 +#define O_RXDATAFIFO3__Rx7DataFifoSize 0 +#define W_RXDATAFIFO3__Rx7DataFifoSize 7 +#define R_RXDATAFIFO4 0x22D +#define O_RXDATAFIFO4__Rx8DataFifoStart 24 +#define W_RXDATAFIFO4__Rx8DataFifoStart 7 +#define O_RXDATAFIFO4__Rx8DataFifoSize 16 +#define W_RXDATAFIFO4__Rx8DataFifoSize 7 +#define O_RXDATAFIFO4__Rx9DataFifoStart 8 +#define W_RXDATAFIFO4__Rx9DataFifoStart 7 +#define O_RXDATAFIFO4__Rx9DataFifoSize 0 +#define W_RXDATAFIFO4__Rx9DataFifoSize 7 +#define R_RXDATAFIFO5 0x22E +#define O_RXDATAFIFO5__Rx10DataFifoStart 24 +#define W_RXDATAFIFO5__Rx10DataFifoStart 7 +#define O_RXDATAFIFO5__Rx10DataFifoSize 16 +#define W_RXDATAFIFO5__Rx10DataFifoSize 7 +#define O_RXDATAFIFO5__Rx11DataFifoStart 8 +#define W_RXDATAFIFO5__Rx11DataFifoStart 7 +#define O_RXDATAFIFO5__Rx11DataFifoSize 0 +#define W_RXDATAFIFO5__Rx11DataFifoSize 7 +#define R_RXDATAFIFO6 0x22F +#define O_RXDATAFIFO6__Rx12DataFifoStart 24 +#define W_RXDATAFIFO6__Rx12DataFifoStart 7 +#define O_RXDATAFIFO6__Rx12DataFifoSize 16 +#define W_RXDATAFIFO6__Rx12DataFifoSize 7 +#define O_RXDATAFIFO6__Rx13DataFifoStart 8 +#define W_RXDATAFIFO6__Rx13DataFifoStart 7 +#define O_RXDATAFIFO6__Rx13DataFifoSize 0 +#define W_RXDATAFIFO6__Rx13DataFifoSize 7 +#define R_RXDATAFIFO7 0x230 +#define O_RXDATAFIFO7__Rx14DataFifoStart 24 +#define W_RXDATAFIFO7__Rx14DataFifoStart 7 +#define O_RXDATAFIFO7__Rx14DataFifoSize 16 +#define W_RXDATAFIFO7__Rx14DataFifoSize 7 +#define O_RXDATAFIFO7__Rx15DataFifoStart 8 +#define W_RXDATAFIFO7__Rx15DataFifoStart 7 +#define O_RXDATAFIFO7__Rx15DataFifoSize 0 +#define W_RXDATAFIFO7__Rx15DataFifoSize 7 +#define R_XGMACPADCALIBRATION 0x231 +#define R_FREEQCARVE 0x233 +#define R_SPI4STATICDELAY0 0x240 +#define O_SPI4STATICDELAY0__DataLine7 28 +#define W_SPI4STATICDELAY0__DataLine7 4 +#define O_SPI4STATICDELAY0__DataLine6 24 +#define W_SPI4STATICDELAY0__DataLine6 4 +#define O_SPI4STATICDELAY0__DataLine5 20 +#define W_SPI4STATICDELAY0__DataLine5 4 +#define O_SPI4STATICDELAY0__DataLine4 16 +#define W_SPI4STATICDELAY0__DataLine4 4 +#define O_SPI4STATICDELAY0__DataLine3 12 +#define W_SPI4STATICDELAY0__DataLine3 4 +#define O_SPI4STATICDELAY0__DataLine2 8 +#define W_SPI4STATICDELAY0__DataLine2 4 +#define O_SPI4STATICDELAY0__DataLine1 4 +#define W_SPI4STATICDELAY0__DataLine1 4 +#define O_SPI4STATICDELAY0__DataLine0 0 +#define W_SPI4STATICDELAY0__DataLine0 4 +#define R_SPI4STATICDELAY1 0x241 +#define O_SPI4STATICDELAY1__DataLine15 28 +#define W_SPI4STATICDELAY1__DataLine15 4 +#define O_SPI4STATICDELAY1__DataLine14 24 +#define W_SPI4STATICDELAY1__DataLine14 4 +#define O_SPI4STATICDELAY1__DataLine13 20 +#define W_SPI4STATICDELAY1__DataLine13 4 +#define O_SPI4STATICDELAY1__DataLine12 16 +#define W_SPI4STATICDELAY1__DataLine12 4 +#define O_SPI4STATICDELAY1__DataLine11 12 +#define W_SPI4STATICDELAY1__DataLine11 4 +#define O_SPI4STATICDELAY1__DataLine10 8 +#define W_SPI4STATICDELAY1__DataLine10 4 +#define O_SPI4STATICDELAY1__DataLine9 4 +#define W_SPI4STATICDELAY1__DataLine9 4 +#define O_SPI4STATICDELAY1__DataLine8 0 +#define W_SPI4STATICDELAY1__DataLine8 4 +#define R_SPI4STATICDELAY2 0x242 +#define O_SPI4STATICDELAY0__TxStat1 8 +#define W_SPI4STATICDELAY0__TxStat1 4 +#define O_SPI4STATICDELAY0__TxStat0 4 +#define W_SPI4STATICDELAY0__TxStat0 4 +#define O_SPI4STATICDELAY0__RxControl 0 +#define W_SPI4STATICDELAY0__RxControl 4 +#define R_SPI4CONTROL 0x243 +#define O_SPI4CONTROL__StaticDelay 2 +#define O_SPI4CONTROL__LVDS_LVTTL 1 +#define O_SPI4CONTROL__SPI4Enable 0 +#define R_CLASSWATERMARKS 0x244 +#define O_CLASSWATERMARKS__Class0Watermark 24 +#define W_CLASSWATERMARKS__Class0Watermark 5 +#define O_CLASSWATERMARKS__Class1Watermark 16 +#define W_CLASSWATERMARKS__Class1Watermark 5 +#define O_CLASSWATERMARKS__Class3Watermark 0 +#define W_CLASSWATERMARKS__Class3Watermark 5 +#define R_RXWATERMARKS1 0x245 +#define O_RXWATERMARKS__Rx0DataWatermark 24 +#define W_RXWATERMARKS__Rx0DataWatermark 7 +#define O_RXWATERMARKS__Rx1DataWatermark 16 +#define W_RXWATERMARKS__Rx1DataWatermark 7 +#define O_RXWATERMARKS__Rx3DataWatermark 0 +#define W_RXWATERMARKS__Rx3DataWatermark 7 +#define R_RXWATERMARKS2 0x246 +#define O_RXWATERMARKS__Rx4DataWatermark 24 +#define W_RXWATERMARKS__Rx4DataWatermark 7 +#define O_RXWATERMARKS__Rx5DataWatermark 16 +#define W_RXWATERMARKS__Rx5DataWatermark 7 +#define O_RXWATERMARKS__Rx6DataWatermark 8 +#define W_RXWATERMARKS__Rx6DataWatermark 7 +#define O_RXWATERMARKS__Rx7DataWatermark 0 +#define W_RXWATERMARKS__Rx7DataWatermark 7 +#define R_RXWATERMARKS3 0x247 +#define O_RXWATERMARKS__Rx8DataWatermark 24 +#define W_RXWATERMARKS__Rx8DataWatermark 7 +#define O_RXWATERMARKS__Rx9DataWatermark 16 +#define W_RXWATERMARKS__Rx9DataWatermark 7 +#define O_RXWATERMARKS__Rx10DataWatermark 8 +#define W_RXWATERMARKS__Rx10DataWatermark 7 +#define O_RXWATERMARKS__Rx11DataWatermark 0 +#define W_RXWATERMARKS__Rx11DataWatermark 7 +#define R_RXWATERMARKS4 0x248 +#define O_RXWATERMARKS__Rx12DataWatermark 24 +#define W_RXWATERMARKS__Rx12DataWatermark 7 +#define O_RXWATERMARKS__Rx13DataWatermark 16 +#define W_RXWATERMARKS__Rx13DataWatermark 7 +#define O_RXWATERMARKS__Rx14DataWatermark 8 +#define W_RXWATERMARKS__Rx14DataWatermark 7 +#define O_RXWATERMARKS__Rx15DataWatermark 0 +#define W_RXWATERMARKS__Rx15DataWatermark 7 +#define R_FREEWATERMARKS 0x249 +#define O_FREEWATERMARKS__FreeOutWatermark 16 +#define W_FREEWATERMARKS__FreeOutWatermark 16 +#define O_FREEWATERMARKS__JumFrWatermark 8 +#define W_FREEWATERMARKS__JumFrWatermark 7 +#define O_FREEWATERMARKS__RegFrWatermark 0 +#define W_FREEWATERMARKS__RegFrWatermark 7 +#define R_EGRESSFIFOCARVINGSLOTS 0x24a + +#define CTRL_RES0 0 +#define CTRL_RES1 1 +#define CTRL_REG_FREE 2 +#define CTRL_JUMBO_FREE 3 +#define CTRL_CONT 4 +#define CTRL_EOP 5 +#define CTRL_START 6 +#define CTRL_SNGL 7 + +#define CTRL_B0_NOT_EOP 0 +#define CTRL_B0_EOP 1 + +#define R_ROUND_ROBIN_TABLE 0 +#define R_PDE_CLASS_0 0x300 +#define R_PDE_CLASS_1 0x302 +#define R_PDE_CLASS_2 0x304 +#define R_PDE_CLASS_3 0x306 + +#define R_MSG_TX_THRESHOLD 0x308 + +#define R_GMAC_JFR0_BUCKET_SIZE 0x320 +#define R_GMAC_RFR0_BUCKET_SIZE 0x321 +#define R_GMAC_TX0_BUCKET_SIZE 0x322 +#define R_GMAC_TX1_BUCKET_SIZE 0x323 +#define R_GMAC_TX2_BUCKET_SIZE 0x324 +#define R_GMAC_TX3_BUCKET_SIZE 0x325 +#define R_GMAC_JFR1_BUCKET_SIZE 0x326 +#define R_GMAC_RFR1_BUCKET_SIZE 0x327 + +#define R_XGS_TX0_BUCKET_SIZE 0x320 +#define R_XGS_TX1_BUCKET_SIZE 0x321 +#define R_XGS_TX2_BUCKET_SIZE 0x322 +#define R_XGS_TX3_BUCKET_SIZE 0x323 +#define R_XGS_TX4_BUCKET_SIZE 0x324 +#define R_XGS_TX5_BUCKET_SIZE 0x325 +#define R_XGS_TX6_BUCKET_SIZE 0x326 +#define R_XGS_TX7_BUCKET_SIZE 0x327 +#define R_XGS_TX8_BUCKET_SIZE 0x328 +#define R_XGS_TX9_BUCKET_SIZE 0x329 +#define R_XGS_TX10_BUCKET_SIZE 0x32A +#define R_XGS_TX11_BUCKET_SIZE 0x32B +#define R_XGS_TX12_BUCKET_SIZE 0x32C +#define R_XGS_TX13_BUCKET_SIZE 0x32D +#define R_XGS_TX14_BUCKET_SIZE 0x32E +#define R_XGS_TX15_BUCKET_SIZE 0x32F +#define R_XGS_JFR_BUCKET_SIZE 0x330 +#define R_XGS_RFR_BUCKET_SIZE 0x331 + +#define R_CC_CPU0_0 0x380 +#define R_CC_CPU1_0 0x388 +#define R_CC_CPU2_0 0x390 +#define R_CC_CPU3_0 0x398 +#define R_CC_CPU4_0 0x3a0 +#define R_CC_CPU5_0 0x3a8 +#define R_CC_CPU6_0 0x3b0 +#define R_CC_CPU7_0 0x3b8 + +struct size_1_desc { + uint64_t entry0; +}; + +struct size_2_desc { + uint64_t entry0; + uint64_t entry1; +}; + +struct size_3_desc { + uint64_t entry0; + uint64_t entry1; + uint64_t entry2; +}; + +struct size_4_desc { + uint64_t entry0; + uint64_t entry1; + uint64_t entry2; + uint64_t entry3; +}; + +struct fr_desc { + struct size_1_desc d1; +}; + +union rx_tx_desc { + struct size_2_desc d2; + /* struct size_3_desc d3; */ + /* struct size_4_desc d4; */ +}; + + +extern unsigned char xlr_base_mac_addr[]; + +#endif diff --git a/sys/dev/rmi/xlr/xgmac_mdio.h b/sys/dev/rmi/xlr/xgmac_mdio.h new file mode 100644 index 00000000000..7a8208e1eb2 --- /dev/null +++ b/sys/dev/rmi/xlr/xgmac_mdio.h @@ -0,0 +1,127 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ +/* MDIO Low level Access routines */ +/* All Phy's accessed from GMAC0 base */ + +#ifndef _XGMAC_MDIO_H_ +#define _XGMAC_MDIO_H_ + +static inline int +xmdio_read(volatile unsigned int *_mmio, + uint32_t phy_addr, uint32_t address); +static inline void +xmdio_write(volatile unsigned int *_mmio, + uint32_t phy_addr, uint32_t address, uint32_t data); +static inline void +xmdio_address(volatile unsigned int *_mmio, + uint32_t phy_addr, uint32_t dev_ad, uint32_t address); + +static inline void +xmdio_address(volatile unsigned int *_mmio, + uint32_t phy_addr, uint32_t dev_ad, uint32_t address) +{ + uint32_t st_field = 0x0; + uint32_t op_type = 0x0; /* address operation */ + uint32_t ta_field = 0x2; /* ta field */ + + _mmio[0x11] = ((st_field & 0x3) << 30) | + ((op_type & 0x3) << 28) | + ((phy_addr & 0x1F) << 23) | + ((dev_ad & 0x1F) << 18) | + ((ta_field & 0x3) << 16) | + ((address & 0xffff) << 0); + + _mmio[0x10] = (0x0 << 3) | 0x5; + _mmio[0x10] = (0x1 << 3) | 0x5; + _mmio[0x10] = (0x0 << 3) | 0x5; + + /* wait for dev_ad cycle to complete */ + while (_mmio[0x14] & 0x1) { + }; + +} + +/* function prototypes */ +static inline int +xmdio_read(volatile unsigned int *_mmio, + uint32_t phy_addr, uint32_t address) +{ + uint32_t st_field = 0x0; + uint32_t op_type = 0x3; /* read operation */ + uint32_t ta_field = 0x2; /* ta field */ + uint32_t data = 0; + + xmdio_address(_mmio, phy_addr, 5, address); + _mmio[0x11] = ((st_field & 0x3) << 30) | + ((op_type & 0x3) << 28) | + ((phy_addr & 0x1F) << 23) | + ((5 & 0x1F) << 18) | + ((ta_field & 0x3) << 16) | + ((data & 0xffff) << 0); + + _mmio[0x10] = (0x0 << 3) | 0x5; + _mmio[0x10] = (0x1 << 3) | 0x5; + _mmio[0x10] = (0x0 << 3) | 0x5; + + /* wait for write cycle to complete */ + while (_mmio[0x14] & 0x1) { + }; + + data = _mmio[0x11] & 0xffff; + return (data); +} + +static inline void +xmdio_write(volatile unsigned int *_mmio, + uint32_t phy_addr, uint32_t address, uint32_t data) +{ + uint32_t st_field = 0x0; + uint32_t op_type = 0x1; /* write operation */ + uint32_t ta_field = 0x2; /* ta field */ + + xmdio_address(_mmio, phy_addr, 5, address); + _mmio[0x11] = ((st_field & 0x3) << 30) | + ((op_type & 0x3) << 28) | + ((phy_addr & 0x1F) << 23) | + ((5 & 0x1F) << 18) | + ((ta_field & 0x3) << 16) | + ((data & 0xffff) << 0); + + _mmio[0x10] = (0x0 << 3) | 0x5; + _mmio[0x10] = (0x1 << 3) | 0x5; + _mmio[0x10] = (0x0 << 3) | 0x5; + + /* wait for write cycle to complete */ + while (_mmio[0x14] & 0x1) { + }; + +} + +#endif From 257c916acf065e8d1af29db4532a0ac57c0ba4d9 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Thu, 15 Oct 2009 21:14:42 +0000 Subject: [PATCH 262/380] More initial RMI files. Note that these so far do NOT compile and many of them may disappear. For example the xlr_boot1_console.c is old code that is ifdef'd out. I will clean these sorts of things up as I make progress on the port. So far the only thing I have I think straightened out is the bits around the interupt handling... and hey that may be broke ;-) --- sys/mips/rmi/Makefile.msgring | 14 + sys/mips/rmi/board.c | 178 ++++ sys/mips/rmi/board.h | 275 ++++++ sys/mips/rmi/clock.c | 213 +++++ sys/mips/rmi/clock.h | 40 + sys/mips/rmi/debug.h | 103 +++ sys/mips/rmi/interrupt.h | 43 + sys/mips/rmi/iodi.c | 272 ++++++ sys/mips/rmi/iomap.h | 110 +++ sys/mips/rmi/msgring.c | 318 +++++++ sys/mips/rmi/msgring.cfg | 1182 +++++++++++++++++++++++++ sys/mips/rmi/msgring.h | 507 +++++++++++ sys/mips/rmi/msgring_xls.c | 218 +++++ sys/mips/rmi/msgring_xls.cfg | 563 ++++++++++++ sys/mips/rmi/on_chip.c | 313 +++++++ sys/mips/rmi/pcibus.c | 328 +++++++ sys/mips/rmi/pcibus.h | 49 + sys/mips/rmi/perfmon.h | 168 ++++ sys/mips/rmi/perfmon_kern.c | 162 ++++ sys/mips/rmi/perfmon_percpu.c | 299 +++++++ sys/mips/rmi/perfmon_utils.h | 113 +++ sys/mips/rmi/perfmon_xlrconfig.h | 156 ++++ sys/mips/rmi/pic.h | 257 ++++++ sys/mips/rmi/shared_structs.h | 108 +++ sys/mips/rmi/shared_structs_func.h | 54 ++ sys/mips/rmi/shared_structs_offsets.h | 76 ++ sys/mips/rmi/uart_bus_xlr_iodi.c | 73 ++ sys/mips/rmi/uart_cpu_mips_xlr.c | 171 ++++ sys/mips/rmi/xlr_boot1_console.c | 113 +++ sys/mips/rmi/xlr_csum_nocopy.S | 217 +++++ sys/mips/rmi/xlr_i2c.c | 442 +++++++++ sys/mips/rmi/xlr_machdep.c | 650 ++++++++++++++ sys/mips/rmi/xlr_pci.c | 410 +++++++++ sys/mips/rmi/xlrconfig.h | 327 +++++++ sys/mips/rmi/xls_ehci.c | 305 +++++++ 35 files changed, 8827 insertions(+) create mode 100644 sys/mips/rmi/Makefile.msgring create mode 100644 sys/mips/rmi/board.c create mode 100644 sys/mips/rmi/board.h create mode 100644 sys/mips/rmi/clock.c create mode 100644 sys/mips/rmi/clock.h create mode 100755 sys/mips/rmi/debug.h create mode 100644 sys/mips/rmi/interrupt.h create mode 100644 sys/mips/rmi/iodi.c create mode 100644 sys/mips/rmi/iomap.h create mode 100644 sys/mips/rmi/msgring.c create mode 100644 sys/mips/rmi/msgring.cfg create mode 100755 sys/mips/rmi/msgring.h create mode 100644 sys/mips/rmi/msgring_xls.c create mode 100755 sys/mips/rmi/msgring_xls.cfg create mode 100644 sys/mips/rmi/on_chip.c create mode 100644 sys/mips/rmi/pcibus.c create mode 100644 sys/mips/rmi/pcibus.h create mode 100644 sys/mips/rmi/perfmon.h create mode 100644 sys/mips/rmi/perfmon_kern.c create mode 100644 sys/mips/rmi/perfmon_percpu.c create mode 100644 sys/mips/rmi/perfmon_utils.h create mode 100644 sys/mips/rmi/perfmon_xlrconfig.h create mode 100644 sys/mips/rmi/pic.h create mode 100755 sys/mips/rmi/shared_structs.h create mode 100755 sys/mips/rmi/shared_structs_func.h create mode 100755 sys/mips/rmi/shared_structs_offsets.h create mode 100644 sys/mips/rmi/uart_bus_xlr_iodi.c create mode 100644 sys/mips/rmi/uart_cpu_mips_xlr.c create mode 100644 sys/mips/rmi/xlr_boot1_console.c create mode 100644 sys/mips/rmi/xlr_csum_nocopy.S create mode 100644 sys/mips/rmi/xlr_i2c.c create mode 100644 sys/mips/rmi/xlr_machdep.c create mode 100644 sys/mips/rmi/xlr_pci.c create mode 100644 sys/mips/rmi/xlrconfig.h create mode 100644 sys/mips/rmi/xls_ehci.c diff --git a/sys/mips/rmi/Makefile.msgring b/sys/mips/rmi/Makefile.msgring new file mode 100644 index 00000000000..d04978e5d1f --- /dev/null +++ b/sys/mips/rmi/Makefile.msgring @@ -0,0 +1,14 @@ +RM = rm +MSGRNG_CFG = msgring.cfg + +MSGRNG_CFG_C = $(patsubst %.cfg,%.c,$(MSGRNG_CFG)) + +#all: msgring.l msgring.y msgring.cfg +all: $(MSGRNG_CFG) + flex -omsgring.lex.c msgring.l + bison -d -omsgring.yacc.c msgring.y + gcc -g3 msgring.lex.c msgring.yacc.c -o msgring + ./msgring -i $(MSGRNG_CFG) -o $(MSGRNG_CFG_C) + +clean: + $(RM) -f msgring.lex.c msgring.yacc.c msgring.yacc.h msgring msgring.o* diff --git a/sys/mips/rmi/board.c b/sys/mips/rmi/board.c new file mode 100644 index 00000000000..44a80151ea5 --- /dev/null +++ b/sys/mips/rmi/board.c @@ -0,0 +1,178 @@ +/********************************************************************* + * + * Copyright 2003-2006 Raza Microelectronics, Inc. (RMI). All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY Raza Microelectronics, Inc. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RMI OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES, LOSS OF USE, DATA, OR PROFITS, OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * *****************************RMI_2**********************************/ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static int xlr_rxstn_to_txstn_map[128] = { + [0 ... 7] = TX_STN_CPU_0, + [8 ... 15] = TX_STN_CPU_1, + [16 ... 23] = TX_STN_CPU_2, + [24 ... 31] = TX_STN_CPU_3, + [32 ... 39] = TX_STN_CPU_4, + [40 ... 47] = TX_STN_CPU_5, + [48 ... 55] = TX_STN_CPU_6, + [56 ... 63] = TX_STN_CPU_7, + [64 ... 95] = TX_STN_INVALID, + [96 ... 103] = TX_STN_GMAC, + [104 ... 107] = TX_STN_DMA, + [108 ... 111] = TX_STN_INVALID, + [112 ... 113] = TX_STN_XGS_0, + [114 ... 115] = TX_STN_XGS_1, + [116 ... 119] = TX_STN_INVALID, + [120 ... 127] = TX_STN_SAE +}; + +static int xls_rxstn_to_txstn_map[128] = { + [0 ... 7] = TX_STN_CPU_0, + [8 ... 15] = TX_STN_CPU_1, + [16 ... 23] = TX_STN_CPU_2, + [24 ... 31] = TX_STN_CPU_3, + [32 ... 63] = TX_STN_INVALID, + [64 ... 71] = TX_STN_PCIE, + [72 ... 79] = TX_STN_INVALID, + [80 ... 87] = TX_STN_GMAC1, + [88 ... 95] = TX_STN_INVALID, + [96 ... 103] = TX_STN_GMAC0, + [104 ... 107] = TX_STN_DMA, + [108 ... 111] = TX_STN_CDE, + [112 ... 119] = TX_STN_INVALID, + [120 ... 127] = TX_STN_SAE +}; + +struct stn_cc *xlr_core_cc_configs[] = {&cc_table_cpu_0, &cc_table_cpu_1, + &cc_table_cpu_2, &cc_table_cpu_3, + &cc_table_cpu_4, &cc_table_cpu_5, + &cc_table_cpu_6, &cc_table_cpu_7 }; + +struct stn_cc *xls_core_cc_configs[] = {&xls_cc_table_cpu_0, &xls_cc_table_cpu_1, + &xls_cc_table_cpu_2, &xls_cc_table_cpu_3}; + +struct xlr_board_info xlr_board_info; + +/* + * All our knowledge of chip and board that cannot be detected by probing + * at run-time goes here + */ +int xlr_board_info_setup() +{ + if (xlr_is_xls()) { + xlr_board_info.is_xls = 1; + xlr_board_info.nr_cpus = 8; + xlr_board_info.usb = 1; + xlr_board_info.cfi = + (xlr_boot1_info.board_major_version != RMI_XLR_BOARD_ARIZONA_VIII); + xlr_board_info.pci_irq = 0; + xlr_board_info.credit_configs = xls_core_cc_configs; + xlr_board_info.bucket_sizes = &xls_bucket_sizes; + xlr_board_info.msgmap = xls_rxstn_to_txstn_map; + xlr_board_info.gmacports = 8; + + /* network block 0 */ + xlr_board_info.gmac_block[0].type = XLR_GMAC; + xlr_board_info.gmac_block[0].enabled = 0xf; + xlr_board_info.gmac_block[0].credit_config = &xls_cc_table_gmac0; + xlr_board_info.gmac_block[0].station_txbase = MSGRNG_STNID_GMACTX0; + xlr_board_info.gmac_block[0].station_rfr = MSGRNG_STNID_GMACRFR_0; + if (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_VI) + xlr_board_info.gmac_block[0].mode = XLR_PORT0_RGMII; + else + xlr_board_info.gmac_block[0].mode = XLR_SGMII; + xlr_board_info.gmac_block[0].baseaddr = XLR_IO_GMAC_0_OFFSET; + xlr_board_info.gmac_block[0].baseirq = PIC_GMAC_0_IRQ; + xlr_board_info.gmac_block[0].baseinst = 0; + + /* network block 1 */ + xlr_board_info.gmac_block[1].type = XLR_GMAC; + xlr_board_info.gmac_block[1].enabled = 0xf; + xlr_board_info.gmac_block[1].credit_config = &xls_cc_table_gmac1; + xlr_board_info.gmac_block[1].station_txbase = MSGRNG_STNID_GMAC1_TX0; + xlr_board_info.gmac_block[1].station_rfr = MSGRNG_STNID_GMAC1_FR_0; + xlr_board_info.gmac_block[1].mode = XLR_SGMII; + xlr_board_info.gmac_block[1].baseaddr = XLR_IO_GMAC_4_OFFSET; + xlr_board_info.gmac_block[1].baseirq = PIC_XGS_0_IRQ; + xlr_board_info.gmac_block[1].baseinst = 4; + + /* network block 2 */ + xlr_board_info.gmac_block[2].enabled = 0; /* disabled on XLS */ + } else { + xlr_board_info.is_xls = 0; + xlr_board_info.nr_cpus = 32; + xlr_board_info.usb = 0; + xlr_board_info.cfi = 1; + xlr_board_info.pci_irq = 0; + xlr_board_info.credit_configs = xlr_core_cc_configs; + xlr_board_info.bucket_sizes = &bucket_sizes; + xlr_board_info.msgmap = xlr_rxstn_to_txstn_map; + xlr_board_info.gmacports = 4; + + /* GMAC0 */ + xlr_board_info.gmac_block[0].type = XLR_GMAC; + xlr_board_info.gmac_block[0].enabled = 0xf; + xlr_board_info.gmac_block[0].credit_config = &cc_table_gmac; + xlr_board_info.gmac_block[0].station_txbase = MSGRNG_STNID_GMACTX0; + xlr_board_info.gmac_block[0].station_rfr = MSGRNG_STNID_GMACRFR_0; + xlr_board_info.gmac_block[0].mode = XLR_RGMII; + xlr_board_info.gmac_block[0].baseaddr = XLR_IO_GMAC_0_OFFSET; + xlr_board_info.gmac_block[0].baseirq = PIC_GMAC_0_IRQ; + xlr_board_info.gmac_block[0].baseinst = 0; + + /* XGMAC0 */ + xlr_board_info.gmac_block[1].type = XLR_XGMAC; + xlr_board_info.gmac_block[1].enabled = 1; + xlr_board_info.gmac_block[1].credit_config = &cc_table_xgs_0; + xlr_board_info.gmac_block[1].station_txbase = MSGRNG_STNID_XGS0_TX; + xlr_board_info.gmac_block[1].station_rfr = MSGRNG_STNID_XGS0FR; + xlr_board_info.gmac_block[1].mode = -1; + xlr_board_info.gmac_block[1].baseaddr = XLR_IO_XGMAC_0_OFFSET; + xlr_board_info.gmac_block[1].baseirq = PIC_XGS_0_IRQ; + xlr_board_info.gmac_block[1].baseinst = 4; + + /* XGMAC1 */ + xlr_board_info.gmac_block[2].type = XLR_XGMAC; + xlr_board_info.gmac_block[2].enabled = 1; + xlr_board_info.gmac_block[2].credit_config = &cc_table_xgs_1; + xlr_board_info.gmac_block[2].station_txbase = MSGRNG_STNID_XGS1_TX; + xlr_board_info.gmac_block[2].station_rfr = MSGRNG_STNID_XGS1FR; + xlr_board_info.gmac_block[2].mode = -1; + xlr_board_info.gmac_block[2].baseaddr = XLR_IO_XGMAC_1_OFFSET; + xlr_board_info.gmac_block[2].baseirq = PIC_XGS_1_IRQ; + xlr_board_info.gmac_block[2].baseinst = 5; + } + return 0; +} diff --git a/sys/mips/rmi/board.h b/sys/mips/rmi/board.h new file mode 100644 index 00000000000..b296d14804a --- /dev/null +++ b/sys/mips/rmi/board.h @@ -0,0 +1,275 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ +#ifndef _RMI_BOARD_H_ +#define _RMI_BOARD_H_ + +#define RMI_XLR_BOARD_ARIZONA_I 1 +#define RMI_XLR_BOARD_ARIZONA_II 2 +#define RMI_XLR_BOARD_ARIZONA_III 3 +#define RMI_XLR_BOARD_ARIZONA_IV 4 +#define RMI_XLR_BOARD_ARIZONA_V 5 +#define RMI_XLR_BOARD_ARIZONA_VI 6 +#define RMI_XLR_BOARD_ARIZONA_VII 7 +#define RMI_XLR_BOARD_ARIZONA_VIII 8 + +#define RMI_CHIP_XLR308_A0 0x0c0600 +#define RMI_CHIP_XLR508_A0 0x0c0700 +#define RMI_CHIP_XLR516_A0 0x0c0800 +#define RMI_CHIP_XLR532_A0 0x0c0900 +#define RMI_CHIP_XLR716_A0 0x0c0a00 +#define RMI_CHIP_XLR732_A0 0x0c0b00 + +#define RMI_CHIP_XLR308_A1 0x0c0601 +#define RMI_CHIP_XLR508_A1 0x0c0701 +#define RMI_CHIP_XLR516_A1 0x0c0801 +#define RMI_CHIP_XLR532_A1 0x0c0901 +#define RMI_CHIP_XLR716_A1 0x0c0a01 +#define RMI_CHIP_XLR732_A1 0x0c0b01 + +#define RMI_CHIP_XLR308_B0 0x0c0602 +#define RMI_CHIP_XLR508_B0 0x0c0702 +#define RMI_CHIP_XLR516_B0 0x0c0802 +#define RMI_CHIP_XLR532_B0 0x0c0902 +#define RMI_CHIP_XLR716_B0 0x0c0a02 +#define RMI_CHIP_XLR732_B0 0x0c0b02 + +#define RMI_CHIP_XLR308_B1 0x0c0603 +#define RMI_CHIP_XLR508_B1 0x0c0703 +#define RMI_CHIP_XLR516_B1 0x0c0803 +#define RMI_CHIP_XLR532_B1 0x0c0903 +#define RMI_CHIP_XLR716_B1 0x0c0a03 +#define RMI_CHIP_XLR732_B1 0x0c0b03 + +#define RMI_CHIP_XLR308_B2 0x0c0604 +#define RMI_CHIP_XLR508_B2 0x0c0704 +#define RMI_CHIP_XLR516_B2 0x0c0804 +#define RMI_CHIP_XLR532_B2 0x0c0904 +#define RMI_CHIP_XLR716_B2 0x0c0a04 +#define RMI_CHIP_XLR732_B2 0x0c0b04 + +#define RMI_CHIP_XLR308_C0 0x0c0705 +#define RMI_CHIP_XLR508_C0 0x0c0b05 +#define RMI_CHIP_XLR516_C0 0x0c0a05 +#define RMI_CHIP_XLR532_C0 0x0c0805 +#define RMI_CHIP_XLR716_C0 0x0c0205 +#define RMI_CHIP_XLR732_C0 0x0c0005 + +#define RMI_CHIP_XLR308_C1 0x0c0706 +#define RMI_CHIP_XLR508_C1 0x0c0b06 +#define RMI_CHIP_XLR516_C1 0x0c0a06 +#define RMI_CHIP_XLR532_C1 0x0c0806 +#define RMI_CHIP_XLR716_C1 0x0c0206 +#define RMI_CHIP_XLR732_C1 0x0c0006 + +#define RMI_CHIP_XLR308_C2 0x0c0707 +#define RMI_CHIP_XLR508_C2 0x0c0b07 +#define RMI_CHIP_XLR516_C2 0x0c0a07 +#define RMI_CHIP_XLR532_C2 0x0c0807 +#define RMI_CHIP_XLR716_C2 0x0c0207 +#define RMI_CHIP_XLR732_C2 0x0c0007 + +#define RMI_CHIP_XLR308_C3 0x0c0708 +#define RMI_CHIP_XLR508_C3 0x0c0b08 +#define RMI_CHIP_XLR516_C3 0x0c0a08 +#define RMI_CHIP_XLR532_C3 0x0c0808 +#define RMI_CHIP_XLR716_C3 0x0c0208 +#define RMI_CHIP_XLR732_C3 0x0c0008 + +#define RMI_CHIP_XLR308_C4 0x0c0709 +#define RMI_CHIP_XLR508_C4 0x0c0b09 +#define RMI_CHIP_XLR516_C4 0x0c0a09 +#define RMI_CHIP_XLR532_C4 0x0c0809 +#define RMI_CHIP_XLR716_C4 0x0c0209 +#define RMI_CHIP_XLR732_C4 0x0c0009 + +#define RMI_CHIP_XLS608_A0 0x0c8000 +#define RMI_CHIP_XLS408_A0 0x0c8800 +#define RMI_CHIP_XLS404_A0 0x0c8c00 +#define RMI_CHIP_XLS208_A0 0x0c8e00 +#define RMI_CHIP_XLS204_A0 0x0c8f00 + +#define RMI_CHIP_XLS608_A1 0x0c8001 +#define RMI_CHIP_XLS408_A1 0x0c8801 +#define RMI_CHIP_XLS404_A1 0x0c8c01 +#define RMI_CHIP_XLS208_A1 0x0c8e01 +#define RMI_CHIP_XLS204_A1 0x0c8f01 + +static __inline__ unsigned int +xlr_revision(void) +{ + return mips_rd_prid() & 0xff00ff; +} + +static __inline__ unsigned int +xlr_is_xls(void) +{ + uint32_t prid = mips_rd_prid(); + + return (prid & 0xf000) == 0x8000 || (prid & 0xf000) == 0x4000; +} + +static __inline__ int +xlr_revision_a0(void) +{ + return xlr_revision() == 0x0c0000; +} + +static __inline__ int +xlr_revision_b0(void) +{ + return xlr_revision() == 0x0c0002; +} + +static __inline__ int +xlr_revision_b1(void) +{ + return xlr_revision() == 0x0c0003; +} + +static __inline__ int +xlr_board_atx_i(void) +{ + return xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_I; +} + +static __inline__ int +xlr_board_atx_ii(void) +{ + return xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_II; +} + +static __inline__ int +xlr_board_atx_ii_b(void) +{ + return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_II) + && (xlr_boot1_info.board_minor_version == 1); +} + +static __inline__ int +xlr_board_atx_iii(void) +{ + return xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_III; +} + +static __inline__ int +xlr_board_atx_iv(void) +{ + return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_IV) + && (xlr_boot1_info.board_minor_version == 0); } +static __inline__ int +xlr_board_atx_iv_b(void) +{ + return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_IV) + && (xlr_boot1_info.board_minor_version == 1); +} +static __inline__ int +xlr_board_atx_v(void) +{ + return xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_V; +} +static __inline__ int +xlr_board_atx_vi(void) +{ + return xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_VI; +} + +static __inline__ int +xlr_board_atx_iii_256(void) +{ + return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_III) + && (xlr_boot1_info.board_minor_version == 0); +} + +static __inline__ int +xlr_board_atx_iii_512(void) +{ + return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_III) + && (xlr_boot1_info.board_minor_version == 1); +} + +static __inline__ int +xlr_board_atx_v_512(void) +{ + return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_V) + && (xlr_boot1_info.board_minor_version == 1); +} + +static __inline__ int +xlr_board_pci(void) +{ + return (xlr_board_atx_iii_256() || xlr_board_atx_iii_512() + || xlr_board_atx_v_512()); +} +static __inline__ int +xlr_is_xls2xx(void) +{ + uint32_t chipid = mips_rd_prid() & 0xffffff00U; + + return chipid == 0x0c8e00 || chipid == 0x0c8f00; +} + +static __inline__ int +xlr_is_xls4xx(void) +{ + uint32_t chipid = mips_rd_prid() & 0xffffff00U; + + return chipid == 0x0c8800 || chipid == 0x0c8c00; +} + +/* all our knowledge of chip and board that cannot be detected run-time goes here */ +enum gmac_block_types { XLR_GMAC, XLR_XGMAC, XLR_SPI4}; +enum gmac_block_modes { XLR_RGMII, XLR_SGMII, XLR_PORT0_RGMII }; +struct xlr_board_info { + int is_xls; + int nr_cpus; + int usb; /* usb enabled ? */ + int cfi; /* compact flash driver for NOR? */ + int pci_irq; + struct stn_cc **credit_configs; /* pointer to Core station credits */ + struct bucket_size *bucket_sizes; /* pointer to Core station bucket */ + int *msgmap; /* mapping of message station to devices */ + int gmacports; /* number of gmac ports on the board */ + struct xlr_gmac_block_t { + int type; /* see enum gmac_block_types */ + unsigned int enabled; /* mask of ports enabled */ + struct stn_cc *credit_config; /* credit configuration */ + int station_txbase; /* station id for tx */ + int station_rfr; /* free desc bucket */ + int mode; /* see gmac_block_modes */ + uint32_t baseaddr; /* IO base */ + int baseirq; /* first irq for this block, the rest are in sequence */ + int baseinst; /* the first rge unit for this block */ + } gmac_block [3]; +}; + +extern struct xlr_board_info xlr_board_info; +int xlr_board_info_setup(void); + +#endif diff --git a/sys/mips/rmi/clock.c b/sys/mips/rmi/clock.c new file mode 100644 index 00000000000..44ba886c2f3 --- /dev/null +++ b/sys/mips/rmi/clock.c @@ -0,0 +1,213 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ + +#include /* RCS ID & Copyright macro defns */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifdef XLR_PERFMON +#include +#endif + +int hw_clockrate; +SYSCTL_INT(_hw, OID_AUTO, clockrate, CTLFLAG_RD, &hw_clockrate, + 0, "CPU instruction clock rate"); + +#define STAT_PROF_CLOCK_SCALE_FACTOR 8 + +static int scale_factor; +static int count_scale_factor[32]; + +uint64_t platform_get_frequency() +{ + return XLR_PIC_HZ; +} + +/* +* count_compare_clockhandler: +* +* Handle the clock interrupt when count becomes equal to +* compare. +*/ +void +count_compare_clockhandler(struct trapframe *tf) +{ + int cpu = PCPU_GET(cpuid); + uint32_t cycles; + + critical_enter(); + + if (cpu == 0) { + mips_wr_compare(0); + } + else { + count_scale_factor[cpu]++; + cycles = mips_rd_count(); + cycles += XLR_CPU_HZ/hz; + mips_wr_compare(cycles); + + hardclock_process((struct clockframe *)tf); + if (count_scale_factor[cpu] == STAT_PROF_CLOCK_SCALE_FACTOR) { + statclock((struct clockframe *)tf); + if(profprocs != 0) { + profclock((struct clockframe *)tf); + } + count_scale_factor[cpu] = 0; + } + + /* If needed , handle count compare tick skew here */ + } + + critical_exit(); +} + +void +pic_hardclockhandler(struct trapframe *tf) +{ + int cpu = PCPU_GET(cpuid); + + critical_enter(); + + if (cpu == 0) { + scale_factor++; + hardclock((struct clockframe *)tf); + if (scale_factor == STAT_PROF_CLOCK_SCALE_FACTOR) { + statclock((struct clockframe *)tf); + if(profprocs != 0) { + profclock((struct clockframe *)tf); + } + scale_factor = 0; + } +#ifdef XLR_PERFMON + if (xlr_perfmon_started) + xlr_perfmon_clockhandler(); +#endif + + } + else { + /* If needed , handle count compare tick skew here */ + } + + critical_exit(); +} + +void +pic_timecounthandler(struct trapframe *tf) +{ +} + +void +platform_initclocks(void) +{ + int cpu = PCPU_GET(cpuid); + void *cookie; + + /* Note: Passing #3 as NULL ensures that clockhandler + * gets called with trapframe + */ + /* profiling/process accounting timer interrupt for non-zero cpus */ + cpu_establish_intr("compare", IRQ_TIMER, + (driver_intr_t *)count_compare_clockhandler, + NULL, INTR_TYPE_CLK|INTR_FAST, &cookie, NULL, NULL); + + /* timekeeping timer interrupt for cpu 0 */ + cpu_establish_intr("hardclk", PIC_TIMER_7_IRQ, + (driver_intr_t *)pic_hardclockhandler, + NULL, INTR_TYPE_CLK|INTR_FAST, &cookie, NULL, NULL); + + /* this is used by timecounter */ + cpu_establish_intr("timecount", PIC_TIMER_6_IRQ, + (driver_intr_t *)pic_timecounthandler, + NULL, INTR_TYPE_CLK|INTR_FAST, &cookie, NULL, NULL); + + if (cpu == 0) { + __uint64_t maxval = XLR_PIC_HZ/hz; + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + + stathz = hz / STAT_PROF_CLOCK_SCALE_FACTOR; + profhz = stathz; + + /* Setup PIC Interrupt */ + + mtx_lock_spin(&xlr_pic_lock); + xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_0, (maxval & 0xffffffff)); + xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_1, (maxval >> 32) & 0xffffffff); + xlr_write_reg(mmio, PIC_IRT_0_TIMER_7, (1 << cpu)); + xlr_write_reg(mmio, PIC_IRT_1_TIMER_7, (1<<31)|(0<<30)|(1<<6)|(PIC_TIMER_7_IRQ)); + pic_update_control(1<<(8+7)); + + xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_0, (0xffffffff & 0xffffffff)); + xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_1, (0x0) & 0xffffffff); + xlr_write_reg(mmio, PIC_IRT_0_TIMER_6, (1 << cpu)); + xlr_write_reg(mmio, PIC_IRT_1_TIMER_6, (1<<31)|(0<<30)|(1<<6)|(PIC_TIMER_6_IRQ)); + pic_update_control(1<<(8+6)); + mtx_unlock_spin(&xlr_pic_lock); + } else { + /* Setup count-compare interrupt for vcpu[1-31] */ + mips_wr_compare((xlr_boot1_info.cpu_frequency)/hz); + } +} + + + +unsigned __attribute__((no_instrument_function)) +platform_get_timecount(struct timecounter *tc) +{ + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + + return 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_0); +} diff --git a/sys/mips/rmi/clock.h b/sys/mips/rmi/clock.h new file mode 100644 index 00000000000..c582de529fa --- /dev/null +++ b/sys/mips/rmi/clock.h @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ +#ifndef _RMI_CLOCK_H_ +#define _RMI_CLOCK_H_ + +#define XLR_PIC_HZ 66000000U +#define XLR_CPU_HZ (xlr_boot1_info.cpu_frequency) + +void count_compare_clockhandler(struct trapframe *); +void pic_hardclockhandler(struct trapframe *); +void pic_timecounthandler(struct trapframe *); + +#endif /* _RMI_CLOCK_H_ */ diff --git a/sys/mips/rmi/debug.h b/sys/mips/rmi/debug.h new file mode 100755 index 00000000000..2507a0478de --- /dev/null +++ b/sys/mips/rmi/debug.h @@ -0,0 +1,103 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ +#ifndef _RMI_DEBUG_H_ +#define _RMI_DEBUG_H_ + +#include + +enum { + //cacheline 0 + MSGRNG_INT, + MSGRNG_PIC_INT, + MSGRNG_MSG, + MSGRNG_EXIT_STATUS, + MSGRNG_MSG_CYCLES, + //cacheline 1 + NETIF_TX = 8, + NETIF_RX, + NETIF_TX_COMPLETE, + NETIF_TX_COMPLETE_TX, + NETIF_RX_CYCLES, + NETIF_TX_COMPLETE_CYCLES, + NETIF_TX_CYCLES, + NETIF_TIMER_START_Q, + //NETIF_REG_FRIN, + //NETIF_INT_REG, + //cacheline 2 + REPLENISH_ENTER = 16, + REPLENISH_ENTER_COUNT, + REPLENISH_CPU, + REPLENISH_FRIN, + REPLENISH_CYCLES, + NETIF_STACK_TX, + NETIF_START_Q, + NETIF_STOP_Q, + //cacheline 3 + USER_MAC_START = 24, + USER_MAC_INT = 24, + USER_MAC_TX_COMPLETE, + USER_MAC_RX, + USER_MAC_POLL, + USER_MAC_TX, + USER_MAC_TX_FAIL, + USER_MAC_TX_COUNT, + USER_MAC_FRIN, + //cacheline 4 + USER_MAC_TX_FAIL_GMAC_CREDITS = 32, + USER_MAC_DO_PAGE_FAULT, + USER_MAC_UPDATE_TLB, + USER_MAC_UPDATE_BIGTLB, + USER_MAC_UPDATE_TLB_PFN0, + USER_MAC_UPDATE_TLB_PFN1, + + XLR_MAX_COUNTERS = 40 +}; +extern int xlr_counters[MAXCPU][XLR_MAX_COUNTERS]; +extern __uint32_t msgrng_msg_cycles; + +#ifdef ENABLE_DEBUG +#define xlr_inc_counter(x) atomic_add_int(&xlr_counters[PCPU_GET(cpuid)][(x)], 1) +#define xlr_dec_counter(x) atomic_subtract_int(&xlr_counters[PCPU_GET(cpuid)][(x)], 1) +#define xlr_set_counter(x, value) atomic_set_int(&xlr_counters[PCPU_GET(cpuid)][(x)], (value)) +#define xlr_get_counter(x) (&xlr_counters[0][(x)]) + +#else /* default mode */ + +#define xlr_inc_counter(x) +#define xlr_dec_counter(x) +#define xlr_set_counter(x, value) +#define xlr_get_counter(x) + +#endif + +#define dbg_msg(fmt, args...) printf(fmt, ##args) +#define dbg_panic(fmt, args...) panic(fmt, ##args) + +#endif diff --git a/sys/mips/rmi/interrupt.h b/sys/mips/rmi/interrupt.h new file mode 100644 index 00000000000..c13a27c756c --- /dev/null +++ b/sys/mips/rmi/interrupt.h @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ +#ifndef _RMI_INTERRUPT_H_ +#define _RMI_INTERRUPT_H_ + +/* Defines for the IRQ numbers */ + +#define IRQ_DUMMY_UART 2 +#define IRQ_IPI_SMP_FUNCTION 3 +#define IRQ_IPI_SMP_RESCHEDULE 4 +#define IRQ_REMOTE_DEBUG 5 +#define IRQ_MSGRING 6 +#define IRQ_TIMER 7 + +#endif /* _RMI_INTERRUPT_H_ */ + diff --git a/sys/mips/rmi/iodi.c b/sys/mips/rmi/iodi.c new file mode 100644 index 00000000000..3a8d3bde6ab --- /dev/null +++ b/sys/mips/rmi/iodi.c @@ -0,0 +1,272 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ + +#define __RMAN_RESOURCE_VISIBLE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +extern void iodi_activateirqs(void); + +extern bus_space_tag_t uart_bus_space_mem; + +static struct resource *iodi_alloc_resource(device_t, device_t, int, int *, + u_long, u_long, u_long, u_int); + +static int iodi_activate_resource(device_t, device_t, int, int, + struct resource *); +static int iodi_setup_intr(device_t, device_t, struct resource *, int, + driver_intr_t *, void *, void **); + +struct iodi_softc *iodi_softc; /* There can be only one. */ + +static void pic_usb_ack(void *arg) +{ + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + int irq = PIC_USB_IRQ ; + + mtx_lock_spin(&xlr_pic_lock); + xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE))); + mtx_unlock_spin(&xlr_pic_lock); +} + +static int +iodi_setup_intr(device_t dev, device_t child, + struct resource *ires, int flags, driver_intr_t *intr, void *arg, + void **cookiep) +{ + int level; + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + xlr_reg_t reg; + + /* FIXME is this the right place to fiddle with PIC? */ + if (strcmp(device_get_name(child),"uart") == 0) { + /* FIXME uart 1? */ + mtx_lock_spin(&xlr_pic_lock); + level = PIC_IRQ_IS_EDGE_TRIGGERED(PIC_IRT_UART_0_INDEX); + xlr_write_reg(mmio, PIC_IRT_0_UART_0, 0x01); + xlr_write_reg(mmio, PIC_IRT_1_UART_0, ((1 << 31) | (level<<30)|(1<<6)|(PIC_UART_0_IRQ))); + mtx_unlock_spin(&xlr_pic_lock); + + cpu_establish_intr("uart", PIC_UART_0_IRQ, + (driver_intr_t *)intr, (void *)arg, flags, cookiep, + NULL, NULL); + + } else if (strcmp(device_get_name(child),"rge") == 0) { + mtx_lock_spin(&xlr_pic_lock); + reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + ires->r_flags - PIC_IRQ_BASE); + xlr_write_reg(mmio, PIC_IRT_1_BASE + ires->r_flags - PIC_IRQ_BASE, reg | (1<<6)|(1<<30)| (1<<31)); + mtx_unlock_spin(&xlr_pic_lock); + cpu_establish_intr("rge", ires->r_flags, + (driver_intr_t *)intr, (void *)arg, + flags, cookiep, NULL, NULL); + } else if (strcmp(device_get_name(child),"ehci") == 0) { + mtx_lock_spin(&xlr_pic_lock); + reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + PIC_USB_IRQ - PIC_IRQ_BASE); + xlr_write_reg(mmio, PIC_IRT_1_BASE + PIC_USB_IRQ - PIC_IRQ_BASE, reg | (1<<6)|(1<<30)| (1<<31)); + mtx_unlock_spin(&xlr_pic_lock); + cpu_establish_intr("ehci", PIC_USB_IRQ, + (driver_intr_t *)intr, (void *)arg, + flags, cookiep, (flags & INTR_FAST)? NULL: pic_usb_ack , NULL); + } + + BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, intr, arg, + cookiep); + return (0); +} + +static struct resource * +iodi_alloc_resource(device_t bus, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + struct resource *res = malloc(sizeof(*res), M_DEVBUF, M_WAITOK); + int unit; + +#ifdef DEBUG + switch (type) { + case SYS_RES_IRQ: + device_printf(bus, "IRQ resource - for %s %lx-%lx\n", + device_get_nameunit(child), start, end); + break; + + case SYS_RES_IOPORT: + device_printf(bus, "IOPORT resource - for %s %lx-%lx\n", + device_get_nameunit(child), start, end); + break; + + case SYS_RES_MEMORY: + device_printf(bus, "MEMORY resource - for %s %lx-%lx\n", + device_get_nameunit(child), start, end); + break; + } +#endif + + if (strcmp(device_get_name(child),"uart") == 0) { + if ((unit=device_get_unit(child)) == 0) { /* uart 0 */ + res->r_bushandle = (xlr_io_base + XLR_IO_UART_0_OFFSET); + } + else if ( unit == 1) { + res->r_bushandle = (xlr_io_base + XLR_IO_UART_1_OFFSET); + } + else + printf("%s: Unknown uart unit\n", __FUNCTION__); + + res->r_bustag = uart_bus_space_mem; + } else if (strcmp(device_get_name(child),"ehci") == 0) { + res->r_bushandle = 0xbef24000; + res->r_bustag = MIPS_BUS_SPACE_PCI; + } else if (strcmp(device_get_name(child),"cfi") == 0) { + res->r_bushandle = 0xbc000000; + res->r_bustag = 0; + } + res->r_start = *rid; + return (res); +} + +static int +iodi_activate_resource(device_t bus, device_t child, int type, int rid, + struct resource *r) +{ + return (0); +} +/* prototypes */ +static int iodi_probe(device_t); +static int iodi_attach(device_t); +static void iodi_identify(driver_t *, device_t); + +int +iodi_probe(device_t dev) +{ + return 0; +} + +void +iodi_identify(driver_t *driver, device_t parent) +{ + + BUS_ADD_CHILD(parent, 0, "iodi", 0); +} + +int +iodi_attach(device_t dev) +{ + device_t tmpd; + /* + * Attach each devices + */ + device_add_child(dev, "uart", 0); + device_add_child(dev, "xlr_i2c", 0); + + if (xlr_board_info.usb) + device_add_child(dev, "ehci", 0); + + if (xlr_board_info.cfi) + device_add_child(dev, "cfi", 0); + + if (xlr_board_info.gmac_block[0].enabled) { + tmpd = device_add_child(dev, "rge", 0); + device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]); + + tmpd = device_add_child(dev, "rge", 1); + device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]); + + tmpd = device_add_child(dev, "rge", 2); + device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]); + + tmpd = device_add_child(dev, "rge", 3); + device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]); + } + + if (xlr_board_info.gmac_block[1].enabled) { + if (xlr_board_info.gmac_block[1].type == XLR_GMAC) { + tmpd = device_add_child(dev, "rge", 4); + device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]); + + tmpd = device_add_child(dev, "rge", 5); + device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]); + + tmpd = device_add_child(dev, "rge", 6); + device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]); + + tmpd = device_add_child(dev, "rge", 7); + device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]); + } else if (xlr_board_info.gmac_block[1].type == XLR_XGMAC) { +#if 0 /* XGMAC not yet */ + tmpd = device_add_child(dev, "rge", 4); + device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]); + + tmpd = device_add_child(dev, "rge", 5); + device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]); +#endif + } else + device_printf(dev, "Unknown type of gmac 1\n"); + } + + bus_generic_probe(dev); + bus_generic_attach(dev); + return 0; +} + +static device_method_t iodi_methods[] = { + DEVMETHOD(device_probe, iodi_probe), + DEVMETHOD(device_attach, iodi_attach), + DEVMETHOD(device_identify, iodi_identify), + DEVMETHOD(bus_alloc_resource, iodi_alloc_resource), + DEVMETHOD(bus_activate_resource, iodi_activate_resource), + DEVMETHOD(bus_setup_intr, iodi_setup_intr), + {0, 0}, +}; + +static driver_t iodi_driver = { + "iodi", + iodi_methods, + 1 /* no softc */ +}; +static devclass_t iodi_devclass; + +DRIVER_MODULE(iodi, nexus, iodi_driver, iodi_devclass, 0, 0); diff --git a/sys/mips/rmi/iomap.h b/sys/mips/rmi/iomap.h new file mode 100644 index 00000000000..4aa8f70b3a0 --- /dev/null +++ b/sys/mips/rmi/iomap.h @@ -0,0 +1,110 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ +#ifndef _RMI_IOMAP_H_ +#define _RMI_IOMAP_H_ + +#include + +#define DEFAULT_XLR_IO_BASE 0xffffffffbef00000ULL +#define XLR_IO_SIZE 0x1000 + +#define XLR_IO_BRIDGE_OFFSET 0x00000 + +#define XLR_IO_DDR2_CHN0_OFFSET 0x01000 +#define XLR_IO_DDR2_CHN1_OFFSET 0x02000 +#define XLR_IO_DDR2_CHN2_OFFSET 0x03000 +#define XLR_IO_DDR2_CHN3_OFFSET 0x04000 + +#define XLR_IO_RLD2_CHN0_OFFSET 0x05000 +#define XLR_IO_RLD2_CHN1_OFFSET 0x06000 + +#define XLR_IO_SRAM_OFFSET 0x07000 + +#define XLR_IO_PIC_OFFSET 0x08000 +#define XLR_IO_PCIX_OFFSET 0x09000 +#define XLR_IO_HT_OFFSET 0x0A000 + +#define XLR_IO_SECURITY_OFFSET 0x0B000 + +#define XLR_IO_GMAC_0_OFFSET 0x0C000 +#define XLR_IO_GMAC_1_OFFSET 0x0D000 +#define XLR_IO_GMAC_2_OFFSET 0x0E000 +#define XLR_IO_GMAC_3_OFFSET 0x0F000 + +#define XLR_IO_SPI4_0_OFFSET 0x10000 +#define XLR_IO_XGMAC_0_OFFSET 0x11000 +#define XLR_IO_SPI4_1_OFFSET 0x12000 +#define XLR_IO_XGMAC_1_OFFSET 0x13000 + +#define XLR_IO_UART_0_OFFSET 0x14000 +#define XLR_IO_UART_1_OFFSET 0x15000 + +#define XLR_IO_I2C_0_OFFSET 0x16000 +#define XLR_IO_I2C_1_OFFSET 0x17000 + +#define XLR_IO_GPIO_OFFSET 0x18000 + +#define XLR_IO_FLASH_OFFSET 0x19000 + +#define XLR_IO_TB_OFFSET 0x1C000 + +#define XLR_IO_GMAC_4_OFFSET 0x20000 +#define XLR_IO_GMAC_5_OFFSET 0x21000 +#define XLR_IO_GMAC_6_OFFSET 0x22000 +#define XLR_IO_GMAC_7_OFFSET 0x23000 + +#define XLR_IO_PCIE_0_OFFSET 0x1E000 +#define XLR_IO_PCIE_1_OFFSET 0x1F000 + +#define XLR_IO_USB_0_OFFSET 0x24000 +#define XLR_IO_USB_1_OFFSET 0x25000 + +#define XLR_IO_COMP_OFFSET 0x1d000 + +/* Base Address (Virtual) of the PCI Config address space + * For now, choose 256M phys in kseg1 = 0xA0000000 + (1<<28) + * Config space spans 256 (num of buses) * 256 (num functions) * 256 bytes + * ie 1<<24 = 16M + */ +#define DEFAULT_PCI_CONFIG_BASE 0x18000000 +#define DEFAULT_HT_TYPE0_CFG_BASE 0x16000000 +#define DEFAULT_HT_TYPE1_CFG_BASE 0x17000000 + +typedef volatile __uint32_t xlr_reg_t; +extern unsigned long xlr_io_base; + +#define xlr_io_mmio(offset) ((xlr_reg_t *)(xlr_io_base+(offset))) + +#define xlr_read_reg(base, offset) (__ntohl((base)[(offset)])) +#define xlr_write_reg(base, offset, value) ((base)[(offset)] = __htonl((value))) + +extern void on_chip_init(void); + +#endif /* _RMI_IOMAP_H_ */ diff --git a/sys/mips/rmi/msgring.c b/sys/mips/rmi/msgring.c new file mode 100644 index 00000000000..472ad43c9e7 --- /dev/null +++ b/sys/mips/rmi/msgring.c @@ -0,0 +1,318 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ +/********************************************************** + * -----------------DO NOT EDIT THIS FILE------------------ + * This file has been autogenerated by the build process + * from "msgring.cfg" + **********************************************************/ + +#include + +struct bucket_size bucket_sizes = { + { + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 0, + 32, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 0, + 0, 32, 32, 32, 32, 32, 0, 32, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 0, 32, 0, 0, 0, 0, + 128, 0, 0, 0, 128, 0, 0, 0, + } +}; + +struct stn_cc cc_table_cpu_0 = {{ + + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 4 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, + {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, + {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, + {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, + {0, 2 , 4 , 4 , 4 , 4 , 0 , 2 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 2 , 0 , 2 , 0 , 0 , 0 , 0 }, + {16, 0 , 0 , 0 , 16 , 0 , 0 , 0 }, + }}; + +struct stn_cc cc_table_cpu_1 = {{ + + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, + {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, + {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, + {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, + {0, 2 , 4 , 4 , 4 , 4 , 0 , 2 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 2 , 0 , 2 , 0 , 0 , 0 , 0 }, + {16, 0 , 0 , 0 , 16 , 0 , 0 , 0 }, + }}; + +struct stn_cc cc_table_cpu_2 = {{ + + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, + {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, + {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, + {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, + {0, 4 , 4 , 4 , 4 , 4 , 0 , 4 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 4 , 0 , 4 , 0 , 0 , 0 , 0 }, + {16, 0 , 0 , 0 , 16 , 0 , 0 , 0 }, + }}; + +struct stn_cc cc_table_cpu_3 = {{ + + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, + {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, + {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, + {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, + {0, 4 , 4 , 4 , 4 , 4 , 0 , 4 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 4 , 0 , 4 , 0 , 0 , 0 , 0 }, + {16, 0 , 0 , 0 , 16 , 0 , 0 , 0 }, + }}; + +struct stn_cc cc_table_cpu_4 = {{ + + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, + {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, + {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, + {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, + {0, 4 , 4 , 4 , 4 , 4 , 0 , 4 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 4 , 0 , 4 , 0 , 0 , 0 , 0 }, + {16, 0 , 0 , 0 , 16 , 0 , 0 , 0 }, + }}; + +struct stn_cc cc_table_cpu_5 = {{ + + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, + {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, + {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, + {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, + {0, 4 , 4 , 4 , 4 , 4 , 0 , 4 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 4 , 0 , 4 , 0 , 0 , 0 , 0 }, + {16, 0 , 0 , 0 , 16 , 0 , 0 , 0 }, + }}; + +struct stn_cc cc_table_cpu_6 = {{ + + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, + {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, + {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, + {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, + {0, 4 , 4 , 4 , 4 , 4 , 0 , 4 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 4 , 0 , 4 , 0 , 0 , 0 , 0 }, + {16, 0 , 0 , 0 , 16 , 0 , 0 , 0 }, + }}; + +struct stn_cc cc_table_cpu_7 = {{ + + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, + {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, + {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, + {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, + {0, 4 , 4 , 4 , 4 , 4 , 0 , 4 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 4 , 0 , 4 , 0 , 0 , 0 , 0 }, + {16, 0 , 0 , 0 , 16 , 0 , 0 , 0 }, + }}; + +struct stn_cc cc_table_xgs_0 = {{ + + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 4 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + }}; + +struct stn_cc cc_table_xgs_1 = {{ + + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 4 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + }}; + +struct stn_cc cc_table_gmac = {{ + + {8, 8 , 8 , 8 , 16 , 16 , 16 , 16 }, + {8, 8 , 8 , 8 , 16 , 16 , 16 , 16 }, + {8, 8 , 8 , 8 , 16 , 16 , 16 , 16 }, + {8, 8 , 8 , 8 , 16 , 16 , 16 , 16 }, + {8, 8 , 8 , 8 , 16 , 16 , 16 , 16 }, + {8, 8 , 8 , 8 , 16 , 16 , 16 , 16 }, + {8, 8 , 8 , 8 , 16 , 16 , 16 , 16 }, + {8, 8 , 8 , 8 , 16 , 16 , 16 , 16 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 4 , 0 , 0 , 0 , 0 , 0 , 4 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + }}; + +struct stn_cc cc_table_dma = {{ + + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + }}; + +struct stn_cc cc_table_sec = {{ + + {8, 8 , 8 , 8 , 0 , 0 , 0 , 0 }, + {8, 8 , 8 , 4 , 0 , 0 , 0 , 0 }, + {8, 8 , 8 , 8 , 0 , 0 , 0 , 0 }, + {8, 8 , 8 , 8 , 0 , 0 , 0 , 0 }, + {8, 8 , 8 , 8 , 0 , 0 , 0 , 0 }, + {8, 8 , 8 , 8 , 0 , 0 , 0 , 0 }, + {8, 8 , 8 , 8 , 0 , 0 , 0 , 0 }, + {8, 8 , 8 , 8 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + }}; + diff --git a/sys/mips/rmi/msgring.cfg b/sys/mips/rmi/msgring.cfg new file mode 100644 index 00000000000..cf9ea54bfe3 --- /dev/null +++ b/sys/mips/rmi/msgring.cfg @@ -0,0 +1,1182 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ +/* + * This file defines the message ring configuration for phoenix-8. It tries to allow + * many different point-point communications between the message stations on the message ring + * and as result is _not_ the best configuration for performance + * + * The message ring on phoenix family of processors connects the cpus, gmacs, xgmac/spi4, + * security engine and the general purpose DMA engines. It provides a high bandwidth, + * low latency communication links. On traditional processors, this communication goes through + * which inherently does not scale very well with increasing number of cpus. + * + * Message ring has an in-built flow control mechanism. Every agent/station on the ring has to + * have software configured credits to send messages to any agent. Every receiving agent on the + * ring has a 256 entry FIFO that can divided into "buckets". All addressing on the ring is + * in terms of buckets. There are a total 128 buckets on the ring. The total number of credits + * across all sending agents should not exceed the bucket size. + * + * Below are the receiving agents and the max number of buckets they can have + * CPU 0 : 8 buckets + * CPU 1 : 8 buckets + * CPU 2 : 8 buckets + * CPU 3 : 8 buckets + * CPU 4 : 8 buckets + * CPU 5 : 8 buckets + * CPU 6 : 8 buckets + * CPU 7 : 8 buckets + * + * XGMAC 0 / SPI4 0 + * TX : 16 buckets + * FREE : 2 buckets + * XGMAC 1 / SPI4 1 + * TX : 16 buckets + * FREE : 2 buckets + * + * GMAC : 8 buckets + * + * SEC : 8 buckets + * + * DMA : 8 buckets + * + * The bucket size of a bucket should be aligned to the bucket's starting index in that + * receiving station's FIFO. For example, if sizes of bucket0 and bucket1 of a station + * are 32 and 32, bucket2's size has to be 64. bucket size 0 is valid. + * + * The format of the file is pretty straight forward. Each bucket definition has the size + * and the list of sending agents to that bucket with the number of credits to send. + * + * Undefined buckets have a size of 0 and Tx stations have 0 credits to send to that bucket. + * + * Following are the currently supported bucket names + * cpu_0_0 + * cpu_0_1 + * cpu_0_2 + * cpu_0_3 + * cpu_0_4 + * cpu_0_5 + * cpu_0_6 + * cpu_0_7 + * + * cpu_1_0 + * cpu_1_1 + * cpu_1_2 + * cpu_1_3 + * cpu_1_4 + * cpu_1_5 + * cpu_1_6 + * cpu_1_7 + * + * cpu_2_0 + * cpu_2_1 + * cpu_2_2 + * cpu_2_3 + * cpu_2_4 + * cpu_2_5 + * cpu_2_6 + * cpu_2_7 + * + * cpu_3_0 + * cpu_3_1 + * cpu_3_2 + * cpu_3_3 + * cpu_3_4 + * cpu_3_5 + * cpu_3_6 + * cpu_3_7 + * + * cpu_4_0 + * cpu_4_1 + * cpu_4_2 + * cpu_4_3 + * cpu_4_4 + * cpu_4_5 + * cpu_4_6 + * cpu_4_7 + * + * cpu_5_0 + * cpu_5_1 + * cpu_5_2 + * cpu_5_3 + * cpu_5_4 + * cpu_5_5 + * cpu_5_6 + * cpu_5_7 + * + * cpu_6_0 + * cpu_6_1 + * cpu_6_2 + * cpu_6_3 + * cpu_6_4 + * cpu_6_5 + * cpu_6_6 + * cpu_6_7 + * + * cpu_7_0 + * cpu_7_1 + * cpu_7_2 + * cpu_7_3 + * cpu_7_4 + * cpu_7_5 + * cpu_7_6 + * cpu_7_7 + * + * xgs_0_tx_0 + * xgs_0_tx_1 + * xgs_0_tx_2 + * xgs_0_tx_3 + * xgs_0_tx_4 + * xgs_0_tx_5 + * xgs_0_tx_6 + * xgs_0_tx_7 + * xgs_0_tx_8 + * xgs_0_tx_9 + * xgs_0_tx_10 + * xgs_0_tx_11 + * xgs_0_tx_12 + * xgs_0_tx_13 + * xgs_0_tx_14 + * xgs_0_tx_15 + * + * xgs_1_tx_0 + * xgs_1_tx_1 + * xgs_1_tx_2 + * xgs_1_tx_3 + * xgs_1_tx_4 + * xgs_1_tx_5 + * xgs_1_tx_6 + * xgs_1_tx_7 + * xgs_1_tx_8 + * xgs_1_tx_9 + * xgs_1_tx_10 + * xgs_1_tx_11 + * xgs_1_tx_12 + * xgs_1_tx_13 + * xgs_1_tx_14 + * xgs_1_tx_15 + * + * gmac_rsvd_0 + * gmac_rfr_0 + * gmac_tx_0 + * gmac_tx_1 + * gmac_tx_2 + * gmac_tx_3 + * gmac_rsvd_1 + * gmac_rfr_1 + * + * xgs_0_rsvd + * xgs_0_rfr + * + * xgs_1_rsvd + * xgs_1_rfr + * + * sec_pipe_0 + * sec_pipe_1 + * sec_pipe_2 + * sec_pipe_3 + * sec_rsa + * + * Following are the currently supported Tx Agent/Station names + * + * tx_stn_cpu_0 + * tx_stn_cpu_1 + * tx_stn_cpu_2 + * tx_stn_cpu_3 + * tx_stn_cpu_4 + * tx_stn_cpu_5 + * tx_stn_cpu_6 + * tx_stn_cpu_7 + * + * tx_stn_xgs_0 + * tx_stn_xgs_1 + * + * tx_stn_gmac + * + * tx_stn_dma + * + * tx_stn_sec + * + * + * + */ + +/*************************************************************/ +// CPU_0 Message Station + +bucket "cpu_0_0" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_0_1" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_0_2" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_0_3" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_0_4" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_0_5" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_0_6" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_0_7" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} + +/*************************************************************/ +// CPU_1 Message Station + +bucket "cpu_1_0" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_1_1" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_1_2" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_1_3" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 4; + "tx_stn_cpu_0" 4; /* NEEDED BY RMIOS IPSEC */ +} +bucket "cpu_1_4" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_1_5" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_1_6" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_1_7" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} + +/*************************************************************/ +// CPU_2 Message Station + +bucket "cpu_2_0" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_2_1" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_2_2" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_2_3" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_2_4" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_2_5" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_2_6" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_2_7" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} + +/*************************************************************/ +// CPU_3 Message Station + +bucket "cpu_3_0" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_3_1" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_3_2" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_3_3" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_3_4" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_3_5" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_3_6" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_3_7" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} + +/*************************************************************/ +// CPU_4 Message Station + +bucket "cpu_4_0" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_4_1" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_4_2" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_4_3" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_4_4" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_4_5" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_4_6" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_4_7" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} + +/*************************************************************/ +// CPU_5 Message Station + +bucket "cpu_5_0" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_5_1" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_5_2" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_5_3" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_5_4" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_5_5" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_5_6" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_5_7" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} + + +/*************************************************************/ +// CPU_6 Message Station + +bucket "cpu_6_0" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_6_1" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_6_2" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_6_3" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_6_4" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_6_5" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_6_6" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_6_7" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} + + +/*************************************************************/ +// CPU_7 Message Station + +bucket "cpu_7_0" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_7_1" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_7_2" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_7_3" { + size 32; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; + "tx_stn_gmac" 8; + "tx_stn_sec" 8; +} +bucket "cpu_7_4" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_7_5" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_7_6" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} +bucket "cpu_7_7" { + size 32; + "tx_stn_gmac" 16; + "tx_stn_xgs_0" 8; + "tx_stn_xgs_1" 8; +} + + +/*************************************************************/ +// GMAC Message Station + +bucket "gmac_rfr_0" { + size 32; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 4; + "tx_stn_cpu_3" 4; + "tx_stn_cpu_4" 4; + "tx_stn_cpu_5" 4; + "tx_stn_cpu_6" 4; + "tx_stn_cpu_7" 4; + "tx_stn_gmac" 4; +} + +bucket "gmac_tx_0" { + size 32; + "tx_stn_cpu_0" 4; + "tx_stn_cpu_1" 4; + "tx_stn_cpu_2" 4; + "tx_stn_cpu_3" 4; + "tx_stn_cpu_4" 4; + "tx_stn_cpu_5" 4; + "tx_stn_cpu_6" 4; + "tx_stn_cpu_7" 4; +} + +bucket "gmac_tx_1" { + size 32; + "tx_stn_cpu_0" 4; + "tx_stn_cpu_1" 4; + "tx_stn_cpu_2" 4; + "tx_stn_cpu_3" 4; + "tx_stn_cpu_4" 4; + "tx_stn_cpu_5" 4; + "tx_stn_cpu_6" 4; + "tx_stn_cpu_7" 4; +} + +bucket "gmac_tx_2" { + size 32; + "tx_stn_cpu_0" 4; + "tx_stn_cpu_1" 4; + "tx_stn_cpu_2" 4; + "tx_stn_cpu_3" 4; + "tx_stn_cpu_4" 4; + "tx_stn_cpu_5" 4; + "tx_stn_cpu_6" 4; + "tx_stn_cpu_7" 4; +} + +bucket "gmac_tx_3" { + size 32; + "tx_stn_cpu_0" 4; + "tx_stn_cpu_1" 4; + "tx_stn_cpu_2" 4; + "tx_stn_cpu_3" 4; + "tx_stn_cpu_4" 4; + "tx_stn_cpu_5" 4; + "tx_stn_cpu_6" 4; + "tx_stn_cpu_7" 4; +} + +bucket "gmac_rfr_1" { + size 32; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 4; + "tx_stn_cpu_3" 4; + "tx_stn_cpu_4" 4; + "tx_stn_cpu_5" 4; + "tx_stn_cpu_6" 4; + "tx_stn_cpu_7" 4; + "tx_stn_gmac" 4; +} +/*********************************************/ +// xgmac +bucket "xgs_0_rfr" { + size 32; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 4; + "tx_stn_cpu_3" 4; + "tx_stn_cpu_4" 4; + "tx_stn_cpu_5" 4; + "tx_stn_cpu_6" 4; + "tx_stn_cpu_7" 4; + "tx_stn_xgs_0" 4; +} + +bucket "xgs_0_tx_0" { + size 32; + "tx_stn_cpu_0" 4; + "tx_stn_cpu_1" 4; + "tx_stn_cpu_2" 4; + "tx_stn_cpu_3" 4; + "tx_stn_cpu_4" 4; + "tx_stn_cpu_5" 4; + "tx_stn_cpu_6" 4; + "tx_stn_cpu_7" 4; +} + +bucket "xgs_0_tx_1" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + +bucket "xgs_0_tx_2" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + +bucket "xgs_0_tx_3" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + +bucket "xgs_0_tx_4" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} +bucket "xgs_0_tx_5" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + +bucket "xgs_0_tx_6" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + +bucket "xgs_0_tx_7" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + +bucket "xgs_0_tx_8" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + +bucket "xgs_0_tx_9" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + +bucket "xgs_0_tx_10" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + + +bucket "xgs_0_tx_11" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + +bucket "xgs_0_tx_12" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + +bucket "xgs_0_tx_13" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + +bucket "xgs_0_tx_14" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + + +bucket "xgs_1_rfr" { + size 32; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 4; + "tx_stn_cpu_3" 4; + "tx_stn_cpu_4" 4; + "tx_stn_cpu_5" 4; + "tx_stn_cpu_6" 4; + "tx_stn_cpu_7" 4; + "tx_stn_xgs_1" 4; +} + +bucket "xgs_1_tx_0" { + size 32; + "tx_stn_cpu_0" 4; + "tx_stn_cpu_1" 4; + "tx_stn_cpu_2" 4; + "tx_stn_cpu_3" 4; + "tx_stn_cpu_4" 4; + "tx_stn_cpu_5" 4; + "tx_stn_cpu_6" 4; + "tx_stn_cpu_7" 4; +} + + +bucket "xgs_1_tx_1" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + +bucket "xgs_1_tx_2" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + +bucket "xgs_1_tx_3" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + +bucket "xgs_1_tx_4" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + +bucket "xgs_1_tx_5" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + +bucket "xgs_1_tx_6" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + +bucket "xgs_1_tx_7" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + + +bucket "xgs_1_tx_8" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + + +bucket "xgs_1_tx_9" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + + +bucket "xgs_1_tx_10" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + +bucket "xgs_1_tx_11" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + +bucket "xgs_1_tx_12" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + +bucket "xgs_1_tx_13" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + +bucket "xgs_1_tx_14" { + size 16; + "tx_stn_cpu_0" 2; + "tx_stn_cpu_1" 2; + "tx_stn_cpu_2" 2; + "tx_stn_cpu_3" 2; + "tx_stn_cpu_4" 2; + "tx_stn_cpu_5" 2; + "tx_stn_cpu_6" 2; + "tx_stn_cpu_7" 2; +} + + + + + + +/*************************************************************/ +// Security Message Station + +bucket "sec_pipe_0" { + size 128; + "tx_stn_cpu_0" 16; + "tx_stn_cpu_1" 16; + "tx_stn_cpu_2" 16; + "tx_stn_cpu_3" 16; + "tx_stn_cpu_4" 16; + "tx_stn_cpu_5" 16; + "tx_stn_cpu_6" 16; + "tx_stn_cpu_7" 16; +} + +bucket "sec_rsa" { + size 128; + "tx_stn_cpu_0" 16; + "tx_stn_cpu_1" 16; + "tx_stn_cpu_2" 16; + "tx_stn_cpu_3" 16; + "tx_stn_cpu_4" 16; + "tx_stn_cpu_5" 16; + "tx_stn_cpu_6" 16; + "tx_stn_cpu_7" 16; +} + diff --git a/sys/mips/rmi/msgring.h b/sys/mips/rmi/msgring.h new file mode 100755 index 00000000000..fba504daa3b --- /dev/null +++ b/sys/mips/rmi/msgring.h @@ -0,0 +1,507 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ +#ifndef _RMI_MSGRING_H_ +#define _RMI_MSGRING_H_ + +#include + +#define MSGRNG_TX_BUF_REG 0 +#define MSGRNG_RX_BUF_REG 1 + +#define MSGRNG_MSG_STATUS_REG 2 +#define MSGRNG_MSG_CONFIG_REG 3 + +#define MSGRNG_MSG_BUCKSIZE_REG 4 + +#define MSGRNG_CC_0_REG 16 +#define MSGRNG_CC_1_REG 17 +#define MSGRNG_CC_2_REG 18 +#define MSGRNG_CC_3_REG 19 +#define MSGRNG_CC_4_REG 20 +#define MSGRNG_CC_5_REG 21 +#define MSGRNG_CC_6_REG 22 +#define MSGRNG_CC_7_REG 23 +#define MSGRNG_CC_8_REG 24 +#define MSGRNG_CC_9_REG 25 +#define MSGRNG_CC_10_REG 26 +#define MSGRNG_CC_11_REG 27 +#define MSGRNG_CC_12_REG 28 +#define MSGRNG_CC_13_REG 29 +#define MSGRNG_CC_14_REG 30 +#define MSGRNG_CC_15_REG 31 + +#define msgrng_read_status() read_c2_register32(MSGRNG_MSG_STATUS_REG, 0) + +#define msgrng_read_config() read_c2_register32(MSGRNG_MSG_CONFIG_REG, 0) +#define msgrng_write_config(value) write_c2_register32(MSGRNG_MSG_CONFIG_REG, 0, value) + +#define msgrng_read_bucksize(bucket) read_c2_register32(MSGRNG_MSG_BUCKSIZE_REG, bucket) +#define msgrng_write_bucksize(bucket, value) write_c2_register32(MSGRNG_MSG_BUCKSIZE_REG, bucket, value) + +#define msgrng_read_cc(reg, pri) read_c2_register32(reg, pri) +#define msgrng_write_cc(reg, value, pri) write_c2_register32(reg, pri, value) + +#define msgrng_load_rx_msg0() read_c2_register64(MSGRNG_RX_BUF_REG, 0) +#define msgrng_load_rx_msg1() read_c2_register64(MSGRNG_RX_BUF_REG, 1) +#define msgrng_load_rx_msg2() read_c2_register64(MSGRNG_RX_BUF_REG, 2) +#define msgrng_load_rx_msg3() read_c2_register64(MSGRNG_RX_BUF_REG, 3) + +#define msgrng_load_tx_msg0(value) write_c2_register64(MSGRNG_TX_BUF_REG, 0, value) +#define msgrng_load_tx_msg1(value) write_c2_register64(MSGRNG_TX_BUF_REG, 1, value) +#define msgrng_load_tx_msg2(value) write_c2_register64(MSGRNG_TX_BUF_REG, 2, value) +#define msgrng_load_tx_msg3(value) write_c2_register64(MSGRNG_TX_BUF_REG, 3, value) + +/* Station IDs */ +#define MSGRNG_STNID_CPU0 0x00 +#define MSGRNG_STNID_CPU1 0x08 +#define MSGRNG_STNID_CPU2 0x10 +#define MSGRNG_STNID_CPU3 0x18 +#define MSGRNG_STNID_CPU4 0x20 +#define MSGRNG_STNID_CPU5 0x28 +#define MSGRNG_STNID_CPU6 0x30 +#define MSGRNG_STNID_CPU7 0x38 +#define MSGRNG_STNID_XGS0_TX 64 +#define MSGRNG_STNID_XMAC0_00_TX 64 +#define MSGRNG_STNID_XMAC0_01_TX 65 +#define MSGRNG_STNID_XMAC0_02_TX 66 +#define MSGRNG_STNID_XMAC0_03_TX 67 +#define MSGRNG_STNID_XMAC0_04_TX 68 +#define MSGRNG_STNID_XMAC0_05_TX 69 +#define MSGRNG_STNID_XMAC0_06_TX 70 +#define MSGRNG_STNID_XMAC0_07_TX 71 +#define MSGRNG_STNID_XMAC0_08_TX 72 +#define MSGRNG_STNID_XMAC0_09_TX 73 +#define MSGRNG_STNID_XMAC0_10_TX 74 +#define MSGRNG_STNID_XMAC0_11_TX 75 +#define MSGRNG_STNID_XMAC0_12_TX 76 +#define MSGRNG_STNID_XMAC0_13_TX 77 +#define MSGRNG_STNID_XMAC0_14_TX 78 +#define MSGRNG_STNID_XMAC0_15_TX 79 + +#define MSGRNG_STNID_XGS1_TX 80 +#define MSGRNG_STNID_XMAC1_00_TX 80 +#define MSGRNG_STNID_XMAC1_01_TX 81 +#define MSGRNG_STNID_XMAC1_02_TX 82 +#define MSGRNG_STNID_XMAC1_03_TX 83 +#define MSGRNG_STNID_XMAC1_04_TX 84 +#define MSGRNG_STNID_XMAC1_05_TX 85 +#define MSGRNG_STNID_XMAC1_06_TX 86 +#define MSGRNG_STNID_XMAC1_07_TX 87 +#define MSGRNG_STNID_XMAC1_08_TX 88 +#define MSGRNG_STNID_XMAC1_09_TX 89 +#define MSGRNG_STNID_XMAC1_10_TX 90 +#define MSGRNG_STNID_XMAC1_11_TX 91 +#define MSGRNG_STNID_XMAC1_12_TX 92 +#define MSGRNG_STNID_XMAC1_13_TX 93 +#define MSGRNG_STNID_XMAC1_14_TX 94 +#define MSGRNG_STNID_XMAC1_15_TX 95 + +#define MSGRNG_STNID_GMAC 96 +#define MSGRNG_STNID_GMACJFR_0 96 +#define MSGRNG_STNID_GMACRFR_0 97 +#define MSGRNG_STNID_GMACTX0 98 +#define MSGRNG_STNID_GMACTX1 99 +#define MSGRNG_STNID_GMACTX2 100 +#define MSGRNG_STNID_GMACTX3 101 +#define MSGRNG_STNID_GMACJFR_1 102 +#define MSGRNG_STNID_GMACRFR_1 103 + +#define MSGRNG_STNID_DMA 104 +#define MSGRNG_STNID_DMA_0 104 +#define MSGRNG_STNID_DMA_1 105 +#define MSGRNG_STNID_DMA_2 106 +#define MSGRNG_STNID_DMA_3 107 + +#define MSGRNG_STNID_XGS0FR 112 +#define MSGRNG_STNID_XMAC0JFR 112 +#define MSGRNG_STNID_XMAC0RFR 113 + +#define MSGRNG_STNID_XGS1FR 114 +#define MSGRNG_STNID_XMAC1JFR 114 +#define MSGRNG_STNID_XMAC1RFR 115 +#define MSGRNG_STNID_SEC 120 +#define MSGRNG_STNID_SEC0 120 +#define MSGRNG_STNID_SEC1 121 +#define MSGRNG_STNID_SEC2 122 +#define MSGRNG_STNID_SEC3 123 +#define MSGRNG_STNID_PK0 124 +#define MSGRNG_STNID_SEC_RSA 124 +#define MSGRNG_STNID_SEC_RSVD0 125 +#define MSGRNG_STNID_SEC_RSVD1 126 +#define MSGRNG_STNID_SEC_RSVD2 127 + +#define MSGRNG_STNID_GMAC1 80 +#define MSGRNG_STNID_GMAC1_FR_0 81 +#define MSGRNG_STNID_GMAC1_TX0 82 +#define MSGRNG_STNID_GMAC1_TX1 83 +#define MSGRNG_STNID_GMAC1_TX2 84 +#define MSGRNG_STNID_GMAC1_TX3 85 +#define MSGRNG_STNID_GMAC1_FR_1 87 +#define MSGRNG_STNID_GMAC0 96 +#define MSGRNG_STNID_GMAC0_FR_0 97 +#define MSGRNG_STNID_GMAC0_TX0 98 +#define MSGRNG_STNID_GMAC0_TX1 99 +#define MSGRNG_STNID_GMAC0_TX2 100 +#define MSGRNG_STNID_GMAC0_TX3 101 +#define MSGRNG_STNID_GMAC0_FR_1 103 +#define MSGRNG_STNID_CMP_0 108 +#define MSGRNG_STNID_CMP_1 109 +#define MSGRNG_STNID_CMP_2 110 +#define MSGRNG_STNID_CMP_3 111 +#define MSGRNG_STNID_PCIE_0 116 +#define MSGRNG_STNID_PCIE_1 117 +#define MSGRNG_STNID_PCIE_2 118 +#define MSGRNG_STNID_PCIE_3 119 +#define MSGRNG_STNID_XLS_PK0 121 + +#define MSGRNG_CODE_MAC 0 +#define MSGRNG_CODE_XGMAC 2 +#define MSGRNG_CODE_SEC 0 +#define MSGRNG_CODE_BOOT_WAKEUP 200 +#define MSGRNG_CODE_SPI4 3 + +static inline int msgrng_xgmac_stid_rfr(int id) +{ + return !id ? MSGRNG_STNID_XMAC0RFR : MSGRNG_STNID_XMAC1RFR; +} + +static inline int msgrng_xgmac_stid_jfr(int id) +{ + return !id ? MSGRNG_STNID_XMAC0JFR : MSGRNG_STNID_XMAC1JFR; +} + +static inline int msgrng_xgmac_stid_tx(int id) +{ + return !id ? MSGRNG_STNID_XMAC0_00_TX : MSGRNG_STNID_XMAC1_00_TX; +} + +static inline int msgrng_gmac_stid_rfr(int id) +{ + return (MSGRNG_STNID_GMACRFR_0); +} + +static inline int msgrng_gmac_stid_rfr_split_mode(int id) +{ + return ((id>>1)?MSGRNG_STNID_GMACRFR_1:MSGRNG_STNID_GMACRFR_0); +} + +static inline int msgrng_gmac_stid_jfr(int id) +{ + return MSGRNG_STNID_GMACJFR_0; +} + +static inline int msgrng_gmac_stid_jfr_split_mode(int id) +{ + return ((id>>1)?MSGRNG_STNID_GMACJFR_1:MSGRNG_STNID_GMACJFR_0); +} + +static inline int msgrng_gmac_stid_tx(int id) +{ + return (MSGRNG_STNID_GMACTX0 + id); +} + +static inline void msgrng_send(unsigned int stid) +{ + __asm__ volatile ( + ".set push\n" + ".set noreorder\n" + "sync\n" + // "msgsnd %0\n" + "move $8, %0\n" + "c2 0x80001\n" + ".set pop\n" + : : "r" (stid) : "$8" + ); +} + +static inline void msgrng_receive(unsigned int pri) +{ + __asm__ volatile ( + ".set push\n" + ".set noreorder\n" + // "msgld %0\n" + "move $8, %0\n" + "c2 0x80002\n" + ".set pop\n" + : : "r" (pri) : "$8" + ); +} +static inline void msgrng_wait(unsigned int mask) +{ + __asm__ volatile ( + ".set push\n" + ".set noreorder\n" + // "msgwait %0\n" + "move $8, %0\n" + "c2 0x80003\n" + ".set pop\n" + : :"r" (mask) : "$8" + ); +} + +#define msgrng_enable(flags) \ +do { \ + __asm__ volatile ( \ + ".set push\n\t" \ + ".set reorder\n\t" \ + ".set noat\n\t" \ + "mfc0 %0, $12\n\t" \ + "li $8, 0x40000001\n\t" \ + "or $1, %0, $8\n\t" \ + "xori $1, 1\n\t" \ + ".set noreorder\n\t" \ + "mtc0 $1, $12\n\t" \ + ".set\tpop\n\t" \ + : "=r" (flags) \ + : \ + : "$8" \ + ); \ +} while (0) + +#define msgrng_disable(flags) __asm__ volatile ( \ + "mtc0 %0, $12" : : "r" (flags)) + +#define msgrng_flags_save(flags) msgrng_enable(flags) +#define msgrng_flags_restore(flags) msgrng_disable(flags) + +struct msgrng_msg { + __uint64_t msg0; + __uint64_t msg1; + __uint64_t msg2; + __uint64_t msg3; +}; + +static inline void message_send_block_fast(int size, unsigned int code, unsigned int stid, + unsigned long long msg0, unsigned long long msg1, + unsigned long long msg2, unsigned long long msg3) +{ + __asm__ __volatile__ (".set push\n" + ".set noreorder\n" + ".set mips64\n" + "dmtc2 %1, $0, 0\n" + "dmtc2 %2, $0, 1\n" + "dmtc2 %3, $0, 2\n" + "dmtc2 %4, $0, 3\n" + "move $8, %0\n" + "1: c2 0x80001\n" + "mfc2 $8, $2\n" + "andi $8, $8, 0x6\n" + "bnez $8, 1b\n" + "move $8, %0\n" + ".set pop\n" + : + : "r"(((size-1)<<16)|(code<<8)|stid), "r" (msg0), "r" (msg1), "r"(msg2), "r"(msg3) + : "$8" + ); +} + +#define message_receive_fast(bucket, size, code, stid, msg0, msg1, msg2, msg3) \ + ( { unsigned int _status=0, _tmp=0; \ + msgrng_receive(bucket); \ + while ( (_status=msgrng_read_status()) & 0x08) ; \ + _tmp = _status & 0x30; \ + if (__builtin_expect((!_tmp), 1)) { \ + (size)=((_status & 0xc0)>>6)+1; \ + (code)=(_status & 0xff00)>>8; \ + (stid)=(_status & 0x7f0000)>>16; \ + (msg0)=msgrng_load_rx_msg0(); \ + (msg1)=msgrng_load_rx_msg1(); \ + (msg2)=msgrng_load_rx_msg2(); \ + (msg3)=msgrng_load_rx_msg3(); \ + _tmp=0; \ + } \ + _tmp; \ + } ) + +static __inline__ int message_send(unsigned int size, unsigned int code, + unsigned int stid, struct msgrng_msg *msg) +{ + unsigned int dest = 0; + unsigned long long status=0; + int i=0; + + msgrng_load_tx_msg0(msg->msg0); + msgrng_load_tx_msg1(msg->msg1); + msgrng_load_tx_msg2(msg->msg2); + msgrng_load_tx_msg3(msg->msg3); + + dest = ((size-1)<<16)|(code<<8)|(stid); + + //dbg_msg("Sending msg<%Lx,%Lx,%Lx,%Lx> to dest = %x\n", + //msg->msg0, msg->msg1, msg->msg2, msg->msg3, dest); + + msgrng_send(dest); + + for(i=0;i<16;i++) { + status = msgrng_read_status(); +// dbg_msg("status = %Lx\n", status); + + if (status & 0x6) { + continue; + } + else break; + } + if (i==16) { + if (dest == 0x61) + //dbg_msg("Processor %x: Unable to send msg to %llx\n", processor_id(), dest); + return status & 0x6; + } + return msgrng_read_status() & 0x06; +} + +static __inline__ int message_send_retry(unsigned int size, unsigned int code, + unsigned int stid, struct msgrng_msg *msg) +{ + int res = 0; + int retry = 0; + + for(;;) { + res = message_send(size, code, stid, msg); + /* retry a pending fail */ + if (res & 0x02) continue; + /* credit fail */ + if (res & 0x04) retry++; + else break; + if (retry == 4) return res & 0x06; + } + + return 0; +} + +static __inline__ int message_receive(int pri, int *size, int *code, int *src_id, + struct msgrng_msg *msg) +{ + int res = message_receive_fast(pri, *size, *code, *src_id, msg->msg0, msg->msg1, msg->msg2, msg->msg3); + +#ifdef MSGRING_DUMP_MESSAGES + if (!res) { + dbg_msg("Received msg <%llx, %llx, %llx, %llx> <%d,%d,%d>\n", + msg->msg0, msg->msg1, msg->msg2, msg->msg3, + *size, *code, *src_id); + } +#endif + + return res; +} +#define MSGRNG_STN_RX_QSIZE 256 + +struct stn_cc { + unsigned short counters[16][8]; +}; + +struct bucket_size { + unsigned short bucket[128]; +}; + +extern struct bucket_size bucket_sizes; + +extern struct stn_cc cc_table_cpu_0; +extern struct stn_cc cc_table_cpu_1; +extern struct stn_cc cc_table_cpu_2; +extern struct stn_cc cc_table_cpu_3; +extern struct stn_cc cc_table_cpu_4; +extern struct stn_cc cc_table_cpu_5; +extern struct stn_cc cc_table_cpu_6; +extern struct stn_cc cc_table_cpu_7; +extern struct stn_cc cc_table_xgs_0; +extern struct stn_cc cc_table_xgs_1; +extern struct stn_cc cc_table_gmac; +extern struct stn_cc cc_table_dma; +extern struct stn_cc cc_table_sec; + +extern struct bucket_size xls_bucket_sizes; + +extern struct stn_cc xls_cc_table_cpu_0; +extern struct stn_cc xls_cc_table_cpu_1; +extern struct stn_cc xls_cc_table_cpu_2; +extern struct stn_cc xls_cc_table_cpu_3; +extern struct stn_cc xls_cc_table_gmac0; +extern struct stn_cc xls_cc_table_gmac1; +extern struct stn_cc xls_cc_table_cmp; +extern struct stn_cc xls_cc_table_pcie; +extern struct stn_cc xls_cc_table_dma; +extern struct stn_cc xls_cc_table_sec; + +#define msgrng_access_save(lock, mflags) do { \ + mtx_lock_spin(lock); \ + msgrng_flags_save(mflags); \ + }while(0) + +#define msgrng_access_restore(lock, mflags) do { \ + msgrng_flags_restore(mflags); \ + mtx_unlock_spin(lock); \ + }while(0) + +#define msgrng_access_enable(mflags) do { \ + critical_enter(); \ + msgrng_flags_save(mflags); \ +} while(0) + +#define msgrng_access_disable(mflags) do { \ + msgrng_flags_restore(mflags); \ + critical_exit(); \ +} while(0) + +/* + * NOTE: this is not stationid/8, ie the station numbers below are just + * for internal use + */ +enum { + TX_STN_CPU_0, + TX_STN_CPU_1, + TX_STN_CPU_2, + TX_STN_CPU_3, + TX_STN_CPU_4, + TX_STN_CPU_5, + TX_STN_CPU_6, + TX_STN_CPU_7, + TX_STN_GMAC, + TX_STN_DMA, + TX_STN_XGS_0, + TX_STN_XGS_1, + TX_STN_SAE, + TX_STN_GMAC0, + TX_STN_GMAC1, + TX_STN_CDE, + TX_STN_PCIE, + TX_STN_INVALID, + MAX_TX_STNS +}; + +extern int register_msgring_handler(int major, + void (*action)(int, int,int,int,struct msgrng_msg *, void *), + void *dev_id); +extern void xlr_msgring_cpu_init(void); + +extern void xlr_msgring_config(void); + +#define cpu_to_msgring_bucket(cpu) ((((cpu) >> 2)<<3)|((cpu) & 0x03)) + +#endif diff --git a/sys/mips/rmi/msgring_xls.c b/sys/mips/rmi/msgring_xls.c new file mode 100644 index 00000000000..f1b116e8f6b --- /dev/null +++ b/sys/mips/rmi/msgring_xls.c @@ -0,0 +1,218 @@ +/********************************************************** + * -----------------DO NOT EDIT THIS FILE------------------ + * This file has been autogenerated by the build process + * from "msgring_xls.cfg" + **********************************************************/ + +#include + +struct bucket_size xls_bucket_sizes = { + { 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 32, 32, 32, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 32, 32, 32, 32, 0, 0, + 64, 64, 64, 64, 32, 32, 32, 32, + 0, 0, 0, 0, 0, 0, 0, 0, + 128, 128, 0, 0, 0, 0, 0, 0, + } +}; + +struct stn_cc xls_cc_table_cpu_0 = {{ + {1, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 8 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 8 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 8 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 4 , 8 , 8 , 8 , 8 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 4 , 8 , 8 , 8 , 8 , 0 , 0 }, + {16, 16 , 16 , 16 , 16 , 16 , 16 , 16 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {32, 32 , 0 , 0 , 0 , 0 , 0 , 0 }, + }}; + +struct stn_cc xls_cc_table_cpu_1 = {{ + {1, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 4 , 8 , 8 , 8 , 8 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 4 , 8 , 8 , 8 , 8 , 0 , 0 }, + {16, 16 , 16 , 16 , 16 , 16 , 16 , 16 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {32, 32 , 0 , 0 , 0 , 0 , 0 , 0 }, + }}; + +struct stn_cc xls_cc_table_cpu_2 = {{ + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 4 , 8 , 8 , 8 , 8 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 4 , 8 , 8 , 8 , 8 , 0 , 0 }, + {16, 16 , 16 , 16 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {32, 32 , 0 , 0 , 0 , 0 , 0 , 0 }, + }}; + +struct stn_cc xls_cc_table_cpu_3 = {{ + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 4 , 8 , 8 , 8 , 8 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 4 , 8 , 8 , 8 , 8 , 0 , 0 }, + {16, 16 , 16 , 16 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {32, 32 , 0 , 0 , 0 , 0 , 0 , 0 }, + }}; + +struct stn_cc xls_cc_table_gmac0 = {{ + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 8 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 8 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + }}; + +struct stn_cc xls_cc_table_gmac1 = {{ + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 8 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 8 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + }}; + +struct stn_cc xls_cc_table_dma = {{ + {4, 4 , 4 , 4 , 4 , 4 , 4 , 4 }, + {4, 4 , 4 , 2 , 4 , 4 , 4 , 4 }, + {4, 4 , 4 , 2 , 4 , 4 , 4 , 4 }, + {4, 4 , 4 , 2 , 4 , 4 , 4 , 4 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + }}; + +struct stn_cc xls_cc_table_cmp = {{ + {4, 4 , 4 , 4 , 4 , 4 , 4 , 4 }, + {4, 4 , 4 , 2 , 4 , 4 , 4 , 4 }, + {4, 4 , 4 , 2 , 4 , 4 , 4 , 4 }, + {4, 4 , 4 , 2 , 4 , 4 , 4 , 4 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + }}; + +struct stn_cc xls_cc_table_pcie = {{ + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + }}; + +struct stn_cc xls_cc_table_sec = {{ + {6, 8 , 8 , 8 , 0 , 0 , 0 , 0 }, + {8, 8 , 8 , 4 , 0 , 0 , 0 , 0 }, + {8, 8 , 8 , 4 , 0 , 0 , 0 , 0 }, + {8, 8 , 8 , 4 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, + }}; + diff --git a/sys/mips/rmi/msgring_xls.cfg b/sys/mips/rmi/msgring_xls.cfg new file mode 100755 index 00000000000..35bfb17f4c4 --- /dev/null +++ b/sys/mips/rmi/msgring_xls.cfg @@ -0,0 +1,563 @@ +/********************************************************************* + * + * Copyright 2003-2006 Raza Microelectronics, Inc. (RMI). All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY Raza Microelectronics, Inc. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RMI OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES, LOSS OF USE, DATA, OR PROFITS, OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * *****************************RMI_2**********************************/ + + +/* + * This file defines the message ring configuration for XLS two core. It tries to allow + * many different point-point communications between the message stations on the message ring + * and as result is _not_ the best configuration for performance + * + * The message ring on phoenix family of processors connects the cpus, gmacs, xgmac/spi4, + * security engine and the general purpose DMA engines. It provides a high bandwidth, + * low latency communication links. On traditional processors, this communication goes through + * which inherently does not scale very well with increasing number of cpus. + * + * Message ring has an in-built flow control mechanism. Every agent/station on the ring has to + * have software configured credits to send messages to any agent. Every receiving agent on the + * ring has a 256 entry FIFO that can divided into "buckets". All addressing on the ring is + * in terms of buckets. There are a total 128 buckets on the ring. The total number of credits + * across all sending agents should not exceed the bucket size. + * + * Below are the receiving agents and the max number of buckets they can have + * CPU 0 : 8 buckets + * CPU 1 : 8 buckets + * + * GMAC : 8 buckets + * + * SEC : 8 buckets + * + * DMA : 8 buckets + * + * CMP : Currently disabled. + * + * The bucket size of a bucket should be aligned to the bucket's starting index in that + * receiving station's FIFO. For example, if sizes of bucket0 and bucket1 of a station + * are 32 and 32, bucket2's size has to be 64. bucket size 0 is valid. + * + * The format of the file is pretty straight forward. Each bucket definition has the size + * and the list of sending agents to that bucket with the number of credits to send. + * + * Undefined buckets have a size of 0 and Tx stations have 0 credits to send to that bucket. + * + * Following are the currently supported bucket names + * cpu_0_0 + * cpu_0_1 + * cpu_0_2 + * cpu_0_3 + * cpu_0_4 + * cpu_0_5 + * cpu_0_6 + * cpu_0_7 + * + * cpu_1_0 + * cpu_1_1 + * cpu_1_2 + * cpu_1_3 + * cpu_1_4 + * cpu_1_5 + * cpu_1_6 + * cpu_1_7 + * + * enabled only for xls-b0 + * cpu_2_0 + * cpu_2_1 + * cpu_2_2 + * cpu_2_3 + * cpu_2_4 + * cpu_2_5 + * cpu_2_6 + * cpu_2_7 + * + * enabled only for xls-b0 + * cpu_3_0 + * cpu_3_1 + * cpu_3_2 + * cpu_3_3 + * cpu_3_4 + * cpu_3_5 + * cpu_3_6 + * cpu_3_7 + * + * gmac0_rfr + * gmac0_tx_0 + * gmac0_tx_1 + * gmac0_tx_2 + * gmac0_tx_3 + * + * gmac1_rfr + * gmac1_tx_0 + * gmac1_tx_1 + * gmac1_tx_2 + * gmac1_tx_3 + * + * sec_pipe_0 + * sec_rsa + * + * Following are the currently supported Tx Agent/Station names + * + * tx_stn_cpu_0 + * tx_stn_cpu_1 + * + * tx_stn_gmac0 + * tx_stn_gmac1 + * + * tx_stn_dma + * + * tx_stn_sec + * + * + */ + +/*************************************************************/ +// CPU_0 Message Station + +bucket "cpu_0_0" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_sec" 6; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; + "tx_stn_cpu_0" 1; + "tx_stn_cpu_1" 1; /* NEEDED BY RMIOS IPSEC */ +} +bucket "cpu_0_1" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_sec" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_0_2" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_sec" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_0_3" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_sec" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_0_4" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_0_5" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_0_6" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_0_7" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} + +/*************************************************************/ +// CPU_1 Message Station + +bucket "cpu_1_0" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_sec" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_1_1" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_sec" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_1_2" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_sec" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_1_3" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_sec" 4; + "tx_stn_cpu_0" 8; /* NEEDED BY RMIOS IPSEC */ + "tx_stn_dma" 2; + "tx_stn_cmp" 2; +} +bucket "cpu_1_4" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_1_5" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_1_6" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_1_7" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} + +/*************************************************************/ +// CPU_2 Message Station + +bucket "cpu_2_0" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_sec" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_2_1" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_sec" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_2_2" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_sec" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_2_3" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_sec" 4; + "tx_stn_cpu_0" 8; /* NEEDED BY RMIOS IPSEC */ + "tx_stn_dma" 2; + "tx_stn_cmp" 2; +} +bucket "cpu_2_4" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_2_5" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_2_6" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_2_7" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} + + +/*************************************************************/ +// CPU_3 Message Station +bucket "cpu_3_0" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_sec" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_3_1" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_sec" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_3_2" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_sec" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_3_3" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_sec" 4; + "tx_stn_cpu_0" 8; /* NEEDED BY RMIOS IPSEC */ + "tx_stn_dma" 2; + "tx_stn_cmp" 2; +} +bucket "cpu_3_4" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_3_5" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_3_6" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} +bucket "cpu_3_7" { + size 32; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; + "tx_stn_dma" 4; + "tx_stn_cmp" 4; +} + +/*************************************************************/ + +// GMAC Message Station + +bucket "gmac0_rfr" { + size 32; + "tx_stn_cpu_0" 4; + "tx_stn_cpu_1" 4; + "tx_stn_cpu_2" 4; + "tx_stn_cpu_3" 4; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; +} + +bucket "gmac0_tx_0" { + size 32; + "tx_stn_cpu_0" 8; + "tx_stn_cpu_1" 8; + "tx_stn_cpu_2" 8; + "tx_stn_cpu_3" 8; +} + +bucket "gmac0_tx_1" { + size 32; + "tx_stn_cpu_0" 8; + "tx_stn_cpu_1" 8; + "tx_stn_cpu_2" 8; + "tx_stn_cpu_3" 8; +} + +bucket "gmac0_tx_2" { + size 32; + "tx_stn_cpu_0" 8; + "tx_stn_cpu_1" 8; + "tx_stn_cpu_2" 8; + "tx_stn_cpu_3" 8; +} + +bucket "gmac0_tx_3" { + size 32; + "tx_stn_cpu_0" 8; + "tx_stn_cpu_1" 8; + "tx_stn_cpu_2" 8; + "tx_stn_cpu_3" 8; +} + +bucket "gmac1_rfr" { + size 32; + "tx_stn_cpu_0" 4; + "tx_stn_cpu_1" 4; + "tx_stn_cpu_2" 4; + "tx_stn_cpu_3" 4; + "tx_stn_gmac0" 8; + "tx_stn_gmac1" 8; +} + +bucket "gmac1_tx_0" { + size 32; + "tx_stn_cpu_0" 8; + "tx_stn_cpu_1" 8; + "tx_stn_cpu_2" 8; + "tx_stn_cpu_3" 8; +} + +bucket "gmac1_tx_1" { + size 32; + "tx_stn_cpu_0" 8; + "tx_stn_cpu_1" 8; + "tx_stn_cpu_2" 8; + "tx_stn_cpu_3" 8; +} + +bucket "gmac1_tx_2" { + size 32; + "tx_stn_cpu_0" 8; + "tx_stn_cpu_1" 8; + "tx_stn_cpu_2" 8; + "tx_stn_cpu_3" 8; +} + +bucket "gmac1_tx_3" { + size 32; + "tx_stn_cpu_0" 8; + "tx_stn_cpu_1" 8; + "tx_stn_cpu_2" 8; + "tx_stn_cpu_3" 8; +} + +/*************************************************************/ +// Security Message Station + +bucket "sec_pipe_0" { + size 128; + "tx_stn_cpu_0" 32; + "tx_stn_cpu_1" 32; + "tx_stn_cpu_2" 32; + "tx_stn_cpu_3" 32; +} + +bucket "sec_rsa_ecc" { + size 128; + "tx_stn_cpu_0" 32; + "tx_stn_cpu_1" 32; + "tx_stn_cpu_2" 32; + "tx_stn_cpu_3" 32; +} + +bucket "dma_rsvd_0" { + size 64; + "tx_stn_cpu_0" 16; + "tx_stn_cpu_1" 16; + "tx_stn_cpu_2" 16; + "tx_stn_cpu_3" 16; +} +bucket "dma_rsvd_1" { + size 64; + "tx_stn_cpu_0" 16; + "tx_stn_cpu_1" 16; + "tx_stn_cpu_2" 16; + "tx_stn_cpu_3" 16; +} + +bucket "dma_rsvd_2" { + size 64; + "tx_stn_cpu_0" 16; + "tx_stn_cpu_1" 16; + "tx_stn_cpu_2" 16; + "tx_stn_cpu_3" 16; +} + +bucket "dma_rsvd_3" { + size 64; + "tx_stn_cpu_0" 16; + "tx_stn_cpu_1" 16; + "tx_stn_cpu_2" 16; + "tx_stn_cpu_3" 16; +} + +/*************************************************************/ +// Compression Message Station + +bucket "cmp_0" { + size 32; + "tx_stn_cpu_0" 16; + "tx_stn_cpu_1" 16; +} + +bucket "cmp_1" { + size 32; + "tx_stn_cpu_0" 16; + "tx_stn_cpu_1" 16; +} + +bucket "cmp_2" { + size 32; + "tx_stn_cpu_0" 16; + "tx_stn_cpu_1" 16; +} + +bucket "cmp_3" { + size 32; + "tx_stn_cpu_0" 16; + "tx_stn_cpu_1" 16; +} + diff --git a/sys/mips/rmi/on_chip.c b/sys/mips/rmi/on_chip.c new file mode 100644 index 00000000000..8addfc4608a --- /dev/null +++ b/sys/mips/rmi/on_chip.c @@ -0,0 +1,313 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +void disable_msgring_int(void *arg) ; +void enable_msgring_int(void *arg) ; +/* definitions */ +struct tx_stn_handler { + void (*action)(int, int, int, int, struct msgrng_msg *, void *); + void *dev_id; +}; + +/* globals */ +static struct tx_stn_handler tx_stn_handlers[MAX_TX_STNS]; + +#define MSGRNG_CC_INIT_CPU_DEST(dest, counter) \ +do { \ + msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][0], 0 ); \ + msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][1], 1 ); \ + msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][2], 2 ); \ + msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][3], 3 ); \ + msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][4], 4 ); \ + msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][5], 5 ); \ + msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][6], 6 ); \ + msgrng_write_cc(MSGRNG_CC_##dest##_REG, counter[dest][7], 7 ); \ +} while(0) + + +/* make this a read/write spinlock */ +static struct mtx msgrng_lock; +static int msgring_int_enabled; +struct mtx xlr_pic_lock; + +static int msgring_pop_num_buckets; +static uint32_t msgring_pop_bucket_mask; +static int msgring_int_type; +static int msgring_watermark_count; +static uint32_t msgring_thread_mask; + +uint32_t msgrng_msg_cycles = 0; + +int xlr_counters[MAXCPU][XLR_MAX_COUNTERS] __aligned(XLR_CACHELINE_SIZE); + +void xlr_msgring_handler(struct trapframe *); + +void xlr_msgring_cpu_init(void) +{ + struct stn_cc *cc_config; + struct bucket_size *bucket_sizes; + int id; + unsigned long flags; + + /* if not thread 0 */ + if (xlr_thr_id() != 0) + return; + id = xlr_cpu_id(); + + bucket_sizes = xlr_board_info.bucket_sizes; + cc_config = xlr_board_info.credit_configs[id]; + + msgrng_flags_save(flags); + + /* Message Stations are shared among all threads in a cpu core + * Assume, thread 0 on all cores are always active when more than + * 1 thread is active in a core + */ + msgrng_write_bucksize(0, bucket_sizes->bucket[id*8 + 0]); + msgrng_write_bucksize(1, bucket_sizes->bucket[id*8 + 1]); + msgrng_write_bucksize(2, bucket_sizes->bucket[id*8 + 2]); + msgrng_write_bucksize(3, bucket_sizes->bucket[id*8 + 3]); + msgrng_write_bucksize(4, bucket_sizes->bucket[id*8 + 4]); + msgrng_write_bucksize(5, bucket_sizes->bucket[id*8 + 5]); + msgrng_write_bucksize(6, bucket_sizes->bucket[id*8 + 6]); + msgrng_write_bucksize(7, bucket_sizes->bucket[id*8 + 7]); + + MSGRNG_CC_INIT_CPU_DEST(0, cc_config->counters); + MSGRNG_CC_INIT_CPU_DEST(1, cc_config->counters); + MSGRNG_CC_INIT_CPU_DEST(2, cc_config->counters); + MSGRNG_CC_INIT_CPU_DEST(3, cc_config->counters); + MSGRNG_CC_INIT_CPU_DEST(4, cc_config->counters); + MSGRNG_CC_INIT_CPU_DEST(5, cc_config->counters); + MSGRNG_CC_INIT_CPU_DEST(6, cc_config->counters); + MSGRNG_CC_INIT_CPU_DEST(7, cc_config->counters); + MSGRNG_CC_INIT_CPU_DEST(8, cc_config->counters); + MSGRNG_CC_INIT_CPU_DEST(9, cc_config->counters); + MSGRNG_CC_INIT_CPU_DEST(10, cc_config->counters); + MSGRNG_CC_INIT_CPU_DEST(11, cc_config->counters); + MSGRNG_CC_INIT_CPU_DEST(12, cc_config->counters); + MSGRNG_CC_INIT_CPU_DEST(13, cc_config->counters); + MSGRNG_CC_INIT_CPU_DEST(14, cc_config->counters); + MSGRNG_CC_INIT_CPU_DEST(15, cc_config->counters); + + msgrng_flags_restore(flags); +} + +void xlr_msgring_config(void) +{ + msgring_int_type = 0x02; + msgring_pop_num_buckets = 8; + msgring_pop_bucket_mask = 0xff; + + msgring_watermark_count = 1; + msgring_thread_mask = 0x01; +/* printf("[%s]: int_type = 0x%x, pop_num_buckets=%d, pop_bucket_mask=%x" */ +/* "watermark_count=%d, thread_mask=%x\n", __FUNCTION__, */ +/* msgring_int_type, msgring_pop_num_buckets, msgring_pop_bucket_mask, */ +/* msgring_watermark_count, msgring_thread_mask); */ +} + +void xlr_msgring_handler(struct trapframe *tf) +{ + unsigned long mflags; + int bucket=0; + int size=0, code=0, rx_stid=0, tx_stid=0; + struct msgrng_msg msg; + unsigned int bucket_empty_bm = 0; + unsigned int status=0; + + xlr_inc_counter(MSGRNG_INT); + /* TODO: not necessary to disable preemption */ + msgrng_flags_save(mflags); + + /* First Drain all the high priority messages */ + for(;;) { + bucket_empty_bm = (msgrng_read_status() >> 24) & msgring_pop_bucket_mask; + + /* all buckets empty, break*/ + if ( bucket_empty_bm == msgring_pop_bucket_mask) break; + + for(bucket=0; bucket < msgring_pop_num_buckets; bucket++) { + uint32_t cycles = 0; + + if ((bucket_empty_bm & (1 << bucket))/*empty*/) continue; + + status = message_receive(bucket, &size, &code, &rx_stid, &msg); + if (status) continue; + + xlr_inc_counter(MSGRNG_MSG); + msgrng_msg_cycles = mips_rd_count(); + cycles = msgrng_msg_cycles; + + tx_stid = xlr_board_info.msgmap[rx_stid]; + + if (!tx_stn_handlers[tx_stid].action) { + printf("[%s]: No Handler for message from stn_id=%d, bucket=%d, " + "size=%d, msg0=%llx, dropping message\n", + __FUNCTION__, tx_stid, bucket, size, msg.msg0); + } + else { + //printf("[%s]: rx_stid = %d\n", __FUNCTION__, rx_stid); + msgrng_flags_restore(mflags); + (*tx_stn_handlers[tx_stid].action)(bucket, size, code, rx_stid, + &msg, tx_stn_handlers[tx_stid].dev_id); + msgrng_flags_save(mflags); + } + xlr_set_counter(MSGRNG_MSG_CYCLES, (read_c0_count()-cycles)); + } + } + + xlr_set_counter(MSGRNG_EXIT_STATUS, msgrng_read_status()); + + msgrng_flags_restore(mflags); + + //dbg_msg("OUT irq=%d\n", irq); + + /* Call the msg callback */ +} + +void enable_msgring_int(void *arg) +{ + unsigned long mflags=0; + + msgrng_access_save(&msgrng_lock, mflags); + /* enable the message ring interrupts */ + msgrng_write_config((msgring_watermark_count<<24)|(IRQ_MSGRING<<16) + |(msgring_thread_mask<<8)|msgring_int_type); + msgrng_access_restore(&msgrng_lock, mflags); +} + +void disable_msgring_int(void *arg) +{ + unsigned long mflags=0; + uint32_t config; + + msgrng_access_save(&msgrng_lock, mflags); + config = msgrng_read_config(); + config &= ~0x3; + msgrng_write_config(config); + msgrng_access_restore(&msgrng_lock, mflags); +} + +extern void platform_prep_smp_launch(void); +extern void msgring_process_fast_intr(void *arg); + +int register_msgring_handler(int major, + void (*action)(int, int,int,int,struct msgrng_msg *, void *), + void *dev_id) +{ + void *cookie; /* FIXME - use? */ + + if (major >= MAX_TX_STNS) + return 1; + + //dbg_msg("major=%d, action=%p, dev_id=%p\n", major, action, dev_id); + + mtx_lock_spin(&msgrng_lock); + tx_stn_handlers[major].action = action; + tx_stn_handlers[major].dev_id = dev_id; + mtx_unlock_spin(&msgrng_lock); + + if (xlr_test_and_set(&msgring_int_enabled)) { + platform_prep_smp_launch(); + + cpu_establish_intr("msgring", IRQ_MSGRING, + (driver_intr_t *)msgring_process_fast_intr, + NULL, INTR_TYPE_NET|INTR_FAST, &cookie, NULL, NULL); + + /* configure the msgring interrupt on cpu 0 */ + enable_msgring_int(NULL); + } + + return 0; +} + +static void pic_init(void) +{ + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + int i=0; + int level; + + dbg_msg("Initializing PIC...\n"); + for(i=0; i + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/sys/alpha/pci/pcibus.c,v 1.36 2005/01/05 20:05:52 imp Exp $"); + +#include "opt_isa.h" + +#define __RMAN_RESOURCE_VISIBLE +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static void bridge_pcix_ack(void *); +static void bridge_pcie_ack(void *); +static void pic_pcix_ack(void *); +static void pic_pcie_ack(void *); + +extern vm_map_t kernel_map; +vm_offset_t kmem_alloc_nofault( vm_map_t map, vm_size_t size); + +int +mips_pci_route_interrupt(device_t bus, device_t dev, int pin) +{ + /* + * Validate requested pin number. + */ + if ((pin < 1) || (pin > 4)) + return(255); + + if (xlr_board_info.is_xls) { + switch (pin) { + case 1: return PIC_PCIE_LINK0_IRQ; + case 2: return PIC_PCIE_LINK1_IRQ; + case 3: return PIC_PCIE_LINK2_IRQ; + case 4: return PIC_PCIE_LINK3_IRQ; + } + } else { + if (pin == 1) { + return (16); + } + } + + return(255); +} + +static struct rman irq_rman, port_rman, mem_rman; + +static void bridge_pcix_ack(void *arg) +{ + xlr_read_reg(xlr_io_mmio(XLR_IO_PCIX_OFFSET), 0x140 >> 2); +} + +static void bridge_pcie_ack(void *arg) +{ + int irq = (int)arg; + uint32_t reg; + xlr_reg_t *pcie_mmio_le = xlr_io_mmio(XLR_IO_PCIE_1_OFFSET); + + switch (irq) { + case PIC_PCIE_LINK0_IRQ : reg = PCIE_LINK0_MSI_STATUS; break; + case PIC_PCIE_LINK1_IRQ : reg = PCIE_LINK1_MSI_STATUS; break; + case PIC_PCIE_LINK2_IRQ : reg = PCIE_LINK2_MSI_STATUS; break; + case PIC_PCIE_LINK3_IRQ : reg = PCIE_LINK3_MSI_STATUS; break; + default: + return; + } + + xlr_write_reg(pcie_mmio_le, reg>>2, 0xffffffff); +} + +static void pic_pcix_ack(void *none) +{ + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + + mtx_lock_spin(&xlr_pic_lock); + xlr_write_reg(mmio, PIC_INT_ACK, (1 << PIC_IRT_PCIX_INDEX)); + mtx_unlock_spin(&xlr_pic_lock); +} + +static void pic_pcie_ack(void *arg) +{ + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + int irq = (int) arg; + + mtx_lock_spin(&xlr_pic_lock); + xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE))); + mtx_unlock_spin(&xlr_pic_lock); +} + + +int +mips_platform_pci_setup_intr(device_t dev, device_t child, + struct resource *irq, int flags, + driver_intr_t *intr, void *arg, + void **cookiep) +{ + int level; + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + int error = 0; + int xlrirq; + + error = rman_activate_resource(irq); + if (error) + return error; + if (irq->r_start != irq->r_end) { + device_printf(dev, "Interrupt allocation %lu != %lu\n", + irq->r_start, irq->r_end); + return EINVAL; + } + + xlrirq = irq->r_start; + if (strcmp(device_get_name(dev),"pcib") != 0) + return 0; + + if (xlr_board_info.is_xls == 0) { + mtx_lock_spin(&xlr_pic_lock); + level = PIC_IRQ_IS_EDGE_TRIGGERED(PIC_IRT_PCIX_INDEX); + xlr_write_reg(mmio, PIC_IRT_0_PCIX, 0x01); + xlr_write_reg(mmio, PIC_IRT_1_PCIX, ((1 << 31) | (level<<30)| + (1<<6)|(PIC_PCIX_IRQ))); + mtx_unlock_spin(&xlr_pic_lock); + cpu_establish_intr(device_get_name(child), PIC_PCIX_IRQ, + (driver_intr_t *)intr, (void *)arg, flags, cookiep, + pic_pcix_ack, bridge_pcix_ack); + } else { + mtx_lock_spin(&xlr_pic_lock); + xlr_write_reg(mmio, PIC_IRT_0_BASE + xlrirq - PIC_IRQ_BASE, 0x01); + xlr_write_reg(mmio, PIC_IRT_1_BASE + xlrirq - PIC_IRQ_BASE, + ((1 << 31) | (1<<30) | (1<<6) | xlrirq)); + mtx_unlock_spin(&xlr_pic_lock); + + if (flags & INTR_FAST) + cpu_establish_intr(device_get_name(child), xlrirq, + (driver_intr_t *)intr, (void *)arg, flags, cookiep, + NULL, bridge_pcie_ack); + else + cpu_establish_intr(device_get_name(child), xlrirq, + (driver_intr_t *)intr, (void *)arg, flags, cookiep, + pic_pcie_ack, bridge_pcie_ack); + + } + return bus_generic_setup_intr(dev, child, irq, flags, intr, + arg, cookiep); +} + +int +mips_platform_pci_teardown_intr(device_t dev, device_t child, + struct resource *irq, void *cookie) +{ + if (strcmp(device_get_name(child),"pci") == 0) { + /* if needed reprogram the pic to clear pcix related entry */ + } + return bus_generic_teardown_intr(dev, child, irq, cookie); +} + +void +pci_init_resources(void) +{ + irq_rman.rm_start = 0; + irq_rman.rm_end = 255; + irq_rman.rm_type = RMAN_ARRAY; + irq_rman.rm_descr = "PCI Mapped Interrupts"; + if (rman_init(&irq_rman) + || rman_manage_region(&irq_rman, 0, 255)) + panic("pci_init_resources irq_rman"); + + port_rman.rm_start = 0; + port_rman.rm_end = ~0u; + port_rman.rm_type = RMAN_ARRAY; + port_rman.rm_descr = "I/O ports"; + if (rman_init(&port_rman) + || rman_manage_region(&port_rman, 0x10000000, 0x1fffffff)) + panic("pci_init_resources port_rman"); + + mem_rman.rm_start = 0; + mem_rman.rm_end = ~0u; + mem_rman.rm_type = RMAN_ARRAY; + mem_rman.rm_descr = "I/O memory"; + if (rman_init(&mem_rman) + || rman_manage_region(&mem_rman, 0xd0000000, 0xdfffffff)) + panic("pci_init_resources mem_rman"); +} + +struct resource * +xlr_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + struct rman *rm; + struct resource *rv; + vm_offset_t va_start, va; + int needactivate = flags & RF_ACTIVE; + +#if 0 + device_printf(bus, "xlr_pci_alloc_resource : child %s, type %d, start %lx end %lx, count %lx, flags %x\n", + device_get_nameunit(child), type, start, end, count, flags); +#endif + + switch (type) { + case SYS_RES_IRQ: + rm = &irq_rman; + break; + + case SYS_RES_IOPORT: + rm = &port_rman; + break; + + case SYS_RES_MEMORY: + rm = &mem_rman; + break; + + default: + return 0; + } + + rv = rman_reserve_resource(rm, start, end, count, flags, child); + if (rv == 0) + return 0; + + rman_set_bustag(rv, MIPS_BUS_SPACE_PCI); + rman_set_rid(rv, *rid); + + if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) { + if ((start + count) > (2 << 28)) { + va_start = kmem_alloc_nofault(kernel_map, count); + } + va = pmap_map_uncached(&va_start, start, start + count); + rman_set_bushandle(rv, va); + /* bushandle is same as virtual addr */ + rman_set_virtual(rv, (void *)va); + rman_set_bustag(rv, MIPS_BUS_SPACE_PCI); + } + + if (needactivate) { + if (bus_activate_resource(child, type, *rid, rv)) { + rman_release_resource(rv); + return (NULL); + } + } + + return rv; +} + +int +pci_activate_resource(device_t bus, device_t child, int type, int rid, + struct resource *r) +{ + return (rman_activate_resource(r)); +} + +int +pci_deactivate_resource(device_t bus, device_t child, int type, int rid, + struct resource *r) +{ + return (rman_deactivate_resource(r)); +} + +int +pci_release_resource(device_t bus, device_t child, int type, int rid, + struct resource *r) +{ + return (rman_release_resource(r)); +} + +struct rman * +pci_get_rman(device_t dev, int type) +{ + switch (type) { + case SYS_RES_IOPORT: + return &port_rman; + + case SYS_RES_MEMORY: + return &mem_rman; + + case SYS_RES_IRQ: + return &irq_rman; + } + + return 0; +} diff --git a/sys/mips/rmi/pcibus.h b/sys/mips/rmi/pcibus.h new file mode 100644 index 00000000000..ed4bb9768ec --- /dev/null +++ b/sys/mips/rmi/pcibus.h @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 1998 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/alpha/pci/pcibus.h,v 1.5 2002/02/28 18:18:41 gallatin Exp $ + */ +#define DEFAULT_PCI_CONFIG_BASE 0x18000000 + +#define MSI_MIPS_ADDR_BASE 0xfee00000 + + +#define PCIE_LINK0_MSI_STATUS 0x90 +#define PCIE_LINK1_MSI_STATUS 0x94 +#define PCIE_LINK2_MSI_STATUS 0x190 +#define PCIE_LINK3_MSI_STATUS 0x194 + +void pci_init_resources(void); +struct resource *xlr_pci_alloc_resource(device_t bus, device_t child, + int type, int *rid, + u_long start, u_long end, u_long count, + u_int flags); +int pci_activate_resource(device_t bus, device_t child, int type, int rid, + struct resource *r); +int pci_deactivate_resource(device_t bus, device_t child, int type, int rid, + struct resource *r); +int pci_release_resource(device_t bus, device_t child, int type, int rid, + struct resource *r); +struct rman *pci_get_rman(device_t dev, int type); diff --git a/sys/mips/rmi/perfmon.h b/sys/mips/rmi/perfmon.h new file mode 100644 index 00000000000..1ba6c468e64 --- /dev/null +++ b/sys/mips/rmi/perfmon.h @@ -0,0 +1,168 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ + +#ifndef PERFMON_H +#define PERFMON_H + +#include + +/* + * category events reported by the perfmon library + */ +enum event_category_t { PERF_CP0_COUNTER=1, PERF_CP2_CREDITS, PERF_L2_COUNTER, + PERF_SBC_COUNTER, PERF_SBC_CREDITS, PERF_GMAC0_COUNTER, PERF_GMAC1_COUNTER, + PERF_GMAC2_COUNTER, PERF_GMAC_STAT_COM, PERF_GMAC_STAT_TX, + PERF_GMAC_STAT_RX, PERF_DRAM_COUNTER, PERF_PARAMETER_CONF=127}; + + +enum perf_param_t { PERF_CPU_SAMPLING_INTERVAL, PERF_SYS_SAMPLING_INTERVAL, PERF_CC_SAMPLE_RATE, PERF_CP0_FLAGS}; + +#define CPO_EVENTS_TEMPLATE 0x06 /* enable kernel and user events */ + +#define PERFMON_ACTIVE_MAGIC 0xc001 +#define PERFMON_ENABLED_MAGIC 0xb007 +#define PERFMON_INITIAL_GENERATION 0x0101 + +#define PERFMON_SERVER_PORT 7007 + +enum system_bridge_credits_t {PCIX_CREDITS, HT_CREDITS, GIO_CREDITS, OTHER_CREDITS}; + +struct perf_config_data { + uint16_t magic; /* monitor start when this is initialized */ + uint16_t generation; /* incremented when the config changes */ + uint16_t flags; + uint16_t cc_sample_rate; /* rate at which credit counters are sampled + relative to sampling_rate */ + uint32_t sampling_rate; /* rate at which events are sampled */ + uint32_t cc_register_mask; /* credit counters registers to be sampled */ + uint64_t events[NTHREADS]; /* events bitmap for each thread */ +}; + +struct perf_sample { + uint32_t counter; + uint32_t timestamp; + uint32_t sample_tag; + uint32_t duration; +}; + +struct sample_q { + int32_t head, tail; + struct perf_sample samples[PERF_SAMPLE_BUFSZ]; + uint32_t overflows; +}; + +struct perf_area { + struct perf_config_data perf_config; + struct sample_q sample_fifo; +}; + +/* + * We have a shared location to keep a global tick counter for all the + * CPUS - TODO is this optimal? effect on cache? + */ +extern uint32_t *xlr_perfmon_timer_loc; +#define PERFMON_TIMESTAMP_LOC (xlr_perfmon_timer_loc) + +static __inline__ uint32_t perfmon_timestamp_get(void) +{ + return *PERFMON_TIMESTAMP_LOC; +} + +static __inline__ void perfmon_timestamp_set(uint32_t val) +{ + *PERFMON_TIMESTAMP_LOC = val; +} + +static __inline__ void perfmon_timestamp_incr(int val) +{ + (*PERFMON_TIMESTAMP_LOC) += val; +} + +static __inline__ void send_sample_gts(uint32_t tag, uint32_t value, uint32_t td) +{ + xlr_send_sample(tag, value, perfmon_timestamp_get(), td); +} + +/* + * Simple FIFO, one producer - one consumer - circlar queue - no locking + */ + +static __inline__ void init_fifo(struct sample_q *q) +{ + q->head = q->tail = 0; +} + +static __inline__ void put_sample(struct sample_q *q, uint32_t sample_tag, uint32_t counter, + uint32_t duration) +{ + uint32_t timestamp = perfmon_timestamp_get(); + int new_tail = (q->tail + 1) % PERF_SAMPLE_BUFSZ; + if (q->head == new_tail) { + q->overflows++; + return; + } + + q->samples[new_tail].sample_tag = sample_tag; + q->samples[new_tail].counter = counter; + q->samples[new_tail].timestamp = timestamp; + q->samples[new_tail].duration = duration; + + q->tail = new_tail; +} + +static __inline__ int get_sample(struct sample_q *q, uint32_t *sample_tag, uint32_t *counter, + uint32_t *timestamp, uint32_t *duration) +{ + int head = q->head; + + if (head == q->tail) + return 0; + *sample_tag = q->samples[head].sample_tag; + *counter = q->samples[head].counter; + *timestamp = q->samples[head].timestamp; + *duration = q->samples[head].duration; + + q->head = (head+1) % PERF_SAMPLE_BUFSZ; + return 1; +} + +static __inline__ void clear_queue(struct sample_q *q) +{ + q->head = q->tail; +} +void xlr_perfmon_init_cpu(void *); +void xlr_perfmon_sampler(void *); +void log_active_core(int core); +int get_start_generation(void); + +void xlr_perfmon_clockhandler (void); +extern int xlr_perfmon_started; + +#endif /* PERFMON_H */ diff --git a/sys/mips/rmi/perfmon_kern.c b/sys/mips/rmi/perfmon_kern.c new file mode 100644 index 00000000000..1e4b7ce2050 --- /dev/null +++ b/sys/mips/rmi/perfmon_kern.c @@ -0,0 +1,162 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +int xlr_perfmon_started = 0; +struct perf_area *xlr_shared_config_area = NULL; +uint32_t *xlr_perfmon_timer_loc; +uint32_t *xlr_cpu_sampling_interval; +uint32_t xlr_perfmon_kernel_version = 1; /* Future use */ +uint32_t xlr_perfmon_ticks; +extern int mips_cpu_online_mask; +extern uint32_t cpu_ltop_map[MAXCPU]; + +#ifdef SMP +static __inline__ void pic_send_perfmon_ipi(int cpu) +{ + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + int tid, pid; + uint32_t ipi; + + tid = cpu & 0x3; + pid = (cpu >> 2) & 0x7; + ipi = (pid << 20) | (tid << 16) | IPI_PERFMON; + + mtx_lock_spin(&xlr_pic_lock); + xlr_write_reg(mmio, PIC_IPI, ipi); + mtx_unlock_spin(&xlr_pic_lock); +} +#endif + + +void +xlr_perfmon_clockhandler(void) +{ +#ifdef SMP + int cpu; + int i; +#endif + + if (xlr_perfmon_ticks++ >= (*xlr_cpu_sampling_interval)/(XLR_PIC_HZ/(hz * 1024))) { + + /* update timer */ + *xlr_perfmon_timer_loc += *xlr_cpu_sampling_interval; + xlr_perfmon_ticks = 0; + xlr_perfmon_sampler(NULL); +#ifdef SMP + for (i=0; inewptr == NULL) + return (error); + + if (!xlr_perfmon_started && val != 0) + xlr_perfmon_start(); + else if (xlr_perfmon_started && val == 0) + xlr_perfmon_stop(); + + return (0); +} + + +SYSCTL_NODE(_debug, OID_AUTO, xlrperf, CTLFLAG_RW, NULL, "XLR PERF Nodes"); +SYSCTL_PROC(_debug_xlrperf, OID_AUTO, start, CTLTYPE_INT | CTLFLAG_RW, + &xlr_perfmon_started, 0, sysctl_xlr_perfmon_start_stop, "I", "set/unset to start/stop " + "performance monitoring"); + diff --git a/sys/mips/rmi/perfmon_percpu.c b/sys/mips/rmi/perfmon_percpu.c new file mode 100644 index 00000000000..5980ff76389 --- /dev/null +++ b/sys/mips/rmi/perfmon_percpu.c @@ -0,0 +1,299 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CC_SAMPLE (PERF_CP2_CREDITS <<24) + +#define CC_REG0 16 +#define CC_REG1 17 +#define CC_REG2 18 +#define CC_REG3 19 +#define CC_REG4 20 +#define CC_REG5 21 +#define CC_REG6 22 +#define CC_REG7 23 +#define CC_REG8 24 +#define CC_REG9 25 +#define CC_REG10 26 +#define CC_REG11 27 +#define CC_REG12 28 +#define CC_REG13 29 +#define CC_REG14 30 +#define CC_REG15 31 + +extern uint32_t cpu_ltop_map[MAXCPU]; +extern struct perf_area *xlr_shared_config_area; + +static __inline__ uint32_t make_cpu_tag(uint32_t val) +{ + return PERF_CP0_COUNTER<<24 | (val & 0xffff); +} + +static __inline__ uint32_t make_cp0_perf_control(uint32_t flags, uint32_t thread, uint32_t event) +{ + return (flags & 0x1f) | (thread & 0x03)<<11 | (event & 0x3f)<<5 | 0x01; +} + +static __inline__ uint32_t cp0_perf_control_get_thread(uint32_t control_word) +{ + return (control_word & 0x1800)>>11; +} + +static __inline__ uint32_t cp0_perf_control_get_event(uint32_t control_word) +{ + return (control_word & 0x7e0)>>5; +} + +static __inline__ uint32_t read_pic_6_timer_count(void) +{ + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + + /* PIC counts down, convert it to count up */ + return 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_0); +} + + +static uint32_t get_num_events(const uint64_t *events) +{ + int total = 0; + int thread; + + for(thread = 0; threadperf_config; + num_events = get_num_events(saved_config.events); + cc_sample = saved_config.cc_sample_rate; + + DPRINT("%d - reconfigure num_events = %d, events = %llx,%llx,%llx,%llx\n", + processor_id(), num_events, saved_config.events[0], + saved_config.events[1],saved_config.events[2],saved_config.events[3] ); + + if (num_events == 0) + return; + + cntr_cntrl = get_first_control_word(saved_config.flags, saved_config.events); + write_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL0, cntr_cntrl); + write_c0_register(CP0_PERF_COUNTER, PERFCNTR0, 0); /* reset count */ + if (num_events > 1) { + cntr_cntrl = get_next_control_word(cntr_cntrl, saved_config.events); + write_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL1, cntr_cntrl); + write_c0_register(CP0_PERF_COUNTER, PERFCNTR1, 0); /* reset count */ + } + saved_timestamp = read_pic_6_timer_count(); +} + +int xlr_perfmon_no_event_count = 0; +int xlr_perfmon_sample_count; + +/* timer callback routine */ +void xlr_perfmon_sampler(void *dummy) +{ + uint32_t current_ts; + uint32_t cntr_cntrl=0; + + /* xlr_ack_interrupt(XLR_PERFMON_IPI_VECTOR); */ + + if (my_perf_area->perf_config.magic != PERFMON_ACTIVE_MAGIC) + return; + /* + * If there has been a change in configuation, update the configuration + */ + if (saved_config.generation != my_perf_area->perf_config.generation) { + reconfigure(); + return; + } + + /* credit counter samples if reqd */ + if(saved_config.cc_register_mask && --cc_sample == 0) { + cc_sample = saved_config.cc_sample_rate; + do_sample_cc_registers(&my_perf_area->sample_fifo, + my_perf_area->perf_config.cc_register_mask); + } + + if (num_events == 0) { + xlr_perfmon_no_event_count++; + return; + } + + /* put samples in the queue */ + current_ts = read_pic_6_timer_count(); + cntr_cntrl = read_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL0); + put_sample(&my_perf_area->sample_fifo, make_cpu_tag(cntr_cntrl), + read_c0_register(CP0_PERF_COUNTER, PERFCNTR0), current_ts - saved_timestamp); + xlr_perfmon_sample_count++; + write_c0_register(CP0_PERF_COUNTER, PERFCNTR0, 0); /* reset count */ + + if(num_events > 1) { + cntr_cntrl = read_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL1); + put_sample(&my_perf_area->sample_fifo, make_cpu_tag(cntr_cntrl), + read_c0_register(CP0_PERF_COUNTER, PERFCNTR1), current_ts - saved_timestamp); + xlr_perfmon_sample_count++; + write_c0_register(CP0_PERF_COUNTER, PERFCNTR1, 0); /* reset count */ + + if(num_events > 2) { + /* multiplex events */ + cntr_cntrl = get_next_control_word(cntr_cntrl, saved_config.events); + write_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL0, cntr_cntrl); + + cntr_cntrl = get_next_control_word(cntr_cntrl, saved_config.events); + write_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL1, cntr_cntrl); + } + } + saved_timestamp = read_pic_6_timer_count(); +} + +/* + * Initializes time to gather CPU performance counters and credit counters + */ +void xlr_perfmon_init_cpu(void *dummy) +{ + int processor = cpu_ltop_map[PCPU_GET(cpuid)]; + + /* run on just one thread per core */ + if(processor % 4) + return; + + DPRINT("%d : configure with %p", processor, my_perf_area); + memset(my_perf_area, 0, sizeof(*my_perf_area)); + init_fifo(&my_perf_area->sample_fifo); + my_perf_area->perf_config.magic = PERFMON_ENABLED_MAGIC; + my_perf_area->perf_config.generation = PERFMON_INITIAL_GENERATION; + DPRINT("%d : Initialize", processor); + + return ; +} diff --git a/sys/mips/rmi/perfmon_utils.h b/sys/mips/rmi/perfmon_utils.h new file mode 100644 index 00000000000..7d86184ff30 --- /dev/null +++ b/sys/mips/rmi/perfmon_utils.h @@ -0,0 +1,113 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ + +#ifndef UTILS_H +#define UTILS_H + +#include /* variable args */ + +/* TODO optimize of mips, even i & (i-1) is better */ + +static int __inline__ get_set_bit_count64(uint64_t value) +{ + int i, result=0; + + for(i=0; i /* for DPRINT */ + +#define NCPUS 32 +#define NCORES 8 +#define NTHREADS 4 +#define PERF_SAMPLE_BUFSZ 32 +/*select timeout is 512*1024 microsecs */ +#define DEFAULT_SYS_SAMPLING_INTERVAL (512*1024) +/* default timer value programmed to PIC is 10*1024*1024 */ +#define DEFAULT_CPU_SAMPLING_INTERVAL (10*1024) +#define DEFAULT_CC_SAMPLE_RATE 16 +#define DEFAULT_CP0_FLAGS 0x0A +#define NUM_L2_BANKS 8 +#define NUM_DRAM_BANKS 4 + +/* CP0 register for timestamp */ +#define CP0_COUNT 9 +#define CP0_EIRR_REG 9 +#define CP0_EIRR_SEL 6 +#define CP0_EIMR_REG 9 +#define CP0_EIMR_SEL 7 + +/* CP0 register for perf counters */ +#define CP0_PERF_COUNTER 25 +/* selector values */ +#define PERFCNTRCTL0 0 +#define PERFCNTR0 1 +#define PERFCNTRCTL1 2 +#define PERFCNTR1 3 + +#define XLR_IO_PIC_OFFSET 0x08000 +#define PIC_SYS_TIMER_0_BASE 0x120 +#define PIC_SYS_TIMER_NUM_6 6 + +/* CP2 registers for reading credit counters */ +#define CC_REG0 16 + +#define read_c0_register(reg, sel) \ +({ unsigned int __rv; \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ + ".set mips32\n\t" \ + "mfc0\t%0,$%1,%2\n\t" \ + ".set\tpop" \ + : "=r" (__rv) : "i" (reg), "i" (sel) ); \ + __rv;}) + +#define write_c0_register(reg, sel, value) \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ + ".set mips32\n\t" \ + "mtc0\t%0,$%1,%2\n\t" \ + ".set\tpop" \ + : : "r" (value), "i" (reg), "i" (sel) ); + +#define read_c2_register(reg, sel) \ +({ unsigned int __rv; \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ + ".set mips32\n\t" \ + "mfc0\t%0,$%1,%2\n\t" \ + ".set\tpop" \ + : "=r" (__rv) : "i"(reg), "i" (sel) ); \ + __rv;}) + +/* + * We have 128 registers in C2 credit counters, reading them one at + * a time using bitmap will take a lot of code, so we have two functions + * to read registers sel0-3 and sel 4-7 into one 32 bit word. + */ + +#define read_cc_registers_0123(reg) \ +({ \ + unsigned int __rv; \ + \ + __asm__ __volatile__( \ + ".set push\n\t" \ + ".set mips32\n\t" \ + ".set noreorder\n\t" \ + "mfc2 %0, $%1, 0\n\t" \ + "mfc2 $8, $%1, 1\n\t" \ + "sll %0, %0, 8\n\t" \ + "or %0, %0, $8\n\t" \ + "mfc2 $8, $%1, 2\n\t" \ + "sll %0, %0, 8\n\t" \ + "or %0, %0, $8\n\t" \ + "mfc2 $8, $%1, 3\n\t" \ + "sll %0, %0, 8\n\t" \ + "or %0, %0, $8\n\t" \ + ".set pop" \ + : "=r" (__rv) : "i"(reg) : "$8"); \ + \ + __rv; \ +}) + +#define read_cc_registers_4567(reg) \ +({ \ + unsigned int __rv; \ + \ + __asm__ __volatile__( \ + ".set push\n\t" \ + ".set mips32\n\t" \ + ".set noreorder\n\t" \ + "mfc2 %0, $%1, 4\n\t" \ + "mfc2 $8, $%1, 5\n\t" \ + "sll %0, %0, 8\n\t" \ + "or %0, %0, $8\n\t" \ + "mfc2 $8, $%1, 6\n\t" \ + "sll %0, %0, 8\n\t" \ + "or %0, %0, $8\n\t" \ + "mfc2 $8, $%1, 7\n\t" \ + "sll %0, %0, 8\n\t" \ + "or %0, %0, $8\n\t" \ + ".set pop" \ + : "=r" (__rv) :"i"(reg) : "$8"); \ + \ + __rv; \ +}) + +#endif +#endif diff --git a/sys/mips/rmi/pic.h b/sys/mips/rmi/pic.h new file mode 100644 index 00000000000..366a73659c7 --- /dev/null +++ b/sys/mips/rmi/pic.h @@ -0,0 +1,257 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ +#ifndef _RMI_PIC_H_ +#define _RMI_PIC_H_ + + +#include +#include +#include + +#define PIC_IRT_WD_INDEX 0 +#define PIC_IRT_TIMER_0_INDEX 1 +#define PIC_IRT_TIMER_1_INDEX 2 +#define PIC_IRT_TIMER_2_INDEX 3 +#define PIC_IRT_TIMER_3_INDEX 4 +#define PIC_IRT_TIMER_4_INDEX 5 +#define PIC_IRT_TIMER_5_INDEX 6 +#define PIC_IRT_TIMER_6_INDEX 7 +#define PIC_IRT_TIMER_7_INDEX 8 +#define PIC_IRT_CLOCK_INDEX PIC_IRT_TIMER_7_INDEX +#define PIC_IRT_UART_0_INDEX 9 +#define PIC_IRT_UART_1_INDEX 10 +#define PIC_IRT_I2C_0_INDEX 11 +#define PIC_IRT_I2C_1_INDEX 12 +#define PIC_IRT_PCMCIA_INDEX 13 +#define PIC_IRT_GPIO_INDEX 14 +#define PIC_IRT_HYPER_INDEX 15 +#define PIC_IRT_PCIX_INDEX 16 +#define PIC_IRT_GMAC0_INDEX 17 +#define PIC_IRT_GMAC1_INDEX 18 +#define PIC_IRT_GMAC2_INDEX 19 +#define PIC_IRT_GMAC3_INDEX 20 +#define PIC_IRT_XGS0_INDEX 21 +#define PIC_IRT_XGS1_INDEX 22 +#define PIC_IRT_HYPER_FATAL_INDEX 23 +#define PIC_IRT_PCIX_FATAL_INDEX 24 +#define PIC_IRT_BRIDGE_AERR_INDEX 25 +#define PIC_IRT_BRIDGE_BERR_INDEX 26 +#define PIC_IRT_BRIDGE_TB_INDEX 27 +#define PIC_IRT_BRIDGE_AERR_NMI_INDEX 28 + +/* numbering for XLS */ +#define PIC_IRT_BRIDGE_ERR_INDEX 25 +#define PIC_IRT_PCIE_LINK0_INDEX 26 +#define PIC_IRT_PCIE_LINK1_INDEX 27 +#define PIC_IRT_PCIE_LINK2_INDEX 23 +#define PIC_IRT_PCIE_LINK3_INDEX 24 +#define PIC_IRT_PCIE_INT_INDEX 28 +#define PIC_IRT_PCIE_FATAL_INDEX 29 +#define PIC_IRT_GPIO_B_INDEX 30 +#define PIC_IRT_USB_INDEX 31 + +#define PIC_NUM_IRTS 32 + +#define PIC_SYS_TIMER_MAXVAL_0_BASE 0x100 +#define PIC_SYS_TIMER_MAXVAL_1_BASE 0x110 + +#define PIC_SYS_TIMER_0_BASE 0x120 +#define PIC_SYS_TIMER_1_BASE 0x130 + +#define PIC_CLOCK_TIMER 7 + +#define PIC_CTRL 0x00 +#define PIC_IPI 0x04 +#define PIC_INT_ACK 0x06 + +#define WD_MAX_VAL_0 0x08 +#define WD_MAX_VAL_1 0x09 +#define WD_MASK_0 0x0a +#define WD_MASK_1 0x0b +#define WD_HEARBEAT_0 0x0c +#define WD_HEARBEAT_1 0x0d + +#define PIC_IRT_0_BASE 0x40 +#define PIC_IRT_1_BASE 0x80 + +#define PIC_IRT_0_WD (PIC_IRT_0_BASE + PIC_IRT_WD_INDEX) +#define PIC_IRT_1_WD (PIC_IRT_1_BASE + PIC_IRT_WD_INDEX) +#define PIC_IRT_0_TIMER_0 (PIC_IRT_0_BASE + PIC_IRT_TIMER_0_INDEX) +#define PIC_IRT_1_TIMER_0 (PIC_IRT_1_BASE + PIC_IRT_TIMER_0_INDEX) +#define PIC_IRT_0_TIMER_1 (PIC_IRT_0_BASE + PIC_IRT_TIMER_1_INDEX) +#define PIC_IRT_1_TIMER_1 (PIC_IRT_1_BASE + PIC_IRT_TIMER_1_INDEX) +#define PIC_IRT_0_TIMER_2 (PIC_IRT_0_BASE + PIC_IRT_TIMER_2_INDEX) +#define PIC_IRT_1_TIMER_2 (PIC_IRT_1_BASE + PIC_IRT_TIMER_2_INDEX) +#define PIC_IRT_0_TIMER_3 (PIC_IRT_0_BASE + PIC_IRT_TIMER_3_INDEX) +#define PIC_IRT_1_TIMER_3 (PIC_IRT_1_BASE + PIC_IRT_TIMER_3_INDEX) +#define PIC_IRT_0_TIMER_4 (PIC_IRT_0_BASE + PIC_IRT_TIMER_4_INDEX) +#define PIC_IRT_1_TIMER_4 (PIC_IRT_1_BASE + PIC_IRT_TIMER_4_INDEX) +#define PIC_IRT_0_TIMER_5 (PIC_IRT_0_BASE + PIC_IRT_TIMER_5_INDEX) +#define PIC_IRT_1_TIMER_5 (PIC_IRT_1_BASE + PIC_IRT_TIMER_5_INDEX) +#define PIC_IRT_0_TIMER_6 (PIC_IRT_0_BASE + PIC_IRT_TIMER_6_INDEX) +#define PIC_IRT_1_TIMER_6 (PIC_IRT_1_BASE + PIC_IRT_TIMER_6_INDEX) +#define PIC_IRT_0_TIMER_7 (PIC_IRT_0_BASE + PIC_IRT_TIMER_7_INDEX) +#define PIC_IRT_1_TIMER_7 (PIC_IRT_1_BASE + PIC_IRT_TIMER_7_INDEX) +#define PIC_IRT_0_CLOCK (PIC_IRT_0_TIMER_7) +#define PIC_IRT_1_CLOCK (PIC_IRT_1_TIMER_7) +#define PIC_IRT_0_UART_0 (PIC_IRT_0_BASE + PIC_IRT_UART_0_INDEX) +#define PIC_IRT_1_UART_0 (PIC_IRT_1_BASE + PIC_IRT_UART_0_INDEX) +#define PIC_IRT_0_UART_1 (PIC_IRT_0_BASE + PIC_IRT_UART_1_INDEX) +#define PIC_IRT_1_UART_1 (PIC_IRT_1_BASE + PIC_IRT_UART_1_INDEX) +#define PIC_IRT_0_I2C_0 (PIC_IRT_0_BASE + PIC_IRT_I2C_0_INDEX) +#define PIC_IRT_1_I2C_0 (PIC_IRT_1_BASE + PIC_IRT_I2C_0_INDEX) +#define PIC_IRT_0_I2C_1 (PIC_IRT_0_BASE + PIC_IRT_I2C_1_INDEX) +#define PIC_IRT_1_I2C_1 (PIC_IRT_1_BASE + PIC_IRT_I2C_1_INDEX) +#define PIC_IRT_0_HYPER (PIC_IRT_0_BASE + PIC_IRT_HYPER_INDEX) +#define PIC_IRT_1_HYPER (PIC_IRT_1_BASE + PIC_IRT_HYPER_INDEX) +#define PIC_IRT_0_PCIX (PIC_IRT_0_BASE + PIC_IRT_PCIX_INDEX) +#define PIC_IRT_1_PCIX (PIC_IRT_1_BASE + PIC_IRT_PCIX_INDEX) + +#define PIC_TIMER_0_MAXVAL_0 (PIC_SYS_TIMER_MAXVAL_0_BASE + 0) +#define PIC_TIMER_0_MAXVAL_1 (PIC_SYS_TIMER_MAXVAL_1_BASE + 0) +#define PIC_TIMER_0_COUNTER_0 (PIC_SYS_TIMER_0_BASE + 0) +#define PIC_TIMER_0_COUNTER_1 (PIC_SYS_TIMER_1_BASE + 0) +#define PIC_TIMER_6_MAXVAL_0 (PIC_SYS_TIMER_MAXVAL_0_BASE + 6) +#define PIC_TIMER_6_MAXVAL_1 (PIC_SYS_TIMER_MAXVAL_1_BASE + 6) +#define PIC_TIMER_6_COUNTER_0 (PIC_SYS_TIMER_0_BASE + 6) +#define PIC_TIMER_6_COUNTER_1 (PIC_SYS_TIMER_1_BASE + 6) +#define PIC_TIMER_7_MAXVAL_0 (PIC_SYS_TIMER_MAXVAL_0_BASE + 7) +#define PIC_TIMER_7_MAXVAL_1 (PIC_SYS_TIMER_MAXVAL_1_BASE + 7) +#define PIC_TIMER_7_COUNTER_0 (PIC_SYS_TIMER_0_BASE + 7) +#define PIC_TIMER_7_COUNTER_1 (PIC_SYS_TIMER_1_BASE + 7) + +#define PIC_IRQ_BASE 8 +#define PIC_IRT_FIRST_IRQ PIC_IRQ_BASE +#define PIC_WD_IRQ (PIC_IRQ_BASE + PIC_IRT_WD_INDEX) +#define PIC_TIMER_0_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_0_INDEX) +#define PIC_TIMER_1_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_1_INDEX) +#define PIC_TIMER_2_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_2_INDEX) +#define PIC_TIMER_3_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_3_INDEX) +#define PIC_TIMER_4_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_4_INDEX) +#define PIC_TIMER_5_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_5_INDEX) +#define PIC_TIMER_6_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_6_INDEX) +#define PIC_TIMER_7_IRQ (PIC_IRQ_BASE + PIC_IRT_TIMER_7_INDEX) +#define PIC_CLOCK_IRQ (PIC_TIMER_7_IRQ) +#define PIC_UART_0_IRQ (PIC_IRQ_BASE + PIC_IRT_UART_0_INDEX) +#define PIC_UART_1_IRQ (PIC_IRQ_BASE + PIC_IRT_UART_1_INDEX) +#define PIC_I2C_0_IRQ (PIC_IRQ_BASE + PIC_IRT_I2C_0_INDEX) +#define PIC_I2C_1_IRQ (PIC_IRQ_BASE + PIC_IRT_I2C_1_INDEX) +#define PIC_PCMCIA_IRQ (PIC_IRQ_BASE + PIC_IRT_PCMCIA_INDEX) +#define PIC_GPIO_IRQ (PIC_IRQ_BASE + PIC_IRT_GPIO_INDEX) +#define PIC_HYPER_IRQ (PIC_IRQ_BASE + PIC_IRT_HYPER_INDEX) +#define PIC_PCIX_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIX_INDEX) +#define PIC_GMAC_0_IRQ (PIC_IRQ_BASE + PIC_IRT_GMAC0_INDEX) +#define PIC_GMAC_1_IRQ (PIC_IRQ_BASE + PIC_IRT_GMAC1_INDEX) +#define PIC_GMAC_2_IRQ (PIC_IRQ_BASE + PIC_IRT_GMAC2_INDEX) +#define PIC_GMAC_3_IRQ (PIC_IRQ_BASE + PIC_IRT_GMAC3_INDEX) +#define PIC_XGS_0_IRQ (PIC_IRQ_BASE + PIC_IRT_XGS0_INDEX) +#define PIC_XGS_1_IRQ (PIC_IRQ_BASE + PIC_IRT_XGS1_INDEX) +#define PIC_HYPER_FATAL_IRQ (PIC_IRQ_BASE + PIC_IRT_HYPER_FATAL_INDEX) +#define PIC_PCIX_FATAL_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIX_FATAL_INDEX) +#define PIC_BRIDGE_AERR_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_AERR_INDEX) +#define PIC_BRIDGE_BERR_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_BERR_INDEX) +#define PIC_BRIDGE_TB_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_TB_INDEX) +#define PIC_BRIDGE_AERR_NMI_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_AERR_NMI_INDEX) + +#define PIC_BRIDGE_ERR_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_ERR_INDEX) +#define PIC_PCIE_LINK0_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_LINK0_INDEX) +#define PIC_PCIE_LINK1_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_LINK1_INDEX) +#define PIC_PCIE_LINK2_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_LINK2_INDEX) +#define PIC_PCIE_LINK3_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_LINK3_INDEX) +#define PIC_PCIE_INT_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_INT__INDEX) +#define PIC_PCIE_FATAL_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_FATAL_INDEX) +#define PIC_GPIO_B_IRQ (PIC_IRQ_BASE + PIC_IRT_GPIO_B_INDEX) +#define PIC_USB_IRQ (PIC_IRQ_BASE + PIC_IRT_USB_INDEX) + +#define PIC_IRT_LAST_IRQ PIC_USB_IRQ + +#define PIC_IRQ_IS_EDGE_TRIGGERED(irq) ( ((irq)>=PIC_TIMER_0_IRQ) && ((irq)<=PIC_TIMER_7_IRQ) ) + +#define PIC_IRQ_IS_IRT(irq) ( ((irq)>=PIC_IRT_FIRST_IRQ) && ((irq)<=PIC_IRT_LAST_IRQ) ) + + +extern struct mtx xlr_pic_lock; + + +static __inline__ __uint32_t pic_read_control(void) +{ + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + __uint32_t reg; + mtx_lock_spin(&xlr_pic_lock); + xlr_read_reg(mmio, PIC_CTRL); + mtx_unlock_spin(&xlr_pic_lock); + return reg; +} + +static __inline__ void pic_write_control(__uint32_t control) +{ + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + mtx_lock_spin(&xlr_pic_lock); + xlr_write_reg(mmio, PIC_CTRL, control); + mtx_unlock_spin(&xlr_pic_lock); +} +static __inline__ void pic_update_control(__uint32_t control) +{ + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + mtx_lock_spin(&xlr_pic_lock); + xlr_write_reg(mmio, PIC_CTRL, (control | xlr_read_reg(mmio, PIC_CTRL))); + mtx_unlock_spin(&xlr_pic_lock); +} + +static __inline__ void pic_ack(int irq) +{ + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + + /* ack the pic, if needed */ + if (!PIC_IRQ_IS_IRT(irq)) return; + + if(PIC_IRQ_IS_EDGE_TRIGGERED(irq)) { + mtx_lock_spin(&xlr_pic_lock); + xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE) )); + mtx_unlock_spin(&xlr_pic_lock); + return; + } + return; +} + +static inline void pic_delayed_ack(int irq) +{ + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + if (!PIC_IRQ_IS_IRT(irq)) return; + + if(!PIC_IRQ_IS_EDGE_TRIGGERED(irq)) { + mtx_lock_spin(&xlr_pic_lock); + xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE) )); + mtx_unlock_spin(&xlr_pic_lock); + return; + } +} + +#endif /* _RMI_PIC_H_ */ diff --git a/sys/mips/rmi/shared_structs.h b/sys/mips/rmi/shared_structs.h new file mode 100755 index 00000000000..fb9505f0a41 --- /dev/null +++ b/sys/mips/rmi/shared_structs.h @@ -0,0 +1,108 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ +#ifndef _SHARED_STRUCTS_H +#define _SHARED_STRUCTS_H + +/* If you make any changes to the below structs, shared_structs_offsets.h + * should be regenerated + */ +#define BOOT1_INFO_VERSION 0x0001 + +struct boot1_info { + uint64_t boot_level; + uint64_t io_base; + uint64_t output_device; + uint64_t uart_print; + uint64_t led_output; + uint64_t init; + uint64_t exit; + uint64_t warm_reset; + uint64_t wakeup; + uint64_t cpu_online_map; + uint64_t master_reentry_sp; + uint64_t master_reentry_gp; + uint64_t master_reentry_fn; + uint64_t slave_reentry_fn; + uint64_t magic_dword; + uint64_t uart_putchar; + uint64_t size; + uint64_t uart_getchar; + uint64_t nmi_handler; + uint64_t psb_version; + uint64_t mac_addr; + uint64_t cpu_frequency; + uint64_t board_version; + uint64_t malloc; + uint64_t free; + uint64_t alloc_pbuf; + uint64_t free_pbuf; + uint64_t psb_os_cpu_map; + uint64_t userapp_cpu_map; + uint64_t wakeup_os; + uint64_t psb_mem_map; + uint64_t board_major_version; + uint64_t board_minor_version; + uint64_t board_manf_revision; + uint64_t board_serial_number; + uint64_t psb_physaddr_map; +}; + +extern struct boot1_info xlr_boot1_info; + + +/* This structure is passed to all applications launched from the linux + loader through K0 register + */ +#define XLR_LOADER_INFO_MAGIC 0x600ddeed +struct xlr_loader_info { + uint32_t magic; + /* xlr_loader_shared_struct_t for CPU 0 will start here */ + unsigned long sh_mem_start; + /* Size of the shared memory b/w linux apps and rmios apps */ + uint32_t app_sh_mem_size; +}; + +/* Boot loader uses the linux mips convention */ +#define BOOT1_MEMMAP_MAX 32 + +enum xlr_phys_memmap_t { BOOT1_MEM_RAM=1, BOOT1_MEM_ROM_DATA, BOOT1_MEM_RESERVED}; + +struct xlr_boot1_mem_map { + uint32_t num_entries; + struct { + uint64_t addr; + uint64_t size; + uint32_t type; + uint32_t pad; + } physmem_map[BOOT1_MEMMAP_MAX]; +}; + + +#endif diff --git a/sys/mips/rmi/shared_structs_func.h b/sys/mips/rmi/shared_structs_func.h new file mode 100755 index 00000000000..54320757b1f --- /dev/null +++ b/sys/mips/rmi/shared_structs_func.h @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ +/* DO NOT EDIT THIS FILE + * This file has been autogenerated by ./gen_struct_offsets + */ +#ifndef _SHARED_STRUCTS_FUNC_H +#define _SHARED_STRUCTS_FUNC_H + +/* struct boot1_info function prototypes */ +#define boot1_info_uart_print_func(info_ptr, ...) ((void (*)(const char *, ...))(unsigned long)(info_ptr->uart_print))( __VA_ARGS__ ) +#define boot1_info_led_output_func(info_ptr, ...) ((void (*)(int))(unsigned long)(info_ptr->led_output))( __VA_ARGS__ ) +#define boot1_info_init_func(info_ptr, ...) ((void (*)(void))(unsigned long)(info_ptr->init))( __VA_ARGS__ ) +#define boot1_info_exit_func(info_ptr, ...) ((void (*)(void))(unsigned long)(info_ptr->exit))( __VA_ARGS__ ) +#define boot1_info_warm_reset_func(info_ptr, ...) ((void (*)(void))(unsigned long)(info_ptr->warm_reset))( __VA_ARGS__ ) +#define boot1_info_wakeup_func(info_ptr, ...) ((int (*)(void *, void *, unsigned int))(unsigned long)(info_ptr->wakeup))( __VA_ARGS__ ) +#define boot1_info_master_reentry_fn_func(info_ptr, ...) ((void (*)(void *))(unsigned long)(info_ptr->master_reentry_fn))( __VA_ARGS__ ) +#define boot1_info_slave_reentry_fn_func(info_ptr, ...) ((void (*)(void *))(unsigned long)(info_ptr->slave_reentry_fn))( __VA_ARGS__ ) +#define boot1_info_uart_putchar_func(info_ptr, ...) ((void (*)(char))(unsigned long)(info_ptr->uart_putchar))( __VA_ARGS__ ) +#define boot1_info_uart_getchar_func(info_ptr, ...) ((char (*)(void))(unsigned long)(info_ptr->uart_getchar))( __VA_ARGS__ ) +#define boot1_info_malloc_func(info_ptr, ...) ((void *(*)(size_t))(unsigned long)(info_ptr->malloc))( __VA_ARGS__ ) +#define boot1_info_free_func(info_ptr, ...) ((void (*)(void *))(unsigned long)(info_ptr->free))( __VA_ARGS__ ) +#define boot1_info_alloc_pbuf_func(info_ptr, ...) ((struct packet *(*)(void))(unsigned long)(info_ptr->alloc_pbuf))( __VA_ARGS__ ) +#define boot1_info_free_pbuf_func(info_ptr, ...) ((void (*)(struct packet *))(unsigned long)(info_ptr->free_pbuf))( __VA_ARGS__ ) +#define boot1_info_wakeup_os_func(info_ptr, ...) ((int (*)(void *, void *, unsigned int))(unsigned long)(info_ptr->wakeup_os))( __VA_ARGS__ ) + + +#endif diff --git a/sys/mips/rmi/shared_structs_offsets.h b/sys/mips/rmi/shared_structs_offsets.h new file mode 100755 index 00000000000..6cbabd8aa73 --- /dev/null +++ b/sys/mips/rmi/shared_structs_offsets.h @@ -0,0 +1,76 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ +/* DO NOT EDIT THIS FILE + * This file has been autogenerated by ./gen_struct_offsets + */ +#ifndef _SHARED_STRUCTS_OFFSETS_H +#define _SHARED_STRUCTS_OFFSETS_H + +/* struct boot1_info offsets */ +#define boot1_info_boot_level_off 0 +#define boot1_info_io_base_off 8 +#define boot1_info_output_device_off 16 +#define boot1_info_uart_print_off 24 +#define boot1_info_led_output_off 32 +#define boot1_info_init_off 40 +#define boot1_info_exit_off 48 +#define boot1_info_warm_reset_off 56 +#define boot1_info_wakeup_off 64 +#define boot1_info_cpu_online_map_off 72 +#define boot1_info_master_reentry_sp_off 80 +#define boot1_info_master_reentry_gp_off 88 +#define boot1_info_master_reentry_fn_off 96 +#define boot1_info_slave_reentry_fn_off 104 +#define boot1_info_magic_dword_off 112 +#define boot1_info_uart_putchar_off 120 +#define boot1_info_size_off 128 +#define boot1_info_uart_getchar_off 136 +#define boot1_info_nmi_handler_off 144 +#define boot1_info_psb_version_off 152 +#define boot1_info_mac_addr_off 160 +#define boot1_info_cpu_frequency_off 168 +#define boot1_info_board_version_off 176 +#define boot1_info_malloc_off 184 +#define boot1_info_free_off 192 +#define boot1_info_alloc_pbuf_off 200 +#define boot1_info_free_pbuf_off 208 +#define boot1_info_psb_os_cpu_map_off 216 +#define boot1_info_userapp_cpu_map_off 224 +#define boot1_info_wakeup_os_off 232 +#define boot1_info_psb_mem_map_off 240 + +/* struct boot1_info size */ +#define boot1_info_size 248 + +/* boot1_info version */ +#define boot1_info_version 1 + + +#endif diff --git a/sys/mips/rmi/uart_bus_xlr_iodi.c b/sys/mips/rmi/uart_bus_xlr_iodi.c new file mode 100644 index 00000000000..20415f4136d --- /dev/null +++ b/sys/mips/rmi/uart_bus_xlr_iodi.c @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 2006 Raza Microelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/sys/dev/uart/uart_bus_iodi.c,v 1.6.2.5 2006/02/15 09:16:01 marius Exp $"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +static int uart_iodi_probe(device_t dev); + +static device_method_t uart_iodi_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, uart_iodi_probe), + DEVMETHOD(device_attach, uart_bus_attach), + DEVMETHOD(device_detach, uart_bus_detach), + { 0, 0 } +}; + +static driver_t uart_iodi_driver = { + uart_driver_name, + uart_iodi_methods, + sizeof(struct uart_softc), +}; + +static int +uart_iodi_probe(device_t dev) +{ + struct uart_softc *sc; + + sc = device_get_softc(dev); + sc->sc_class = &uart_ns8250_class; + + /* regshft = 2, rclk = 66000000, rid = 0, chan = 0 */ + return (uart_bus_probe(dev, 2, 66000000, 0, 0)); +} + +DRIVER_MODULE(uart, iodi, uart_iodi_driver, uart_devclass, 0, 0); diff --git a/sys/mips/rmi/uart_cpu_mips_xlr.c b/sys/mips/rmi/uart_cpu_mips_xlr.c new file mode 100644 index 00000000000..09703f55d4b --- /dev/null +++ b/sys/mips/rmi/uart_cpu_mips_xlr.c @@ -0,0 +1,171 @@ +/*- + * Copyright (c) 2006 Wojciech A. Koszek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: uart_cpu_mips_xlr.c,v 1.5 2008-07-16 20:22:39 jayachandranc Exp $ + */ +/* + * Skeleton of this file was based on respective code for ARM + * code written by Olivier Houchard. + */ +/* + * XLRMIPS: This file is hacked from arm/... + */ +#include "opt_uart.h" + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +static int xlr_uart_probe(struct uart_bas *bas); +static void xlr_uart_init(struct uart_bas *bas, int, int, int, int); +static void xlr_uart_term(struct uart_bas *bas); +static void xlr_uart_putc(struct uart_bas *bas, int); +static int xlr_uart_poll(struct uart_bas *bas); +static int xlr_uart_getc(struct uart_bas *bas); +struct mtx xlr_uart_mtx; /*UartLock*/ + +struct uart_ops xlr_uart_ns8250_ops = { + .probe = xlr_uart_probe, + .init = xlr_uart_init, + .term = xlr_uart_term, + .putc = xlr_uart_putc, + .poll = xlr_uart_poll, + .getc = xlr_uart_getc, +}; + +bus_space_tag_t uart_bus_space_io; +bus_space_tag_t uart_bus_space_mem; + +static __inline void xlr_uart_lock(struct mtx *hwmtx) +{ + if(!mtx_initialized(hwmtx)) + return; + if(!kdb_active && hwmtx != NULL) + mtx_lock_spin(hwmtx); +} + +static __inline void xlr_uart_unlock(struct mtx *hwmtx) +{ + if(!mtx_initialized(hwmtx)) + return; + if(!kdb_active && hwmtx != NULL) + mtx_unlock_spin(hwmtx); +} + + +static int xlr_uart_probe(struct uart_bas *bas) +{ + int res; + xlr_uart_lock(&xlr_uart_mtx); + res = uart_ns8250_ops.probe(bas); + xlr_uart_unlock(&xlr_uart_mtx); + return res; +} + +static void xlr_uart_init(struct uart_bas *bas, int baudrate, int databits, + int stopbits, int parity) + +{ + xlr_uart_lock(&xlr_uart_mtx); + uart_ns8250_ops.init(bas,baudrate,databits,stopbits,parity); + xlr_uart_unlock(&xlr_uart_mtx); +} + +static void xlr_uart_term(struct uart_bas *bas) +{ + xlr_uart_lock(&xlr_uart_mtx); + uart_ns8250_ops.term(bas); + xlr_uart_unlock(&xlr_uart_mtx); +} + +static void xlr_uart_putc(struct uart_bas *bas, int c) +{ + xlr_uart_lock(&xlr_uart_mtx); + uart_ns8250_ops.putc(bas,c); + xlr_uart_unlock(&xlr_uart_mtx); +} + +static int xlr_uart_poll(struct uart_bas *bas) +{ + int res; + xlr_uart_lock(&xlr_uart_mtx); + res = uart_ns8250_ops.poll(bas); + xlr_uart_unlock(&xlr_uart_mtx); + return res; +} + +static int xlr_uart_getc(struct uart_bas *bas) +{ + return uart_ns8250_ops.getc(bas); +} + +int +uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) +{ + return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0); +} + + +int +uart_cpu_getdev(int devtype, struct uart_devinfo *di) +{ + di->ops = xlr_uart_ns8250_ops; + di->bas.chan = 0; + di->bas.bst = uart_bus_space_mem; + /* TODO Need to call bus_space_map() here */ + di->bas.bsh = 0xbef14000; /* Try with UART0 */ + di->bas.regshft = 2; + /* divisor = rclk / (baudrate * 16); */ + di->bas.rclk = 66000000; + + di->baudrate = 38400; + di->databits = 8; + di->stopbits = 1; + di->parity = UART_PARITY_NONE; + + /* TODO: Read env variables for all console parameters */ + + return (0); +} + +static void xlr_uart_mtx_init(void *dummy __unused) +{ + mtx_init(&xlr_uart_mtx, "uart lock",NULL,MTX_SPIN); +} +SYSINIT(xlr_init_uart_mtx, SI_SUB_LOCK, SI_ORDER_ANY, xlr_uart_mtx_init, NULL); + diff --git a/sys/mips/rmi/xlr_boot1_console.c b/sys/mips/rmi/xlr_boot1_console.c new file mode 100644 index 00000000000..01e67b573f3 --- /dev/null +++ b/sys/mips/rmi/xlr_boot1_console.c @@ -0,0 +1,113 @@ +/*- + * Copyright (c) 2006 Wojciech A. Koszek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: xlr_boot1_console.c,v 1.6 2008-07-16 20:22:49 jayachandranc Exp $ + */ +/* + * Adapted for XLR bootloader + * RMi + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "opt_comconsole.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#if 0 +static cn_probe_t xlr_boot1_cnprobe; +static cn_init_t xlr_boot1_cninit; +static cn_term_t xlr_boot1_cnterm; +static cn_getc_t xlr_boot1_cngetc; +static cn_checkc_t xlr_boot1_cncheckc; +static cn_putc_t xlr_boot1_cnputc; + +CONS_DRIVER(xlrboot, xlr_boot1_cnprobe, xlr_boot1_cninit, xlr_boot1_cnterm, xlr_boot1_cngetc, + xlr_boot1_cncheckc, xlr_boot1_cnputc, NULL); + +/* + * Device gets probed. Firmwire should be checked here probably. + */ +static void +xlr_boot1_cnprobe(struct consdev *cp) +{ + cp->cn_pri = CN_NORMAL; + cp->cn_tp = NULL; + cp->cn_arg = NULL; /* softc */ + cp->cn_unit = -1; /* ? */ + cp->cn_flags = 0; +} + +/* + * Initialization. + */ +static void +xlr_boot1_cninit(struct consdev *cp) +{ + sprintf(cp->cn_name, "boot1"); +} + +static void +xlr_boot1_cnterm(struct consdev *cp) +{ + cp->cn_pri = CN_DEAD; + cp->cn_flags = 0; + return; +} + +static int +xlr_boot1_cngetc(struct consdev *cp) +{ + return boot1_info_uart_getchar_func(&xlr_boot1_info); +} + +static void +xlr_boot1_cnputc(struct consdev *cp, int c) +{ + boot1_info_uart_putchar_func(&xlr_boot1_info, c); +} + +static int +xlr_boot1_cncheckc(struct consdev *cp) +{ + return 0; +} + +#endif diff --git a/sys/mips/rmi/xlr_csum_nocopy.S b/sys/mips/rmi/xlr_csum_nocopy.S new file mode 100644 index 00000000000..8b51a7f10f1 --- /dev/null +++ b/sys/mips/rmi/xlr_csum_nocopy.S @@ -0,0 +1,217 @@ +#include + + +/* + * a0: source address + * a1: length of the area to checksum + * a2: partial checksum + * a3: dst + */ + +#define src a0 +#define dst a3 +#define sum v0 + + .text + .set noreorder + + .macro CSUM_BIGCHUNK_AND_COPY offset + pref 0, (\offset+0x0)(a0) + ld t0, (\offset+0x00)(a0) + ld t1, (\offset+0x08)(a0) + .word 0x70481038 /*daddwc v0, v0, t0 */ + .word 0x70491038 /*daddwc v0, v0, t1 */ + ld t0, (\offset + 0x10)(a0) + ld t1, (\offset + 0x18)(a0) + .word 0x70481038 /* daddwc v0, v0, t0 */ + .word 0x70491038 /*daddwc v0, v0, t1 */ + .endm + +small_csumcpy: /* unknown src alignment and < 8 bytes to go */ + move a1, t2 + + andi t0, a1, 4 + beqz t0, 1f + andi t0, a1, 2 + + ulw t1, (src) /* Still a full word to go */ + daddiu src, 4 + .word 0x70491038 /*daddwc v0, v0, t1 */ + +1: move t1, zero + beqz t0, 1f + andi t0, a1, 1 + + ulhu t1, (src) /* Still a halfword to go */ + daddiu src, 2 + +1: beqz t0, 1f + sll t1, t1, 16 + + lbu t2, (src) + nop + +#ifdef __MIPSEB__ + sll t2, t2, 8 +#endif + or t1, t2 + +1: .word 0x70491038 /*daddwc v0, v0, t1 */ + + .word 0x70461038 /*daddwc v0, v0, a2 */ + .word 0x70401038 /*daddwc v0, v0, $0 */ + + /* Ideally at this point of time the status flag must be cleared */ + + dsll32 v1, sum, 0 + .word 0x70431038 /*daddwc v0, v0, v1 */ + dsrl32 sum, sum, 0 + .word 0x70401038 /*daddwc v0, v0, zero */ + + /* fold the checksum */ + sll v1, sum, 16 + addu sum, v1 + sltu v1, sum, v1 + srl sum, sum, 16 + addu sum, v1 +1: + .set reorder + jr ra + .set noreorder + +/* ------------------------------------------------------------------ */ + + .align 5 +LEAF(xlr_csum_partial_nocopy) + move sum, zero + move t7, zero + + sltiu t8, a1, 0x8 + bnez t8, small_csumcpy /* < 8 bytes to copy */ + move t2, a1 + + beqz a1, out + andi t7, src, 0x1 /* odd buffer? */ + +hword_align: + beqz t7, word_align + andi t8, src, 0x2 + + lbu t0, (src) + dsubu a1, a1, 0x1 + .word 0x70481038 /*daddwc v0, v0, t0 */ + daddu src, src, 0x1 + andi t8, src, 0x2 + +word_align: + beqz t8, dword_align + sltiu t8, a1, 56 + + lhu t0, (src) + dsubu a1, a1, 0x2 + .word 0x70481038 /*daddwc v0, v0, t0 */ + sltiu t8, a1, 56 + daddu src, src, 0x2 + +dword_align: + bnez t8, do_end_words + move t8, a1 + + andi t8, src, 0x4 + beqz t8, qword_align + andi t8, src, 0x8 + + lw t0, 0x00(src) + dsubu a1, a1, 0x4 + .word 0x70481038 /*daddwc v0, v0, t0 */ + daddu src, src, 0x4 + andi t8, src, 0x8 + +qword_align: + beqz t8, oword_align + andi t8, src, 0x10 + + ld t0, 0x00(src) + dsubu a1, a1, 0x8 + .word 0x70481038 /*daddwc v0, v0, t0 */ + daddu src, src, 0x8 + andi t8, src, 0x10 + +oword_align: + beqz t8, begin_movement + dsrl t8, a1, 0x7 + + ld t3, 0x08(src) + ld t0, 0x00(src) + .word 0x704b1038 /*daddwc v0, v0, t3 */ + .word 0x70481038 /*daddwc v0, v0, t0 */ + dsubu a1, a1, 0x10 + daddu src, src, 0x10 + dsrl t8, a1, 0x7 + +begin_movement: + beqz t8, 1f + andi t2, a1, 0x40 + +move_128bytes: + pref 0, 0x20(a0) + pref 0, 0x40(a0) + pref 0, 0x60(a0) + CSUM_BIGCHUNK_AND_COPY(0x00) + CSUM_BIGCHUNK_AND_COPY(0x20) + CSUM_BIGCHUNK_AND_COPY(0x40) + CSUM_BIGCHUNK_AND_COPY(0x60) + dsubu t8, t8, 0x01 + bnez t8, move_128bytes /* flag */ + daddu src, src, 0x80 + +1: + beqz t2, 1f + andi t2, a1, 0x20 + +move_64bytes: + pref 0, 0x20(a0) + pref 0, 0x40(a0) + CSUM_BIGCHUNK_AND_COPY(0x00) + CSUM_BIGCHUNK_AND_COPY(0x20) + daddu src, src, 0x40 + +1: + beqz t2, do_end_words + andi t8, a1, 0x1c + +move_32bytes: + pref 0, 0x20(a0) + CSUM_BIGCHUNK_AND_COPY(0x00) + andi t8, a1, 0x1c + daddu src, src, 0x20 + +do_end_words: + beqz t8, maybe_end_cruft + dsrl t8, t8, 0x2 + +end_words: + lw t0, (src) + dsubu t8, t8, 0x1 + .word 0x70481038 /*daddwc v0, v0, t0 */ + bnez t8, end_words + daddu src, src, 0x4 + +maybe_end_cruft: + andi t2, a1, 0x3 + +small_memcpy: + j small_csumcpy; move a1, t2 + beqz t2, out + move a1, t2 + +end_bytes: + lb t0, (src) + dsubu a1, a1, 0x1 + bnez a2, end_bytes + daddu src, src, 0x1 + +out: + jr ra + move v0, sum + END(xlr_csum_partial_nocopy) diff --git a/sys/mips/rmi/xlr_i2c.c b/sys/mips/rmi/xlr_i2c.c new file mode 100644 index 00000000000..60e51c596a8 --- /dev/null +++ b/sys/mips/rmi/xlr_i2c.c @@ -0,0 +1,442 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ + +#include +__FBSDID("$FreeBSD: src/sys/mips/xlr/xlr_i2c.c,v 1.20.8.1 2008/08/25 23:17:51 cognet Exp $"); + +/* + * I2C driver for the Palm-BK3220 I2C Host adapter on the RMI XLR. + */ + +#include +#include +#include +#include +#include +#include + + +#include +#include + +#include +#include + +#include "iicbus_if.h" + +#define DEVTOIICBUS(dev) ((struct iicbus_device*)device_get_ivars(dev)) + +#define I2C_PALM_CFG 0x00 +#define I2C_PALM_CLKDIV 0x01 +#define I2C_PALM_DEVADDR 0x02 +#define I2C_PALM_ADDR 0x03 +#define I2C_PALM_DATAOUT 0x04 +#define I2C_PALM_DATAIN 0x05 +#define I2C_PALM_STATUS 0x06 +#define I2C_PALM_STARTXFR 0x07 +#define I2C_PALM_BYTECNT 0x08 +#define I2C_PALM_HDSTATIM 0x09 + +/* TEST Values!! Change as required */ +#define I2C_PALM_CFG_DEF 0x000000F8 /* 8-Bit Addr + POR Values */ +#define I2C_PALM_CLKDIV_DEF 0x14A //0x00000052 +#define I2C_PALM_HDSTATIM_DEF 0x107 //0x00000000 + +#define I2C_PALM_STARTXFR_RD 0x00000001 +#define I2C_PALM_STARTXFR_WR 0x00000000 + + +#define PHOENIX_IO_I2C_0_OFFSET 0x16000 +#define PHOENIX_IO_I2C_1_OFFSET 0x17000 + +#define ARIZONA_I2c_BUS 1 + +int bus =1; + + +uint8_t current_slave; +uint8_t read_address; +static xlr_reg_t* iobase_i2c_regs; + +static devclass_t xlr_i2c_devclass; + +/* + * Device methods + */ +static int xlr_i2c_probe(device_t); +static int xlr_i2c_attach(device_t); +static int xlr_i2c_detach(device_t); + +static int xlr_i2c_start(device_t dev, u_char slave, int timeout); +static int xlr_i2c_stop(device_t dev); +static int xlr_i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay ); +static int xlr_i2c_write(device_t dev, char *buf, int len, int *sent, int timeout ); + + +struct xlr_i2c_softc +{ + device_t dev; /* Myself */ + struct resource *mem_res; /* Memory resource */ + volatile int flags; +#define RXRDY 4 +#define TXRDY 0x10 + int sc_started; + int twi_addr; + device_t iicbus; +}; + + +#define MDELAY(a){ \ + unsigned long local_loop = 0xfffff; \ + while(local_loop--); \ +}\ + +static void get_i2c_base(void) +{ + if(bus == 0) + iobase_i2c_regs = xlr_io_mmio(PHOENIX_IO_I2C_0_OFFSET); + else + iobase_i2c_regs = xlr_io_mmio(PHOENIX_IO_I2C_1_OFFSET); + return; +} + +static void palm_write(int reg, int value) +{ + get_i2c_base(); + xlr_write_reg(iobase_i2c_regs, reg, value); + return; +} + + +static int palm_read(int reg) +{ + uint32_t val; + get_i2c_base(); + val = xlr_read_reg(iobase_i2c_regs, reg); + return ((int) val); +} + +static int palm_addr_only(uint8_t addr, uint8_t offset) +{ + volatile uint32_t regVal=0x00; + + palm_write(I2C_PALM_ADDR, offset); + palm_write(I2C_PALM_DEVADDR, addr); + palm_write(I2C_PALM_CFG, 0xfa); + palm_write(I2C_PALM_STARTXFR,0x02); + regVal = palm_read(I2C_PALM_STATUS); + if (regVal & 0x0008) { + printf("palm_addr_only: ACKERR. Aborting...\n"); + return -1; + } + return 0; +} + + +static int palm_rx(uint8_t addr, uint8_t offset, uint8_t len, + uint8_t *buf) +{ + volatile uint32_t regVal=0x00, ctr=0x00; + int timeOut, numBytes=0x00; + + palm_write(I2C_PALM_CFG, 0xfa); + palm_write(I2C_PALM_BYTECNT, len); + palm_write(I2C_PALM_DEVADDR, addr); //DEVADDR=0x4c, 0x68 + MDELAY(1); + + for (numBytes=0x00; numBytes < len; numBytes++) { + palm_write(I2C_PALM_ADDR, offset+numBytes);//I2C_PALM_ADDR:offset + MDELAY(1); + if (!ctr) { + /* Trigger a READ Transaction */ + palm_write(I2C_PALM_STARTXFR, I2C_PALM_STARTXFR_RD); + ctr++; + } + + /* Error Conditions [Begin] */ + regVal = palm_read(I2C_PALM_STATUS); + MDELAY(1); + if (regVal & 0x0008) { + printf("palm_rx: ACKERR. Aborting...\n"); + return -1; + } + timeOut=10; + while ((regVal & 0x0030) && timeOut--) { + palm_write(I2C_PALM_STARTXFR, I2C_PALM_STARTXFR_RD); + regVal = palm_read(I2C_PALM_STATUS); + } + if (timeOut==0x00) { + printf("palm_rx: TimedOut on Valid STARTXFR/Arbitration\n"); + return -1; + } + timeOut=10; + /* Do we have valid data from the device yet..? */ + regVal &= 0x0004; + while (!regVal && timeOut--) { + regVal = palm_read(I2C_PALM_STATUS) & 0x0004; + } + if (timeOut==0x00) { + printf("palm_rx: TimedOut Waiting for Valid Data\n"); + return -1; + } + /* Error Conditions [End] */ + /* Read the data */ + buf[numBytes] = (uint8_t)palm_read(I2C_PALM_DATAIN); + } + return 0; +} + + + +static int wait_for_idle(void) +{ + int timeOut=0x1000; + volatile uint32_t regVal=0x00; + regVal = palm_read(I2C_PALM_STATUS) & 0x0001; + while (regVal && timeOut--) { + regVal = palm_read(I2C_PALM_STATUS) & 0x0001; + } + if (timeOut == 0x00) + return -1; /* Timed Out */ + else + return 0; +} + + +static int palm_tx(uint8_t addr, uint8_t offset, uint8_t* buf, uint8_t len) +{ + volatile uint32_t regVal=0x00; + int timeOut, ctr=0x00, numBytes=len; + + for (ctr=0x00; ctrmem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (sc->mem_res == NULL) + { + printf("not able to allocate the bus resource\n"); + } + + if((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL) + printf("could not allocate iicbus instance\n"); + + bus_generic_attach(dev); + + return (0); +} + +static int +xlr_i2c_detach(device_t dev) +{ + bus_generic_detach(dev); + + return (0); +} + +/* +static int +xlr_i2c_add_child(device_t dev, int order, const char *name, int unit) +{ + printf("********* %s ******** \n", __FUNCTION__); + device_add_child_ordered(dev, order, name, unit); + + bus_generic_attach(dev); + + return (0); +} +*/ + +static int xlr_i2c_start(device_t dev, u_char slave, int timeout) +{ + int error =0; + struct xlr_i2c_softc *sc; + + sc = device_get_softc(dev); + sc->sc_started = 1; + + current_slave = (slave >> 1); + return error; + +} + +static int xlr_i2c_stop(device_t dev) +{ + int error =0; + + return error; + +} + +static int xlr_i2c_read(device_t dev, char *buf, int len, int *read, int last, + int delay ) +{ + int error =0; + + if(palm_addr_only(current_slave,read_address) == -1){ + printf("I2C ADDRONLY Phase Fail.\n"); + return -1; + } + + + if(palm_rx(current_slave,read_address,len,buf)== -1){ + printf("I2C Read Fail.\n"); + return -1; + } + *read = len; + return error; + +} + + +static int xlr_i2c_write(device_t dev, char *buf, int len, int *sent, int timeout /* us */) +{ + + int error =0; + uint8_t write_address; + + if(len == 1){ + /* address for the next read*/ + read_address=buf[0]; + return error; + } + if(len < 2) + return (-1); + + write_address = buf[0]; + + /*for write operation, buf[0] contains the register offset and + buf[1] onwards contains the value*/ + palm_tx(current_slave,write_address, &buf[1], len-1); + + return error; + +} + +static int +xlr_i2c_callback(device_t dev, int index, caddr_t *data) +{ + return 0; +} + +static int +xlr_i2c_repeated_start(device_t dev, u_char slave, int timeout) +{ + return 0; +} + + +static device_method_t xlr_i2c_methods[] = { + /* device interface */ + DEVMETHOD(device_probe, xlr_i2c_probe), + DEVMETHOD(device_attach, xlr_i2c_attach), + DEVMETHOD(device_detach, xlr_i2c_detach), + + /* iicbus interface */ + DEVMETHOD(iicbus_callback, xlr_i2c_callback), + DEVMETHOD(iicbus_repeated_start, xlr_i2c_repeated_start), + DEVMETHOD(iicbus_start, xlr_i2c_start), + DEVMETHOD(iicbus_stop, xlr_i2c_stop), + DEVMETHOD(iicbus_write, xlr_i2c_write), + DEVMETHOD(iicbus_read, xlr_i2c_read), + { 0, 0 } +}; + +static driver_t xlr_i2c_driver = { + "xlr_i2c", + xlr_i2c_methods, + sizeof(struct xlr_i2c_softc), +}; + +DRIVER_MODULE(xlr_i2c, iodi, xlr_i2c_driver, xlr_i2c_devclass, 0, 0); diff --git a/sys/mips/rmi/xlr_machdep.c b/sys/mips/rmi/xlr_machdep.c new file mode 100644 index 00000000000..f28bdaa63cb --- /dev/null +++ b/sys/mips/rmi/xlr_machdep.c @@ -0,0 +1,650 @@ +/*- + * Copyright (c) 2002-2004 Juli Mallett + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include /* cinit() */ +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef XLR_PERFMON +#include +#endif + + + +void platform_prep_smp_launch(void); + +unsigned long xlr_io_base = (unsigned long)(DEFAULT_XLR_IO_BASE); + +/* 4KB static data aread to keep a copy of the bootload env until + the dynamic kenv is setup */ +char boot1_env[4096]; +extern unsigned long _gp; + +/* + * Parameters from boot loader + */ +struct boot1_info xlr_boot1_info; +struct xlr_loader_info xlr_loader_info; /* FIXME : Unused */ +int xlr_run_mode; +int xlr_argc; +char **xlr_argv, **xlr_envp; +uint64_t cpu_mask_info; +uint32_t xlr_online_cpumask; +#ifdef SMP +static unsigned long xlr_secondary_gp[MAXCPU]; +static unsigned long xlr_secondary_sp[MAXCPU]; +#endif +extern int mips_cpu_online_mask; +extern int mips_cpu_logical_mask; +extern uint32_t cpu_ltop_map[MAXCPU]; +extern uint32_t cpu_ptol_map[MAXCPU]; +uint32_t xlr_core_cpu_mask=0x1; /* Core 0 thread 0 is always there */ + +void +platform_reset(void) +{ + /* FIXME : use proper define */ + u_int32_t *mmio = (u_int32_t *)0xbef18000; + + printf("Rebooting the system now\n"); + mmio[8] = 0x1; +} + +void platform_secondary_init(void) +{ +#ifdef SMP + xlr_msgring_cpu_init(); + + /* Setup interrupts for secondary CPUs here */ + platform_update_intrmask(IPI_SMP_CALL_FUNCTION); + platform_update_intrmask(IPI_STOP); + platform_update_intrmask(IPI_RENDEZVOUS); + platform_update_intrmask(IPI_AST); + platform_update_intrmask(IRQ_TIMER); +#ifdef XLR_PERFMON + platform_update_intrmask(IPI_PERFMON); +#endif + + return; +#endif +} + + +int xlr_asid_pcpu=256; /* This the default */ +int xlr_shtlb_enabled=0; +/* This function sets up the number of tlb entries available + to the kernel based on the number of threads brought up. + The ASID range also gets divided similarly. + THE NUMBER OF THREADS BROUGHT UP IN EACH CORE MUST BE THE SAME +NOTE: This function will mark all 64TLB entries as available +to the threads brought up in the core. If kernel is brought with say mask +0x33333333, no TLBs will be available to the threads in each core. +*/ +static void setup_tlb_resource(void) +{ + int mmu_setup; + int value = 0; + uint32_t cpu_map = xlr_boot1_info.cpu_online_map; + uint32_t thr_mask = cpu_map >> (xlr_cpu_id() << 2); + uint8_t core0 = xlr_boot1_info.cpu_online_map & 0xf; + uint8_t core_thr_mask; + int i=0, count=0; + + /* If CPU0 did not enable shared TLB, other cores need to follow */ + if((xlr_cpu_id() != 0) && (xlr_shtlb_enabled == 0)) + return; + /* First check if each core is brought up with the same mask */ + for(i=1; i < 8; i++) { + core_thr_mask = cpu_map >> (i << 2); + core_thr_mask &= 0xf; + if(core_thr_mask && core_thr_mask != core0){ + printf + ("Each core must be brought with same cpu mask\n"); + printf("Cannot enabled shared TLB. "); + printf("Falling back to split TLB mode\n"); + return; + } + } + + xlr_shtlb_enabled = 1; + for(i=0;i<4;i++) if (thr_mask & (1< sizeof(boot1_env)) { + printf("*** Environment could not be copied in full\n"); + break; + } + + printf("\t%s\n", xlr_argv[i]); + memcpy(&boot1_env[j], xlr_argv[i], len+1); /* copy the '\0' too */ + j += len+1; + } + boot1_env[j] = '\0'; + kern_envp = boot1_env; + + xlr_set_boot_flags(); + + /* get physical memory info from boot loader*/ + boot_map = (struct xlr_boot1_mem_map *) + (unsigned long)xlr_boot1_info.psb_mem_map; + for(i=0, j=0; inum_entries; i++, j+=2) { + if (boot_map->physmem_map[i].type == BOOT1_MEM_RAM) { + if (j == 14) { + printf("*** ERROR *** memory map too large ***\n"); + break; + } + if (j == 0) { + /*TODO FIXME */ + /* start after kernel end */ + phys_avail[0] = (vm_paddr_t) + MIPS_KSEG0_TO_PHYS(&_end) + 0x20000; + /* boot loader start */ + /* HACK to Use bootloaders memory region */ + /*TODO FIXME */ + if(boot_map->physmem_map[0].size == 0x0c000000) { + boot_map->physmem_map[0].size = 0x0ff00000; + } + phys_avail[1] = boot_map->physmem_map[0].addr + + boot_map->physmem_map[0].size; + + } else { +/* + * Can't use this code yet, because most of the fixed allocations happen from + * the biggest physical area. If we have more than 512M memory the kernel will try + * to map from the second are which is not in KSEG0 and not mapped + */ + phys_avail[j] = (vm_paddr_t) + boot_map->physmem_map[i].addr; + phys_avail[j+1] = phys_avail[j] + + boot_map->physmem_map[i].size; +#if 0 /* FIXME TOD0 */ + phys_avail[j] = phys_avail[j+1] = 0; +#endif + } + physsz += boot_map->physmem_map[i].size; + } + } + + /* FIXME XLR TODO */ + phys_avail[j] = phys_avail[j+1] = 0; + realmem = physmem = btoc(physsz); + + /*Store pcpu in scratch 5*/ + write_c0_register32(MIPS_COP_0_OSSCRATCH,5,pcpup); + + /* Set up hz, among others. */ + mips_init(); + pcpup = (struct pcpu *)NULL; /* TODO To be removed */ + +#ifdef SMP + /*If thread 0 of any core is not available then mark whole core as + not available*/ + tmp = xlr_boot1_info.cpu_online_map; + for(i=4; ii_thread; + p = td->td_proc; + + /* Interrupt thread will enable the interrupts after processing + all messages + */ + mtx_lock_spin(&sched_lock); + disable_msgring_int(NULL); + it->i_pending = 1; + if (TD_AWAITING_INTR(td)) { + CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, p->p_pid, + p->p_comm); + TD_CLR_IWAIT(td); + setrunqueue(td, SRQ_INTR); + } else { + CTR4(KTR_INTR, "%s: pid %d (%s): state %d", + __func__, p->p_pid, p->p_comm, td->td_state); + } + mtx_unlock_spin(&sched_lock); + +} +#define MIT_DEAD 4 +static void +msgring_process(void * arg) +{ + volatile struct msgring_ithread *ithd; + struct thread *td; + struct proc *p; + + td = curthread; + p = td->td_proc; + ithd = (volatile struct msgring_ithread *)arg; + KASSERT(ithd->i_thread == td, + ("%s:msg_ithread and proc linkage out of sync", __func__)); + + /* First bind this thread to the right CPU */ + mtx_lock_spin(&sched_lock); + sched_bind(td, ithd->i_cpu); + mtx_unlock_spin(&sched_lock); + +// printf("Started %s on CPU %d\n", __FUNCTION__, ithd->i_cpu); + + while(1) { + if (ithd->i_flags & MIT_DEAD) { + CTR3(KTR_INTR, "%s: pid %d (%s) exiting", __func__, + p->p_pid, p->p_comm); + kthread_exit(0); + } + while (ithd->i_pending) { + /* + * This might need a full read and write barrier + * to make sure that this write posts before any + * of the memory or device accesses in the + * handlers. + */ + atomic_store_rel_int(&ithd->i_pending, 0); + xlr_msgring_handler(NULL); + } + mtx_lock_spin(&sched_lock); + if (!ithd->i_pending && !(ithd->i_flags & MIT_DEAD)) { + TD_SET_IWAIT(td); + enable_msgring_int(NULL); + mi_switch(SW_VOL, NULL); + } + mtx_unlock_spin(&sched_lock); + } + +} +void platform_prep_smp_launch(void) +{ + int cpu; + uint32_t cpu_mask; + struct msgring_ithread *ithd; + struct thread *td; + struct proc *p; + int error; + + cpu_mask = PCPU_GET(cpumask) | PCPU_GET(other_cpus); + + /* Create kernel threads for message ring interrupt processing */ + /* Currently create one task for thread 0 of each core */ + for(cpu=0; cpu < MAXCPU; cpu+=1) { + + if(!((1 << cpu) & cpu_mask)) + continue; + + if((cpu_ltop_map[cpu]%4) != 0) + continue; + + ithd = &msgring_ithreads[cpu]; + sprintf(ithd_name[cpu], "msg_intr%d", cpu); + error = kthread_create(msgring_process, (void *)ithd, &p, + RFSTOPPED | RFHIGHPID, 0, "%s", ithd_name[cpu]); + if (error) + panic("kthread_create() failed with %d", error); + td = FIRST_THREAD_IN_PROC(p); /* XXXKSE */ + mtx_lock_spin(&sched_lock); + td->td_ksegrp->kg_pri_class = PRI_ITHD; + TD_SET_IWAIT(td); + mtx_unlock_spin(&sched_lock); + td->td_pflags |= TDP_ITHREAD; + ithd->i_thread = td; + ithd->i_pending = 0; + ithd->i_cpu = cpu; + CTR2(KTR_INTR, "%s: created %s", __func__, ithd_name[cpu]); + } +} + diff --git a/sys/mips/rmi/xlr_pci.c b/sys/mips/rmi/xlr_pci.c new file mode 100644 index 00000000000..31fe5cf7306 --- /dev/null +++ b/sys/mips/rmi/xlr_pci.c @@ -0,0 +1,410 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "pcib_if.h" + +#define LSU_CFG0_REGID 0 +#define LSU_CERRLOG_REGID 9 +#define LSU_CERROVF_REGID 10 +#define LSU_CERRINT_REGID 11 +#define SWAP32(x)\ + (((x) & 0xff000000) >> 24) | \ + (((x) & 0x000000ff) << 24) | \ + (((x) & 0x0000ff00) << 8) | \ + (((x) & 0x00ff0000) >> 8) + + +/* MSI support */ + +#define MSI_MIPS_ADDR_DEST 0x000ff000 +#define MSI_MIPS_ADDR_RH 0x00000008 +# define MSI_MIPS_ADDR_RH_OFF 0x00000000 +# define MSI_MIPS_ADDR_RH_ON 0x00000008 +#define MSI_MIPS_ADDR_DM 0x00000004 +# define MSI_MIPS_ADDR_DM_PHYSICAL 0x00000000 +# define MSI_MIPS_ADDR_DM_LOGICAL 0x00000004 + +/* Fields in data for Intel MSI messages. */ +#define MSI_MIPS_DATA_TRGRMOD 0x00008000 /* Trigger mode */ +# define MSI_MIPS_DATA_TRGREDG 0x00000000 /* edge */ +# define MSI_MIPS_DATA_TRGRLVL 0x00008000 /* level */ + +#define MSI_MIPS_DATA_LEVEL 0x00004000 /* Polarity. */ +# define MSI_MIPS_DATA_DEASSERT 0x00000000 +# define MSI_MIPS_DATA_ASSERT 0x00004000 + +#define MSI_MIPS_DATA_DELMOD 0x00000700 /* Delivery Mode */ +# define MSI_MIPS_DATA_DELFIXED 0x00000000 /* fixed */ +# define MSI_MIPS_DATA_DELLOPRI 0x00000100 /* lowest priority */ + +#define MSI_MIPS_DATA_INTVEC 0x000000ff + +/* + * Build Intel MSI message and data values from a source. AMD64 systems + * seem to be compatible, so we use the same function for both. + */ +#define MIPS_MSI_ADDR(cpu) \ + (MSI_MIPS_ADDR_BASE | (cpu) << 12 | \ + MSI_MIPS_ADDR_RH_OFF | MSI_MIPS_ADDR_DM_PHYSICAL) + +#define MIPS_MSI_DATA(irq) \ + (MSI_MIPS_DATA_TRGRLVL | MSI_MIPS_DATA_DELFIXED | \ + MSI_MIPS_DATA_ASSERT | (irq)) + +struct xlr_hose_softc { + int junk; /* no softc */ +}; +static devclass_t pcib_devclass; +static int pci_bus_status = 0; +static void *pci_config_base; + +static uint32_t pci_cfg_read_32bit(uint32_t addr); +static void pci_cfg_write_32bit(uint32_t addr, uint32_t data); + +static int +xlr_pcib_probe(device_t dev) +{ + device_set_desc(dev, "xlr system bridge controller"); + + pci_init_resources(); + pci_config_base = (void *)MIPS_PHYS_TO_KSEG1(DEFAULT_PCI_CONFIG_BASE); + pci_bus_status = 1; + + return 0; +} + +static int +xlr_pcib_read_ivar(device_t dev, device_t child, int which, u_long *result) +{ +#if 0 + device_printf(dev, "xlr_pcib_read_ivar : read ivar %d for child %s\n", which, device_get_nameunit(child)); +#endif + switch (which) { + case PCIB_IVAR_BUS: + *result = 0; + return 0; + } + return ENOENT; +} + +static int +xlr_pcib_maxslots(device_t dev) +{ + if (xlr_board_info.is_xls) + return 4; + else + return 32; +} + +#define pci_cfg_offset(bus,slot,devfn,where) (((bus)<<16) + ((slot) << 11)+((devfn)<<8)+(where)) + +static __inline__ void disable_and_clear_cache_error(void) +{ + uint64_t lsu_cfg0 = read_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID); + lsu_cfg0 = lsu_cfg0 & ~0x2e; + write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID, lsu_cfg0); + /* Clear cache error log */ + write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID, 0); +} + +static __inline__ void clear_and_enable_cache_error(void) +{ + uint64_t lsu_cfg0 = 0; + + /* first clear the cache error logging register */ + write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID, 0); + write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERROVF_REGID, 0); + write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRINT_REGID, 0); + + lsu_cfg0 = read_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID); + lsu_cfg0 = lsu_cfg0 | 0x2e; + write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID, lsu_cfg0); +} + +static uint32_t phoenix_pciread(u_int b, u_int s, u_int f, + u_int reg, int width) +{ + uint32_t data = 0; + + if ((width == 2) && (reg & 1)) + return 0xFFFFFFFF; + else if ((width == 4) && (reg & 3)) + return 0xFFFFFFFF; + + if (pci_bus_status) + data = pci_cfg_read_32bit(pci_cfg_offset(b, s, f, reg)); + else + data = 0xFFFFFFFF; + + if (width == 1) + return ((data >> ((reg & 3) << 3)) & 0xff); + else if (width == 2) + return ((data >> ((reg & 3) << 3)) & 0xffff); + else + return data; +} + +static void phoenix_pciwrite(u_int b, u_int s, u_int f, + u_int reg, u_int val, int width) +{ + uint32_t cfgaddr = pci_cfg_offset(b, s, f, reg); + uint32_t data = 0; + + if ((width == 2) && (reg & 1)) + return ; + else if ((width == 4) && (reg & 3)) + return ; + + if (!pci_bus_status) + return ; + + if (width == 1) { + data = pci_cfg_read_32bit(cfgaddr); + data = (data & ~(0xff << ((reg & 3) << 3))) | + (val << ((reg & 3) << 3)); + } else if (width == 2) { + data = pci_cfg_read_32bit(cfgaddr); + data = (data & ~(0xffff << ((reg & 3) << 3))) | + (val << ((reg & 3) << 3)); + } else { + data = val; + } + + pci_cfg_write_32bit(cfgaddr, data); + + return ; +} + +static uint32_t pci_cfg_read_32bit(uint32_t addr) +{ + uint32_t temp = 0; + uint32_t *p = (uint32_t *) ((uint32_t)pci_config_base + (addr & ~3)); + uint64_t cerr_cpu_log = 0; + + disable_and_clear_cache_error(); + + temp = SWAP32(*p); + + /* Read cache err log */ + cerr_cpu_log = read_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID); + + if(cerr_cpu_log) + { + /* Device don't exist. */ + temp = ~0x0; + } + clear_and_enable_cache_error(); + return temp; +} + + +static void pci_cfg_write_32bit(uint32_t addr, uint32_t data) +{ + unsigned int *p = (unsigned int *)((uint32_t)pci_config_base + (addr & ~3)); + + *p = SWAP32(data); +} + +static u_int32_t +xlr_pcib_read_config(device_t dev, u_int b, u_int s, u_int f, + u_int reg, int width) +{ + return phoenix_pciread(b, s, f, reg, width); +} + +static void +xlr_pcib_write_config(device_t dev, u_int b, u_int s, u_int f, + u_int reg, u_int32_t val, int width) +{ + phoenix_pciwrite(b, s, f, reg, val, width); +} + +static int xlr_pcib_attach(device_t dev) +{ + device_add_child(dev, "pci", 0); + bus_generic_attach(dev); + return 0; +} + +#define PCIE_LINK_STATE 0x4000 + +static void +xlr_pcib_identify(driver_t *driver, device_t parent) +{ + xlr_reg_t *pcie_mmio_le = xlr_io_mmio(XLR_IO_PCIE_1_OFFSET); + xlr_reg_t reg_link0 = xlr_read_reg(pcie_mmio_le, (0x80 >> 2)); + xlr_reg_t reg_link1 = xlr_read_reg(pcie_mmio_le, (0x84 >> 2)); + + if ((uint16_t)reg_link0 & PCIE_LINK_STATE) { + device_printf(parent, "Link 0 up\n"); + } + if ((uint16_t)reg_link1 & PCIE_LINK_STATE) { + device_printf(parent, "Link 1 up\n"); + } + + BUS_ADD_CHILD(parent, 0, "pcib", 0); + +} +static int +xlr_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs); +static int +xlr_release_msi(device_t pcib, device_t dev, int count, int *irqs); + +static int +xlr_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs) +{ + int pciirq; + int i; + device_t parent, tmp; + + + /* find the lane on which the slot is connected to */ + tmp = dev; + while (1) { + parent = device_get_parent(tmp); + if (parent == NULL || parent == pcib) { + device_printf(dev, "Cannot find parent bus\n"); + return ENXIO; + } + if (strcmp(device_get_nameunit(parent), "pci0") == 0) + break; + tmp = parent; + } + + switch (pci_get_slot(tmp)) { + case 0: pciirq = PIC_PCIE_LINK0_IRQ; break; + case 1: pciirq = PIC_PCIE_LINK1_IRQ; break; + case 2: pciirq = PIC_PCIE_LINK2_IRQ; break; + case 3: pciirq = PIC_PCIE_LINK3_IRQ; break; + default: return ENXIO; + } + + irqs[0] = pciirq; + /* + For now put in some fixed values for the other requested MSI, + TODO handle multiple messages + */ + for (i=1; i +#include +#include + +#define read_c0_register32(reg, sel) \ +({ unsigned int __rv; \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ + ".set mips32\n\t" \ + "mfc0\t%0,$%1,%2\n\t" \ + ".set\tpop" \ + : "=r" (__rv) : "i" (reg), "i" (sel) ); \ + __rv;}) + +#define write_c0_register32(reg, sel, value) \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ + ".set mips32\n\t" \ + "mtc0\t%0,$%1,%2\n\t" \ + ".set\tpop" \ + : : "r" (value), "i" (reg), "i" (sel) ); + +#define read_c0_register64(reg, sel) \ + ({ unsigned int __high, __low; \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ + ".set mips64\n\t" \ + "dmfc0\t $8, $%2, %3\n\t" \ + "dsrl32\t%0, $8, 0\n\t" \ + "dsll32\t$8, $8, 0\n\t" \ + "dsrl32\t%1, $8, 0\n\t" \ + ".set\tpop" \ + : "=r"(__high), "=r"(__low): "i"(reg), "i"(sel): "$8" );\ + (((unsigned long long)__high << 32) | __low);}) + +#define write_c0_register64(reg, sel, value) \ + do{ \ + unsigned int __high = val>>32; \ + unsigned int __low = val & 0xffffffff; \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ + ".set mips64\n\t" \ + "dsll32\t$8, %1, 0\n\t" \ + "dsll32\t$9, %0, 0\n\t" \ + "or\t $8, $8, $9\n\t" \ + "dmtc0\t $8, $%2, %3\n\t" \ + ".set\tpop" \ + :: "r"(high), "r"(low), "i"(reg), "i"(sel):"$8", "$9");\ + } while(0) + +#define read_c2_register32(reg, sel) \ +({ unsigned int __rv; \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ + ".set mips32\n\t" \ + "mfc2\t%0,$%1,%2\n\t" \ + ".set\tpop" \ + : "=r" (__rv) : "i" (reg), "i" (sel) ); \ + __rv;}) + +#define write_c2_register32(reg, sel, value) \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ + ".set mips32\n\t" \ + "mtc2\t%0,$%1,%2\n\t" \ + ".set\tpop" \ + : : "r" (value), "i" (reg), "i" (sel) ); + +#define read_c2_register64(reg, sel) \ + ({ unsigned int __high, __low; \ + __asm__ __volatile__( \ + ".set mips64\n\t" \ + "dmfc2\t $8, $%2, %3\n\t" \ + "dsrl32\t%0, $8, 0\n\t" \ + "dsll32\t$8, $8, 0\n\t" \ + "dsrl32\t%1, $8, 0\n\t" \ + ".set\tmips0" \ + : "=r"(__high), "=r"(__low): "i"(reg), "i"(sel): "$8" );\ + (((unsigned long long)__high << 32) | __low);}) + +#define write_c2_register64(reg, sel, value) \ + do{ \ + unsigned int __high = value>>32; \ + unsigned int __low = value & 0xffffffff; \ + __asm__ __volatile__( \ + ".set mips64\n\t" \ + "dsll32\t$8, %1, 0\n\t" \ + "dsll32\t$9, %0, 0\n\t" \ + "dsrl32\t$8, $8, 0\n\t" \ + "or\t $8, $8, $9\n\t" \ + "dmtc2\t $8, $%2, %3\n\t" \ + ".set\tmips0" \ + :: "r"(__high), "r"(__low), \ + "i"(reg), "i"(sel) \ + :"$8", "$9"); \ + } while(0) + +#if 0 +#define xlr_processor_id() \ +({int __id; \ + __asm__ __volatile__ ( \ + ".set push\n" \ + ".set noreorder\n" \ + ".word 0x40088007\n" \ + "srl $8, $8, 10\n" \ + "andi %0, $8, 0x3f\n" \ + ".set pop\n" \ + : "=r" (__id) : : "$8"); \ + __id;}) +#endif + +#define xlr_cpu_id() \ +({int __id; \ + __asm__ __volatile__ ( \ + ".set push\n" \ + ".set noreorder\n" \ + ".word 0x40088007\n" \ + "srl $8, $8, 4\n" \ + "andi %0, $8, 0x7\n" \ + ".set pop\n" \ + : "=r" (__id) : : "$8"); \ + __id;}) + +#define xlr_thr_id() \ +({int __id; \ + __asm__ __volatile__ ( \ + ".set push\n" \ + ".set noreorder\n" \ + ".word 0x40088007\n" \ + "andi %0, $8, 0x03\n" \ + ".set pop\n" \ + : "=r" (__id) : : "$8"); \ + __id;}) + + +/* Additional registers on the XLR */ +#define MIPS_COP_0_OSSCRATCH 22 + +#define XLR_CACHELINE_SIZE 32 + +#define XLR_MAX_CORES 8 + +/* functions to write to and read from the extended + * cp0 registers. + * EIRR : Extended Interrupt Request Register + * cp0 register 9 sel 6 + * bits 0...7 are same as cause register 8...15 + * EIMR : Extended Interrupt Mask Register + * cp0 register 9 sel 7 + * bits 0...7 are same as status register 8...15 + */ + +static inline uint64_t read_c0_eirr64(void) +{ + __uint32_t high, low; + + __asm__ __volatile__ ( + ".set push\n" + ".set noreorder\n" + ".set noat\n" + ".set mips4\n" + + ".word 0x40214806 \n\t" + "nop \n\t" + "dsra32 %0, $1, 0 \n\t" + "sll %1, $1, 0 \n\t" + + ".set pop\n" + + : "=r" (high), "=r" (low) + ); + + return ( ((__uint64_t)high) << 32) | low; +} + +static inline __uint64_t read_c0_eimr64(void) +{ + __uint32_t high, low; + + __asm__ __volatile__ ( + ".set push\n" + ".set noreorder\n" + ".set noat\n" + ".set mips4\n" + + ".word 0x40214807 \n\t" + "nop \n\t" + "dsra32 %0, $1, 0 \n\t" + "sll %1, $1, 0 \n\t" + + ".set pop\n" + + : "=r" (high), "=r" (low) + ); + + return ( ((__uint64_t)high) << 32) | low; +} + +static inline void write_c0_eirr64(__uint64_t value) +{ + __uint32_t low, high; + + high = value >> 32; + low = value & 0xffffffff; + + __asm__ __volatile__ ( + ".set push\n" + ".set noreorder\n" + ".set noat\n" + ".set mips4\n\t" + + "dsll32 $2, %1, 0 \n\t" + "dsll32 $1, %0, 0 \n\t" + "dsrl32 $2, $2, 0 \n\t" + "or $1, $1, $2 \n\t" + ".word 0x40a14806 \n\t" + "nop \n\t" + + ".set pop\n" + + : + : "r" (high), "r" (low) + : "$1", "$2"); +} + +static inline void write_c0_eimr64(__uint64_t value) +{ + __uint32_t low, high; + + high = value >> 32; + low = value & 0xffffffff; + + __asm__ __volatile__ ( + ".set push\n" + ".set noreorder\n" + ".set noat\n" + ".set mips4\n\t" + + "dsll32 $2, %1, 0 \n\t" + "dsll32 $1, %0, 0 \n\t" + "dsrl32 $2, $2, 0 \n\t" + "or $1, $1, $2 \n\t" + ".word 0x40a14807 \n\t" + "nop \n\t" + + ".set pop\n" + + : + : "r" (high), "r" (low) + : "$1", "$2"); +} + +static __inline__ int xlr_test_and_set(int *lock) +{ + int oldval = 0; + + __asm__ __volatile__ (".set push\n" + ".set noreorder\n" + "move $9, %2\n" + "li $8, 1\n" + //"swapw $8, $9\n" + ".word 0x71280014\n" + "move %1, $8\n" + ".set pop\n" + : "+m" (*lock), "=r" (oldval) + : "r" ((unsigned long)lock) + : "$8", "$9" + ); + return (oldval == 0 ? 1/*success*/ : 0/*failure*/); +} + +static __inline__ uint32_t xlr_mfcr(uint32_t reg) +{ + uint32_t val; + + __asm__ __volatile__ ( + "move $8, %1\n" + ".word 0x71090018\n" + "move %0, $9\n" + : "=r"(val) + : "r"(reg) : "$8", "$9"); + + return val; +} + +static __inline__ void xlr_mtcr(uint32_t reg, uint32_t val) +{ + __asm__ __volatile__ ( + "move $8, %1\n" + "move $9, %0\n" + ".word 0x71090019\n" + ::"r"(val), "r"(reg) + : "$8", "$9"); +} +#endif diff --git a/sys/mips/rmi/xls_ehci.c b/sys/mips/rmi/xls_ehci.c new file mode 100644 index 00000000000..7d44eee4662 --- /dev/null +++ b/sys/mips/rmi/xls_ehci.c @@ -0,0 +1,305 @@ +/*- + * Copyright (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Lennart Augustsson (augustss@carlstedt.se) at + * Carlstedt Research & Technology. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/sys/dev/usb/ehci_pci.c,v 1.18.2.4 2008/04/23 18:54:51 jhb Exp $"); + +/* + * USB Enhanced Host Controller Driver, a.k.a. USB 2.0 controller. + * + * The EHCI 1.0 spec can be found at + * http://developer.intel.com/technology/usb/download/ehci-r10.pdf + * and the USB 2.0 spec at + * http://www.usb.org/developers/docs/usb_20.zip + */ + +/* The low level controller code for EHCI has been split into + * PCI probes and EHCI specific code. This was done to facilitate the + * sharing of code between *BSD's + */ + +#include "opt_bus.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#ifdef USB_DEBUG +#define EHCI_DEBUG USB_DEBUG +#define DPRINTF(x) do { if (ehcidebug) logprintf x; } while (0) +extern int ehcidebug; +#else +#define DPRINTF(x) +#endif + +static int ehci_xls_attach(device_t self); +static int ehci_xls_detach(device_t self); +static int ehci_xls_shutdown(device_t self); +static int ehci_xls_suspend(device_t self); +static int ehci_xls_resume(device_t self); +static void ehci_xls_givecontroller(device_t self); +static void ehci_xls_takecontroller(device_t self); + +static int +ehci_xls_suspend(device_t self) +{ + ehci_softc_t *sc = device_get_softc(self); + int err; + + err = bus_generic_suspend(self); + if (err) + return (err); + ehci_power(PWR_SUSPEND, sc); + + return 0; +} + +static int +ehci_xls_resume(device_t self) +{ + ehci_softc_t *sc = device_get_softc(self); + + ehci_xls_takecontroller(self); + ehci_power(PWR_RESUME, sc); + bus_generic_resume(self); + + return 0; +} + +static int +ehci_xls_shutdown(device_t self) +{ + ehci_softc_t *sc = device_get_softc(self); + int err; + + err = bus_generic_shutdown(self); + if (err) + return (err); + ehci_shutdown(sc); + ehci_xls_givecontroller(self); + + return 0; +} + + +static const char *xlr_usb_dev_desc = "RMI XLR USB 2.0 controller"; +static const char *xlr_vendor_desc = "RMI Corp"; +static int +ehci_xls_probe(device_t self) +{ + + /* TODO see if usb is enabled on the board */ + device_set_desc(self, xlr_usb_dev_desc); + return BUS_PROBE_DEFAULT; +} + +static int +ehci_xls_attach(device_t self) +{ + ehci_softc_t *sc = device_get_softc(self); + device_t parent; + device_t *neighbors; + int err; + int rid; + int count; + int res; + + + sc->sc_bus.usbrev = USBREV_2_0; + + rid = 0; + sc->io_res = bus_alloc_resource(self, SYS_RES_MEMORY, &rid, + 0ul, ~0ul, 0x400, RF_ACTIVE); + if (!sc->io_res) { + device_printf(self, "Could not map memory\n"); + return ENXIO; + } + sc->iot = rman_get_bustag(sc->io_res); + sc->ioh = rman_get_bushandle(sc->io_res); + + rid = 0; + sc->irq_res = bus_alloc_resource(self, SYS_RES_IRQ, &rid, + 39, 39, 1, RF_SHAREABLE | RF_ACTIVE); + if (sc->irq_res == NULL) { + device_printf(self, "Could not allocate irq\n"); + ehci_xls_detach(self); + return ENXIO; + } + sc->sc_bus.bdev = device_add_child(self, "usb", -1); + if (!sc->sc_bus.bdev) { + device_printf(self, "Could not add USB device\n"); + ehci_xls_detach(self); + return ENOMEM; + } + device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus); + + /* ehci_pci_match will never return NULL if ehci_pci_probe succeeded */ + device_set_desc(sc->sc_bus.bdev, xlr_usb_dev_desc); + sprintf(sc->sc_vendor, xlr_vendor_desc); + + err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO, + (driver_intr_t *) ehci_intr, sc, &sc->ih); + if (err) { + device_printf(self, "Could not setup irq, %d\n", err); + sc->ih = NULL; + ehci_xls_detach(self); + return ENXIO; + } + + /* + * Find companion controllers. According to the spec they always + * have lower function numbers so they should be enumerated already. + */ + parent = device_get_parent(self); + res = device_get_children(parent, &neighbors, &count); + if (res != 0) { + device_printf(self, "Error finding companion busses\n"); + ehci_xls_detach(self); + return ENXIO; + } + + sc->sc_ncomp = 0; + + ehci_xls_takecontroller(self); + err = ehci_init(sc); + if (!err) { + sc->sc_flags |= EHCI_SCFLG_DONEINIT; + err = device_probe_and_attach(sc->sc_bus.bdev); + } + + if (err) { + device_printf(self, "USB init failed err=%d\n", err); + ehci_xls_detach(self); + return EIO; + } + return 0; +} + +static int +ehci_xls_detach(device_t self) +{ + ehci_softc_t *sc = device_get_softc(self); + + if (sc->sc_flags & EHCI_SCFLG_DONEINIT) { + ehci_detach(sc, 0); + sc->sc_flags &= ~EHCI_SCFLG_DONEINIT; + } + + /* + * disable interrupts that might have been switched on in ehci_init + */ + if (sc->iot && sc->ioh) + bus_space_write_4(sc->iot, sc->ioh, EHCI_USBINTR, 0); + + if (sc->irq_res && sc->ih) { + int err = bus_teardown_intr(self, sc->irq_res, sc->ih); + + if (err) + /* XXX or should we panic? */ + device_printf(self, "Could not tear down irq, %d\n", + err); + sc->ih = NULL; + } + if (sc->sc_bus.bdev) { + device_delete_child(self, sc->sc_bus.bdev); + sc->sc_bus.bdev = NULL; + } + if (sc->irq_res) { + bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res); + sc->irq_res = NULL; + } + if (sc->io_res) { + bus_release_resource(self, SYS_RES_MEMORY, PCI_CBMEM, sc->io_res); + sc->io_res = NULL; + sc->iot = 0; + sc->ioh = 0; + } + return 0; +} + +static void +ehci_xls_takecontroller(device_t self) +{ + //device_printf(self, "In func %s\n", __func__); +} + +static void +ehci_xls_givecontroller(device_t self) +{ + //device_printf(self, "In func %s\n", __func__); +} + +static device_method_t ehci_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, ehci_xls_probe), + DEVMETHOD(device_attach, ehci_xls_attach), + DEVMETHOD(device_detach, ehci_xls_detach), + DEVMETHOD(device_suspend, ehci_xls_suspend), + DEVMETHOD(device_resume, ehci_xls_resume), + DEVMETHOD(device_shutdown, ehci_xls_shutdown), + + /* Bus interface */ + DEVMETHOD(bus_print_child, bus_generic_print_child), + + {0, 0} +}; + +static driver_t ehci_driver = { + "ehci", + ehci_methods, + sizeof(ehci_softc_t), +}; + +static devclass_t ehci_devclass; + +DRIVER_MODULE(ehci, iodi, ehci_driver, ehci_devclass, 0, 0); +/* DRIVER_MODULE(ehci, cardbus, ehci_driver, ehci_devclass, 0, 0); */ From 7dba4abc79ff14f331946c32002def622a6f2e70 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 16 Oct 2009 22:52:18 +0000 Subject: [PATCH 263/380] - Get rid of label_t. It came from NetBSD and was used only in one place --- sys/mips/include/_types.h | 4 ---- sys/mips/include/pcb.h | 2 +- sys/mips/mips/gdb_machdep.c | 24 ++++++++++++------------ sys/mips/mips/vm_machdep.c | 32 ++++++++++++++++---------------- 4 files changed, 29 insertions(+), 33 deletions(-) diff --git a/sys/mips/include/_types.h b/sys/mips/include/_types.h index 6ee30e3737f..1fd760f9cb5 100644 --- a/sys/mips/include/_types.h +++ b/sys/mips/include/_types.h @@ -165,8 +165,4 @@ typedef char * __va_list; typedef __va_list __gnuc_va_list; /* compatibility w/GNU headers*/ #endif -typedef struct label_t { - __register_t val[13]; -} label_t; - #endif /* !_MACHINE__TYPES_H_ */ diff --git a/sys/mips/include/pcb.h b/sys/mips/include/pcb.h index 16d274dbf41..208e52f21d4 100644 --- a/sys/mips/include/pcb.h +++ b/sys/mips/include/pcb.h @@ -50,7 +50,7 @@ struct pcb { struct trapframe pcb_regs; /* saved CPU and registers */ - label_t pcb_context; /* kernel context for resume */ + __register_t pcb_context[13]; /* kernel context for resume */ int pcb_onfault; /* for copyin/copyout faults */ }; diff --git a/sys/mips/mips/gdb_machdep.c b/sys/mips/mips/gdb_machdep.c index ae77e6bc606..0f5b5ed2a20 100644 --- a/sys/mips/mips/gdb_machdep.c +++ b/sys/mips/mips/gdb_machdep.c @@ -126,17 +126,17 @@ gdb_cpu_getreg(int regnum, size_t *regsz) } } switch (regnum) { - case 16: return (&kdb_thrctx->pcb_context.val[0]); - case 17: return (&kdb_thrctx->pcb_context.val[1]); - case 18: return (&kdb_thrctx->pcb_context.val[2]); - case 19: return (&kdb_thrctx->pcb_context.val[3]); - case 20: return (&kdb_thrctx->pcb_context.val[4]); - case 21: return (&kdb_thrctx->pcb_context.val[5]); - case 22: return (&kdb_thrctx->pcb_context.val[6]); - case 23: return (&kdb_thrctx->pcb_context.val[7]); - case 29: return (&kdb_thrctx->pcb_context.val[8]); - case 30: return (&kdb_thrctx->pcb_context.val[9]); - case 31: return (&kdb_thrctx->pcb_context.val[10]); + case 16: return (&kdb_thrctx->pcb_context[0]); + case 17: return (&kdb_thrctx->pcb_context[1]); + case 18: return (&kdb_thrctx->pcb_context[2]); + case 19: return (&kdb_thrctx->pcb_context[3]); + case 20: return (&kdb_thrctx->pcb_context[4]); + case 21: return (&kdb_thrctx->pcb_context[5]); + case 22: return (&kdb_thrctx->pcb_context[6]); + case 23: return (&kdb_thrctx->pcb_context[7]); + case 29: return (&kdb_thrctx->pcb_context[8]); + case 30: return (&kdb_thrctx->pcb_context[9]); + case 31: return (&kdb_thrctx->pcb_context[10]); } return (NULL); } @@ -146,7 +146,7 @@ gdb_cpu_setreg(int regnum, void *val) { switch (regnum) { case GDB_REG_PC: - kdb_thrctx->pcb_context.val[10] = *(register_t *)val; + kdb_thrctx->pcb_context[10] = *(register_t *)val; if (kdb_thread == PCPU_GET(curthread)) kdb_frame->pc = *(register_t *)val; } diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c index 7e815e26b93..0b51fa1b62d 100644 --- a/sys/mips/mips/vm_machdep.c +++ b/sys/mips/mips/vm_machdep.c @@ -142,14 +142,14 @@ cpu_fork(register struct thread *td1,register struct proc *p2, if (td1 == PCPU_GET(fpcurthread)) MipsSaveCurFPState(td1); - pcb2->pcb_context.val[PCB_REG_RA] = (register_t)fork_trampoline; + pcb2->pcb_context[PCB_REG_RA] = (register_t)fork_trampoline; /* Make sp 64-bit aligned */ - pcb2->pcb_context.val[PCB_REG_SP] = (register_t)(((vm_offset_t)td2->td_pcb & + pcb2->pcb_context[PCB_REG_SP] = (register_t)(((vm_offset_t)td2->td_pcb & ~(sizeof(__int64_t) - 1)) - STAND_FRAME_SIZE); - pcb2->pcb_context.val[PCB_REG_S0] = (register_t)fork_return; - pcb2->pcb_context.val[PCB_REG_S1] = (register_t)td2; - pcb2->pcb_context.val[PCB_REG_S2] = (register_t)td2->td_frame; - pcb2->pcb_context.val[PCB_REG_SR] = SR_INT_MASK & mips_rd_status(); + pcb2->pcb_context[PCB_REG_S0] = (register_t)fork_return; + pcb2->pcb_context[PCB_REG_S1] = (register_t)td2; + pcb2->pcb_context[PCB_REG_S2] = (register_t)td2->td_frame; + pcb2->pcb_context[PCB_REG_SR] = SR_INT_MASK & mips_rd_status(); /* * FREEBSD_DEVELOPERS_FIXME: * Setup any other CPU-Specific registers (Not MIPS Standard) @@ -161,7 +161,7 @@ cpu_fork(register struct thread *td1,register struct proc *p2, td2->td_md.md_saved_intr = MIPS_SR_INT_IE; td2->td_md.md_spinlock_count = 1; #ifdef TARGET_OCTEON - pcb2->pcb_context.val[PCB_REG_SR] |= MIPS_SR_COP_2_BIT | MIPS32_SR_PX | MIPS_SR_UX | MIPS_SR_KX | MIPS_SR_SX; + pcb2->pcb_context[PCB_REG_SR] |= MIPS_SR_COP_2_BIT | MIPS32_SR_PX | MIPS_SR_UX | MIPS_SR_KX | MIPS_SR_SX; #endif } @@ -179,8 +179,8 @@ cpu_set_fork_handler(struct thread *td, void (*func) __P((void *)), void *arg) * Note that the trap frame follows the args, so the function * is really called like this: func(arg, frame); */ - td->td_pcb->pcb_context.val[PCB_REG_S0] = (register_t) func; - td->td_pcb->pcb_context.val[PCB_REG_S1] = (register_t) arg; + td->td_pcb->pcb_context[PCB_REG_S0] = (register_t) func; + td->td_pcb->pcb_context[PCB_REG_S1] = (register_t) arg; } void @@ -293,18 +293,18 @@ cpu_set_upcall(struct thread *td, struct thread *td0) * Set registers for trampoline to user mode. */ - pcb2->pcb_context.val[PCB_REG_RA] = (register_t)fork_trampoline; + pcb2->pcb_context[PCB_REG_RA] = (register_t)fork_trampoline; /* Make sp 64-bit aligned */ - pcb2->pcb_context.val[PCB_REG_SP] = (register_t)(((vm_offset_t)td->td_pcb & + pcb2->pcb_context[PCB_REG_SP] = (register_t)(((vm_offset_t)td->td_pcb & ~(sizeof(__int64_t) - 1)) - STAND_FRAME_SIZE); - pcb2->pcb_context.val[PCB_REG_S0] = (register_t)fork_return; - pcb2->pcb_context.val[PCB_REG_S1] = (register_t)td; - pcb2->pcb_context.val[PCB_REG_S2] = (register_t)td->td_frame; + pcb2->pcb_context[PCB_REG_S0] = (register_t)fork_return; + pcb2->pcb_context[PCB_REG_S1] = (register_t)td; + pcb2->pcb_context[PCB_REG_S2] = (register_t)td->td_frame; /* Dont set IE bit in SR. sched lock release will take care of it */ - pcb2->pcb_context.val[PCB_REG_SR] = SR_INT_MASK & mips_rd_status(); + pcb2->pcb_context[PCB_REG_SR] = SR_INT_MASK & mips_rd_status(); #ifdef TARGET_OCTEON - pcb2->pcb_context.val[PCB_REG_SR] |= MIPS_SR_COP_2_BIT | MIPS_SR_COP_0_BIT | + pcb2->pcb_context[PCB_REG_SR] |= MIPS_SR_COP_2_BIT | MIPS_SR_COP_0_BIT | MIPS32_SR_PX | MIPS_SR_UX | MIPS_SR_KX | MIPS_SR_SX; #endif From 4e6df32763886d96437c69eda4d8781f5e5418b9 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sat, 17 Oct 2009 00:22:07 +0000 Subject: [PATCH 264/380] - Use PC/RA/SP values as arguments for stacktrace_subr instead of trapframe. Context info could be obtained from other sources (see below) no only from td_pcb field - Do not show a0..a3 values unless they're obtained from the stack. These are only confirmed values. - Fix bt command in DDB. Previous implementation used thread's trapframe structure as a source info for trace unwinding, but this structure is filled only when exception occurs. Valid register values for sleeping processes are in pcb_context array. For curthread use pc/sp/ra for current frame --- sys/mips/include/db_machdep.h | 2 +- sys/mips/mips/db_trace.c | 112 +++++++++++++++++++++------------- sys/mips/mips/trap.c | 2 +- 3 files changed, 73 insertions(+), 43 deletions(-) diff --git a/sys/mips/include/db_machdep.h b/sys/mips/include/db_machdep.h index 3bb8a7e06d6..26dafe4501e 100644 --- a/sys/mips/include/db_machdep.h +++ b/sys/mips/include/db_machdep.h @@ -94,7 +94,7 @@ db_addr_t next_instr_address(db_addr_t, boolean_t); int db_inst_type(int); void db_dump_tlb(int, int); db_addr_t branch_taken(int inst, db_addr_t pc); -void stacktrace_subr(db_regs_t *, int (*)(const char *, ...)); +void stacktrace_subr(register_t pc, register_t sp, register_t ra, int (*)(const char *, ...)); int kdbpeek(int *); #endif /* !_MIPS_DB_MACHDEP_H_ */ diff --git a/sys/mips/mips/db_trace.c b/sys/mips/mips/db_trace.c index ebc02a60df5..d18d6aadb49 100644 --- a/sys/mips/mips/db_trace.c +++ b/sys/mips/mips/db_trace.c @@ -105,27 +105,31 @@ fn_name(uintptr_t addr) } void -stacktrace_subr(struct trapframe *regs, int (*printfn) (const char *,...)) +stacktrace_subr(register_t pc, register_t sp, register_t ra, + int (*printfn) (const char *,...)) { InstFmt i; - uintptr_t a0, a1, a2, a3, pc, sp, fp, ra, va, subr; + /* + * Arrays for a0..a3 registers and flags if content + * of these registers is valid, e.g. obtained from the stack + */ + int valid_args[4]; + uintptr_t args[4]; + uintptr_t va, subr; unsigned instr, mask; unsigned int frames = 0; - int more, stksize; - - /* get initial values from the exception frame */ - sp = regs->sp; - pc = regs->pc; - fp = regs->s8; - ra = regs->ra; /* May be a 'leaf' function */ - a0 = regs->a0; - a1 = regs->a1; - a2 = regs->a2; - a3 = regs->a3; + int more, stksize, j; /* Jump here when done with a frame, to start a new one */ loop: + /* + * Invalidate arguments values + */ + valid_args[0] = 0; + valid_args[1] = 0; + valid_args[2] = 0; + valid_args[3] = 0; /* Jump here after a nonstandard (interrupt handler) frame */ stksize = 0; subr = 0; @@ -265,23 +269,23 @@ loop: mask |= (1 << i.IType.rt); switch (i.IType.rt) { case 4:/* a0 */ - a0 = kdbpeek((int *)(sp + (short)i.IType.imm)); + args[0] = kdbpeek((int *)(sp + (short)i.IType.imm)); + valid_args[0] = 1; break; case 5:/* a1 */ - a1 = kdbpeek((int *)(sp + (short)i.IType.imm)); + args[1] = kdbpeek((int *)(sp + (short)i.IType.imm)); + valid_args[1] = 1; break; case 6:/* a2 */ - a2 = kdbpeek((int *)(sp + (short)i.IType.imm)); + args[2] = kdbpeek((int *)(sp + (short)i.IType.imm)); + valid_args[2] = 1; break; case 7:/* a3 */ - a3 = kdbpeek((int *)(sp + (short)i.IType.imm)); - break; - - case 30: /* fp */ - fp = kdbpeek((int *)(sp + (short)i.IType.imm)); + args[3] = kdbpeek((int *)(sp + (short)i.IType.imm)); + valid_args[3] = 1; break; case 31: /* ra */ @@ -299,23 +303,23 @@ loop: mask |= (1 << i.IType.rt); switch (i.IType.rt) { case 4:/* a0 */ - a0 = kdbpeekD((int *)(sp + (short)i.IType.imm)); + args[0] = kdbpeekD((int *)(sp + (short)i.IType.imm)); + valid_args[0] = 1; break; case 5:/* a1 */ - a1 = kdbpeekD((int *)(sp + (short)i.IType.imm)); + args[1] = kdbpeekD((int *)(sp + (short)i.IType.imm)); + valid_args[1] = 1; break; case 6:/* a2 */ - a2 = kdbpeekD((int *)(sp + (short)i.IType.imm)); + args[2] = kdbpeekD((int *)(sp + (short)i.IType.imm)); + valid_args[2] = 1; break; case 7:/* a3 */ - a3 = kdbpeekD((int *)(sp + (short)i.IType.imm)); - break; - - case 30: /* fp */ - fp = kdbpeekD((int *)(sp + (short)i.IType.imm)); + args[3] = kdbpeekD((int *)(sp + (short)i.IType.imm)); + valid_args[3] = 1; break; case 31: /* ra */ @@ -333,8 +337,17 @@ loop: } done: - (*printfn) ("%s+%x (%x,%x,%x,%x) ra %x sz %d\n", - fn_name(subr), pc - subr, a0, a1, a2, a3, ra, stksize); + (*printfn) ("%s+%x (", fn_name(subr), pc - subr); + for (j = 0; j < 4; j ++) { + if (j > 0) + (*printfn)(","); + if (valid_args[j]) + (*printfn)("%x", args[j]); + else + (*printfn)("?"); + } + + (*printfn) (") ra %x sz %d\n", ra, stksize); if (ra) { if (pc == ra && stksize == 0) @@ -376,14 +389,6 @@ db_md_list_watchpoints() { } -static int -db_backtrace(struct thread *td, db_addr_t frame, int count) -{ - stacktrace_subr((struct trapframe *)frame, - (int (*) (const char *, ...))db_printf); - return (0); -} - void db_trace_self(void) { @@ -394,10 +399,35 @@ db_trace_self(void) int db_trace_thread(struct thread *thr, int count) { + register_t pc, ra, sp; struct pcb *ctx; - ctx = kdb_thr_ctx(thr); - return (db_backtrace(thr, (db_addr_t) &ctx->pcb_regs, count)); + if (thr == curthread) { + sp = (register_t)__builtin_frame_address(0); + ra = (register_t)__builtin_return_address(0); + + __asm __volatile( + "jal 99f\n" + "nop\n" + "99:\n" + "move %0, $31\n" /* get ra */ + "move $31, %1\n" /* restore ra */ + : "=r" (pc) + : "r" (ra)); + + } + + else { + ctx = thr->td_pcb; + sp = (register_t)ctx->pcb_context[PREG_SP]; + pc = (register_t)ctx->pcb_context[PREG_PC]; + ra = (register_t)ctx->pcb_context[PREG_RA]; + } + + stacktrace_subr(pc, sp, ra, + (int (*) (const char *, ...))db_printf); + + return (0); } void diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c index a20f54cf451..3ccef9020be 100644 --- a/sys/mips/mips/trap.c +++ b/sys/mips/mips/trap.c @@ -1203,7 +1203,7 @@ MipsEmulateBranch(struct trapframe *framePtr, uintptr_t instPC, int fpcCSR, void stacktrace(struct trapframe *regs) { - stacktrace_subr(regs, printf); + stacktrace_subr(regs->pc, regs->sp, regs->ra, printf); } #endif From f107b0cc55e7b66733fb039f63dad692b84d6e74 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 18 Oct 2009 14:55:55 +0000 Subject: [PATCH 265/380] Use correct signature for MipsEmulateBranch. The other one doesn't work for 64-bit compiles. --- sys/mips/mips/trap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c index 3ccef9020be..f64afc9f448 100644 --- a/sys/mips/mips/trap.c +++ b/sys/mips/mips/trap.c @@ -1057,7 +1057,7 @@ trapDump(char *msg) /* * Return the resulting PC as if the branch was executed. */ -u_int +uintptr_t MipsEmulateBranch(struct trapframe *framePtr, uintptr_t instPC, int fpcCSR, uintptr_t instptr) { From d14d3e08663a7e85315571efc5cfcf166419a092 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 18 Oct 2009 14:56:33 +0000 Subject: [PATCH 266/380] _ALIGN has to return u_long, since pointers don't fit into u_int in 64-bit mips. --- sys/mips/include/_align.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/mips/include/_align.h b/sys/mips/include/_align.h index 4484a28aa0b..f945164d260 100644 --- a/sys/mips/include/_align.h +++ b/sys/mips/include/_align.h @@ -44,10 +44,10 @@ /* * Round p (pointer or byte index) up to a correctly-aligned value for all - * data types (int, long, ...). The result is u_int and must be cast to + * data types (int, long, ...). The result is u_long and must be cast to * any desired pointer type. */ #define _ALIGNBYTES 7 -#define _ALIGN(p) (((u_int)(p) + _ALIGNBYTES) &~ _ALIGNBYTES) +#define _ALIGN(p) (((u_long)(p) + _ALIGNBYTES) &~ _ALIGNBYTES) #endif /* !_MIPS_INCLUDE__ALIGN_H_ */ From f43da83b9dc6b060f190a040bbcefa89d236f501 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 18 Oct 2009 14:57:04 +0000 Subject: [PATCH 267/380] Undo spamage of last MFC. --- sys/mips/include/param.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/mips/include/param.h b/sys/mips/include/param.h index b8186494046..8edd48ece16 100644 --- a/sys/mips/include/param.h +++ b/sys/mips/include/param.h @@ -93,7 +93,7 @@ * This does not reflect the optimal alignment, just the possibility * (within reasonable limits). */ -#define ALIGNED_POINTER(p, t) ((((unsigned)(p)) & (sizeof (t) - 1)) == 0) +#define ALIGNED_POINTER(p, t) ((((unsigned long)(p)) & (sizeof (t) - 1)) == 0) /* * CACHE_LINE_SIZE is the compile-time maximum cache line size for an @@ -154,10 +154,10 @@ /* * Conversion macros */ -#define mips_round_page(x) ((((unsigned)(x)) + NBPG - 1) & ~(NBPG-1)) -#define mips_trunc_page(x) ((unsigned)(x) & ~(NBPG-1)) -#define mips_btop(x) ((unsigned)(x) >> PGSHIFT) -#define mips_ptob(x) ((unsigned)(x) << PGSHIFT) +#define mips_round_page(x) ((((unsigned long)(x)) + NBPG - 1) & ~(NBPG-1)) +#define mips_trunc_page(x) ((unsigned long)(x) & ~(NBPG-1)) +#define mips_btop(x) ((unsigned long)(x) >> PGSHIFT) +#define mips_ptob(x) ((unsigned long)(x) << PGSHIFT) #define round_page mips_round_page #define trunc_page mips_trunc_page #define atop(x) ((unsigned long)(x) >> PAGE_SHIFT) From f2c23ba7c4cce456e9fd24de64bd01aba246be94 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 18 Oct 2009 15:21:48 +0000 Subject: [PATCH 268/380] Get the PC from the trap frame, since it isn't saved as part of the pcb regs. --- sys/mips/mips/db_trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/mips/db_trace.c b/sys/mips/mips/db_trace.c index d18d6aadb49..4df810f0c44 100644 --- a/sys/mips/mips/db_trace.c +++ b/sys/mips/mips/db_trace.c @@ -420,7 +420,7 @@ db_trace_thread(struct thread *thr, int count) else { ctx = thr->td_pcb; sp = (register_t)ctx->pcb_context[PREG_SP]; - pc = (register_t)ctx->pcb_context[PREG_PC]; + pc = (register_t)ctx->pcb_regs.pc; ra = (register_t)ctx->pcb_context[PREG_RA]; } From d428afbbbb6b9aeff6cf763041c6e38da128a66d Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Tue, 20 Oct 2009 04:31:20 +0000 Subject: [PATCH 269/380] The default KERNLOADADDR does not work on MALTA hardware. On my platform the "First free SDRAM address" reported by YAMON is 0x800b6e61. So use a conservative KERNLOADADDR of 0x80100000. Approved by: imp (mentor) --- sys/mips/conf/MALTA | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/mips/conf/MALTA b/sys/mips/conf/MALTA index ac6bd6d59f2..1d65cfc3a08 100644 --- a/sys/mips/conf/MALTA +++ b/sys/mips/conf/MALTA @@ -21,6 +21,7 @@ ident MALTA #makeoptions ARCH_FLAGS=-march=mips32 makeoptions MIPS_LITTLE_ENDIAN=defined +makeoptions KERNLOADADDR=0x80100000 options YAMON From 344214e344ecf6d01b5da8a55ee0c67a86124178 Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Tue, 20 Oct 2009 04:36:08 +0000 Subject: [PATCH 270/380] Fix a bug where we would think that the L1 instruction and data cache are present even though the line size field in the CP0 Config1 register is 0. Approved by: imp (mentor) --- sys/mips/mips/cpu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/mips/mips/cpu.c b/sys/mips/mips/cpu.c index 7bd27184d6c..177ec4854ba 100644 --- a/sys/mips/mips/cpu.c +++ b/sys/mips/mips/cpu.c @@ -94,9 +94,9 @@ mips_get_identity(struct mips_cpuinfo *cpuinfo) ((cfg1 & MIPS_CONFIG1_TLBSZ_MASK) >> MIPS_CONFIG1_TLBSZ_SHIFT) + 1; /* L1 instruction cache. */ - tmp = 1 << (((cfg1 & MIPS_CONFIG1_IL_MASK) >> MIPS_CONFIG1_IL_SHIFT) + 1); + tmp = (cfg1 & MIPS_CONFIG1_IL_MASK) >> MIPS_CONFIG1_IL_SHIFT; if (tmp != 0) { - cpuinfo->l1.ic_linesize = tmp; + cpuinfo->l1.ic_linesize = 1 << (tmp + 1); cpuinfo->l1.ic_nways = (((cfg1 & MIPS_CONFIG1_IA_MASK) >> MIPS_CONFIG1_IA_SHIFT)) + 1; cpuinfo->l1.ic_nsets = 1 << (((cfg1 & MIPS_CONFIG1_IS_MASK) >> MIPS_CONFIG1_IS_SHIFT) + 6); @@ -105,9 +105,9 @@ mips_get_identity(struct mips_cpuinfo *cpuinfo) } /* L1 data cache. */ - tmp = 1 << (((cfg1 & MIPS_CONFIG1_DL_MASK) >> MIPS_CONFIG1_DL_SHIFT) + 1); + tmp = (cfg1 & MIPS_CONFIG1_DL_MASK) >> MIPS_CONFIG1_DL_SHIFT; if (tmp != 0) { - cpuinfo->l1.dc_linesize = tmp; + cpuinfo->l1.dc_linesize = 1 << (tmp + 1); cpuinfo->l1.dc_nways = (((cfg1 & MIPS_CONFIG1_DA_MASK) >> MIPS_CONFIG1_DA_SHIFT)) + 1; cpuinfo->l1.dc_nsets = From 55173ef287fa0d7dc4332dad319aff6413d55a5e Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 20 Oct 2009 23:13:08 +0000 Subject: [PATCH 271/380] - Commit missing part of "bt" fix: store PC register in pcb_context struct in cpu_switch and use it in stack_trace function later. pcb_regs contains state of the process stored by exception handler and therefor is not valid for sleeping processes. --- sys/mips/include/pcb.h | 3 ++- sys/mips/include/regnum.h | 3 +-- sys/mips/mips/db_trace.c | 2 +- sys/mips/mips/swtch.S | 4 ++++ 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/sys/mips/include/pcb.h b/sys/mips/include/pcb.h index 208e52f21d4..a0828632264 100644 --- a/sys/mips/include/pcb.h +++ b/sys/mips/include/pcb.h @@ -50,7 +50,7 @@ struct pcb { struct trapframe pcb_regs; /* saved CPU and registers */ - __register_t pcb_context[13]; /* kernel context for resume */ + __register_t pcb_context[14]; /* kernel context for resume */ int pcb_onfault; /* for copyin/copyout faults */ }; @@ -70,6 +70,7 @@ struct pcb #define PCB_REG_RA 10 #define PCB_REG_SR 11 #define PCB_REG_GP 12 +#define PCB_REG_PC 13 #ifdef _KERNEL diff --git a/sys/mips/include/regnum.h b/sys/mips/include/regnum.h index 6293e790730..baa60bd8b86 100644 --- a/sys/mips/include/regnum.h +++ b/sys/mips/include/regnum.h @@ -63,8 +63,7 @@ #define PREG_RA 10 #define PREG_SR 11 #define PREG_GP 12 - - +#define PREG_PC 13 /* * Location of the saved registers relative to ZERO. diff --git a/sys/mips/mips/db_trace.c b/sys/mips/mips/db_trace.c index 4df810f0c44..d18d6aadb49 100644 --- a/sys/mips/mips/db_trace.c +++ b/sys/mips/mips/db_trace.c @@ -420,7 +420,7 @@ db_trace_thread(struct thread *thr, int count) else { ctx = thr->td_pcb; sp = (register_t)ctx->pcb_context[PREG_SP]; - pc = (register_t)ctx->pcb_regs.pc; + pc = (register_t)ctx->pcb_context[PREG_PC]; ra = (register_t)ctx->pcb_context[PREG_RA]; } diff --git a/sys/mips/mips/swtch.S b/sys/mips/mips/swtch.S index 2d93ef29e7c..6ccf0a1ae4f 100644 --- a/sys/mips/mips/swtch.S +++ b/sys/mips/mips/swtch.S @@ -313,6 +313,10 @@ NON_LEAF(cpu_switch, STAND_FRAME_SIZE, ra) SAVE_U_PCB_CONTEXT(ra, PREG_RA, a0) # save return address SAVE_U_PCB_CONTEXT(t0, PREG_SR, a0) # save status register SAVE_U_PCB_CONTEXT(gp, PREG_GP, a0) + jal getpc + nop +getpc: + SAVE_U_PCB_CONTEXT(ra, PREG_PC, a0) # save return address /* * FREEBSD_DEVELOPERS_FIXME: * In case there are CPU-specific registers that need From 561f0b80b14ed48ec9edc549ffab2d812abcd166 Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Wed, 21 Oct 2009 00:56:13 +0000 Subject: [PATCH 272/380] Update options.mips to support config options required to build the SWARM kernel. The SWARM kernel does not build yet but at least it gets past the kernel config stage. Approved by: imp (mentor) --- sys/conf/options.mips | 14 ++++++++++++++ sys/mips/conf/SWARM | 7 +++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/sys/conf/options.mips b/sys/conf/options.mips index cc6e33340ea..d533bfffd02 100644 --- a/sys/conf/options.mips +++ b/sys/conf/options.mips @@ -33,6 +33,7 @@ CPU_MIPS32 opt_global.h CPU_MIPS64 opt_global.h CPU_SENTRY5 opt_global.h CPU_HAVEFPU opt_global.h +CPU_SB1 opt_global.h ISA_MIPS1 opt_cputype.h ISA_MIPS3 opt_cputype.h @@ -56,3 +57,16 @@ TARGET_EMULATOR opt_ddb.h TICK_USE_YAMON_FREQ opt_global.h TICK_USE_MALTA_RTC opt_global.h + +# +# The MIPS architecture does not have separate memory and i/o address space +# like x86. However some MIPS processors provide a memory-mapped window that +# maps onto the PCI I/O space. +# +PCI_IOSPACE_SIZE opt_global.h +PCI_IOSPACE_ADDR opt_global.h + +# +# The highest memory address that can be used by the kernel in units of KB. +# +MAXMEM opt_global.h diff --git a/sys/mips/conf/SWARM b/sys/mips/conf/SWARM index bd395d8fe2f..eb5d588758e 100644 --- a/sys/mips/conf/SWARM +++ b/sys/mips/conf/SWARM @@ -3,7 +3,6 @@ # ident SWARM -options CPU_NOFPU options CPU_SB1 files "../sibyte/files.sibyte" @@ -14,8 +13,9 @@ options PCI_IOSPACE_SIZE=0x02000000 # # 32-bit kernel cannot deal with physical memory beyond 4GB +# XXX pmap assumes that all the memory can be mapped using KSEG0 # -options MAXMEM=4096*1024 +options MAXMEM=512*1024 options CFE options CFE_CONSOLE @@ -54,8 +54,6 @@ options INVARIANTS options INVARIANT_SUPPORT options WITNESS -options MD_ROOT -options MD_ROOT_SIZE=4096 options FFS #Fast filesystem device pci @@ -64,6 +62,7 @@ device bge device loop device ether device md +device random options USB_DEBUG device usb From 1a71736fb1f9a0ce03b754b8be094de597d86b6e Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 21 Oct 2009 20:33:50 +0000 Subject: [PATCH 273/380] - Keep recovering from "MFC went wrong". Add missing ieee80211_* parts, mergeinfo is already in place --- share/man/man9/ieee80211_amrr.9 | 194 +++++++++++++++ share/man/man9/ieee80211_beacon.9 | 115 +++++++++ share/man/man9/ieee80211_bmiss.9 | 91 +++++++ share/man/man9/ieee80211_ddb.9 | 72 ++++++ share/man/man9/ieee80211_regdomain.9 | 143 +++++++++++ share/man/man9/ieee80211_scan.9 | 350 +++++++++++++++++++++++++++ share/man/man9/ieee80211_vap.9 | 154 ++++++++++++ 7 files changed, 1119 insertions(+) create mode 100644 share/man/man9/ieee80211_amrr.9 create mode 100644 share/man/man9/ieee80211_beacon.9 create mode 100644 share/man/man9/ieee80211_bmiss.9 create mode 100644 share/man/man9/ieee80211_ddb.9 create mode 100644 share/man/man9/ieee80211_regdomain.9 create mode 100644 share/man/man9/ieee80211_scan.9 create mode 100644 share/man/man9/ieee80211_vap.9 diff --git a/share/man/man9/ieee80211_amrr.9 b/share/man/man9/ieee80211_amrr.9 new file mode 100644 index 00000000000..8206b2da55d --- /dev/null +++ b/share/man/man9/ieee80211_amrr.9 @@ -0,0 +1,194 @@ +.\" +.\" Copyright (c) 2009 Sam Leffler, Errno Consulting +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd August 4, 2009 +.Dt IEEE8021_AMRR 9 +.Os +.Sh NAME +.Nm ieee80211_amrr +.Nd 802.11 network driver transmit rate control support +.Sh SYNOPSIS +.In net80211/ieee80211_amrr.h +.Ft void +.Fo ieee80211_amrr_init +.Fa "struct ieee80211_amrr *" +.Fa "struct ieee80211vap *" +.Fa "int amin" +.Fa "int amax" +.Fa "int interval" +.Fc +.\" +.Ft void +.Fn ieee80211_amrr_cleanup "struct ieee80211_amrr *" +.\" +.Ft void +.Fn ieee80211_amrr_setinterval "struct ieee80211_amrr *" "int interval" +.\" +.Ft void +.Fo ieee80211_amrr_node_init +.Fa "struct ieee80211_amrr *" +.Fa "struct ieee80211_amrr_node *" +.Fa "struct ieee80211_node *" +.Fc +.\" +.Ft int +.Fo ieee80211_amrr_choose +.Fa "struct ieee80211_node *" +.Fa "struct ieee80211_amrr_node *" +.Fc +.\" +.Ft void +.Fo ieee80211_amrr_tx_complete +.Fa "struct ieee80211_amrr_node *" +.Fa "int ok" +.Fa "int retries" +.Fc +.\" +.Ft void +.Fo ieee80211_amrr_tx_update +.Fa "struct ieee80211_amrr_node *" +.Fa "int txnct" +.Fa "int success" +.Fa "int retrycnt" +.Fc +.Sh DESCRIPTION +.Nm +is an implementation of the AMRR transmit rate control algorithm +for drivers that use the +.Nm net80211 +software layer. +A rate control algorithm is responsible for choosing the transmit +rate for each frame. +To maximize throughput algorithms try to use the highest rate that +is appropriate for the operating conditions. +The rate will vary as conditions change; the distance between two stations +may change, transient noise may be present that affects signal quality, +etc. +.Nm +uses very simple information from a driver to do it's job: +whether a frame was successfully delivered and how many transmit +attempts were made. +While this enables its use with virtually any wireless device it +limits it's effectiveness--do not expect it to function well in +difficult environments and/or respond quickly to changing conditions. +.Pp +.Nm +requires per-vap state and per-node state for each station it is to +select rates for. +The API's are designed for drivers to pre-allocate state in the +driver-private extension areas of each vap and node. +For example the +.Xr ral 4 +driver defines a vap as: +.Bd -literal -offset indent +struct rt2560_vap { + struct ieee80211vap ral_vap; + struct ieee80211_beacon_offsets ral_bo; + struct ieee80211_amrr amrr; + + int (*ral_newstate)(struct ieee80211vap *, + enum ieee80211_state, int); +}; +.Ed +.Pp +The +.Vt amrr +structure member holds the per-vap state for +.Nm +and +.Xr ral 4 +initializes it in the vap create method with: +.Bd -literal -offset indent +ieee80211_amrr_init(&rvp->amrr, vap, + IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, + IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, + 500 /* ms */); +.Ed +.Pp +The node is defined as: +.Bd -literal -offset indent +struct rt2560_node { + struct ieee80211_node ni; + struct ieee80211_amrr_node amrr; +}; +.Ed +.Pp +with initialization done in the driver's +.Vt iv_newassoc +method: +.Bd -literal -offset indent +static void +rt2560_newassoc(struct ieee80211_node *ni, int isnew) +{ + struct ieee80211vap *vap = ni->ni_vap; + + ieee80211_amrr_node_init(&RT2560_VAP(vap)->amrr, + &RT2560_NODE(ni)->amrr, ni); +} +.Ed +.Pp +Once +.Nm +state is setup, transmit rates are requested by calling +.Fn ieee80211_amrr_choose +in the transmit path; e.g.: +.Bd -literal -offset indent +tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; +if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { + rate = tp->mcastrate; +} else if (m0->m_flags & M_EAPOL) { + rate = tp->mgmtrate; +} else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) { + rate = tp->ucastrate; +} else { + (void) ieee80211_amrr_choose(ni, &RT2560_NODE(ni)->amrr); + rate = ni->ni_txrate; +} +.Ed +.Pp +Note a rate is chosen only for unicast data frames when a fixed +transmit rate is not configured; the other cases are handled with +the +.Nm net80211 +transmit parameters. +Note also that +.Fn ieee80211_amrr_choose +writes the chosen rate in +.Vt ni_txrate ; +this eliminates copying the value as it is exported to user applications so +they can display the current transmit rate in status. +.Pp +The remaining work a driver must do is feed status back to +.Nm +when a frame transmit completes using +.Fn ieee80211_amrr_tx_complete . +Drivers that poll a device to retrieve statistics can use +.Fn ieee80211_amrr_tx_update +(instead or in addition). +.Sh SEE ALSO +.Xr ieee80211 9 , +.Xr ieee80211_output 9 diff --git a/share/man/man9/ieee80211_beacon.9 b/share/man/man9/ieee80211_beacon.9 new file mode 100644 index 00000000000..87115fcbd60 --- /dev/null +++ b/share/man/man9/ieee80211_beacon.9 @@ -0,0 +1,115 @@ +.\" +.\" Copyright (c) 2009 Sam Leffler, Errno Consulting +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd August 4, 2009 +.Dt IEEE80211_BEACON 9 +.Os +.Sh NAME +.Nm ieee80211_beacon +.Nd 802.11 beacon support +.Sh SYNOPSIS +.In net80211/ieee80211_var.h +.Pp +.Ft "struct mbuf *" +.Fo ieee80211_beacon_alloc +.Fa "struct ieee80211_node *" +.Fa "struct ieee80211_beacon_offsets *" +.Fc +.\" +.Ft int +.Fo ieee80211_beacon_update +.Fa "struct ieee80211_node *" +.Fa "struct ieee80211_beacon_offsets *" +.Fa "struct mbuf *" +.Fa "int mcast" +.Fc +.\" +.Ft void +.Fn ieee80211_beacon_notify "struct ieee80211vap *" "int what" +.Sh DESCRIPTION +The +.Nm net80211 +software layer provides a support framework for drivers that includes +a template-based mechanism for dynamic update of beacon frames transmit +in hostap, adhoc, and mesh operating modes. +Drivers should use +.Fn ieee80211_beacon_alloc +to create an initial beacon frame. +The +.Vt ieee80211_beacon_offsets +structure holds information about the beacon contents that is used +to optimize updates done with +.Fn ieee80211_beacon_update . +.Pp +Update calls should only be done when something changes that +affects the contents of the beacon frame. +When this happens the +.Dv iv_update_beacon +method is invoked and a driver-supplied routine must do the right thing. +For devices that involve the host to transmit each +beacon frame this work may be as simple as marking a bit in the +.Vt ieee80211_beacon_offsets +structure: +.Bd -literal +static void +ath_beacon_update(struct ieee80211vap *vap, int item) +{ + struct ieee80211_beacon_offsets *bo = &ATH_VAP(vap)->av_boff; + setbit(bo->bo_flags, item); +} +.Ed +.Pp +with the +.Fn ieee80211_beacon_update +call done before the next beacon is to be sent. +.Pp +Devices that off-load beacon generation may instead choose to use +this callback to push updates immediately to the device. +Exactly how that is accomplished is unspecified. +One possibility is to update the beacon frame contents and extract +the appropriate information element, but other scenarios are possible. +.Sh MULTI-VAP BEACON SCHEDULING +Drivers that support multiple vaps that can each beacon need to consider +how to schedule beacon frames. +There are two possibilities at the moment: +.Em burst +all beacons at TBTT or +.Em stagger beacons +over the beacon interval. +Bursting beacon frames may result in aperiodic delivery that can affect +power save operation of associated stations. +Applying some jitter (e.g. by randomly ordering burst frames) may be +sufficient to combat this and typically this is not an issue unless +stations are using aggressive power save techniques +such as U-APSD (sometimes employed by VoIP phones). +Staggering frames requires more interrupts and device support that +may not be available. +Staggering beacon frames is usually superior to bursting frames, up to +about eight vaps, at which point the overhead becomes significant and +the channel becomes noticeably busy anyway. +.Sh SEE ALSO +.Xr ieee80211 9 diff --git a/share/man/man9/ieee80211_bmiss.9 b/share/man/man9/ieee80211_bmiss.9 new file mode 100644 index 00000000000..bd82c3c0b4c --- /dev/null +++ b/share/man/man9/ieee80211_bmiss.9 @@ -0,0 +1,91 @@ +.\" +.\" Copyright (c) 2009 Sam Leffler, Errno Consulting +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd August 4, 2009 +.Dt IEEE80211_BMISS 9 +.Os +.Sh NAME +.Nm ieee80211_bmiss +.Nd 802.11 beacon miss support +.Sh SYNOPSIS +.In net80211/ieee80211_var.h +.Pp +.Ft void +.Fn ieee80211_beacon_miss "struct ieee80211com *" +.Sh DESCRIPTION +The +.Nm net80211 +software layer provides a support framework for drivers that includes +handling beacon miss events in station mode. +Drivers can dispatch beacon miss events that are recognized in hardware or +.Nm net80211 +can detect beacon miss if the driver dispatches received beacon frames +through the normal receive path. +Software beacon miss support is especially useful when multiple vaps +are operating and any hardware beacon miss support is not available +(e.g. operating as an access point together with one or more station +mode vaps). +.Pp +Drivers should dispatch beacon miss events recognized in the driver with +.Fn ieee80211_beacon_miss . +This causes some number of ProbeRequest frames to be sent to the +access point to check if the association is still alive. +If no response is received and roaming mode is set to +.Dv IEEE80211_ROAMING_AUTO +then +.Nm net80211 +will try to re-associate and if that fails +trigger a scan to look for the access point or another suitable AP. +When the +.Nm net80211 +state machine is being operated manually, e.g. by +.Xr wpa_supplicant 8 , +then applications are notified of the state change and are responsible +for handling the work of scanning for a new access point. +The number of beacon miss events (without a ProbeResponse) is user +settable with the +.Dv IEEE80211_IOC_BMISSTHRESHOLD +request. +.Pp +Software beacon miss detection is enabled per-vap by setting the +.Dv IEEE80211_FEXT_SWBMISS +flag. +Typically this is done when a vap is setup +when the +.Dv IEEE80211_CLONE_NOBEACONS +option is supplied to the clone operation. +But drivers may also force this when they know they need help detecting +beacon miss. +When beacon miss is detected in software the event is dispatched without +driver involvement. +Note that software beacon miss handling is not limited to station mode; +it can be used in any operating mode where beacons from a peer station +are received. +.Sh SEE ALSO +.Xr wpa_supplicant 8 , +.Xr ieee80211 9 , +.Xr ieee80211_vap 9 diff --git a/share/man/man9/ieee80211_ddb.9 b/share/man/man9/ieee80211_ddb.9 new file mode 100644 index 00000000000..93bee7e4c28 --- /dev/null +++ b/share/man/man9/ieee80211_ddb.9 @@ -0,0 +1,72 @@ +.\" +.\" Copyright (c) 2009 Sam Leffler, Errno Consulting +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd August 4, 2009 +.Dt IEEE80211_DDB 9 +.Os +.Sh NAME +.Nm ieee80211_ddb +.Nd 802.11 ddb support +.Sh SYNOPSIS +.Bd -ragged +.Cd options DDB +.Ed +.Pp +.Bd -ragged +.Cd show vap [addr] +.Cd show all vaps +.Cd show com [addr] +.Cd show sta [addr] +.Cd show statab [addr] +.Cd show mesh [addr] +.Ed +.Sh DESCRIPTION +The +.Nm net80211 +layer includes +.Xr ddb 4 +support for displaying important data structures. +This is especially important because wireless applications are often +built for embedded environments where cross-machine or post-mortem +debugging facilities like +.Xr kgdb 1 +are infeasible. +.Pp +The most commonly used command is +.Bd -literal -offset indent +show all vaps/a +.Ed +.Pp +which dumps the contents of all +.Vt ieee80211vap , +.Vt ieee80211com , +and +.Vt ieee80211_node +data structures in the system. +.Sh SEE ALSO +.Xr ddb 4 , +.Xr ieee80211 9 diff --git a/share/man/man9/ieee80211_regdomain.9 b/share/man/man9/ieee80211_regdomain.9 new file mode 100644 index 00000000000..527deb51cbd --- /dev/null +++ b/share/man/man9/ieee80211_regdomain.9 @@ -0,0 +1,143 @@ +.\" +.\" Copyright (c) 2009 Sam Leffler, Errno Consulting +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd August 4, 2009 +.Dt IEEE80211_REGDOMAIN 9 +.Os +.Sh NAME +.Nm ieee80211_regdomain +.Nd 802.11 regulatory support +.Sh SYNOPSIS +.In net80211/ieee80211_var.h +.In net80211/ieee80211_regdomain.h +.Pp +.Ft int +.Fo ieee80211_init_channels +.Fa "struct ieee80211com *" +.Fa "const struct ieee80211_regdomain *" +.Fa "const uint8_t bands[]" +.Fc +.\" +.Ft void +.Fo ieee80211_sort_channels +.Fa "struct ieee80211_channel *" +.Fa "int nchans" +.Fc +.\" +.Ft "struct ieee80211_appie *" +.Fn ieee80211_alloc_countryie "struct ieee80211com *" +.Sh DESCRIPTION +The +.Nm net80211 +software layer provides a support framework for drivers that includes +comprehensive regulatory support. +.Nm net80211 +provides mechanisms that enforce +.Em "regulatory policy" +by privileged user applications. +.Pp +Drivers define a device's capabilities and can +intercept and control regulatory changes requested through +.Nm net80211 . +The initial regulatory state, including the channel list, must be +filled in by the driver before calling +.Fn ieee80211_ifattach . +The channel list should reflect the set of channels the device is +.Em calibrated +for use on. +This list may also be requested later through the +.Vt ic_getradiocaps +method in the +.Vt ieee80211com +structure. +The +.Fn ieee80211_init_channels +function is provided as a rudimentary fallback for drivers that do not +(or cannot) fill in a proper channel list. +Default regulatory state is supplied such as the regulatory SKU, +ISO country code, location (e.g. indoor, outdoor), and a set of +frequency bands the device is capable of operating on. +.Nm net80211 +populates the channel table in +.Vt ic_channels +with a default set of channels and capabilities. +Note this mechanism should be used with care as any mismatch between +the channel list created and the device's capabilities can result +in runtime errors (e.g. a request to operate on a channel the device +does not support). +The SKU and country information are used for generating 802.11h protocol +elements and related operation such as for 802.11d; mis-setup by a +driver is not fatal, only potentially confusing. +.Pp +Devices that do not have a fixed/default regulatory state can set +the regulatory SKU to +.Dv SKU_DEBUG +and country code to +.Dv CTRY_DEFAULT +and leave proper setup to user applications. +If default settings are known they can be installed and/or an event +can be dispatched to user space using +.Fn ieee80211_notify_country +so that +.Xr devd 8 +will do the appropriate setup work at system boot (or device insertion). +.Pp +The channel table is sorted to optimize lookups using the +.Fn ieee80211_sort_channels +routine. +This should be done whenever the channel table contents are modified. +.Pp +The +.Fn ieee80211_alloc_countryie +function allocates an information element as specified by 802.11h. +Because this is expensive to generate it is cached in +.Vt ic_countryie +and generated only when regulatory state changes. +Drivers that call +.Fn ieee80211_alloc_countryie +directly should not help with this caching; doing so may confuse the +.Nm net80211 +layer. +.Sh DRIVER REGULATORY CONTROL +Drivers can control regulatory change requests by overriding the +.Vt ic_setregdomain +method that checks change requests. +While drivers can reject any request that does not meet its requirements +it is recommended that one be lenient in what is accepted and, whenever +possible, instead of rejecting a request, alter it to be correct. +For example, if the transmit power cap for a channel is too high the +driver can either reject the request or (better) reduce the cap to be +compliant. +Requests that include unacceptable channels should cause the request +to be rejected as otherwise a mismatch may be created between application +state and the state managed by +.Nm net80211 . +The exact rules by which to operate are still being codified. +.Sh SEE ALSO +.Xr regdomain 5 , +.Xr ifconfig 8 , +.Xr ieee80211 9 diff --git a/share/man/man9/ieee80211_scan.9 b/share/man/man9/ieee80211_scan.9 new file mode 100644 index 00000000000..7ac41bdb903 --- /dev/null +++ b/share/man/man9/ieee80211_scan.9 @@ -0,0 +1,350 @@ +.\" +.\" Copyright (c) 2009 Sam Leffler, Errno Consulting +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd August 4, 2009 +.Dt IEEE80211_SCAN 9 +.Os +.Sh NAME +.Nm ieee80211_scan +.Nd 802.11 scanning support +.Sh SYNOPSIS +.In net80211/ieee80211_var.h +.Pp +.Ft int +.Fo ieee80211_start_scan +.Fa "struct ieee80211vap *" +.Fa "int flags" +.Fa "u_int duration" +.Fa "u_int mindwell" +.Fa "u_int maxdwell" +.Fa "u_int nssid" +.Fa "const struct ieee80211_scan_ssid ssids[]" +.Fc +.\" +.Ft int +.Fo ieee80211_check_scan +.Fa "struct ieee80211vap *" +.Fa "int flags" +.Fa "u_int duration" +.Fa "u_int mindwell" +.Fa "u_int maxdwell" +.Fa "u_int nssid" +.Fa "const struct ieee80211_scan_ssid ssids[]" +.Fc +.\" +.Ft int +.Fn ieee80211_check_scan_current "struct ieee80211vap *" +.\" +.Ft int +.Fn ieee80211_bg_scan "struct ieee80211vap *" "int" +.\" +.Ft int +.Fn ieee80211_cancel_scan "struct ieee80211vap *" +.\" +.Ft int +.Fn ieee80211_cancel_scan_any "struct ieee80211vap *" +.\" +.Ft int +.Fn ieee80211_scan_next "struct ieee80211vap *" +.\" +.Ft int +.Fn ieee80211_scan_done "struct ieee80211vap *" +.\" +.Ft int +.Fn ieee80211_probe_curchan "struct ieee80211vap *" "int" +.\" +.Ft void +.Fo ieee80211_add_scan +.Fa "struct ieee80211vap *" +.Fa "const struct ieee80211_scanparams *" +.Fa "const struct ieee80211_frame *" +.Fa "int subtype" +.Fa "int rssi" +.Fa "int noise" +.Fc +.\" +.Ft void +.Fn ieee80211_scan_timeout "struct ieee80211com *" +.\" +.Ft void +.Fo ieee80211_scan_assoc_fail +.Fa "struct ieee80211vap *" +.Fa "const uint8_t mac[IEEE80211_ADDR_LEN]" +.Fa "int reason" +.Fc +.\" +.Ft void +.Fn ieee80211_scan_flush "struct ieee80211vap *" +.\" +.Ft void +.Fo ieee80211_scan_iterate +.Fa "struct ieee80211vap *" +.Fa "ieee80211_scan_iter_func" +.Fa "void *" +.Fc +.\" +.Ft void +.Fn ieee80211_scan_dump_channels "const struct ieee80211_scan_state *" +.\" +.Ft void +.Fo ieee80211_scanner_register +.Fa "enum ieee80211_opmode" +.Fa "const struct ieee80211_scanner *" +.Fc +.\" +.Ft void +.Fo ieee80211_scanner_unregister +.Fa "enum ieee80211_opmode" +.Fa "const struct ieee80211_scanner *" +.Fc +.\" +.Ft void +.Fn ieee80211_scanner_unregister_all "const struct ieee80211_scanner *" +.\" +.Ft const struct ieee80211_scanner * +.Fn ieee80211_scanner_get "enum ieee80211_opmode" +.Sh DESCRIPTION +The +.Nm net80211 +software layer provides an extensible framework for scanning. +Scanning is the procedure by which a station locates a BSS to join +(in infrastructure and IBSS mode), or a channel to use (when operating +as an AP or an IBSS master). +Scans are either +.Dq active +or +.Dq passive . +An active scan causes one or more ProbeRequest frames to be sent on +visiting each channel. +A passive request causes each channel in the scan set to be visited but +no frames to be transmitted; the station only listens for traffic. +Note that active scanning may still need to listen for traffic before +sending ProbeRequest frames depending on regulatory constraints. +.Pp +A scan operation involves constructing a set of channels to inspect +(the scan set), +visiting each channel and collecting information +(e.g. what BSS are present), +and then analyzing the results to make decisions such as which BSS to join. +This process needs to be as fast as possible so +.Nm net80211 +does things like intelligently construct scan sets and dwell on a channel +only as long as necessary. +Scan results are cached and the scan cache is used to avoid scanning when +possible and to enable roaming between access points when operating +in infrastructure mode. +.Pp +Scanning is handled by pluggable modules that implement +.Em policy +per-operating mode. +The core scanning support provides an infrastructure to support these +modules and exports a common API to the rest of the +.Nm net80211 +layer. +Policy modules decide what channels to visit, what state to record to +make decisions, and selects the final station/channel to return as the +result of a scan. +.Pp +Scanning is done synchronously when initially bringing a vap to +an operational state and optionally in the background to maintain +the scan cache for doing roaming and rogue AP monitoring. +Scanning is not tied to the +.Nm net80211 +state machine that governs vaps except for linkage to the +.Dv IEEE80211_S_SCAN +state. +One one vap at a time may be scanning; this scheduling policy +is handle in +.Fn ieee80211_new_state +and is transparent to scanning code. +.Pp +Scanning is controlled by a set of parameters that (potentially) +constrains the channel set and any desired SSID's and BSSID's. +.Nm net80211 +comes with a standard scanner module that works with all available +operating modes and supports +.Dq background scanning +and +.Dq roaming +operation. +.Sh SCANNER MODULES +Scanning modules use a registration mechanism to hook into the +.Nm net80211 +layer. +Use +.Fn ieee80211_scanner_register +to register a scan module for a particular operating mode and +.Fn ieee80211_scanner_unregister +or +.Fn ieee80211_scanner_unregister_all +to clear entries (typically on module unload). +Only one scanner module can be registered at any time for an operating mode. +.Sh DRIVER SUPPORT +Scanning operations are usually managed by the +.Nm net80211 +layer. +Drivers must provide +.Vt ic_scan_start +and +.Vt ic_scan_stop +methods that are called at the start of a scan and when the +work is done; these should handle work such as enabling receive +of Beacon and ProbeResponse frames and disable any BSSID matching. +The +.Vt ic_set_channel +method is used to change channels while scanning. +.Nm net80211 +will generate ProbeRequest frames and transmit them using the +.Nm ic_raw_xmit +method. +Frames received while scanning are dispatched to +.Nm net80211 +using the normal receive path. +Devices that off-load scan work to firmware most easily mesh with +.Nm net80211 +by operating on a channel-at-a-time basis as this defers control to +.Nm net80211's +scan machine scheduler. +But multi-channel scanning +is supported if the driver manually dispatches results using +.Fn ieee80211_add_scan +routine to enter results into the scan cache. +.Sh SCAN REQUESTS +Scan requests occur by way of the +.Dv IEEE80211_SCAN_REQUEST +ioctl or through a change in a vap's state machine that requires +scanning. +In both cases the scan cache can be checked first and, if it is deemed +suitably +.Dq warm +then it's contents are used without leaving the current channel. +To start a scan without checking the cache +.Fn ieee80211_start_scan +can be called; otherwise +.Fn ieee80211_check_scan +can be used to first check the scan cache, kicking off a scan if +the cache contents are out of date. +There is also +.Fn ieee80211_check_scan_current +which is a shorthand for using previously set scan parameters for +checking the scan cache and then scanning. +.Pp +Background scanning is done using +.Fn ieee80211_bg_scan +in a co-routine fashion. +The first call to this routine will start a background scan that +runs for a limited period of time before returning to the BSS channel. +Subsequent calls advance through the scan set until all channels are +visited. +Typically these later calls are timed to allow receipt of +frames buffered by an access point for the station. +.Pp +A scan operation can be canceled using +.Fn ieee80211_cancel_scan +if it was initiated by the specified vap, or +.Fn ieee80211_cancel_scan_any +to force termination regardless which vap started it. +These requests are mostly used by +.Nm net80211 +in the transmit path to cancel background scans when frames are to be sent. +Drivers should not need to use these calls (or most of the calls described +on this page). +.Pp +The +.Fn ieee80211_scan_next +and +.Fn ieee80211_scan_done +routines do explicit iteration through the scan set and should +not normally be used by drivers. +.Fn ieee80211_probe_curchan +handles the work of transmitting ProbeRequest frames when visiting +a channel during an active scan. +When the channel attributes are marked with +.Dv IEEE80211_CHAN_PASSIVE +this function will arrange that before any frame is transmitted 802.11 +traffic is first received (in order to comply with regulatory constraints). +.Pp +Min/max dwell time parameters are used to constrain time spent visiting +a channel. +The maximum dwell time constrains the time spent listening for traffic. +The minimum dwell time is used to reduce this time--when it is reached +and one or more frames have been received then an immediate channel +change will be done. +Drivers can override this behaviour through the +.Vt iv_scan_mindwell +method. +.Sh SCAN CACHE MANAGEMENT +The scan cache contents are managed by the scan policy module and +are opaque outside this module. +The +.Nm net80211 +scan framework defines API's for interacting. +The validity of the scan cache contents are controlled by +.Vt iv_scanvalid +which is exported to user space through the +.Dv IEEE80211_SCAN_VALID +request. +.Pp +The cache contents can be explicitly flushed with +.Fn ieee80211_scan_flush +or by setting the +.Dv IEEE80211_SCAN_FLUSH +flag when starting a scan operation. +.Pp +Scan cache entries are created with the +.Fn ieee80211_add_scan +routine; usually on receipt of Beacon or ProbeResponse frames. +Existing entries are typically updated based on the latest information +though some information such as RSSI and noise floor readings may be +combined to present an average. +.Pp +The cache contents is aged through +.Fn ieee80211_scan_timeout +calls. +Typically these happen together with other station table activity; every +.Dv IEEE80211_INACT_WAIT +seconds (default 15). +.Pp +Individual cache entries are marked usable with +.Fn ieee80211_scan_assoc_success +and faulty with +.Fn ieee80211_scan_assoc_fail +with the latter taking an argument to identify if there was no response +to Authentication/Association requests or if a negative response was +received (which might hasten cache eviction or blacklist the entry). +.Pp +The cache contents can be viewed using the +.Fn ieee80211_scan_iterate +call. +Cache entries are exported in a public format that is exported to user +applications through the +.Dv IEEE80211_SCAN_RESULTS +request. +.Sh SEE ALSO +.Xr ioctl 2 , +.Xr ieee80211 9 . +.Xr ieee80211_proto 9 diff --git a/share/man/man9/ieee80211_vap.9 b/share/man/man9/ieee80211_vap.9 new file mode 100644 index 00000000000..c5a5c60756c --- /dev/null +++ b/share/man/man9/ieee80211_vap.9 @@ -0,0 +1,154 @@ +.\" +.\" Copyright (c) 2009 Sam Leffler, Errno Consulting +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd August 4, 2009 +.Dt IEEE8021_VAP 9 +.Os +.Sh NAME +.Nm net80211_vap +.Nd 802.11 network layer virtual radio support +.Sh SYNOPSIS +.In net80211/ieee80211_var.h +.Ft int +.Fo ieee80211_vap_setup +.Fa "struct ieee80211com *" +.Fa "struct ieee80211vap *" +.Fa "const char name[IFNAMSIZ]" +.Fa "int unit" +.Fa "int opmode" +.Fa "int flags" +.Fa "const uint8_t bssid[IEEE80211_ADDR_LEN]" +.Fa "const uint8_t macaddr[IEEE80211_ADDR_LEN]" +.Fc +.\" +.Ft int +.Fo ieee80211_vap_attach +.Fa "struct ieee80211vap *" +.Fa "ifm_change_cb_t media_change" +.Fa "ifm_stat_cb_t media_stat" +.Fc +.\" +.Ft void +.Fn ieee80211_vap_detach "struct ieee80211vap *" +.Sh DESCRIPTION +The +.Nm net80211 +software layer provides a support framework for drivers that includes +a virtual radio API that is exported to +users through network interfaces (aka vaps) that are cloned from the +underlying device. +These interfaces have an operating mode +(station, adhoc, hostap, wds, monitor, etc.) +that is fixed for the lifetime of the interface. +Devices that can support multiple concurrent interfaces allow +multiple vaps to be cloned. +.Pp +The virtual radio interface defined by the +.Nm net80211 +layer means that drivers must be structured to follow specific rules. +Drivers that support only a single interface at any time must still +follow these rules. +.Pp +The virtual radio architecture splits state between a single per-device +.Vt ieee80211com +structure and one or more +.Vt ieee80211vap +structures. +Vaps are created with the +.Dv SIOCIFCREATE2 +request. +This results in a call into the driver's +.Vt ic_vap_create +method where the driver can decide if the request should be accepted. +.Pp +The vap creation process is done in three steps. +First the driver allocates the data structure with +.Xr malloc 9 . +This data structure must have an +.Vt ieee80211vap +structure at the front but is usually extended with driver-private state. +Next the vap is setup with a call to +.Fn ieee80211_vap_setup . +This request initializes +.Nm net80211 +state but does not activate the interface. +The driver can then override methods setup by +.Nm net80211 +and setup driver resources before finally calling +.Fn ieee80211_vap_attach +to complete the process. +Both these calls must be done without holding any driver locks as +work may require the process block/sleep. +.Pp +A vap is deleted when an +.Dv SIOCIFDESTROY +ioctl request is made or when the device detaches (causing all +associated vaps to automatically be deleted). +Delete requests cause the +.Vt ic_vap_delete +method to be called. +Drivers must quiesce the device before calling +.Fn ieee80211_vap_detach +to deactivate the vap and isolate it from activities such as requests +from user applications. +The driver can then reclaim resources held by the vap and re-enable +device operation. +The exact procedure for quiesceing a device is unspecified but typically +it involves blocking interrupts and stopping transmit and receive +processing. +.Sh MULTI-VAP OPERATION +Drivers are responsible for deciding if multiple vaps can be created +and how to manage them. +Whether or not multiple concurrent vaps can be supported depends on a +device's capabilities. +For example, multiple hostap vaps can usually be supported but many +devices do not support assigning each vap a unique BSSID. +If a device supports hostap operation it can usually support concurrent +station mode vaps but possibly with limitations such as losing support +for hardware beacon miss support. +Devices that are capable of hostap operation and can send and receive +4-address frames should be able to support WDS vaps together with an +ap vap. +But in contrast some devices cannot support WDS vaps without at least one +ap vap (this however can be finessed by forcing the ap vap to not transmit +beacon frames). +All devices should support the creation of any number of monitor mode vaps +concurrent with other vaps but it is the responsibility of the driver to +allow this. +.Pp +An important consequence of supporting multiple concurrent vaps is that +a driver's +.Vt iv_newstate +method must be written to handle being called for each vap. +Where necessary, drivers must track private state for all vaps +and not just the one whose state is being changed (e.g. for +handling beacon timers the driver may need to know if all vaps +that beacon are stopped before stopping the hardware timers). +.Sh SEE ALSO +.Xr ieee80211 9 , +.Xr ifnet 9 , +.Xr malloc 9 From 24c8d4c173dcf9d0212a059eab46616684047e65 Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Thu, 22 Oct 2009 02:51:31 +0000 Subject: [PATCH 274/380] Get rid of the hardcoded constants to define cacheable memory: SDRAM_ADDR_START, SDRAM_ADDR_END and SDRAM_MEM_SIZE Instead we now keep a copy of the memory regions enumerated by platform-specific code and use that to determine whether an address is cacheable or not. Approved by: imp (mentor) --- sys/mips/include/md_var.h | 4 ++-- sys/mips/include/pltfm.h | 16 ---------------- sys/mips/include/pmap.h | 16 +++++++++++++++- sys/mips/mips/machdep.c | 18 ++++++++++++++++-- sys/mips/mips/mem.c | 14 ++------------ sys/mips/mips/pmap.c | 9 ++++++++- sys/mips/mips/vm_machdep.c | 29 ----------------------------- 7 files changed, 43 insertions(+), 63 deletions(-) delete mode 100644 sys/mips/include/pltfm.h diff --git a/sys/mips/include/md_var.h b/sys/mips/include/md_var.h index f53074f39bf..f7210ffa26c 100644 --- a/sys/mips/include/md_var.h +++ b/sys/mips/include/md_var.h @@ -52,8 +52,8 @@ uintptr_t MipsEmulateBranch(struct trapframe *, uintptr_t, int, uintptr_t); void MipsSwitchFPState(struct thread *, struct trapframe *); u_long kvtop(void *addr); int is_physical_memory(vm_offset_t addr); -int is_cacheable_mem(vm_offset_t pa); -int is_coherent_mem(vm_offset_t pa); + +#define is_cacheable_mem(pa) is_physical_memory((pa)) #define MIPS_DEBUG 0 diff --git a/sys/mips/include/pltfm.h b/sys/mips/include/pltfm.h deleted file mode 100644 index 86d50d964c4..00000000000 --- a/sys/mips/include/pltfm.h +++ /dev/null @@ -1,16 +0,0 @@ -/*- - * JNPR: pltfm.h,v 1.5.2.1 2007/09/10 05:56:11 girish - * $FreeBSD$ - */ - -#ifndef _MACHINE_PLTFM_H_ -#define _MACHINE_PLTFM_H_ - -/* - * This files contains platform-specific definitions. - */ -#define SDRAM_ADDR_START 0 /* SDRAM addr space */ -#define SDRAM_ADDR_END (SDRAM_ADDR_START + (1024*0x100000)) -#define SDRAM_MEM_SIZE (SDRAM_ADDR_END - SDRAM_ADDR_START) - -#endif /* !_MACHINE_PLTFM_H_ */ diff --git a/sys/mips/include/pmap.h b/sys/mips/include/pmap.h index 3e4231350f6..eedd4f3f801 100644 --- a/sys/mips/include/pmap.h +++ b/sys/mips/include/pmap.h @@ -145,7 +145,21 @@ typedef struct pv_entry { #define PMAP_DIAGNOSTIC #endif -extern vm_offset_t phys_avail[]; +/* + * physmem_desc[] is a superset of phys_avail[] and describes all the + * memory present in the system. + * + * phys_avail[] is similar but does not include the memory stolen by + * pmap_steal_memory(). + * + * Each memory region is described by a pair of elements in the array + * so we can describe up to (PHYS_AVAIL_ENTRIES / 2) distinct memory + * regions. + */ +#define PHYS_AVAIL_ENTRIES 10 +extern vm_offset_t phys_avail[PHYS_AVAIL_ENTRIES + 2]; +extern vm_offset_t physmem_desc[PHYS_AVAIL_ENTRIES + 2]; + extern char *ptvmmap; /* poor name! */ extern vm_offset_t virtual_avail; extern vm_offset_t virtual_end; diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c index 9a28b2485ea..a746b24c812 100644 --- a/sys/mips/mips/machdep.c +++ b/sys/mips/mips/machdep.c @@ -79,7 +79,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -120,7 +119,9 @@ struct pcpu pcpu; struct pcpu *pcpup = &pcpu; #endif -vm_offset_t phys_avail[10]; +vm_offset_t phys_avail[PHYS_AVAIL_ENTRIES + 2]; +vm_offset_t physmem_desc[PHYS_AVAIL_ENTRIES + 2]; + #ifdef UNIMPLEMENTED struct platform platform; #endif @@ -426,3 +427,16 @@ cpu_idle_wakeup(int cpu) return (0); } + +int +is_physical_memory(vm_offset_t addr) +{ + int i; + + for (i = 0; physmem_desc[i + 1] != 0; i += 2) { + if (addr >= physmem_desc[i] && addr < physmem_desc[i + 1]) + return (1); + } + + return (0); +} diff --git a/sys/mips/mips/mem.c b/sys/mips/mips/mem.c index 1a03d5b79a7..3a3cbaebb52 100644 --- a/sys/mips/mips/mem.c +++ b/sys/mips/mips/mem.c @@ -65,7 +65,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include @@ -101,17 +100,8 @@ memrw(dev, uio, flags) vm_paddr_t pa; register int o; -#ifdef CPU_SB1 - if (!is_physical_memory(v) || - !is_physical_memory(roundup2(v, PAGE_SIZE) - 1)) { - return (EFAULT); - } -#else - if (v + c > (SDRAM_ADDR_START + ctob(physmem))) - return (EFAULT); -#endif - - if (is_cacheable_mem(v) && is_cacheable_mem(v + c)) { + if (is_cacheable_mem(v) && + is_cacheable_mem(v + c - 1)) { struct fpage *fp; struct sysmaps *sysmaps; diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index 33b8040c1a5..bfdadb7d4cc 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -96,7 +96,6 @@ __FBSDID("$FreeBSD$"); #endif #include -#include #include #if defined(DIAGNOSTIC) @@ -313,6 +312,14 @@ again: } } + /* + * Copy the phys_avail[] array before we start stealing memory from it. + */ + for (i = 0; phys_avail[i + 1] != 0; i += 2) { + physmem_desc[i] = phys_avail[i]; + physmem_desc[i + 1] = phys_avail[i + 1]; + } + Maxmem = atop(phys_avail[i - 1]); if (bootverbose) { diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c index 0b51fa1b62d..9b4829eb9df 100644 --- a/sys/mips/mips/vm_machdep.c +++ b/sys/mips/mips/vm_machdep.c @@ -57,7 +57,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include @@ -399,34 +398,6 @@ kvtop(void *addr) #define ZIDLE_LO(v) ((v) * 2 / 3) #define ZIDLE_HI(v) ((v) * 4 / 5) -/* - * Tell whether this address is in some physical memory region. - * Currently used by the kernel coredump code in order to avoid - * dumping non-memory physical address space. - */ -int -is_physical_memory(vm_offset_t addr) -{ - if (addr >= SDRAM_ADDR_START && addr <= SDRAM_ADDR_END) - return 1; - else - return 0; -} - -int -is_cacheable_mem(vm_offset_t pa) -{ - if ((pa >= SDRAM_ADDR_START && pa <= SDRAM_ADDR_END) || -#ifdef FLASH_ADDR_START - (pa >= FLASH_ADDR_START && pa <= FLASH_ADDR_END)) -#else - 0) -#endif - return 1; - else - return 0; -} - /* * Allocate a pool of sf_bufs (sendfile(2) or "super-fast" if you prefer. :-)) */ From abd74e0c14946469e67c2e1c31368ee248119915 Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Thu, 22 Oct 2009 04:35:32 +0000 Subject: [PATCH 275/380] Remove redundant instructions from tlb.S The "_MTC0 v0, COP_0_TLB_HI" is actually incorrect because v0 has not been initialized at that point. It worked correctly because we subsequently did the right thing and initialized TLB_HI correctly. The "li v0, MIPS_KSEG0_START" is redundant because we do exactly the same thing 2 instructions down. Approved by: imp (mentor) --- sys/mips/mips/tlb.S | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sys/mips/mips/tlb.S b/sys/mips/mips/tlb.S index 7829bd879ac..46a15f81ca4 100644 --- a/sys/mips/mips/tlb.S +++ b/sys/mips/mips/tlb.S @@ -231,7 +231,6 @@ LEAF(Mips_TLBFlush) ITLBNOPFIX mfc0 t1, COP_0_TLB_WIRED _MFC0 t0, COP_0_TLB_HI # Save the PID - _MTC0 v0, COP_0_TLB_HI # Mark entry high as invalid _MTC0 zero, COP_0_TLB_LO0 # Zero out low entry0. _MTC0 zero, COP_0_TLB_LO1 # Zero out low entry1. mtc0 zero, COP_0_TLB_PG_MASK # Zero out mask entry. @@ -250,12 +249,8 @@ LEAF(Mips_TLBFlush) 1: mtc0 t1, COP_0_TLB_INDEX # Set the index register. ITLBNOPFIX -#xxx imp -# _MTC0 t0, COP_0_TLB_HI # Restore the PID _MTC0 v0, COP_0_TLB_HI # Mark entry high as invalid addu t1, t1, 1 # Increment index. -#xxx imp -# addu t0, t0, 8 * 1024 addu v0, v0, 8 * 1024 MIPS_CPU_NOP_DELAY tlbwi # Write the TLB entry. @@ -481,7 +476,6 @@ LEAF(mips_TBIAP) _MFC0 ta0, COP_0_TLB_HI # Get current PID move t2, a0 mfc0 t1, COP_0_TLB_WIRED - li v0, MIPS_KSEG0_START # invalid address # # Load invalid entry, each TLB entry should have it's own bogus # address calculated by following expression: From c3655ab0d0a3a84bcc6b962e15ad09eafffc973e Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sun, 25 Oct 2009 08:43:38 +0000 Subject: [PATCH 276/380] - Add write support for mx25l flash chip - Some minor style(9) fixes --- sys/dev/flash/mx25l.c | 103 ++++++++++++++++++++++++++++++++++++++- sys/dev/flash/mx25lreg.h | 2 + 2 files changed, 104 insertions(+), 1 deletion(-) diff --git a/sys/dev/flash/mx25l.c b/sys/dev/flash/mx25l.c index cdbf4e519bd..ff51fd7c550 100644 --- a/sys/dev/flash/mx25l.c +++ b/sys/dev/flash/mx25l.c @@ -156,6 +156,50 @@ mx25l_get_device_ident(struct mx25l_softc *sc) return (NULL); } +static void +mx25l_set_writable(device_t dev, int writable) +{ + uint8_t txBuf[1], rxBuf[1]; + struct spi_command cmd; + int err; + + memset(&cmd, 0, sizeof(cmd)); + memset(txBuf, 0, sizeof(txBuf)); + memset(rxBuf, 0, sizeof(rxBuf)); + + txBuf[0] = writable ? CMD_WRITE_ENABLE : CMD_WRITE_DISABLE; + cmd.tx_cmd = txBuf; + cmd.rx_cmd = rxBuf; + cmd.rx_cmd_sz = 1; + cmd.tx_cmd_sz = 1; + err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd); +} + +static void +mx25l_erase_sector(device_t dev, off_t sector) +{ + uint8_t txBuf[4], rxBuf[4]; + struct spi_command cmd; + int err; + + mx25l_wait_for_device_ready(dev); + mx25l_set_writable(dev, 1); + + memset(&cmd, 0, sizeof(cmd)); + memset(txBuf, 0, sizeof(txBuf)); + memset(rxBuf, 0, sizeof(rxBuf)); + + txBuf[0] = CMD_SECTOR_ERASE; + cmd.tx_cmd = txBuf; + cmd.rx_cmd = rxBuf; + cmd.rx_cmd_sz = 4; + cmd.tx_cmd_sz = 4; + txBuf[1] = ((sector >> 16) & 0xff); + txBuf[2] = ((sector >> 8) & 0xff); + txBuf[3] = (sector & 0xff); + err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd); +} + static int mx25l_probe(device_t dev) { @@ -233,7 +277,6 @@ mx25l_ioctl(struct disk *dp, u_long cmd, void *data, int fflag, return (EINVAL); } - static void mx25l_strategy(struct bio *bp) { @@ -254,6 +297,8 @@ mx25l_task(void *arg) uint8_t txBuf[8], rxBuf[8]; struct spi_command cmd; device_t dev, pdev; + off_t write_offset; + long bytes_to_write, bytes_writen; for (;;) { dev = sc->sc_dev; @@ -284,11 +329,67 @@ mx25l_task(void *arg) cmd.tx_data_sz = bp->bio_bcount; cmd.rx_data = bp->bio_data; cmd.rx_data_sz = bp->bio_bcount; + bp->bio_error = SPIBUS_TRANSFER(pdev, dev, &cmd); } + else if (bp->bio_cmd == BIO_WRITE) { + mx25l_erase_sector(dev, bp->bio_offset); + + cmd.tx_cmd_sz = 4; + cmd.rx_cmd_sz = 4; + + bytes_writen = 0; + write_offset = bp->bio_offset; + + /* + * I assume here that we write per-sector only + * and sector size should be 256 bytes aligned + */ + KASSERT(write_offset % FLASH_PAGE_SIZE == 0, + ("offset for BIO_WRITE is not %d bytes aliIgned", + FLASH_PAGE_SIZE)); + + /* + * Maximum write size for CMD_PAGE_PROGRAM is + * FLASH_PAGE_SIZE, so split data to chunks + * FLASH_PAGE_SIZE bytes eash and write them + * one by one + */ + while (bytes_writen < bp->bio_bcount) { + txBuf[0] = CMD_PAGE_PROGRAM; + txBuf[1] = ((write_offset >> 16) & 0xff); + txBuf[2] = ((write_offset >> 8) & 0xff); + txBuf[3] = (write_offset & 0xff); + + bytes_to_write = MIN(FLASH_PAGE_SIZE, + bp->bio_bcount - bytes_writen); + cmd.tx_cmd = txBuf; + cmd.rx_cmd = rxBuf; + cmd.tx_data = bp->bio_data + bytes_writen; + cmd.tx_data_sz = bytes_to_write; + cmd.rx_data = bp->bio_data + bytes_writen; + cmd.rx_data_sz = bytes_to_write; + + /* + * Eash completed write operation resets WEL + * (write enable latch) to disabled state, + * so we re-enable it here + */ + mx25l_wait_for_device_ready(dev); + mx25l_set_writable(dev, 1); + + bp->bio_error = SPIBUS_TRANSFER(pdev, dev, &cmd); + if (bp->bio_error) + break; + + bytes_writen += bytes_to_write; + write_offset += bytes_to_write; + } + } else bp->bio_error = EINVAL; + biodone(bp); } } diff --git a/sys/dev/flash/mx25lreg.h b/sys/dev/flash/mx25lreg.h index 7575b5be076..49808af603b 100644 --- a/sys/dev/flash/mx25lreg.h +++ b/sys/dev/flash/mx25lreg.h @@ -52,5 +52,7 @@ #define STATUS_WEL (1 << 1) #define STATUS_WIP (1 << 0) +#define FLASH_PAGE_SIZE 256 + #endif /* __MX25LREG_H__ */ From c64429e2b5728cb78a015254b20aa5b68bee1354 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Sun, 25 Oct 2009 19:13:39 +0000 Subject: [PATCH 277/380] If the FIS entry is smaller than the sector size then set it as hot so g_slice calls us to fix it, we then issue a read for a full sector and then copy in/out the payload. This will happen if Redboot is compiled with CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG. --- sys/geom/geom_redboot.c | 158 +++++++++++++++++++++++++++++++++------- 1 file changed, 132 insertions(+), 26 deletions(-) diff --git a/sys/geom/geom_redboot.c b/sys/geom/geom_redboot.c index 3ece7c15c43..e8f4ba80af3 100644 --- a/sys/geom/geom_redboot.c +++ b/sys/geom/geom_redboot.c @@ -71,6 +71,7 @@ struct fis_image_desc { struct g_redboot_softc { uint32_t entry[REDBOOT_MAXSLICE]; uint32_t dsize[REDBOOT_MAXSLICE]; + uint32_t sectoff[REDBOOT_MAXSLICE]; uint8_t readonly[REDBOOT_MAXSLICE]; g_access_t *parent_access; }; @@ -104,29 +105,125 @@ g_redboot_access(struct g_provider *pp, int dread, int dwrite, int dexcl) return (sc->parent_access(pp, dread, dwrite, dexcl)); } -static int -g_redboot_start(struct bio *bp) +static void +g_redboot_done(struct bio *bp) { + struct bio *bp2; struct g_provider *pp; + struct g_consumer *cp; struct g_geom *gp; struct g_redboot_softc *sc; struct g_slicer *gsp; int idx; + bp2 = bp->bio_parent; + pp = bp2->bio_to; + idx = pp->index; + gp = pp->geom; + gsp = gp->softc; + sc = gsp->softc; + + bp2->bio_error = bp->bio_error; + if (bp2->bio_error != 0) + goto done; + + KASSERT(sc->sectoff[idx] + bp2->bio_length <= bp->bio_length, + ("overflowed bio data")); + if (bp2->bio_cmd == BIO_READ) { + /* Copy out read data */ + memcpy(bp2->bio_data, bp->bio_data + sc->sectoff[idx], + bp2->bio_length); + bp2->bio_completed = bp2->bio_length; + } else { + if (bp->bio_cmd == BIO_READ) { + /* Copy in and reissue as write */ + cp = LIST_FIRST(&gp->consumer); + memcpy(bp->bio_data + sc->sectoff[idx], bp2->bio_data, + bp2->bio_length); + bp->bio_cmd = BIO_WRITE; + g_io_request(bp, cp); + return; + } else { + /* Write done */ + bp2->bio_completed = bp2->bio_length; + } + } +done: + /* + * Finish processing the request. + */ + free(bp->bio_data, M_GEOM); + g_destroy_bio(bp); + g_io_deliver(bp2, bp2->bio_error); +} + +static int +g_redboot_start(struct bio *bp) +{ + struct g_provider *pp, *pp2; + struct g_geom *gp; + struct g_redboot_softc *sc; + struct g_slicer *gsp; + struct g_slice *gsl; + struct g_consumer *cp; + struct bio *bp2; + size_t bsize; + int idx; + pp = bp->bio_to; idx = pp->index; gp = pp->geom; gsp = gp->softc; + gsl = &gsp->slices[idx]; sc = gsp->softc; - if (bp->bio_cmd == BIO_GETATTR) { - if (g_handleattr_int(bp, REDBOOT_CLASS_NAME "::entry", - sc->entry[idx])) - return (1); - if (g_handleattr_int(bp, REDBOOT_CLASS_NAME "::dsize", - sc->dsize[idx])) - return (1); + switch (bp->bio_cmd) { + /* + * Read/Write are handled in g_redboot_done() after reading + * the sector + */ + case BIO_READ: + case BIO_WRITE: + break; + case BIO_GETATTR: + if (g_handleattr_int(bp, REDBOOT_CLASS_NAME "::entry", + sc->entry[idx])) + return (1); + if (g_handleattr_int(bp, REDBOOT_CLASS_NAME "::dsize", + sc->dsize[idx])) + return (1); + if (g_handleattr_int(bp, REDBOOT_CLASS_NAME "::sectoff", + sc->sectoff[idx])) + return (1); + return (0); + default: + return (EINVAL); } + cp = LIST_FIRST(&gp->consumer); + pp2 = cp->provider; + bsize = pp2->sectorsize; + + /* + * At this point we have a request which is less than the flash sector + * size, to do this we read the entire sector and then copy the data + * in/out. + */ + KASSERT(bp->bio_length < bsize, ("length greater than one sector")); + KASSERT(bp->bio_offset == 0, ("not at start of sector")); + + bp2 = g_clone_bio(bp); + if (bp2 == NULL) + return (ENOMEM); + bp2->bio_cmd = BIO_READ; + bp2->bio_done = g_redboot_done; + bp2->bio_offset = gsl->offset - sc->sectoff[idx]; + bp2->bio_length = bsize; + bp2->bio_data = malloc(bsize, M_GEOM, M_NOWAIT); + if (bp2->bio_data == NULL) { + g_destroy_bio(bp2); + return (ENOMEM); + } + g_io_request(bp2, cp); return (0); } @@ -144,11 +241,14 @@ g_redboot_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, if (indent == NULL) { sbuf_printf(sb, " entry %d", sc->entry[pp->index]); sbuf_printf(sb, " dsize %d", sc->dsize[pp->index]); + sbuf_printf(sb, " sectoff %d", sc->sectoff[pp->index]); } else { sbuf_printf(sb, "%s%d\n", indent, sc->entry[pp->index]); sbuf_printf(sb, "%s%d\n", indent, sc->dsize[pp->index]); + sbuf_printf(sb, "%s%d\n", indent, + sc->sectoff[pp->index]); } } } @@ -172,7 +272,7 @@ parse_fis_directory(u_char *buf, size_t bufsize, off_t offset, uint32_t offmask) { #define match(a,b) (bcmp(a, b, sizeof(b)-1) == 0) struct fis_image_desc *fd, *efd; - struct fis_image_desc *fisdir, *redbcfg; + struct fis_image_desc *fisdir; struct fis_image_desc *head, **tail; int i; @@ -193,15 +293,13 @@ parse_fis_directory(u_char *buf, size_t bufsize, off_t offset, uint32_t offmask) /* * Scan forward collecting entries in a list. */ - fisdir = redbcfg = NULL; + fisdir = NULL; *(tail = &head) = NULL; for (i = 0; fd < efd; i++, fd++) { if (fd->name[0] == 0xff) continue; if (match(fd->name, FISDIR_NAME)) fisdir = fd; - else if (match(fd->name, REDBCFG_NAME)) - redbcfg = fd; if (nameok(fd->name)) { /* * NB: flash address includes platform mapping; @@ -220,16 +318,6 @@ parse_fis_directory(u_char *buf, size_t bufsize, off_t offset, uint32_t offmask) (long) offset); return (NULL); } - if (redbcfg != NULL && - fisdir->offset + fisdir->size == redbcfg->offset) { - /* - * Merged FIS/RedBoot config directory. - */ - if (bootverbose) - printf("FIS/RedBoot merged at 0x%jx (not yet)\n", - offset + fisdir->offset); - /* XXX */ - } return head; #undef match } @@ -252,7 +340,8 @@ g_redboot_taste(struct g_class *mp, struct g_provider *pp, int insist) if (!strcmp(pp->geom->class->name, REDBOOT_CLASS_NAME)) return (NULL); /* XXX only taste flash providers */ - if (strncmp(pp->name, "cfi", 3)) + if (strncmp(pp->name, "cfi", 3) && + strncmp(pp->name, "flash/spi", 9)) return (NULL); gp = g_slice_new(mp, REDBOOT_MAXSLICE, pp, &cp, &sc, sizeof(*sc), g_redboot_start); @@ -300,8 +389,25 @@ again: for (fd = head, i = 0; fd != NULL; fd = fd->next) { if (fd->name[0] == '\0') continue; - error = g_slice_config(gp, i, G_SLICE_CONFIG_SET, - fd->offset, fd->size, sectorsize, "redboot/%s", fd->name); + if (fd->size < sectorsize) { + /* + * If the FIS entry is smaller than the sector size + * then set it as hot so g_slice calls us to fix it. + * This will happen if Redboot is compiled with + * CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG. + */ + sc->sectoff[i] = fd->offset & (sectorsize - 1); + error = g_slice_config(gp, i, G_SLICE_CONFIG_SET, + fd->offset, fd->size, fd->size, + "redboot/%s", fd->name); + g_slice_conf_hot(gp, i, fd->offset, fd->size, + G_SLICE_HOT_START, G_SLICE_HOT_DENY, + G_SLICE_HOT_START); + } else { + error = g_slice_config(gp, i, G_SLICE_CONFIG_SET, + fd->offset, fd->size, sectorsize, "redboot/%s", + fd->name); + } if (error) printf("%s: g_slice_config returns %d for \"%s\"\n", __func__, error, fd->name); From 8ab98910b4c10f9e68da834e642b3532dcd51e2e Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Mon, 26 Oct 2009 10:59:55 +0000 Subject: [PATCH 278/380] Fix Copyright ;-) --- sys/mips/rmi/intr_machdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/rmi/intr_machdep.c b/sys/mips/rmi/intr_machdep.c index 40fda6f74ae..10539c4d617 100644 --- a/sys/mips/rmi/intr_machdep.c +++ b/sys/mips/rmi/intr_machdep.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2006 Fill this file and put your name here + * Copyright (c) 2006-2009 RMI Corporation * Copyright (c) 2002-2004 Juli Mallett * All rights reserved. * From ee093123700af436c666b58f1adce9b189523390 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Mon, 26 Oct 2009 11:00:37 +0000 Subject: [PATCH 279/380] White space changes. --- sys/mips/rmi/board.c | 148 +++++++++++++++++++++---------------------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/sys/mips/rmi/board.c b/sys/mips/rmi/board.c index 44a80151ea5..73d783d5184 100644 --- a/sys/mips/rmi/board.c +++ b/sys/mips/rmi/board.c @@ -40,45 +40,45 @@ #include static int xlr_rxstn_to_txstn_map[128] = { - [0 ... 7] = TX_STN_CPU_0, - [8 ... 15] = TX_STN_CPU_1, - [16 ... 23] = TX_STN_CPU_2, - [24 ... 31] = TX_STN_CPU_3, - [32 ... 39] = TX_STN_CPU_4, - [40 ... 47] = TX_STN_CPU_5, - [48 ... 55] = TX_STN_CPU_6, - [56 ... 63] = TX_STN_CPU_7, - [64 ... 95] = TX_STN_INVALID, - [96 ... 103] = TX_STN_GMAC, - [104 ... 107] = TX_STN_DMA, - [108 ... 111] = TX_STN_INVALID, - [112 ... 113] = TX_STN_XGS_0, - [114 ... 115] = TX_STN_XGS_1, - [116 ... 119] = TX_STN_INVALID, - [120 ... 127] = TX_STN_SAE + [0 ... 7] = TX_STN_CPU_0, + [8 ... 15] = TX_STN_CPU_1, + [16 ... 23] = TX_STN_CPU_2, + [24 ... 31] = TX_STN_CPU_3, + [32 ... 39] = TX_STN_CPU_4, + [40 ... 47] = TX_STN_CPU_5, + [48 ... 55] = TX_STN_CPU_6, + [56 ... 63] = TX_STN_CPU_7, + [64 ... 95] = TX_STN_INVALID, + [96 ... 103] = TX_STN_GMAC, + [104 ... 107] = TX_STN_DMA, + [108 ... 111] = TX_STN_INVALID, + [112 ... 113] = TX_STN_XGS_0, + [114 ... 115] = TX_STN_XGS_1, + [116 ... 119] = TX_STN_INVALID, + [120 ... 127] = TX_STN_SAE }; static int xls_rxstn_to_txstn_map[128] = { - [0 ... 7] = TX_STN_CPU_0, - [8 ... 15] = TX_STN_CPU_1, - [16 ... 23] = TX_STN_CPU_2, - [24 ... 31] = TX_STN_CPU_3, - [32 ... 63] = TX_STN_INVALID, - [64 ... 71] = TX_STN_PCIE, - [72 ... 79] = TX_STN_INVALID, - [80 ... 87] = TX_STN_GMAC1, - [88 ... 95] = TX_STN_INVALID, - [96 ... 103] = TX_STN_GMAC0, - [104 ... 107] = TX_STN_DMA, - [108 ... 111] = TX_STN_CDE, - [112 ... 119] = TX_STN_INVALID, - [120 ... 127] = TX_STN_SAE + [0 ... 7] = TX_STN_CPU_0, + [8 ... 15] = TX_STN_CPU_1, + [16 ... 23] = TX_STN_CPU_2, + [24 ... 31] = TX_STN_CPU_3, + [32 ... 63] = TX_STN_INVALID, + [64 ... 71] = TX_STN_PCIE, + [72 ... 79] = TX_STN_INVALID, + [80 ... 87] = TX_STN_GMAC1, + [88 ... 95] = TX_STN_INVALID, + [96 ... 103] = TX_STN_GMAC0, + [104 ... 107] = TX_STN_DMA, + [108 ... 111] = TX_STN_CDE, + [112 ... 119] = TX_STN_INVALID, + [120 ... 127] = TX_STN_SAE }; struct stn_cc *xlr_core_cc_configs[] = {&cc_table_cpu_0, &cc_table_cpu_1, - &cc_table_cpu_2, &cc_table_cpu_3, - &cc_table_cpu_4, &cc_table_cpu_5, - &cc_table_cpu_6, &cc_table_cpu_7 }; + &cc_table_cpu_2, &cc_table_cpu_3, + &cc_table_cpu_4, &cc_table_cpu_5, + &cc_table_cpu_6, &cc_table_cpu_7 }; struct stn_cc *xls_core_cc_configs[] = {&xls_cc_table_cpu_0, &xls_cc_table_cpu_1, &xls_cc_table_cpu_2, &xls_cc_table_cpu_3}; @@ -106,30 +106,30 @@ int xlr_board_info_setup() /* network block 0 */ xlr_board_info.gmac_block[0].type = XLR_GMAC; xlr_board_info.gmac_block[0].enabled = 0xf; - xlr_board_info.gmac_block[0].credit_config = &xls_cc_table_gmac0; - xlr_board_info.gmac_block[0].station_txbase = MSGRNG_STNID_GMACTX0; - xlr_board_info.gmac_block[0].station_rfr = MSGRNG_STNID_GMACRFR_0; + xlr_board_info.gmac_block[0].credit_config = &xls_cc_table_gmac0; + xlr_board_info.gmac_block[0].station_txbase = MSGRNG_STNID_GMACTX0; + xlr_board_info.gmac_block[0].station_rfr = MSGRNG_STNID_GMACRFR_0; if (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_VI) xlr_board_info.gmac_block[0].mode = XLR_PORT0_RGMII; else xlr_board_info.gmac_block[0].mode = XLR_SGMII; - xlr_board_info.gmac_block[0].baseaddr = XLR_IO_GMAC_0_OFFSET; - xlr_board_info.gmac_block[0].baseirq = PIC_GMAC_0_IRQ; - xlr_board_info.gmac_block[0].baseinst = 0; + xlr_board_info.gmac_block[0].baseaddr = XLR_IO_GMAC_0_OFFSET; + xlr_board_info.gmac_block[0].baseirq = PIC_GMAC_0_IRQ; + xlr_board_info.gmac_block[0].baseinst = 0; - /* network block 1 */ + /* network block 1 */ xlr_board_info.gmac_block[1].type = XLR_GMAC; - xlr_board_info.gmac_block[1].enabled = 0xf; - xlr_board_info.gmac_block[1].credit_config = &xls_cc_table_gmac1; - xlr_board_info.gmac_block[1].station_txbase = MSGRNG_STNID_GMAC1_TX0; - xlr_board_info.gmac_block[1].station_rfr = MSGRNG_STNID_GMAC1_FR_0; - xlr_board_info.gmac_block[1].mode = XLR_SGMII; - xlr_board_info.gmac_block[1].baseaddr = XLR_IO_GMAC_4_OFFSET; - xlr_board_info.gmac_block[1].baseirq = PIC_XGS_0_IRQ; - xlr_board_info.gmac_block[1].baseinst = 4; + xlr_board_info.gmac_block[1].enabled = 0xf; + xlr_board_info.gmac_block[1].credit_config = &xls_cc_table_gmac1; + xlr_board_info.gmac_block[1].station_txbase = MSGRNG_STNID_GMAC1_TX0; + xlr_board_info.gmac_block[1].station_rfr = MSGRNG_STNID_GMAC1_FR_0; + xlr_board_info.gmac_block[1].mode = XLR_SGMII; + xlr_board_info.gmac_block[1].baseaddr = XLR_IO_GMAC_4_OFFSET; + xlr_board_info.gmac_block[1].baseirq = PIC_XGS_0_IRQ; + xlr_board_info.gmac_block[1].baseinst = 4; - /* network block 2 */ - xlr_board_info.gmac_block[2].enabled = 0; /* disabled on XLS */ + /* network block 2 */ + xlr_board_info.gmac_block[2].enabled = 0; /* disabled on XLS */ } else { xlr_board_info.is_xls = 0; xlr_board_info.nr_cpus = 32; @@ -141,38 +141,38 @@ int xlr_board_info_setup() xlr_board_info.msgmap = xlr_rxstn_to_txstn_map; xlr_board_info.gmacports = 4; - /* GMAC0 */ + /* GMAC0 */ xlr_board_info.gmac_block[0].type = XLR_GMAC; - xlr_board_info.gmac_block[0].enabled = 0xf; - xlr_board_info.gmac_block[0].credit_config = &cc_table_gmac; - xlr_board_info.gmac_block[0].station_txbase = MSGRNG_STNID_GMACTX0; - xlr_board_info.gmac_block[0].station_rfr = MSGRNG_STNID_GMACRFR_0; + xlr_board_info.gmac_block[0].enabled = 0xf; + xlr_board_info.gmac_block[0].credit_config = &cc_table_gmac; + xlr_board_info.gmac_block[0].station_txbase = MSGRNG_STNID_GMACTX0; + xlr_board_info.gmac_block[0].station_rfr = MSGRNG_STNID_GMACRFR_0; xlr_board_info.gmac_block[0].mode = XLR_RGMII; - xlr_board_info.gmac_block[0].baseaddr = XLR_IO_GMAC_0_OFFSET; - xlr_board_info.gmac_block[0].baseirq = PIC_GMAC_0_IRQ; - xlr_board_info.gmac_block[0].baseinst = 0; + xlr_board_info.gmac_block[0].baseaddr = XLR_IO_GMAC_0_OFFSET; + xlr_board_info.gmac_block[0].baseirq = PIC_GMAC_0_IRQ; + xlr_board_info.gmac_block[0].baseinst = 0; - /* XGMAC0 */ + /* XGMAC0 */ xlr_board_info.gmac_block[1].type = XLR_XGMAC; - xlr_board_info.gmac_block[1].enabled = 1; - xlr_board_info.gmac_block[1].credit_config = &cc_table_xgs_0; - xlr_board_info.gmac_block[1].station_txbase = MSGRNG_STNID_XGS0_TX; - xlr_board_info.gmac_block[1].station_rfr = MSGRNG_STNID_XGS0FR; + xlr_board_info.gmac_block[1].enabled = 1; + xlr_board_info.gmac_block[1].credit_config = &cc_table_xgs_0; + xlr_board_info.gmac_block[1].station_txbase = MSGRNG_STNID_XGS0_TX; + xlr_board_info.gmac_block[1].station_rfr = MSGRNG_STNID_XGS0FR; xlr_board_info.gmac_block[1].mode = -1; - xlr_board_info.gmac_block[1].baseaddr = XLR_IO_XGMAC_0_OFFSET; - xlr_board_info.gmac_block[1].baseirq = PIC_XGS_0_IRQ; - xlr_board_info.gmac_block[1].baseinst = 4; + xlr_board_info.gmac_block[1].baseaddr = XLR_IO_XGMAC_0_OFFSET; + xlr_board_info.gmac_block[1].baseirq = PIC_XGS_0_IRQ; + xlr_board_info.gmac_block[1].baseinst = 4; - /* XGMAC1 */ + /* XGMAC1 */ xlr_board_info.gmac_block[2].type = XLR_XGMAC; - xlr_board_info.gmac_block[2].enabled = 1; - xlr_board_info.gmac_block[2].credit_config = &cc_table_xgs_1; - xlr_board_info.gmac_block[2].station_txbase = MSGRNG_STNID_XGS1_TX; - xlr_board_info.gmac_block[2].station_rfr = MSGRNG_STNID_XGS1FR; + xlr_board_info.gmac_block[2].enabled = 1; + xlr_board_info.gmac_block[2].credit_config = &cc_table_xgs_1; + xlr_board_info.gmac_block[2].station_txbase = MSGRNG_STNID_XGS1_TX; + xlr_board_info.gmac_block[2].station_rfr = MSGRNG_STNID_XGS1FR; xlr_board_info.gmac_block[2].mode = -1; - xlr_board_info.gmac_block[2].baseaddr = XLR_IO_XGMAC_1_OFFSET; - xlr_board_info.gmac_block[2].baseirq = PIC_XGS_1_IRQ; - xlr_board_info.gmac_block[2].baseinst = 5; + xlr_board_info.gmac_block[2].baseaddr = XLR_IO_XGMAC_1_OFFSET; + xlr_board_info.gmac_block[2].baseirq = PIC_XGS_1_IRQ; + xlr_board_info.gmac_block[2].baseinst = 5; } return 0; } From 7e60d1a36c0ca33aa723f67f5ecbb1364f2f54c3 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 27 Oct 2009 23:45:48 +0000 Subject: [PATCH 280/380] - Replace stubs with actual cache info - minor style(9) fix --- sys/mips/mips/cache.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sys/mips/mips/cache.c b/sys/mips/mips/cache.c index 64e03c9544e..946166032c9 100644 --- a/sys/mips/mips/cache.c +++ b/sys/mips/mips/cache.c @@ -81,6 +81,7 @@ struct mips_cache_ops mips_cache_ops; void mips_config_cache(struct mips_cpuinfo * cpuinfo) { + switch (cpuinfo->l1.ic_linesize) { case 16: mips_cache_ops.mco_icache_sync_all = mipsNN_icache_sync_all_16; @@ -223,7 +224,9 @@ mips_config_cache(struct mips_cpuinfo * cpuinfo) #endif /* Check that all cache ops are set up. */ - if (mips_picache_size || 1) { /* XXX- must have primary Icache */ + /* must have primary Icache */ + if (cpuinfo->l1.ic_size) { + if (!mips_cache_ops.mco_icache_sync_all) panic("no icache_sync_all cache op"); if (!mips_cache_ops.mco_icache_sync_range) @@ -231,7 +234,8 @@ mips_config_cache(struct mips_cpuinfo * cpuinfo) if (!mips_cache_ops.mco_icache_sync_range_index) panic("no icache_sync_range_index cache op"); } - if (mips_pdcache_size || 1) { /* XXX- must have primary Icache */ + /* must have primary Dcache */ + if (cpuinfo->l1.dc_size) { if (!mips_cache_ops.mco_pdcache_wbinv_all) panic("no pdcache_wbinv_all"); if (!mips_cache_ops.mco_pdcache_wbinv_range) From 0ffd7b67599dd4376e46310d5c14a2d63d2b4692 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 28 Oct 2009 00:01:20 +0000 Subject: [PATCH 281/380] - Remove bunch of declared but not defined cach-related variables - Add mips_picache_linesize and mips_pdcache_linesize variables --- sys/mips/include/cache.h | 46 ++---------------------------------- sys/mips/mips/cache_mipsNN.c | 10 ++++++++ 2 files changed, 12 insertions(+), 44 deletions(-) diff --git a/sys/mips/include/cache.h b/sys/mips/include/cache.h index 8c8cf34d9dd..d73daa211d1 100644 --- a/sys/mips/include/cache.h +++ b/sys/mips/include/cache.h @@ -159,50 +159,8 @@ struct mips_cache_ops { extern struct mips_cache_ops mips_cache_ops; /* PRIMARY CACHE VARIABLES */ -extern u_int mips_picache_size; -extern u_int mips_picache_line_size; -extern u_int mips_picache_ways; -extern u_int mips_picache_way_size; -extern u_int mips_picache_way_mask; - -extern u_int mips_pdcache_size; /* and unified */ -extern u_int mips_pdcache_line_size; -extern u_int mips_pdcache_ways; -extern u_int mips_pdcache_way_size; -extern u_int mips_pdcache_way_mask; -extern int mips_pdcache_write_through; - -extern int mips_pcache_unified; - -/* SECONDARY CACHE VARIABLES */ -extern u_int mips_sicache_size; -extern u_int mips_sicache_line_size; -extern u_int mips_sicache_ways; -extern u_int mips_sicache_way_size; -extern u_int mips_sicache_way_mask; - -extern u_int mips_sdcache_size; /* and unified */ -extern u_int mips_sdcache_line_size; -extern u_int mips_sdcache_ways; -extern u_int mips_sdcache_way_size; -extern u_int mips_sdcache_way_mask; -extern int mips_sdcache_write_through; - -extern int mips_scache_unified; - -/* TERTIARY CACHE VARIABLES */ -extern u_int mips_tcache_size; /* always unified */ -extern u_int mips_tcache_line_size; -extern u_int mips_tcache_ways; -extern u_int mips_tcache_way_size; -extern u_int mips_tcache_way_mask; -extern int mips_tcache_write_through; - -extern u_int mips_dcache_align; -extern u_int mips_dcache_align_mask; - -extern u_int mips_cache_alias_mask; -extern u_int mips_cache_prefer_mask; +extern int mips_picache_linesize; +extern int mips_pdcache_linesize; #define __mco_noargs(prefix, x) \ do { \ diff --git a/sys/mips/mips/cache_mipsNN.c b/sys/mips/mips/cache_mipsNN.c index 93556aa0a8f..822079b9423 100644 --- a/sys/mips/mips/cache_mipsNN.c +++ b/sys/mips/mips/cache_mipsNN.c @@ -65,6 +65,11 @@ __FBSDID("$FreeBSD$"); #define SYNCI #endif +/* + * Exported variables for consumers like bus_dma code + */ +int mips_picache_linesize; +int mips_pdcache_linesize; static int picache_size; static int picache_stride; @@ -107,10 +112,15 @@ mipsNN_cache_init(struct mips_cpuinfo * cpuinfo) pdcache_loopcount = (cpuinfo->l1.dc_nsets * cpuinfo->l1.dc_linesize / PAGE_SIZE) * cpuinfo->l1.dc_nways; } + + mips_picache_linesize = cpuinfo->l1.ic_linesize; + mips_pdcache_linesize = cpuinfo->l1.dc_linesize; + picache_size = cpuinfo->l1.ic_size; picache_way_mask = cpuinfo->l1.ic_nways - 1; pdcache_size = cpuinfo->l1.dc_size; pdcache_way_mask = cpuinfo->l1.dc_nways - 1; + #define CACHE_DEBUG #ifdef CACHE_DEBUG printf("Cache info:\n"); From 1453f4e1126a805e8db1a8c7b69e3b2e2d771ffd Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 28 Oct 2009 03:34:05 +0000 Subject: [PATCH 282/380] - Fix busdma sync: dcache invalidation operates on cache line aligned addresses and could modify areas of memory that share the same cache line at the beginning and at the ending of the buffer. In order to prevent a data loss we save these chunks in temporary buffer before invalidation and restore them afer it. Idea suggested by: cognet --- sys/mips/mips/busdma_machdep.c | 51 +++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/sys/mips/mips/busdma_machdep.c b/sys/mips/mips/busdma_machdep.c index d371cbdb026..94238a57148 100644 --- a/sys/mips/mips/busdma_machdep.c +++ b/sys/mips/mips/busdma_machdep.c @@ -1029,10 +1029,43 @@ _bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map) static void bus_dmamap_sync_buf(void *buf, int len, bus_dmasync_op_t op) { + char tmp_cl[mips_pdcache_linesize], tmp_clend[mips_pdcache_linesize]; + vm_offset_t buf_cl, buf_clend; + vm_size_t size_cl, size_clend; + int cache_linesize_mask = mips_pdcache_linesize - 1; + + /* + * dcache invalidation operates on cache line aligned addresses + * and could modify areas of memory that share the same cache line + * at the beginning and the ending of the buffer. In order to + * prevent a data loss we save these chunks in temporary buffer + * before invalidation and restore them afer it + */ + buf_cl = (vm_offset_t)buf & ~cache_linesize_mask; + size_cl = (vm_offset_t)buf & cache_linesize_mask; + buf_clend = (vm_offset_t)buf + len; + size_clend = (mips_pdcache_linesize - + (buf_clend & cache_linesize_mask)) & cache_linesize_mask; + switch (op) { case BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE: case BUS_DMASYNC_POSTREAD: + + /* + * Save buffers that might be modified by invalidation + */ + if (size_cl) + memcpy (tmp_cl, (void*)buf_cl, size_cl); + if (size_clend) + memcpy (tmp_clend, (void*)buf_clend, size_clend); mips_dcache_inv_range((vm_offset_t)buf, len); + /* + * Restore them + */ + if (size_cl) + memcpy ((void*)buf_cl, tmp_cl, size_cl); + if (size_clend) + memcpy ((void*)buf_clend, tmp_clend, size_clend); break; case BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE: @@ -1040,11 +1073,21 @@ bus_dmamap_sync_buf(void *buf, int len, bus_dmasync_op_t op) break; case BUS_DMASYNC_PREREAD: -#if 0 - mips_dcache_wbinv_range((vm_offset_t)buf, len); -#else + /* + * Save buffers that might be modified by invalidation + */ + if (size_cl) + memcpy (tmp_cl, (void *)buf_cl, size_cl); + if (size_clend) + memcpy (tmp_clend, (void *)buf_clend, size_clend); mips_dcache_inv_range((vm_offset_t)buf, len); -#endif + /* + * Restore them + */ + if (size_cl) + memcpy ((void *)buf_cl, tmp_cl, size_cl); + if (size_clend) + memcpy ((void *)buf_clend, tmp_clend, size_clend); break; case BUS_DMASYNC_PREWRITE: From 5919fef7acda53ab819414a61affd59fd0cded68 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 28 Oct 2009 17:03:20 +0000 Subject: [PATCH 283/380] Remove useless for statement. i isn't used after it. Remove needless braces. --- sys/mips/mips/pmap.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index bfdadb7d4cc..844f203a97c 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -291,9 +291,8 @@ pmap_bootstrap(void) /* Sort. */ again: for (i = 0; phys_avail[i + 1] != 0; i += 2) { - if (phys_avail[i + 1] >= MIPS_KSEG0_LARGEST_PHYS) { + if (phys_avail[i + 1] >= MIPS_KSEG0_LARGEST_PHYS) memory_larger_than_512meg++; - } if (i < 2) continue; if (phys_avail[i - 2] > phys_avail[i]) { @@ -414,9 +413,6 @@ again: for (i = 0, j = (virtual_avail >> SEGSHIFT); i < nkpt; i++, j++) kernel_segmap[j] = (pd_entry_t)(pgtab + (i * NPTEPG)); - for (i = 0; phys_avail[i + 2]; i += 2) - continue; - /* * The kernel's pmap is statically allocated so we don't have to use * pmap_create, which is unlikely to work correctly at this part of From ed7d70c2bb10788705b509edabc2dcc43589df4b Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 28 Oct 2009 21:25:22 +0000 Subject: [PATCH 284/380] Allow a scratch buffer to be set in order to be able to use setenv() while booting, before dynamic kenv is running. A few platforms implement their own scratch+sprintf handling to save data from the boot environment. --- sys/kern/kern_environment.c | 33 +++++++++++++++++++++++++++++++++ sys/sys/systm.h | 1 + 2 files changed, 34 insertions(+) diff --git a/sys/kern/kern_environment.c b/sys/kern/kern_environment.c index fc0039a56e5..73551f4b00d 100644 --- a/sys/kern/kern_environment.c +++ b/sys/kern/kern_environment.c @@ -60,6 +60,8 @@ static MALLOC_DEFINE(M_KENV, "kenv", "kernel environment"); /* pointer to the static environment */ char *kern_envp; +static int env_len; +static int env_pos; static char *kernenv_next(char *); /* dynamic environment variables */ @@ -208,6 +210,14 @@ done: return (error); } +void +init_static_kenv(char *buf, size_t len) +{ + kern_envp = buf; + env_len = len; + env_pos = 0; +} + /* * Setup the dynamic kernel environment. */ @@ -336,6 +346,26 @@ testenv(const char *name) return (0); } +static int +setenv_static(const char *name, const char *value) +{ + int len; + + if (env_pos >= env_len) + return (-1); + + /* Check space for x=y and two nuls */ + len = strlen(name) + strlen(value); + if (len + 3 < env_len - env_pos) { + len = sprintf(&kern_envp[env_pos], "%s=%s", name, value); + env_pos += len+1; + kern_envp[env_pos] = '\0'; + return (0); + } else + return (-1); + +} + /* * Set an environment variable by name. */ @@ -345,6 +375,9 @@ setenv(const char *name, const char *value) char *buf, *cp, *oldenv; int namelen, vallen, i; + if (dynamic_kenv == 0 && env_len > 0) + return (setenv_static(name, value)); + KENV_CHECK; namelen = strlen(name) + 1; diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 397976fd564..75e89aeab06 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -164,6 +164,7 @@ void critical_exit(void); void init_param1(void); void init_param2(long physpages); void init_param3(long kmempages); +void init_static_kenv(char *, size_t); void tablefull(const char *); int kvprintf(char const *, void (*)(int, void*), void *, int, __va_list) __printflike(1, 0); From 3c2330f2e42fb0b10f2a66980c55672162cb9cbf Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 28 Oct 2009 21:27:56 +0000 Subject: [PATCH 285/380] Parse and save the command line passed in from RedBoot (exec -c "xxx") and also the board specific environment variables. This is not ar71xx specific and should be shared better. --- sys/mips/atheros/ar71xx_machdep.c | 46 +++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/sys/mips/atheros/ar71xx_machdep.c b/sys/mips/atheros/ar71xx_machdep.c index 6ca395a3a71..a4139c30af1 100644 --- a/sys/mips/atheros/ar71xx_machdep.c +++ b/sys/mips/atheros/ar71xx_machdep.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -59,6 +60,42 @@ __FBSDID("$FreeBSD$"); extern int *edata; extern int *end; uint32_t ar711_base_mac[ETHER_ADDR_LEN]; +/* 4KB static data aread to keep a copy of the bootload env until + the dynamic kenv is setup */ +char boot1_env[4096]; + +/* + * We get a string in from Redboot with the all the arguments together, + * "foo=bar bar=baz". Split them up and save in kenv. + */ +static void +parse_argv(char *str) +{ + char *n, *v; + + while ((v = strsep(&str, " ")) != NULL) { + if (*v == '\0') + continue; + if (*v == '-') { + while (*v != '\0') { + v++; + switch (*v) { + case 'a': boothowto |= RB_ASKNAME; break; + case 'd': boothowto |= RB_KDB; break; + case 'g': boothowto |= RB_GDB; break; + case 's': boothowto |= RB_SINGLE; break; + case 'v': boothowto |= RB_VERBOSE; break; + } + } + } else { + n = strsep(&v, "="); + if (v == NULL) + setenv(n, "1"); + else + setenv(n, v); + } + } +} void platform_halt(void) @@ -154,6 +191,7 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, platform_counter_freq = ar71xx_cpu_freq(); mips_timer_init_params(platform_counter_freq, 1); cninit(); + init_static_kenv(boot1_env, sizeof(boot1_env)); printf("platform frequency: %lld\n", platform_counter_freq); printf("arguments: \n"); @@ -164,8 +202,10 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, printf("Cmd line:"); if (MIPS_IS_VALID_PTR(argv)) { - for (i = 0; i < argc; i++) + for (i = 0; i < argc; i++) { printf(" %s", argv[i]); + parse_argv(argv[i]); + } } else printf ("argv is invalid"); @@ -173,8 +213,10 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, printf("Environment:\n"); if (MIPS_IS_VALID_PTR(envp)) { - for (i = 0; envp[i]; i+=2) + for (i = 0; envp[i]; i+=2) { printf(" %s = %s\n", envp[i], envp[i+1]); + setenv(envp[i], envp[i+1]); + } } else printf ("envp is invalid\n"); From d1c3ac3a7ae487046bbcb23dc6b7164b6fd86b7c Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 28 Oct 2009 21:36:46 +0000 Subject: [PATCH 286/380] Use init_static_kenv() and setenv() to simplify the environment string handling. --- sys/mips/rmi/xlr_machdep.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/sys/mips/rmi/xlr_machdep.c b/sys/mips/rmi/xlr_machdep.c index f28bdaa63cb..c6d89b0b0ad 100644 --- a/sys/mips/rmi/xlr_machdep.c +++ b/sys/mips/rmi/xlr_machdep.c @@ -331,7 +331,7 @@ void platform_start() { vm_size_t physsz = 0; - int i, j; + int i; struct xlr_boot1_mem_map *boot_map; #ifdef SMP uint32_t tmp; @@ -358,23 +358,21 @@ platform_start() /* clockrate used by delay, so initialize it here */ hw_clockrate = xlr_boot1_info.cpu_frequency/1000000 ; cninit(); + init_static_kenv(boot1_env, sizeof(boot1_env)); printf("Environment (from %d args):\n", xlr_argc-1); if (xlr_argc == 1) printf("\tNone\n"); - for(i=1,j=0; i sizeof(boot1_env)) { - printf("*** Environment could not be copied in full\n"); - break; - } - + for(i=1; i Date: Wed, 28 Oct 2009 21:39:33 +0000 Subject: [PATCH 287/380] Fix build from r198563 --- sys/mips/rmi/xlr_machdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/rmi/xlr_machdep.c b/sys/mips/rmi/xlr_machdep.c index c6d89b0b0ad..89d4c24ea59 100644 --- a/sys/mips/rmi/xlr_machdep.c +++ b/sys/mips/rmi/xlr_machdep.c @@ -368,7 +368,7 @@ platform_start() printf("\t%s\n", xlr_argv[i]); n = strsep(&xlr_argv[i], "="); - if (v == NULL) + if (xlr_argv[i] == NULL) setenv(n, "1"); else setenv(n, xlr_argv[i]); From 64ec125306be8379d709f39dea2bfc77026f1f2a Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 28 Oct 2009 21:41:23 +0000 Subject: [PATCH 288/380] Fix build from r198563 (again). Sigh. --- sys/mips/rmi/xlr_machdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/rmi/xlr_machdep.c b/sys/mips/rmi/xlr_machdep.c index 89d4c24ea59..84bdb64a6d9 100644 --- a/sys/mips/rmi/xlr_machdep.c +++ b/sys/mips/rmi/xlr_machdep.c @@ -331,7 +331,7 @@ void platform_start() { vm_size_t physsz = 0; - int i; + int i, j; struct xlr_boot1_mem_map *boot_map; #ifdef SMP uint32_t tmp; From 131ec9efd8004ca4ea139c3f556c0e8ce3226c5d Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Thu, 29 Oct 2009 05:18:02 +0000 Subject: [PATCH 289/380] Deal with overflow of the COUNT register correctly. The 'cycles_per_hz' has nothing to do with the rollover. Approved by: imp (mentor) --- sys/mips/mips/tick.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/mips/mips/tick.c b/sys/mips/mips/tick.c index d767950c24e..42f34a7e9ba 100644 --- a/sys/mips/mips/tick.c +++ b/sys/mips/mips/tick.c @@ -223,9 +223,9 @@ DELAY(int n) /* Check to see if the timer has wrapped around. */ if (cur < last) - delta += (cur + (cycles_per_hz - last)); + delta += cur + (0xffffffff - last) + 1; else - delta += (cur - last); + delta += cur - last; last = cur; From 6e3272ee6f95f47c23efd8a0719b7b2e144035f1 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Thu, 29 Oct 2009 15:55:25 +0000 Subject: [PATCH 290/380] more Updates on the RMI code close to compiling now ;-) --- sys/mips/rmi/board.c | 7 +- sys/mips/rmi/clock.c | 225 +++++++++++++++++------ sys/mips/rmi/clock.h | 2 +- sys/mips/rmi/ehcireg.h | 301 +++++++++++++++++++++++++++++++ sys/mips/rmi/ehcivar.h | 191 ++++++++++++++++++++ sys/mips/rmi/files.xlr | 9 +- sys/mips/rmi/intr_machdep.c | 28 +-- sys/mips/rmi/iodi.c | 67 ++++--- sys/mips/rmi/msgring.c | 2 +- sys/mips/rmi/msgring.h | 2 +- sys/mips/rmi/msgring_xls.c | 2 +- sys/mips/rmi/on_chip.c | 18 +- sys/mips/rmi/pcibus.c | 105 +++++++---- sys/mips/rmi/pcibus.h | 9 + sys/mips/rmi/perfmon.h | 2 +- sys/mips/rmi/perfmon_kern.c | 6 +- sys/mips/rmi/perfmon_percpu.c | 12 +- sys/mips/rmi/perfmon_xlrconfig.h | 2 +- sys/mips/rmi/pic.h | 2 +- sys/mips/rmi/std.xlr | 4 +- sys/mips/rmi/tick.c | 113 ++++++++++++ sys/mips/rmi/uart_cpu_mips_xlr.c | 17 +- sys/mips/rmi/xlr_boot1_console.c | 6 +- sys/mips/rmi/xlr_i2c.c | 2 +- sys/mips/rmi/xlr_machdep.c | 136 +++++++++----- sys/mips/rmi/xlr_pci.c | 14 +- sys/mips/rmi/xlrconfig.h | 4 +- sys/mips/rmi/xls_ehci.c | 9 +- 28 files changed, 1064 insertions(+), 233 deletions(-) create mode 100644 sys/mips/rmi/ehcireg.h create mode 100644 sys/mips/rmi/ehcivar.h create mode 100644 sys/mips/rmi/tick.c diff --git a/sys/mips/rmi/board.c b/sys/mips/rmi/board.c index 73d783d5184..e50101eb968 100644 --- a/sys/mips/rmi/board.c +++ b/sys/mips/rmi/board.c @@ -35,9 +35,10 @@ #include #include -#include -#include -#include +#include +#include +#include +#include static int xlr_rxstn_to_txstn_map[128] = { [0 ... 7] = TX_STN_CPU_0, diff --git a/sys/mips/rmi/clock.c b/sys/mips/rmi/clock.c index 44ba886c2f3..2e5e0486b94 100644 --- a/sys/mips/rmi/clock.c +++ b/sys/mips/rmi/clock.c @@ -53,19 +53,24 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #ifdef XLR_PERFMON -#include +#include #endif -int hw_clockrate; -SYSCTL_INT(_hw, OID_AUTO, clockrate, CTLFLAG_RD, &hw_clockrate, - 0, "CPU instruction clock rate"); +uint64_t counter_freq; +uint64_t cycles_per_tick; +uint64_t cycles_per_usec; +uint64_t cycles_per_sec; +uint64_t cycles_per_hz; + +u_int32_t counter_upper = 0; +u_int32_t counter_lower_last = 0; #define STAT_PROF_CLOCK_SCALE_FACTOR 8 @@ -77,6 +82,15 @@ uint64_t platform_get_frequency() return XLR_PIC_HZ; } +void +mips_timer_early_init(uint64_t clock_hz) +{ + /* Initialize clock early so that we can use DELAY sooner */ + counter_freq = clock_hz; + cycles_per_usec = (clock_hz / (1000 * 1000)); + +} + /* * count_compare_clockhandler: * @@ -100,11 +114,11 @@ count_compare_clockhandler(struct trapframe *tf) cycles += XLR_CPU_HZ/hz; mips_wr_compare(cycles); - hardclock_process((struct clockframe *)tf); + hardclock_cpu(USERMODE(tf->sr)); if (count_scale_factor[cpu] == STAT_PROF_CLOCK_SCALE_FACTOR) { - statclock((struct clockframe *)tf); + statclock(USERMODE(tf->sr)); if(profprocs != 0) { - profclock((struct clockframe *)tf); + profclock(USERMODE(tf->sr), tf->pc); } count_scale_factor[cpu] = 0; } @@ -124,11 +138,11 @@ pic_hardclockhandler(struct trapframe *tf) if (cpu == 0) { scale_factor++; - hardclock((struct clockframe *)tf); + hardclock(USERMODE(tf->sr), tf->pc); if (scale_factor == STAT_PROF_CLOCK_SCALE_FACTOR) { - statclock((struct clockframe *)tf); + statclock(USERMODE(tf->sr)); if(profprocs != 0) { - profclock((struct clockframe *)tf); + profclock(USERMODE(tf->sr), tf->pc); } scale_factor = 0; } @@ -141,73 +155,164 @@ pic_hardclockhandler(struct trapframe *tf) else { /* If needed , handle count compare tick skew here */ } - critical_exit(); } -void +int pic_timecounthandler(struct trapframe *tf) { + return (FILTER_HANDLED); } void platform_initclocks(void) { - int cpu = PCPU_GET(cpuid); - void *cookie; + int cpu = PCPU_GET(cpuid); + void *cookie; - /* Note: Passing #3 as NULL ensures that clockhandler - * gets called with trapframe - */ - /* profiling/process accounting timer interrupt for non-zero cpus */ - cpu_establish_intr("compare", IRQ_TIMER, - (driver_intr_t *)count_compare_clockhandler, - NULL, INTR_TYPE_CLK|INTR_FAST, &cookie, NULL, NULL); + /* Note: Passing #3 as NULL ensures that clockhandler + * gets called with trapframe + */ + /* profiling/process accounting timer interrupt for non-zero cpus */ + cpu_establish_hardintr("compare", + NULL, + (driver_intr_t *)count_compare_clockhandler, + NULL, + IRQ_TIMER, + INTR_TYPE_CLK|INTR_FAST, &cookie); - /* timekeeping timer interrupt for cpu 0 */ - cpu_establish_intr("hardclk", PIC_TIMER_7_IRQ, - (driver_intr_t *)pic_hardclockhandler, - NULL, INTR_TYPE_CLK|INTR_FAST, &cookie, NULL, NULL); + /* timekeeping timer interrupt for cpu 0 */ + cpu_establish_hardintr("hardclk", + NULL, + (driver_intr_t *)pic_hardclockhandler, + NULL, + PIC_TIMER_7_IRQ, + INTR_TYPE_CLK|INTR_FAST, + &cookie); - /* this is used by timecounter */ - cpu_establish_intr("timecount", PIC_TIMER_6_IRQ, - (driver_intr_t *)pic_timecounthandler, - NULL, INTR_TYPE_CLK|INTR_FAST, &cookie, NULL, NULL); + /* this is used by timecounter */ + cpu_establish_hardintr("timecount", + (driver_filter_t *)pic_timecounthandler, NULL, + NULL, PIC_TIMER_6_IRQ, INTR_TYPE_CLK|INTR_FAST, + &cookie); + + if (cpu == 0) { + __uint64_t maxval = XLR_PIC_HZ/hz; + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); - if (cpu == 0) { - __uint64_t maxval = XLR_PIC_HZ/hz; - xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + stathz = hz / STAT_PROF_CLOCK_SCALE_FACTOR; + profhz = stathz; - stathz = hz / STAT_PROF_CLOCK_SCALE_FACTOR; - profhz = stathz; + /* Setup PIC Interrupt */ - /* Setup PIC Interrupt */ + mtx_lock_spin(&xlr_pic_lock); + xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_0, (maxval & 0xffffffff)); /* 0x100 + 7*/ + xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_1, (maxval >> 32) & 0xffffffff);/* 0x110 + 7 */ + /* 0x40 + 8 */ + /* reg 40 is lower bits 31-0 and holds CPU mask */ + xlr_write_reg(mmio, PIC_IRT_0_TIMER_7, (1 << cpu)); + /* 0x80 + 8 */ + /* Reg 80 is upper bits 63-32 and holds */ + /* Valid Edge Local IRQ */ + xlr_write_reg(mmio, PIC_IRT_1_TIMER_7, (1<<31)|(0<<30)|(1<<6)|(PIC_TIMER_7_IRQ)); + pic_update_control(1<<(8+7)); - mtx_lock_spin(&xlr_pic_lock); - xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_0, (maxval & 0xffffffff)); - xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_1, (maxval >> 32) & 0xffffffff); - xlr_write_reg(mmio, PIC_IRT_0_TIMER_7, (1 << cpu)); - xlr_write_reg(mmio, PIC_IRT_1_TIMER_7, (1<<31)|(0<<30)|(1<<6)|(PIC_TIMER_7_IRQ)); - pic_update_control(1<<(8+7)); - - xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_0, (0xffffffff & 0xffffffff)); - xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_1, (0x0) & 0xffffffff); - xlr_write_reg(mmio, PIC_IRT_0_TIMER_6, (1 << cpu)); - xlr_write_reg(mmio, PIC_IRT_1_TIMER_6, (1<<31)|(0<<30)|(1<<6)|(PIC_TIMER_6_IRQ)); - pic_update_control(1<<(8+6)); - mtx_unlock_spin(&xlr_pic_lock); - } else { - /* Setup count-compare interrupt for vcpu[1-31] */ - mips_wr_compare((xlr_boot1_info.cpu_frequency)/hz); - } + xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_0, (0xffffffff & 0xffffffff)); + xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_1, (0xffffffff & 0xffffffff)); + xlr_write_reg(mmio, PIC_IRT_0_TIMER_6, (1 << cpu)); + xlr_write_reg(mmio, PIC_IRT_1_TIMER_6, (1<<31)|(0<<30)|(1<<6)|(PIC_TIMER_6_IRQ)); + pic_update_control(1<<(8+6)); + mtx_unlock_spin(&xlr_pic_lock); + } else { + /* Setup count-compare interrupt for vcpu[1-31] */ + mips_wr_compare((xlr_boot1_info.cpu_frequency)/hz); + } } - - unsigned __attribute__((no_instrument_function)) -platform_get_timecount(struct timecounter *tc) +platform_get_timecount(struct timecounter *tc __unused) { xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); return 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_0); } + +void +DELAY(int n) +{ + uint32_t cur, last, delta, usecs; + + /* + * This works by polling the timer and counting the number of + * microseconds that go by. + */ + last = platform_get_timecount(NULL); + delta = usecs = 0; + + while (n > usecs) { + cur = platform_get_timecount(NULL); + + /* Check to see if the timer has wrapped around. */ + if (cur < last) + delta += (cur + (cycles_per_hz - last)); + else + delta += (cur - last); + + last = cur; + + if (delta >= cycles_per_usec) { + usecs += delta / cycles_per_usec; + delta %= cycles_per_usec; + } + } +} + +static +uint64_t read_pic_counter(void) +{ + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + uint32_t lower, upper; + uint64_t tc; + /* Pull the value of the 64 bit counter which is stored in + * PIC register 120+N and 130+N + */ + upper = 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_1); + lower = 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_0); + tc = (((uint64_t)upper << 32) | (uint64_t)lower); + return(tc); +} + +extern struct timecounter counter_timecounter; + +void +mips_timer_init_params(uint64_t platform_counter_freq, int double_count) +{ + + /* + * XXX: Do not use printf here: uart code 8250 may use DELAY so this + * function should be called before cninit. + */ + counter_freq = platform_counter_freq; + /* + * XXX: Some MIPS32 cores update the Count register only every two + * pipeline cycles. + */ + if (double_count != 0) + counter_freq /= 2; + + cycles_per_tick = counter_freq / 1000; + cycles_per_hz = counter_freq / hz; + cycles_per_usec = counter_freq / (1 * 1000 * 1000); + cycles_per_sec = counter_freq ; + + counter_timecounter.tc_frequency = counter_freq; + printf("hz=%d cyl_per_hz:%jd cyl_per_usec:%jd freq:%jd cyl_per_hz:%jd cyl_per_sec:%jd\n", + hz, + cycles_per_tick, + cycles_per_usec, + counter_freq, + cycles_per_hz, + cycles_per_sec + ); + set_cputicker(read_pic_counter, counter_freq, 1); +} diff --git a/sys/mips/rmi/clock.h b/sys/mips/rmi/clock.h index c582de529fa..750c3dae127 100644 --- a/sys/mips/rmi/clock.h +++ b/sys/mips/rmi/clock.h @@ -35,6 +35,6 @@ void count_compare_clockhandler(struct trapframe *); void pic_hardclockhandler(struct trapframe *); -void pic_timecounthandler(struct trapframe *); +int pic_timecounthandler(struct trapframe *); #endif /* _RMI_CLOCK_H_ */ diff --git a/sys/mips/rmi/ehcireg.h b/sys/mips/rmi/ehcireg.h new file mode 100644 index 00000000000..e1e7dc3a19e --- /dev/null +++ b/sys/mips/rmi/ehcireg.h @@ -0,0 +1,301 @@ +/* $NetBSD: ehcireg.h,v 1.18 2004/10/22 10:38:17 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/ehcireg.h,v 1.7.2.2.2.1 2008/10/02 02:57:24 kensmith Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Lennart Augustsson (lennart@augustsson.net). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * The EHCI 0.96 spec can be found at + * http://developer.intel.com/technology/usb/download/ehci-r096.pdf + * and the USB 2.0 spec at + * http://www.usb.org/developers/data/usb_20.zip + */ + +#ifndef _DEV_PCI_EHCIREG_H_ +#define _DEV_PCI_EHCIREG_H_ + +/*** PCI config registers ***/ + +#define PCI_CBMEM 0x10 /* configuration base MEM */ + +#define PCI_INTERFACE_EHCI 0x20 + +#define PCI_USBREV 0x60 /* RO USB protocol revision */ +#define PCI_USBREV_MASK 0xff +#define PCI_USBREV_PRE_1_0 0x00 +#define PCI_USBREV_1_0 0x10 +#define PCI_USBREV_1_1 0x11 +#define PCI_USBREV_2_0 0x20 + +#define PCI_EHCI_FLADJ 0x61 /*RW Frame len adj, SOF=59488+6*fladj */ + +#define PCI_EHCI_PORTWAKECAP 0x62 /* RW Port wake caps (opt) */ + +/* EHCI Extended Capabilities */ +#define EHCI_EC_LEGSUP 0x01 + +#define EHCI_EECP_NEXT(x) (((x) >> 8) & 0xff) +#define EHCI_EECP_ID(x) ((x) & 0xff) + +/* Legacy support extended capability */ +#define EHCI_LEGSUP_OS_SEM 0x03 /* OS owned semaphore */ +#define EHCI_LEGSUP_BIOS_SEM 0x02 /* BIOS owned semaphore */ +#define EHCI_LEGSUP_USBLEGCTLSTS 0x04 + +/*** EHCI capability registers ***/ + +#define EHCI_CAPLENGTH 0x00 /*RO Capability register length field */ +/* reserved 0x01 */ +#define EHCI_HCIVERSION 0x02 /* RO Interface version number */ + +#define EHCI_HCSPARAMS 0x04 /* RO Structural parameters */ +#define EHCI_HCS_DEBUGPORT(x) (((x) >> 20) & 0xf) +#define EHCI_HCS_P_INDICATOR(x) ((x) & 0x10000) +#define EHCI_HCS_N_CC(x) (((x) >> 12) & 0xf) /* # of companion ctlrs */ +#define EHCI_HCS_N_PCC(x) (((x) >> 8) & 0xf) /* # of ports per comp. */ +#define EHCI_HCS_PPC(x) ((x) & 0x10) /* port power control */ +#define EHCI_HCS_N_PORTS(x) ((x) & 0xf) /* # of ports */ + +#define EHCI_HCCPARAMS 0x08 /* RO Capability parameters */ +#define EHCI_HCC_EECP(x) (((x) >> 8) & 0xff) /* extended ports caps */ +#define EHCI_HCC_IST(x) (((x) >> 4) & 0xf) /* isoc sched threshold */ +#define EHCI_HCC_ASPC(x) ((x) & 0x4) /* async sched park cap */ +#define EHCI_HCC_PFLF(x) ((x) & 0x2) /* prog frame list flag */ +#define EHCI_HCC_64BIT(x) ((x) & 0x1) /* 64 bit address cap */ + +#define EHCI_HCSP_PORTROUTE 0x0c /*RO Companion port route description */ + +/* EHCI operational registers. Offset given by EHCI_CAPLENGTH register */ +#define EHCI_USBCMD 0x00 /* RO, RW, WO Command register */ +#define EHCI_CMD_ITC_M 0x00ff0000 /* RW interrupt threshold ctrl */ +#define EHCI_CMD_ITC_1 0x00010000 +#define EHCI_CMD_ITC_2 0x00020000 +#define EHCI_CMD_ITC_4 0x00040000 +#define EHCI_CMD_ITC_8 0x00080000 +#define EHCI_CMD_ITC_16 0x00100000 +#define EHCI_CMD_ITC_32 0x00200000 +#define EHCI_CMD_ITC_64 0x00400000 +#define EHCI_CMD_ASPME 0x00000800 /* RW/RO async park enable */ +#define EHCI_CMD_ASPMC 0x00000300 /* RW/RO async park count */ +#define EHCI_CMD_LHCR 0x00000080 /* RW light host ctrl reset */ +#define EHCI_CMD_IAAD 0x00000040 /* RW intr on async adv door bell */ +#define EHCI_CMD_ASE 0x00000020 /* RW async sched enable */ +#define EHCI_CMD_PSE 0x00000010 /* RW periodic sched enable */ +#define EHCI_CMD_FLS_M 0x0000000c /* RW/RO frame list size */ +#define EHCI_CMD_FLS(x) (((x) >> 2) & 3) /* RW/RO frame list size */ +#define EHCI_CMD_HCRESET 0x00000002 /* RW reset */ +#define EHCI_CMD_RS 0x00000001 /* RW run/stop */ + +#define EHCI_USBSTS 0x04 /* RO, RW, RWC Status register */ +#define EHCI_STS_ASS 0x00008000 /* RO async sched status */ +#define EHCI_STS_PSS 0x00004000 /* RO periodic sched status */ +#define EHCI_STS_REC 0x00002000 /* RO reclamation */ +#define EHCI_STS_HCH 0x00001000 /* RO host controller halted */ +#define EHCI_STS_IAA 0x00000020 /* RWC interrupt on async adv */ +#define EHCI_STS_HSE 0x00000010 /* RWC host system error */ +#define EHCI_STS_FLR 0x00000008 /* RWC frame list rollover */ +#define EHCI_STS_PCD 0x00000004 /* RWC port change detect */ +#define EHCI_STS_ERRINT 0x00000002 /* RWC error interrupt */ +#define EHCI_STS_INT 0x00000001 /* RWC interrupt */ +#define EHCI_STS_INTRS(x) ((x) & 0x3f) + +#define EHCI_NORMAL_INTRS (EHCI_STS_IAA | EHCI_STS_HSE | EHCI_STS_PCD | EHCI_STS_ERRINT | EHCI_STS_INT) + +#define EHCI_USBINTR 0x08 /* RW Interrupt register */ +#define EHCI_INTR_IAAE 0x00000020 /* interrupt on async advance ena */ +#define EHCI_INTR_HSEE 0x00000010 /* host system error ena */ +#define EHCI_INTR_FLRE 0x00000008 /* frame list rollover ena */ +#define EHCI_INTR_PCIE 0x00000004 /* port change ena */ +#define EHCI_INTR_UEIE 0x00000002 /* USB error intr ena */ +#define EHCI_INTR_UIE 0x00000001 /* USB intr ena */ + +#define EHCI_FRINDEX 0x0c /* RW Frame Index register */ + +#define EHCI_CTRLDSSEGMENT 0x10 /* RW Control Data Structure Segment */ + +#define EHCI_PERIODICLISTBASE 0x14 /* RW Periodic List Base */ +#define EHCI_ASYNCLISTADDR 0x18 /* RW Async List Base */ + +#define EHCI_CONFIGFLAG 0x40 /* RW Configure Flag register */ +#define EHCI_CONF_CF 0x00000001 /* RW configure flag */ + +#define EHCI_PORTSC(n) (0x40+4*(n)) /* RO, RW, RWC Port Status reg */ +#define EHCI_PS_WKOC_E 0x00400000 /* RW wake on over current ena */ +#define EHCI_PS_WKDSCNNT_E 0x00200000 /* RW wake on disconnect ena */ +#define EHCI_PS_WKCNNT_E 0x00100000 /* RW wake on connect ena */ +#define EHCI_PS_PTC 0x000f0000 /* RW port test control */ +#define EHCI_PS_PIC 0x0000c000 /* RW port indicator control */ +#define EHCI_PS_PO 0x00002000 /* RW port owner */ +#define EHCI_PS_PP 0x00001000 /* RW,RO port power */ +#define EHCI_PS_LS 0x00000c00 /* RO line status */ +#define EHCI_PS_IS_LOWSPEED(x) (((x) & EHCI_PS_LS) == 0x00000400) +#define EHCI_PS_PR 0x00000100 /* RW port reset */ +#define EHCI_PS_SUSP 0x00000080 /* RW suspend */ +#define EHCI_PS_FPR 0x00000040 /* RW force port resume */ +#define EHCI_PS_OCC 0x00000020 /* RWC over current change */ +#define EHCI_PS_OCA 0x00000010 /* RO over current active */ +#define EHCI_PS_PEC 0x00000008 /* RWC port enable change */ +#define EHCI_PS_PE 0x00000004 /* RW port enable */ +#define EHCI_PS_CSC 0x00000002 /* RWC connect status change */ +#define EHCI_PS_CS 0x00000001 /* RO connect status */ +#define EHCI_PS_CLEAR (EHCI_PS_OCC|EHCI_PS_PEC|EHCI_PS_CSC) + +#define EHCI_PORT_RESET_COMPLETE 2 /* ms */ + +#define EHCI_FLALIGN_ALIGN 0x1000 + +/* No data structure may cross a page boundary. */ +#define EHCI_PAGE_SIZE 0x1000 +#define EHCI_PAGE(x) ((x) &~ 0xfff) +#define EHCI_PAGE_OFFSET(x) ((x) & 0xfff) +#if defined(__FreeBSD__) +#define EHCI_PAGE_MASK(x) ((x) & 0xfff) +#endif + +typedef u_int32_t ehci_link_t; +#define EHCI_LINK_TERMINATE 0x00000001 +#define EHCI_LINK_TYPE(x) ((x) & 0x00000006) +#define EHCI_LINK_ITD 0x0 +#define EHCI_LINK_QH 0x2 +#define EHCI_LINK_SITD 0x4 +#define EHCI_LINK_FSTN 0x6 +#define EHCI_LINK_ADDR(x) ((x) &~ 0x1f) + +typedef u_int32_t ehci_physaddr_t; + +/* Isochronous Transfer Descriptor */ +typedef struct { + ehci_link_t itd_next; + /* XXX many more */ +} ehci_itd_t; +#define EHCI_ITD_ALIGN 32 + +/* Split Transaction Isochronous Transfer Descriptor */ +typedef struct { + ehci_link_t sitd_next; + /* XXX many more */ +} ehci_sitd_t; +#define EHCI_SITD_ALIGN 32 + +/* Queue Element Transfer Descriptor */ +#define EHCI_QTD_NBUFFERS 5 +typedef struct { + ehci_link_t qtd_next; + ehci_link_t qtd_altnext; + u_int32_t qtd_status; +#define EHCI_QTD_GET_STATUS(x) (((x) >> 0) & 0xff) +#define EHCI_QTD_SET_STATUS(x) ((x) << 0) +#define EHCI_QTD_ACTIVE 0x80 +#define EHCI_QTD_HALTED 0x40 +#define EHCI_QTD_BUFERR 0x20 +#define EHCI_QTD_BABBLE 0x10 +#define EHCI_QTD_XACTERR 0x08 +#define EHCI_QTD_MISSEDMICRO 0x04 +#define EHCI_QTD_SPLITXSTATE 0x02 +#define EHCI_QTD_PINGSTATE 0x01 +#define EHCI_QTD_STATERRS 0x7c +#define EHCI_QTD_GET_PID(x) (((x) >> 8) & 0x3) +#define EHCI_QTD_SET_PID(x) ((x) << 8) +#define EHCI_QTD_PID_OUT 0x0 +#define EHCI_QTD_PID_IN 0x1 +#define EHCI_QTD_PID_SETUP 0x2 +#define EHCI_QTD_GET_CERR(x) (((x) >> 10) & 0x3) +#define EHCI_QTD_SET_CERR(x) ((x) << 10) +#define EHCI_QTD_GET_C_PAGE(x) (((x) >> 12) & 0x7) +#define EHCI_QTD_SET_C_PAGE(x) ((x) << 12) +#define EHCI_QTD_GET_IOC(x) (((x) >> 15) & 0x1) +#define EHCI_QTD_IOC 0x00008000 +#define EHCI_QTD_GET_BYTES(x) (((x) >> 16) & 0x7fff) +#define EHCI_QTD_SET_BYTES(x) ((x) << 16) +#define EHCI_QTD_GET_TOGGLE(x) (((x) >> 31) & 0x1) +#define EHCI_QTD_SET_TOGGLE(x) ((x) << 31) +#define EHCI_QTD_TOGGLE_MASK 0x80000000 + ehci_physaddr_t qtd_buffer[EHCI_QTD_NBUFFERS]; + ehci_physaddr_t qtd_buffer_hi[EHCI_QTD_NBUFFERS]; +} ehci_qtd_t; +#define EHCI_QTD_ALIGN 32 + +/* Queue Head */ +typedef struct { + ehci_link_t qh_link; + u_int32_t qh_endp; +#define EHCI_QH_GET_ADDR(x) (((x) >> 0) & 0x7f) /* endpoint addr */ +#define EHCI_QH_SET_ADDR(x) (x) +#define EHCI_QH_ADDRMASK 0x0000007f +#define EHCI_QH_GET_INACT(x) (((x) >> 7) & 0x01) /* inactivate on next */ +#define EHCI_QH_INACT 0x00000080 +#define EHCI_QH_GET_ENDPT(x) (((x) >> 8) & 0x0f) /* endpoint no */ +#define EHCI_QH_SET_ENDPT(x) ((x) << 8) +#define EHCI_QH_GET_EPS(x) (((x) >> 12) & 0x03) /* endpoint speed */ +#define EHCI_QH_SET_EPS(x) ((x) << 12) +#define EHCI_QH_SPEED_FULL 0x0 +#define EHCI_QH_SPEED_LOW 0x1 +#define EHCI_QH_SPEED_HIGH 0x2 +#define EHCI_QH_GET_DTC(x) (((x) >> 14) & 0x01) /* data toggle control */ +#define EHCI_QH_DTC 0x00004000 +#define EHCI_QH_GET_HRECL(x) (((x) >> 15) & 0x01) /* head of reclamation */ +#define EHCI_QH_HRECL 0x00008000 +#define EHCI_QH_GET_MPL(x) (((x) >> 16) & 0x7ff) /* max packet len */ +#define EHCI_QH_SET_MPL(x) ((x) << 16) +#define EHCI_QH_MPLMASK 0x07ff0000 +#define EHCI_QH_GET_CTL(x) (((x) >> 27) & 0x01) /* control endpoint */ +#define EHCI_QH_CTL 0x08000000 +#define EHCI_QH_GET_NRL(x) (((x) >> 28) & 0x0f) /* NAK reload */ +#define EHCI_QH_SET_NRL(x) ((x) << 28) + u_int32_t qh_endphub; +#define EHCI_QH_GET_SMASK(x) (((x) >> 0) & 0xff) /* intr sched mask */ +#define EHCI_QH_SET_SMASK(x) ((x) << 0) +#define EHCI_QH_GET_CMASK(x) (((x) >> 8) & 0xff) /* split completion mask */ +#define EHCI_QH_SET_CMASK(x) ((x) << 8) +#define EHCI_QH_GET_HUBA(x) (((x) >> 16) & 0x7f) /* hub address */ +#define EHCI_QH_SET_HUBA(x) ((x) << 16) +#define EHCI_QH_GET_PORT(x) (((x) >> 23) & 0x7f) /* hub port */ +#define EHCI_QH_SET_PORT(x) ((x) << 23) +#define EHCI_QH_GET_MULT(x) (((x) >> 30) & 0x03) /* pipe multiplier */ +#define EHCI_QH_SET_MULT(x) ((x) << 30) + ehci_link_t qh_curqtd; + ehci_qtd_t qh_qtd; +} ehci_qh_t; +#define EHCI_QH_ALIGN 32 + +/* Periodic Frame Span Traversal Node */ +typedef struct { + ehci_link_t fstn_link; + ehci_link_t fstn_back; +} ehci_fstn_t; +#define EHCI_FSTN_ALIGN 32 + +#endif /* _DEV_PCI_EHCIREG_H_ */ diff --git a/sys/mips/rmi/ehcivar.h b/sys/mips/rmi/ehcivar.h new file mode 100644 index 00000000000..eb318ad03c2 --- /dev/null +++ b/sys/mips/rmi/ehcivar.h @@ -0,0 +1,191 @@ +/* $NetBSD: ehcivar.h,v 1.19 2005/04/29 15:04:29 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/ehcivar.h,v 1.9.2.1.8.1 2008/10/02 02:57:24 kensmith Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Lennart Augustsson (lennart@augustsson.net). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +typedef struct ehci_soft_qtd { + ehci_qtd_t qtd; + struct ehci_soft_qtd *nextqtd; /* mirrors nextqtd in TD */ + ehci_physaddr_t physaddr; + usbd_xfer_handle xfer; + LIST_ENTRY(ehci_soft_qtd) hnext; + u_int16_t len; +} ehci_soft_qtd_t; +#define EHCI_SQTD_SIZE ((sizeof (struct ehci_soft_qtd) + EHCI_QTD_ALIGN - 1) / EHCI_QTD_ALIGN * EHCI_QTD_ALIGN) +#define EHCI_SQTD_CHUNK (EHCI_PAGE_SIZE / EHCI_SQTD_SIZE) + +typedef struct ehci_soft_qh { + ehci_qh_t qh; + struct ehci_soft_qh *next; + struct ehci_soft_qh *prev; + struct ehci_soft_qtd *sqtd; + ehci_physaddr_t physaddr; + int islot; /* Interrupt list slot. */ +} ehci_soft_qh_t; +#define EHCI_SQH_SIZE ((sizeof (struct ehci_soft_qh) + EHCI_QH_ALIGN - 1) / EHCI_QH_ALIGN * EHCI_QH_ALIGN) +#define EHCI_SQH_CHUNK (EHCI_PAGE_SIZE / EHCI_SQH_SIZE) + +struct ehci_xfer { + struct usbd_xfer xfer; + struct usb_task abort_task; + LIST_ENTRY(ehci_xfer) inext; /* list of active xfers */ + ehci_soft_qtd_t *sqtdstart; + ehci_soft_qtd_t *sqtdend; + u_int32_t ehci_xfer_flags; +#ifdef DIAGNOSTIC + int isdone; +#endif +}; +#define EHCI_XFER_ABORTING 0x0001 /* xfer is aborting. */ +#define EHCI_XFER_ABORTWAIT 0x0002 /* abort completion is being awaited. */ + +#define EXFER(xfer) ((struct ehci_xfer *)(xfer)) + +/* + * Information about an entry in the interrupt list. + */ +struct ehci_soft_islot { + ehci_soft_qh_t *sqh; /* Queue Head. */ +}; + +#define EHCI_FRAMELIST_MAXCOUNT 1024 +#define EHCI_IPOLLRATES 8 /* Poll rates (1ms, 2, 4, 8 ... 128) */ +#define EHCI_INTRQHS ((1 << EHCI_IPOLLRATES) - 1) +#define EHCI_MAX_POLLRATE (1 << (EHCI_IPOLLRATES - 1)) +#define EHCI_IQHIDX(lev, pos) \ + ((((pos) & ((1 << (lev)) - 1)) | (1 << (lev))) - 1) +#define EHCI_ILEV_IVAL(lev) (1 << (lev)) + +#define EHCI_HASH_SIZE 128 +#define EHCI_COMPANION_MAX 8 + +#define EHCI_SCFLG_DONEINIT 0x0001 /* ehci_init() has been called. */ +#define EHCI_SCFLG_LOSTINTRBUG 0x0002 /* workaround for VIA / ATI chipsets */ + +typedef struct ehci_softc { + struct usbd_bus sc_bus; /* base device */ + int sc_flags; + bus_space_tag_t iot; + bus_space_handle_t ioh; + bus_size_t sc_size; +#if defined(__FreeBSD__) + void *ih; + + struct resource *io_res; + struct resource *irq_res; +#endif + u_int sc_offs; /* offset to operational regs */ + + char sc_vendor[32]; /* vendor string for root hub */ + int sc_id_vendor; /* vendor ID for root hub */ + + u_int32_t sc_cmd; /* shadow of cmd reg during suspend */ +#if defined(__NetBSD__) || defined(__OpenBSD__) + void *sc_powerhook; /* cookie from power hook */ + void *sc_shutdownhook; /* cookie from shutdown hook */ +#endif + + u_int sc_ncomp; + u_int sc_npcomp; + struct usbd_bus *sc_comps[EHCI_COMPANION_MAX]; + + usb_dma_t sc_fldma; + ehci_link_t *sc_flist; + u_int sc_flsize; +#ifndef __FreeBSD__ + u_int sc_rand; /* XXX need proper intr scheduling */ +#endif + + struct ehci_soft_islot sc_islots[EHCI_INTRQHS]; + + LIST_HEAD(, ehci_xfer) sc_intrhead; + + ehci_soft_qh_t *sc_freeqhs; + ehci_soft_qtd_t *sc_freeqtds; + + int sc_noport; + u_int8_t sc_addr; /* device address */ + u_int8_t sc_conf; /* device configuration */ + usbd_xfer_handle sc_intrxfer; + char sc_isreset; +#ifdef USB_USE_SOFTINTR + char sc_softwake; +#endif /* USB_USE_SOFTINTR */ + + u_int32_t sc_eintrs; + ehci_soft_qh_t *sc_async_head; + + SIMPLEQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */ + + struct lock sc_doorbell_lock; + + usb_callout_t sc_tmo_pcd; + usb_callout_t sc_tmo_intrlist; + +#if defined(__NetBSD__) || defined(__OpenBSD__) + device_ptr_t sc_child; /* /dev/usb# device */ +#endif + char sc_dying; +#if defined(__NetBSD__) + struct usb_dma_reserve sc_dma_reserve; +#endif +} ehci_softc_t; + +#define EREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (a)) +#define EREAD2(sc, a) bus_space_read_2((sc)->iot, (sc)->ioh, (a)) +#define EREAD4(sc, a) bus_space_read_4((sc)->iot, (sc)->ioh, (a)) +#define EWRITE1(sc, a, x) bus_space_write_1((sc)->iot, (sc)->ioh, (a), (x)) +#define EWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (a), (x)) +#define EWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (a), (x)) +#define EOREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a)) +#define EOREAD2(sc, a) bus_space_read_2((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a)) +#define EOREAD4(sc, a) bus_space_read_4((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a)) +#define EOWRITE1(sc, a, x) bus_space_write_1((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x)) +#define EOWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x)) +#define EOWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x)) + +usbd_status ehci_init(ehci_softc_t *); +int ehci_intr(void *); +int ehci_detach(ehci_softc_t *, int); +#if defined(__NetBSD__) || defined(__OpenBSD__) +int ehci_activate(device_ptr_t, enum devact); +#endif +void ehci_power(int state, void *priv); +void ehci_shutdown(void *v); + +#define MS_TO_TICKS(ms) ((ms) * hz / 1000) + diff --git a/sys/mips/rmi/files.xlr b/sys/mips/rmi/files.xlr index 736e434ffb8..4cdd361c87f 100644 --- a/sys/mips/rmi/files.xlr +++ b/sys/mips/rmi/files.xlr @@ -1,13 +1,14 @@ # $FreeBSD$ -mips/rmi/xlr_boot1_console.c standard +#mips/rmi/xlr_boot1_console.c standard mips/rmi/xlr_machdep.c standard -#mips/rmi/clock.c standard +mips/rmi/clock.c standard +mips/rmi/tick.c standard mips/rmi/iodi.c standard mips/rmi/msgring.c standard mips/rmi/msgring_xls.c standard mips/rmi/board.c standard mips/rmi/on_chip.c standard -mips/rmip/intr_machdep.c standard +mips/rmi/intr_machdep.c standard mips/rmi/xlr_i2c.c optional iic mips/rmi/uart_bus_xlr_iodi.c optional uart mips/rmi/uart_cpu_mips_xlr.c optional uart @@ -15,7 +16,7 @@ mips/rmi/perfmon_kern.c optional xlr_perfmon mips/rmi/perfmon_percpu.c optional xlr_perfmon mips/rmi/pcibus.c optional pci mips/rmi/xlr_pci.c optional pci -mips/rmi/xls_ehci.c optional usb ehci +#mips/rmi/xls_ehci.c optional usb ehci dev/rmi/xlr/rge.c optional rge dev/iicbus/xlr_rtc.c optional xlr_rtc dev/iicbus/xlr_temperature.c optional xlr_temperature diff --git a/sys/mips/rmi/intr_machdep.c b/sys/mips/rmi/intr_machdep.c index 10539c4d617..3245ea7e2ac 100644 --- a/sys/mips/rmi/intr_machdep.c +++ b/sys/mips/rmi/intr_machdep.c @@ -44,7 +44,11 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include +#include +#include + +/*#include */ struct mips_intrhand mips_intr_handlers[XLR_MAX_INTR]; @@ -72,16 +76,16 @@ cpu_establish_hardintr(const char *name, driver_filter_t *filt, struct intr_event *ie; /* descriptor for the IRQ */ int errcode; - if (intr < 0 || intr > XLR_MAX_INTR) - panic("%s called for unknown hard intr %d", __func__, intr); + if (irq < 0 || irq > XLR_MAX_INTR) + panic("%s called for unknown hard intr %d", __func__, irq); /* FIXME locking - not needed now, because we do this only on startup from CPU0 */ mih = &mips_intr_handlers[irq]; - mih->cntp = &intrcnt[irq]; + /*mih->cntp = &intrcnt[irq]; */ ie = mih->mih_event; if (ie == NULL) { - errcode = intr_event_create(&event, (void *)(uintptr_t)irq, 0, + errcode = intr_event_create(&ie, (void *)(uintptr_t)irq, 0, irq, mips_mask_hard_irq, mips_unmask_hard_irq, NULL, NULL, "hard intr%d:", irq); @@ -90,7 +94,7 @@ cpu_establish_hardintr(const char *name, driver_filter_t *filt, return; } } - intr_event_add_handler(event, name, filt, handler, arg, + intr_event_add_handler(ie, name, filt, handler, arg, intr_priority(flags), flags, cookiep); mih->mih_event = ie; mips_unmask_hard_irq((void*)(uintptr_t)irq); @@ -103,17 +107,18 @@ cpu_establish_softintr(const char *name, driver_filter_t *filt, void **cookiep) { /* we don't separate them into soft/hard like other mips */ - cpu_establish_hardintr(name, filt, handler, arg, intr, flags, cookiep); + cpu_establish_hardintr(name, filt, handler, arg, irq, flags, cookiep); } + + void cpu_intr(struct trapframe *tf) { struct mips_intrhand *mih; - struct intr_handler *ih; struct intr_event *ie; register_t eirr; - int i, thread, error; + int i; critical_enter(); eirr = read_c0_eirr64(); @@ -156,7 +161,7 @@ cpu_intr(struct trapframe *tf) #endif #endif mih = &mips_intr_handlers[i]; - atomic_add_long(mih->cntp, 1); + /*atomic_add_long(mih->cntp, 1);*/ ie = mih->mih_event; write_c0_eirr64(1ULL << i); @@ -166,8 +171,7 @@ cpu_intr(struct trapframe *tf) } if (intr_event_handle(ie, tf) != 0) { - printf("stray %s interrupt %d\n", - hard ? "hard" : "soft", i); + printf("stray interrupt %d\n",i); } } diff --git a/sys/mips/rmi/iodi.c b/sys/mips/rmi/iodi.c index 3a8d3bde6ab..256d1bb8f3c 100644 --- a/sys/mips/rmi/iodi.c +++ b/sys/mips/rmi/iodi.c @@ -46,11 +46,30 @@ #include #include #include -#include -#include -#include +#include +#include +#include +#include #include + +#include +#include +#include /* for DELAY */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + extern void iodi_activateirqs(void); extern bus_space_tag_t uart_bus_space_mem; @@ -61,10 +80,11 @@ static struct resource *iodi_alloc_resource(device_t, device_t, int, int *, static int iodi_activate_resource(device_t, device_t, int, int, struct resource *); static int iodi_setup_intr(device_t, device_t, struct resource *, int, - driver_intr_t *, void *, void **); + driver_filter_t *, driver_intr_t *, void *, void **); struct iodi_softc *iodi_softc; /* There can be only one. */ +/* static void pic_usb_ack(void *arg) { xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); @@ -74,10 +94,11 @@ static void pic_usb_ack(void *arg) xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE))); mtx_unlock_spin(&xlr_pic_lock); } +*/ static int iodi_setup_intr(device_t dev, device_t child, - struct resource *ires, int flags, driver_intr_t *intr, void *arg, + struct resource *ires, int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep) { int level; @@ -92,34 +113,38 @@ iodi_setup_intr(device_t dev, device_t child, xlr_write_reg(mmio, PIC_IRT_0_UART_0, 0x01); xlr_write_reg(mmio, PIC_IRT_1_UART_0, ((1 << 31) | (level<<30)|(1<<6)|(PIC_UART_0_IRQ))); mtx_unlock_spin(&xlr_pic_lock); - - cpu_establish_intr("uart", PIC_UART_0_IRQ, - (driver_intr_t *)intr, (void *)arg, flags, cookiep, - NULL, NULL); + cpu_establish_hardintr("uart", NULL, + (driver_intr_t *)intr, (void *)arg, PIC_UART_0_IRQ, flags, cookiep); } else if (strcmp(device_get_name(child),"rge") == 0) { + int irq; + irq = rman_get_rid(ires); mtx_lock_spin(&xlr_pic_lock); - reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + ires->r_flags - PIC_IRQ_BASE); - xlr_write_reg(mmio, PIC_IRT_1_BASE + ires->r_flags - PIC_IRQ_BASE, reg | (1<<6)|(1<<30)| (1<<31)); + reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE); + xlr_write_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE, reg | (1<<6)|(1<<30)| (1<<31)); mtx_unlock_spin(&xlr_pic_lock); - cpu_establish_intr("rge", ires->r_flags, - (driver_intr_t *)intr, (void *)arg, - flags, cookiep, NULL, NULL); + cpu_establish_hardintr("rge", NULL, (driver_intr_t *)intr, (void *)arg, irq, flags, cookiep); + } else if (strcmp(device_get_name(child),"ehci") == 0) { mtx_lock_spin(&xlr_pic_lock); reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + PIC_USB_IRQ - PIC_IRQ_BASE); xlr_write_reg(mmio, PIC_IRT_1_BASE + PIC_USB_IRQ - PIC_IRQ_BASE, reg | (1<<6)|(1<<30)| (1<<31)); mtx_unlock_spin(&xlr_pic_lock); - cpu_establish_intr("ehci", PIC_USB_IRQ, - (driver_intr_t *)intr, (void *)arg, - flags, cookiep, (flags & INTR_FAST)? NULL: pic_usb_ack , NULL); + cpu_establish_hardintr("ehci", NULL, (driver_intr_t *)intr, (void *)arg, PIC_USB_IRQ, flags, cookiep); } - BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, intr, arg, - cookiep); + BUS_SETUP_INTR(device_get_parent(dev), + child, ires, flags, filt, intr, arg, cookiep); + + return (0); } +/* Strange hook found in mips/include/bus.h */ +#ifndef MIPS_BUS_SPACE_PCI +#define MIPS_BUS_SPACE_PCI 10 +#endif + static struct resource * iodi_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) @@ -159,12 +184,12 @@ iodi_alloc_resource(device_t bus, device_t child, int type, int *rid, res->r_bustag = uart_bus_space_mem; } else if (strcmp(device_get_name(child),"ehci") == 0) { res->r_bushandle = 0xbef24000; - res->r_bustag = MIPS_BUS_SPACE_PCI; + res->r_bustag = (bus_space_tag_t)MIPS_BUS_SPACE_PCI; } else if (strcmp(device_get_name(child),"cfi") == 0) { res->r_bushandle = 0xbc000000; res->r_bustag = 0; } - res->r_start = *rid; + /*res->r_start = *rid;*/ return (res); } diff --git a/sys/mips/rmi/msgring.c b/sys/mips/rmi/msgring.c index 472ad43c9e7..860cd72a394 100644 --- a/sys/mips/rmi/msgring.c +++ b/sys/mips/rmi/msgring.c @@ -33,7 +33,7 @@ * from "msgring.cfg" **********************************************************/ -#include +#include struct bucket_size bucket_sizes = { { diff --git a/sys/mips/rmi/msgring.h b/sys/mips/rmi/msgring.h index fba504daa3b..8cc6898b54a 100755 --- a/sys/mips/rmi/msgring.h +++ b/sys/mips/rmi/msgring.h @@ -30,7 +30,7 @@ #ifndef _RMI_MSGRING_H_ #define _RMI_MSGRING_H_ -#include +#include #define MSGRNG_TX_BUF_REG 0 #define MSGRNG_RX_BUF_REG 1 diff --git a/sys/mips/rmi/msgring_xls.c b/sys/mips/rmi/msgring_xls.c index f1b116e8f6b..2171f1404bf 100644 --- a/sys/mips/rmi/msgring_xls.c +++ b/sys/mips/rmi/msgring_xls.c @@ -4,7 +4,7 @@ * from "msgring_xls.cfg" **********************************************************/ -#include +#include struct bucket_size xls_bucket_sizes = { { 32, 32, 32, 32, 32, 32, 32, 32, diff --git a/sys/mips/rmi/on_chip.c b/sys/mips/rmi/on_chip.c index 8addfc4608a..1a3d67e17fe 100644 --- a/sys/mips/rmi/on_chip.c +++ b/sys/mips/rmi/on_chip.c @@ -42,12 +42,12 @@ #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include void disable_msgring_int(void *arg) ; void enable_msgring_int(void *arg) ; @@ -258,9 +258,9 @@ int register_msgring_handler(int major, if (xlr_test_and_set(&msgring_int_enabled)) { platform_prep_smp_launch(); - cpu_establish_intr("msgring", IRQ_MSGRING, - (driver_intr_t *)msgring_process_fast_intr, - NULL, INTR_TYPE_NET|INTR_FAST, &cookie, NULL, NULL); + cpu_establish_hardintr("msgring", (driver_filter_t *)NULL, + (driver_intr_t *)msgring_process_fast_intr, + NULL, IRQ_MSGRING, INTR_TYPE_NET|INTR_FAST, &cookie); /* configure the msgring interrupt on cpu 0 */ enable_msgring_int(NULL); diff --git a/sys/mips/rmi/pcibus.c b/sys/mips/rmi/pcibus.c index 0aeacd68b77..133e4708c49 100644 --- a/sys/mips/rmi/pcibus.c +++ b/sys/mips/rmi/pcibus.c @@ -47,26 +47,28 @@ __FBSDID("$FreeBSD: src/sys/alpha/pci/pcibus.c,v 1.36 2005/01/05 20:05:52 imp Ex #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include #include #include -#include - +#include +/* static void bridge_pcix_ack(void *); static void bridge_pcie_ack(void *); static void pic_pcix_ack(void *); static void pic_pcie_ack(void *); +*/ extern vm_map_t kernel_map; vm_offset_t kmem_alloc_nofault( vm_map_t map, vm_size_t size); + int mips_pci_route_interrupt(device_t bus, device_t dev, int pin) { @@ -94,11 +96,13 @@ mips_pci_route_interrupt(device_t bus, device_t dev, int pin) static struct rman irq_rman, port_rman, mem_rman; +/* static void bridge_pcix_ack(void *arg) { xlr_read_reg(xlr_io_mmio(XLR_IO_PCIX_OFFSET), 0x140 >> 2); -} - + } +*/ +/* static void bridge_pcie_ack(void *arg) { int irq = (int)arg; @@ -116,7 +120,8 @@ static void bridge_pcie_ack(void *arg) xlr_write_reg(pcie_mmio_le, reg>>2, 0xffffffff); } - +*/ +/* static void pic_pcix_ack(void *none) { xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); @@ -125,7 +130,8 @@ static void pic_pcix_ack(void *none) xlr_write_reg(mmio, PIC_INT_ACK, (1 << PIC_IRT_PCIX_INDEX)); mtx_unlock_spin(&xlr_pic_lock); } - +*/ +/* static void pic_pcie_ack(void *arg) { xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); @@ -136,12 +142,15 @@ static void pic_pcie_ack(void *arg) mtx_unlock_spin(&xlr_pic_lock); } +*/ + int mips_platform_pci_setup_intr(device_t dev, device_t child, - struct resource *irq, int flags, - driver_intr_t *intr, void *arg, - void **cookiep) + struct resource *irq, int flags, + driver_filter_t *filt, + driver_intr_t *intr, void *arg, + void **cookiep) { int level; xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); @@ -151,13 +160,13 @@ mips_platform_pci_setup_intr(device_t dev, device_t child, error = rman_activate_resource(irq); if (error) return error; - if (irq->r_start != irq->r_end) { + if (rman_get_start(irq) != rman_get_end(irq)) { device_printf(dev, "Interrupt allocation %lu != %lu\n", - irq->r_start, irq->r_end); + rman_get_start(irq), rman_get_end(irq)); return EINVAL; } - xlrirq = irq->r_start; + xlrirq = rman_get_start(irq); if (strcmp(device_get_name(dev),"pcib") != 0) return 0; @@ -168,9 +177,9 @@ mips_platform_pci_setup_intr(device_t dev, device_t child, xlr_write_reg(mmio, PIC_IRT_1_PCIX, ((1 << 31) | (level<<30)| (1<<6)|(PIC_PCIX_IRQ))); mtx_unlock_spin(&xlr_pic_lock); - cpu_establish_intr(device_get_name(child), PIC_PCIX_IRQ, - (driver_intr_t *)intr, (void *)arg, flags, cookiep, - pic_pcix_ack, bridge_pcix_ack); + cpu_establish_hardintr(device_get_name(child), filt, + (driver_intr_t *)intr, (void *)arg, PIC_PCIX_IRQ, flags, cookiep); + } else { mtx_lock_spin(&xlr_pic_lock); xlr_write_reg(mmio, PIC_IRT_0_BASE + xlrirq - PIC_IRQ_BASE, 0x01); @@ -179,19 +188,22 @@ mips_platform_pci_setup_intr(device_t dev, device_t child, mtx_unlock_spin(&xlr_pic_lock); if (flags & INTR_FAST) - cpu_establish_intr(device_get_name(child), xlrirq, - (driver_intr_t *)intr, (void *)arg, flags, cookiep, - NULL, bridge_pcie_ack); + cpu_establish_hardintr(device_get_name(child), filt, + (driver_intr_t *)intr, (void *)arg, xlrirq, flags, cookiep); else - cpu_establish_intr(device_get_name(child), xlrirq, - (driver_intr_t *)intr, (void *)arg, flags, cookiep, - pic_pcie_ack, bridge_pcie_ack); + cpu_establish_hardintr(device_get_name(child), filt, + (driver_intr_t *)intr, (void *)arg, xlrirq, flags, cookiep); + } - return bus_generic_setup_intr(dev, child, irq, flags, intr, + return bus_generic_setup_intr(dev, child, irq, flags, filt, intr, arg, cookiep); } + +int +mips_platform_pci_teardown_intr(device_t dev, device_t child, + struct resource *irq, void *cookie); int mips_platform_pci_teardown_intr(device_t dev, device_t child, struct resource *irq, void *cookie) @@ -230,13 +242,18 @@ pci_init_resources(void) panic("pci_init_resources mem_rman"); } +/* hack from bus.h in mips/include/bus.h */ +#ifndef MIPS_BUS_SPACE_PCI +#define MIPS_BUS_SPACE_PCI 10 +#endif + struct resource * xlr_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { struct rman *rm; struct resource *rv; - vm_offset_t va_start, va; + vm_offset_t va; int needactivate = flags & RF_ACTIVE; #if 0 @@ -265,18 +282,24 @@ xlr_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, if (rv == 0) return 0; - rman_set_bustag(rv, MIPS_BUS_SPACE_PCI); - rman_set_rid(rv, *rid); + rman_set_bustag(rv, (bus_space_tag_t)MIPS_BUS_SPACE_PCI); + rman_set_rid(rv, *rid); if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) { - if ((start + count) > (2 << 28)) { + /* if ((start + count) > (2 << 28)) { va_start = kmem_alloc_nofault(kernel_map, count); - } - va = pmap_map_uncached(&va_start, start, start + count); + }*/ + /* This called for pmap_map_uncached, but the pmap_map + * calls pmap_kenter which does a is_cacheable_mem() check and + * thus sets the PTE_UNCACHED bit. Hopefully this will work + * for this guy... RRS + */ + /* va = pmap_map(&va_start, start, start + count, 0);*/ + va = (vm_offset_t)pmap_mapdev(start, start + count); rman_set_bushandle(rv, va); /* bushandle is same as virtual addr */ rman_set_virtual(rv, (void *)va); - rman_set_bustag(rv, MIPS_BUS_SPACE_PCI); + rman_set_bustag(rv, (bus_space_tag_t)MIPS_BUS_SPACE_PCI); } if (needactivate) { @@ -289,6 +312,14 @@ xlr_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, return rv; } + +int +pci_deactivate_resource(device_t bus, device_t child, int type, int rid, + struct resource *r) +{ + return (rman_deactivate_resource(r)); +} +/* now in pci.c int pci_activate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) @@ -296,19 +327,13 @@ pci_activate_resource(device_t bus, device_t child, int type, int rid, return (rman_activate_resource(r)); } -int -pci_deactivate_resource(device_t bus, device_t child, int type, int rid, - struct resource *r) -{ - return (rman_deactivate_resource(r)); -} - int pci_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { return (rman_release_resource(r)); } +*/ struct rman * pci_get_rman(device_t dev, int type) diff --git a/sys/mips/rmi/pcibus.h b/sys/mips/rmi/pcibus.h index ed4bb9768ec..2f4fda8ccdb 100644 --- a/sys/mips/rmi/pcibus.h +++ b/sys/mips/rmi/pcibus.h @@ -47,3 +47,12 @@ int pci_deactivate_resource(device_t bus, device_t child, int type, int rid, int pci_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r); struct rman *pci_get_rman(device_t dev, int type); + +int +mips_platform_pci_setup_intr(device_t dev, device_t child, + struct resource *irq, int flags, + driver_filter_t *filt, + driver_intr_t *intr, void *arg, + void **cookiep); +int +mips_pci_route_interrupt(device_t bus, device_t dev, int pin); diff --git a/sys/mips/rmi/perfmon.h b/sys/mips/rmi/perfmon.h index 1ba6c468e64..23523caab6f 100644 --- a/sys/mips/rmi/perfmon.h +++ b/sys/mips/rmi/perfmon.h @@ -31,7 +31,7 @@ #ifndef PERFMON_H #define PERFMON_H -#include +#include /* * category events reported by the perfmon library diff --git a/sys/mips/rmi/perfmon_kern.c b/sys/mips/rmi/perfmon_kern.c index 1e4b7ce2050..6b74f72bec3 100644 --- a/sys/mips/rmi/perfmon_kern.c +++ b/sys/mips/rmi/perfmon_kern.c @@ -37,10 +37,10 @@ #include #include #include -#include -#include +#include +#include #include -#include +#include int xlr_perfmon_started = 0; diff --git a/sys/mips/rmi/perfmon_percpu.c b/sys/mips/rmi/perfmon_percpu.c index 5980ff76389..44ba3567111 100644 --- a/sys/mips/rmi/perfmon_percpu.c +++ b/sys/mips/rmi/perfmon_percpu.c @@ -33,12 +33,12 @@ #include #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #define CC_SAMPLE (PERF_CP2_CREDITS <<24) diff --git a/sys/mips/rmi/perfmon_xlrconfig.h b/sys/mips/rmi/perfmon_xlrconfig.h index 8156c125951..587334e5a91 100644 --- a/sys/mips/rmi/perfmon_xlrconfig.h +++ b/sys/mips/rmi/perfmon_xlrconfig.h @@ -33,7 +33,7 @@ #ifndef XLRCONFIG_PERFMON_H #define XLRCONFIG_PERFMON_H -#include /* for DPRINT */ +#include /* for DPRINT */ #define NCPUS 32 #define NCORES 8 diff --git a/sys/mips/rmi/pic.h b/sys/mips/rmi/pic.h index 366a73659c7..eee251e6dda 100644 --- a/sys/mips/rmi/pic.h +++ b/sys/mips/rmi/pic.h @@ -33,7 +33,7 @@ #include #include -#include +#include #define PIC_IRT_WD_INDEX 0 #define PIC_IRT_TIMER_0_INDEX 1 diff --git a/sys/mips/rmi/std.xlr b/sys/mips/rmi/std.xlr index da42ffeff05..c6221b95f68 100644 --- a/sys/mips/rmi/std.xlr +++ b/sys/mips/rmi/std.xlr @@ -1,10 +1,10 @@ # $FreeBSD$ -files "../xlr/files.xlr" +files "../rmi/files.xlr" # # XXXMIPS: It's a stub, isn't it? # -cpu CPU_MIPSXLR +cpu CPU_MIPS4KC option NOFPU # Kludge for now options TARGET_XLR_XLS diff --git a/sys/mips/rmi/tick.c b/sys/mips/rmi/tick.c new file mode 100644 index 00000000000..1f4fcbea2d4 --- /dev/null +++ b/sys/mips/rmi/tick.c @@ -0,0 +1,113 @@ +/*- + * Copyright (c) 2006-2009 RMI Corporation + * Copyright (c) 2006 Bruce M. Simpson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Simple driver for the 32-bit interval counter built in to all + * MIPS32 CPUs. + * XXX: For calibration this either needs an external clock, or + * to be explicitly told what the frequency is. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +struct timecounter counter_timecounter = { + platform_get_timecount, /* get_timecount */ + 0, /* no poll_pps */ + ~0u, /* counter_mask */ + 0, /* frequency */ + "MIPS32", /* name */ + 800, /* quality (adjusted in code) */ +}; + +void tick_init(void); + + +void +tick_init(void) +{ + counter_freq = platform_get_frequency(); + if (bootverbose) + printf("MIPS32 clock: %u MHz", cpu_clock); + + counter_timecounter.tc_frequency = counter_freq; + tc_init(&counter_timecounter); +} + + +void +cpu_startprofclock(void) +{ + /* nothing to do */ +} + +void +cpu_stopprofclock(void) +{ + /* nothing to do */ +} + + +static int +sysctl_machdep_counter_freq(SYSCTL_HANDLER_ARGS) +{ + int error; + uint64_t freq; + /* + * RRS wonders if this will really work. You don't + * change the req of the system here, it would require + * changes to the RMI PIC in order to get the TC to + * run at a differrent frequency. + */ + + if (counter_timecounter.tc_frequency == 0) + return (EOPNOTSUPP); + freq = counter_freq; + error = sysctl_handle_int(oidp, &freq, sizeof(freq), req); + if (error == 0 && req->newptr != NULL) { + counter_freq = freq; + counter_timecounter.tc_frequency = counter_freq; + } + return (error); +} + +SYSCTL_PROC(_machdep, OID_AUTO, counter_freq, CTLTYPE_QUAD | CTLFLAG_RW, + 0, sizeof(u_int), sysctl_machdep_counter_freq, "IU", ""); diff --git a/sys/mips/rmi/uart_cpu_mips_xlr.c b/sys/mips/rmi/uart_cpu_mips_xlr.c index 09703f55d4b..6cbea14a303 100644 --- a/sys/mips/rmi/uart_cpu_mips_xlr.c +++ b/sys/mips/rmi/uart_cpu_mips_xlr.c @@ -55,16 +55,18 @@ static int xlr_uart_probe(struct uart_bas *bas); static void xlr_uart_init(struct uart_bas *bas, int, int, int, int); static void xlr_uart_term(struct uart_bas *bas); static void xlr_uart_putc(struct uart_bas *bas, int); -static int xlr_uart_poll(struct uart_bas *bas); -static int xlr_uart_getc(struct uart_bas *bas); +/*static int xlr_uart_poll(struct uart_bas *bas);*/ +static int xlr_uart_getc(struct uart_bas *bas, struct mtx *hwmtx); struct mtx xlr_uart_mtx; /*UartLock*/ +extern struct uart_ops uart_ns8250_ops; + struct uart_ops xlr_uart_ns8250_ops = { .probe = xlr_uart_probe, .init = xlr_uart_init, .term = xlr_uart_term, .putc = xlr_uart_putc, - .poll = xlr_uart_poll, + /* .poll = xlr_uart_poll, ?? */ .getc = xlr_uart_getc, }; @@ -119,7 +121,7 @@ static void xlr_uart_putc(struct uart_bas *bas, int c) uart_ns8250_ops.putc(bas,c); xlr_uart_unlock(&xlr_uart_mtx); } - +/* static int xlr_uart_poll(struct uart_bas *bas) { int res; @@ -128,10 +130,11 @@ static int xlr_uart_poll(struct uart_bas *bas) xlr_uart_unlock(&xlr_uart_mtx); return res; } +*/ -static int xlr_uart_getc(struct uart_bas *bas) +static int xlr_uart_getc(struct uart_bas *bas, struct mtx *hwmtx) { - return uart_ns8250_ops.getc(bas); + return uart_ns8250_ops.getc(bas, hwmtx); } int @@ -144,7 +147,7 @@ uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) int uart_cpu_getdev(int devtype, struct uart_devinfo *di) { - di->ops = xlr_uart_ns8250_ops; + di->ops = &xlr_uart_ns8250_ops; di->bas.chan = 0; di->bas.bst = uart_bus_space_mem; /* TODO Need to call bus_space_map() here */ diff --git a/sys/mips/rmi/xlr_boot1_console.c b/sys/mips/rmi/xlr_boot1_console.c index 01e67b573f3..10b650eefd5 100644 --- a/sys/mips/rmi/xlr_boot1_console.c +++ b/sys/mips/rmi/xlr_boot1_console.c @@ -45,9 +45,9 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include -#include +#include +#include +#include #include diff --git a/sys/mips/rmi/xlr_i2c.c b/sys/mips/rmi/xlr_i2c.c index 60e51c596a8..5f36f7cd797 100644 --- a/sys/mips/rmi/xlr_i2c.c +++ b/sys/mips/rmi/xlr_i2c.c @@ -46,7 +46,7 @@ __FBSDID("$FreeBSD: src/sys/mips/xlr/xlr_i2c.c,v 1.20.8.1 2008/08/25 23:17:51 co #include #include -#include +#include #include #include "iicbus_if.h" diff --git a/sys/mips/rmi/xlr_machdep.c b/sys/mips/rmi/xlr_machdep.c index 84bdb64a6d9..e909b38c10d 100644 --- a/sys/mips/rmi/xlr_machdep.c +++ b/sys/mips/rmi/xlr_machdep.c @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2006-2009 RMI Corporation * Copyright (c) 2002-2004 Juli Mallett * All rights reserved. * @@ -70,15 +71,15 @@ #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #ifdef XLR_PERFMON -#include +#include #endif @@ -108,8 +109,8 @@ static unsigned long xlr_secondary_sp[MAXCPU]; #endif extern int mips_cpu_online_mask; extern int mips_cpu_logical_mask; -extern uint32_t cpu_ltop_map[MAXCPU]; -extern uint32_t cpu_ptol_map[MAXCPU]; +uint32_t cpu_ltop_map[MAXCPU]; +uint32_t cpu_ptol_map[MAXCPU]; uint32_t xlr_core_cpu_mask=0x1; /* Core 0 thread 0 is always there */ void @@ -128,13 +129,13 @@ void platform_secondary_init(void) xlr_msgring_cpu_init(); /* Setup interrupts for secondary CPUs here */ - platform_update_intrmask(IPI_SMP_CALL_FUNCTION); - platform_update_intrmask(IPI_STOP); - platform_update_intrmask(IPI_RENDEZVOUS); - platform_update_intrmask(IPI_AST); - platform_update_intrmask(IRQ_TIMER); + mips_mask_hard_irq(IPI_SMP_CALL_FUNCTION); + mips_mask_hard_irq(IPI_STOP); + mips_mask_hard_irq(IPI_RENDEZVOUS); + mips_mask_hard_irq(IPI_AST); + mips_mask_hard_irq(IRQ_TIMER); #ifdef XLR_PERFMON - platform_update_intrmask(IPI_PERFMON); + mips_mask_hard_irq(IPI_PERFMON); #endif return; @@ -325,10 +326,45 @@ static void xlr_set_boot_flags(void) return; } - extern uint32_t _end; + + +static void +mips_init(void) +{ + init_param1(); + init_param2(physmem); + + /* XXX: Catch 22. Something touches the tlb. */ + + mips_cpu_init(); + pmap_bootstrap(); + + mips_proc0_init(); + write_c0_register32(MIPS_COP_0_OSSCRATCH,7, pcpup->pc_curthread); + + mutex_init(); + + PMAP_LOCK_INIT(kernel_pmap); + +#ifdef DDB +#ifdef SMP + setup_nmi(); +#endif /* SMP */ + kdb_init(); + if (boothowto & RB_KDB) { + kdb_enter("Boot flags requested debugger"); + } +#endif +} + +void tick_init(void); + void -platform_start() +platform_start(__register_t a0 __unused, + __register_t a1 __unused, + __register_t a2 __unused, + __register_t a3 __unused) { vm_size_t physsz = 0; int i, j; @@ -356,7 +392,15 @@ platform_start() boothowto |= (RB_SERIAL | RB_MULTIPLE); /* Use multiple consoles */ /* clockrate used by delay, so initialize it here */ - hw_clockrate = xlr_boot1_info.cpu_frequency/1000000 ; + cpu_clock = xlr_boot1_info.cpu_frequency/1000000 ; + + /* Note the time counter on CPU0 runs not at system + * clock speed, but at PIC time counter speed (which is + * returned by platform_get_frequency(). Thus we do not + * use xlr_boot1_info.cpu_frequency here. + */ + mips_timer_early_init(platform_get_frequency()); + mips_timer_init_params(platform_get_frequency(), 0); cninit(); init_static_kenv(boot1_env, sizeof(boot1_env)); @@ -448,7 +492,7 @@ platform_start() /* Allocate stack for all other cpus from fbsd kseg0 memory. */ if((1U<i_thread; p = td->td_proc; - + /* Interrupt thread will enable the interrupts after processing all messages */ - mtx_lock_spin(&sched_lock); disable_msgring_int(NULL); it->i_pending = 1; if (TD_AWAITING_INTR(td)) { + thread_lock(td); CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, p->p_pid, p->p_comm); TD_CLR_IWAIT(td); - setrunqueue(td, SRQ_INTR); + sched_add(td, SRQ_INTR); + thread_unlock(td); } else { CTR4(KTR_INTR, "%s: pid %d (%s): state %d", __func__, p->p_pid, p->p_comm, td->td_state); } - mtx_unlock_spin(&sched_lock); } #define MIT_DEAD 4 @@ -574,9 +618,9 @@ msgring_process(void * arg) ("%s:msg_ithread and proc linkage out of sync", __func__)); /* First bind this thread to the right CPU */ - mtx_lock_spin(&sched_lock); + thread_lock(td); sched_bind(td, ithd->i_cpu); - mtx_unlock_spin(&sched_lock); + thread_unlock(td); // printf("Started %s on CPU %d\n", __FUNCTION__, ithd->i_cpu); @@ -584,7 +628,7 @@ msgring_process(void * arg) if (ithd->i_flags & MIT_DEAD) { CTR3(KTR_INTR, "%s: pid %d (%s) exiting", __func__, p->p_pid, p->p_comm); - kthread_exit(0); + kthread_exit(); } while (ithd->i_pending) { /* @@ -596,13 +640,14 @@ msgring_process(void * arg) atomic_store_rel_int(&ithd->i_pending, 0); xlr_msgring_handler(NULL); } - mtx_lock_spin(&sched_lock); if (!ithd->i_pending && !(ithd->i_flags & MIT_DEAD)) { + thread_lock(td); + sched_class(td, PRI_ITHD); TD_SET_IWAIT(td); + thread_unlock(td); enable_msgring_int(NULL); mi_switch(SW_VOL, NULL); } - mtx_unlock_spin(&sched_lock); } } @@ -629,16 +674,21 @@ void platform_prep_smp_launch(void) ithd = &msgring_ithreads[cpu]; sprintf(ithd_name[cpu], "msg_intr%d", cpu); - error = kthread_create(msgring_process, (void *)ithd, &p, - RFSTOPPED | RFHIGHPID, 0, "%s", ithd_name[cpu]); + error = kproc_create(msgring_process, + (void *)ithd, + &p, + (RFSTOPPED | RFHIGHPID), + 2, + ithd_name[cpu]); + if (error) - panic("kthread_create() failed with %d", error); + panic("kproc_create() failed with %d", error); td = FIRST_THREAD_IN_PROC(p); /* XXXKSE */ - mtx_lock_spin(&sched_lock); - td->td_ksegrp->kg_pri_class = PRI_ITHD; + + thread_lock(td); + sched_class(td, PRI_ITHD); TD_SET_IWAIT(td); - mtx_unlock_spin(&sched_lock); - td->td_pflags |= TDP_ITHREAD; + thread_unlock(td); ithd->i_thread = td; ithd->i_pending = 0; ithd->i_cpu = cpu; diff --git a/sys/mips/rmi/xlr_pci.c b/sys/mips/rmi/xlr_pci.c index 31fe5cf7306..3b11bf19e10 100644 --- a/sys/mips/rmi/xlr_pci.c +++ b/sys/mips/rmi/xlr_pci.c @@ -49,11 +49,11 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include "pcib_if.h" #define LSU_CFG0_REGID 0 @@ -127,7 +127,7 @@ xlr_pcib_probe(device_t dev) } static int -xlr_pcib_read_ivar(device_t dev, device_t child, int which, u_long *result) +xlr_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) { #if 0 device_printf(dev, "xlr_pcib_read_ivar : read ivar %d for child %s\n", which, device_get_nameunit(child)); @@ -392,7 +392,9 @@ static device_method_t xlr_pcib_methods[] = { DEVMETHOD(pcib_maxslots, xlr_pcib_maxslots), DEVMETHOD(pcib_read_config, xlr_pcib_read_config), DEVMETHOD(pcib_write_config, xlr_pcib_write_config), + DEVMETHOD(pcib_route_interrupt, mips_pci_route_interrupt), + DEVMETHOD(pcib_alloc_msi, xlr_alloc_msi), DEVMETHOD(pcib_release_msi, xlr_release_msi), DEVMETHOD(pcib_map_msi, xlr_map_msi), diff --git a/sys/mips/rmi/xlrconfig.h b/sys/mips/rmi/xlrconfig.h index c446595c7a0..01b67cb5d10 100644 --- a/sys/mips/rmi/xlrconfig.h +++ b/sys/mips/rmi/xlrconfig.h @@ -31,8 +31,8 @@ #define XLRCONFIG_H #include -#include -#include +#include +#include #define read_c0_register32(reg, sel) \ ({ unsigned int __rv; \ diff --git a/sys/mips/rmi/xls_ehci.c b/sys/mips/rmi/xls_ehci.c index 7d44eee4662..c351bb6ecca 100644 --- a/sys/mips/rmi/xls_ehci.c +++ b/sys/mips/rmi/xls_ehci.c @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD: src/sys/dev/usb/ehci_pci.c,v 1.18.2.4 2008/04/23 18:54:51 jh #include #include #include +#include #include #include #include @@ -67,11 +68,11 @@ __FBSDID("$FreeBSD: src/sys/dev/usb/ehci_pci.c,v 1.18.2.4 2008/04/23 18:54:51 jh #include #include -#include -#include +/*#include */ +/*#include */ -#include -#include +#include +#include #ifdef USB_DEBUG #define EHCI_DEBUG USB_DEBUG From 1b4a3a93eae23954ffb50577cb0a96f99326d18c Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Thu, 29 Oct 2009 15:55:58 +0000 Subject: [PATCH 291/380] updates to rge to get it to compile --- sys/dev/rmi/xlr/rge.c | 189 +++++++++--------------------------------- sys/dev/rmi/xlr/rge.h | 119 ++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 152 deletions(-) diff --git a/sys/dev/rmi/xlr/rge.c b/sys/dev/rmi/xlr/rge.c index 9b4936e5317..fa9807602a9 100644 --- a/sys/dev/rmi/xlr/rge.c +++ b/sys/dev/rmi/xlr/rge.c @@ -79,30 +79,33 @@ #include #include #include /* for DELAY */ -#include +#include /* */ #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -#include + + #include #include -#include "miidevs.h" #include -#include "miibus_if.h" + #include +#include /* #include "opt_rge.h" */ +#include "miibus_if.h" + MODULE_DEPEND(rge, ether, 1, 1, 1); MODULE_DEPEND(rge, miibus, 1, 1, 1); @@ -160,93 +163,6 @@ int mac_debug = 0; *****************************************************************/ extern uint32_t cpu_ltop_map[32]; -typedef enum { - xlr_mac_speed_10, xlr_mac_speed_100, - xlr_mac_speed_1000, xlr_mac_speed_rsvd -} xlr_mac_speed_t; - -typedef enum { - xlr_mac_duplex_auto, xlr_mac_duplex_half, - xlr_mac_duplex_full -} xlr_mac_duplex_t; - -typedef enum { - xlr_mac_link_down, - xlr_mac_link_up, -} xlr_mac_link_t; - -typedef enum { - xlr_mac_fc_auto, xlr_mac_fc_disabled, xlr_mac_fc_frame, - xlr_mac_fc_collision, xlr_mac_fc_carrier -} xlr_mac_fc_t; - - -struct rge_softc_stats { - unsigned long rx_frames; - unsigned long tx_frames; - unsigned long rx_packets; - unsigned long rx_bytes; - unsigned long tx_packets; - unsigned long tx_bytes; -}; - -struct driver_data { - - /* - * Let these be the first fields in this structure the structure is - * cacheline aligned when allocated in init_etherdev - */ - struct fr_desc *frin_spill; - struct fr_desc *frout_spill; - union rx_tx_desc *class_0_spill; - union rx_tx_desc *class_1_spill; - union rx_tx_desc *class_2_spill; - union rx_tx_desc *class_3_spill; - int spill_configured; - - struct rge_softc *sc; /* pointer to freebsd device soft-pointer */ - struct rge_softc_stats stats; - struct mtx lock; - - xlr_reg_t *mmio; - xlr_reg_t *mii_mmio; - xlr_reg_t *pcs_mmio; - xlr_reg_t *serdes_mmio; - - int txbucket; - int rfrbucket; - - int phy_oldbmsr; - int phy_oldanlpar; - int phy_oldk1stsr; - int phy_oldlinkstat; - unsigned char phys_addr[2]; - - xlr_mac_speed_t speed; /* current speed */ - xlr_mac_duplex_t duplex;/* current duplex */ - xlr_mac_link_t link; /* current link */ - xlr_mac_fc_t flow_ctrl; /* current flow control setting */ - int advertising; - - int id; - int type; - int mode; - int instance; - int phy_addr; - int frin_to_be_sent[8]; - int init_frin_desc; -}; - -/* static int mac_frin_to_be_sent_thr[8]; */ - -enum { - PORT_TX, - PORT_TX_COMPLETE, - PORT_STARTQ, - PORT_STOPQ, - PORT_START_DEV_STATE, - PORT_STOP_DEV_STATE, -}; #ifdef ENABLED_DEBUG static int port_counters[4][8] __aligned(XLR_CACHELINE_SIZE); @@ -285,37 +201,6 @@ ldadd_wu(unsigned int value, unsigned long *addr) /* #define mac_stats_add(x, val) ({(x) += (val);}) */ #define mac_stats_add(x, val) ldadd_wu(val, &x) -struct rge_softc { - int unit; - int irq; - unsigned char dev_addr[6]; - unsigned long base_addr; - unsigned long mem_end; - struct ifnet *rge_ifp;/* interface info */ - device_t rge_dev; - int mtu; - int flags; - struct driver_data priv; - struct mtx rge_mtx; - device_t rge_miibus; - struct mii_data rge_mii;/* MII/media information */ - bus_space_handle_t rge_bhandle; - bus_space_tag_t rge_btag; - void *rge_intrhand; - struct resource rge_irq; - struct resource *rge_res; - struct ifmedia rge_ifmedia; /* TBI media info */ - int rge_if_flags; - int rge_link; /* link state */ - int rge_link_evt; /* pending link event */ - struct callout rge_stat_ch; - void (*xmit) (struct ifnet *); - void (*stop) (struct rge_softc *); - int (*ioctl) (struct ifnet *, u_long, caddr_t); - struct rge_softc_stats *(*get_stats) (struct rge_softc *); - int active; - int link_up; -}; #define XLR_MAX_CORE 8 #define RGE_LOCK_INIT(_sc, _name) \ @@ -354,7 +239,7 @@ static int rge_ioctl(struct ifnet *, u_long, caddr_t); static void rge_init(void *); static void rge_stop(struct rge_softc *); static void rge_watchdog(struct ifnet *); -static void rge_shutdown(device_t); +static int rge_shutdown(device_t); static void rge_reset(struct rge_softc *); static struct mbuf *get_mbuf(void); @@ -367,8 +252,8 @@ static void rmi_xlr_mac_set_enable(struct driver_data *priv, int flag); static void rmi_xlr_xgmac_init(struct driver_data *priv); static void rmi_xlr_gmac_init(struct driver_data *priv); static void mac_common_init(void); -static void rge_mii_write(struct device *, int, int, int); -static int rge_mii_read(struct device *, int, int); +static int rge_mii_write(device_t, int, int, int); +static int rge_mii_read(device_t, int, int); static void rmi_xlr_mac_mii_statchg(device_t); static int rmi_xlr_mac_mediachange(struct ifnet *); static void rmi_xlr_mac_mediastatus(struct ifnet *, struct ifmediareq *); @@ -418,8 +303,8 @@ static device_method_t rge_methods[] = { /* MII interface */ DEVMETHOD(miibus_readreg, rge_mii_read), - DEVMETHOD(miibus_writereg, rge_mii_write), DEVMETHOD(miibus_statchg, rmi_xlr_mac_mii_statchg), + DEVMETHOD(miibus_writereg, rge_mii_write), {0, 0} }; @@ -693,7 +578,7 @@ build_frag_list(struct mbuf *m_head, struct msgrng_msg *p2p_msg, struct p2d_tx_d p1 = vtophys(taddr); if ((p2 + len2) != p1) { - printf("p1 = %llx p2 = %llx\n", p1, p2); + printf("p1 = %p p2 = %p\n", (void *)p1, (void *)p2); printf("len1 = %x len2 = %x\n", len1, len2); printf("m_data %p\n", m->m_data); @@ -989,7 +874,7 @@ rge_mii_read_internal(xlr_reg_t *mii_mmio, int phyaddr, int regidx) } static int -rge_mii_read(struct device *dev, int phyaddr, int regidx) +rge_mii_read(device_t dev, int phyaddr, int regidx) { struct rge_softc *sc = device_get_softc(dev); return rge_mii_read_internal(sc->priv.mii_mmio, phyaddr, regidx); @@ -1051,7 +936,7 @@ rmi_xlr_mac_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) * Return value: * nothing ********************************************************************* */ -static void +static void rge_mii_write_internal(xlr_reg_t *mii_mmio, int phyaddr, int regidx, int regval) { int i = 0; @@ -1071,16 +956,17 @@ rge_mii_write_internal(xlr_reg_t *mii_mmio, int phyaddr, int regidx, int regval) return; } -static void -rge_mii_write(struct device *dev, int phyaddr, int regidx, int regval) +static int +rge_mii_write(device_t dev, int phyaddr, int regidx, int regval) { struct rge_softc *sc = device_get_softc(dev); rge_mii_write_internal(sc->priv.mii_mmio, phyaddr, regidx, regval); + return (0); } static void -rmi_xlr_mac_mii_statchg(device_t dev) +rmi_xlr_mac_mii_statchg(struct device *dev) { } @@ -1906,8 +1792,7 @@ static void xlr_tx_q_wakeup(void *addr) } static int -rge_attach(dev) - device_t dev; +rge_attach(device_t dev) { struct ifnet *ifp; struct rge_softc *sc; @@ -2017,12 +1902,12 @@ rge_attach(dev) /* Initialize the rge_softc */ sc->irq = gmac_conf->baseirq + priv->instance % 4; - sc->rge_irq.r_flags = (u_int) sc->irq; /* We will use r_flags for - * storing irq which - * iodi_setup_intr can check */ + + /* Set the IRQ into the rid field */ + rman_set_rid(&sc->rge_irq, sc->irq); ret = bus_setup_intr(dev, &sc->rge_irq, INTR_FAST | INTR_TYPE_NET | INTR_MPSAFE, - rge_intr, sc, &sc->rge_intrhand); + NULL, rge_intr, sc, &sc->rge_intrhand); if (ret) { rge_detach(dev); @@ -2047,7 +1932,7 @@ rge_attach(dev) */ sc->rge_mii.mii_ifp = ifp; sc->rge_mii.mii_readreg = rge_mii_read; - sc->rge_mii.mii_writereg = rge_mii_write; + sc->rge_mii.mii_writereg = (mii_writereg_t)rge_mii_write; sc->rge_mii.mii_statchg = rmi_xlr_mac_mii_statchg; ifmedia_init(&sc->rge_mii.mii_media, 0, rmi_xlr_mac_mediachange, rmi_xlr_mac_mediastatus); @@ -2235,7 +2120,7 @@ rge_rx(struct rge_softc *sc, vm_paddr_t paddr, int len) if (mag != 0xf00bad) { /* somebody else packet Error - FIXME in intialization */ - printf("cpu %d: *ERROR* Not my packet paddr %llx\n", xlr_cpu_id(), paddr); + printf("cpu %d: *ERROR* Not my packet paddr %p\n", xlr_cpu_id(), (void *)paddr); return; } @@ -2469,7 +2354,7 @@ rge_watchdog(struct ifnet *sc) { } -static void +static int rge_shutdown(device_t dev) { struct rge_softc *sc; @@ -2480,7 +2365,7 @@ rge_shutdown(device_t dev) rge_reset(sc); RGE_UNLOCK(sc); - return; + return(0); } static int @@ -2800,7 +2685,7 @@ mac_common_init(void) } } -#if notyet + /* Not yet if (xlr_board_atx_ii()) { if (register_msgring_handler (TX_STN_XGS_0, rmi_xlr_mac_msgring_handler, NULL)) { @@ -2811,5 +2696,5 @@ mac_common_init(void) panic("Couldn't register msgring handler for TX_STN_XGS_1\n"); } } -#endif + */ } diff --git a/sys/dev/rmi/xlr/rge.h b/sys/dev/rmi/xlr/rge.h index 1ece628264e..8ccc8a2ebb5 100644 --- a/sys/dev/rmi/xlr/rge.h +++ b/sys/dev/rmi/xlr/rge.h @@ -940,6 +940,125 @@ #define R_CC_CPU6_0 0x3b0 #define R_CC_CPU7_0 0x3b8 +typedef enum { + xlr_mac_speed_10, xlr_mac_speed_100, + xlr_mac_speed_1000, xlr_mac_speed_rsvd +} xlr_mac_speed_t; + +typedef enum { + xlr_mac_duplex_auto, xlr_mac_duplex_half, + xlr_mac_duplex_full +} xlr_mac_duplex_t; + +typedef enum { + xlr_mac_link_down, + xlr_mac_link_up, +} xlr_mac_link_t; + +typedef enum { + xlr_mac_fc_auto, xlr_mac_fc_disabled, xlr_mac_fc_frame, + xlr_mac_fc_collision, xlr_mac_fc_carrier +} xlr_mac_fc_t; + +/* static int mac_frin_to_be_sent_thr[8]; */ + +enum { + PORT_TX, + PORT_TX_COMPLETE, + PORT_STARTQ, + PORT_STOPQ, + PORT_START_DEV_STATE, + PORT_STOP_DEV_STATE, +}; + +struct rge_softc_stats { + unsigned long rx_frames; + unsigned long tx_frames; + unsigned long rx_packets; + unsigned long rx_bytes; + unsigned long tx_packets; + unsigned long tx_bytes; +}; + +struct driver_data { + + /* + * Let these be the first fields in this structure the structure is + * cacheline aligned when allocated in init_etherdev + */ + struct fr_desc *frin_spill; + struct fr_desc *frout_spill; + union rx_tx_desc *class_0_spill; + union rx_tx_desc *class_1_spill; + union rx_tx_desc *class_2_spill; + union rx_tx_desc *class_3_spill; + int spill_configured; + + struct rge_softc *sc; /* pointer to freebsd device soft-pointer */ + struct rge_softc_stats stats; + struct mtx lock; + + xlr_reg_t *mmio; + xlr_reg_t *mii_mmio; + xlr_reg_t *pcs_mmio; + xlr_reg_t *serdes_mmio; + + int txbucket; + int rfrbucket; + + int phy_oldbmsr; + int phy_oldanlpar; + int phy_oldk1stsr; + int phy_oldlinkstat; + unsigned char phys_addr[2]; + + xlr_mac_speed_t speed; /* current speed */ + xlr_mac_duplex_t duplex;/* current duplex */ + xlr_mac_link_t link; /* current link */ + xlr_mac_fc_t flow_ctrl; /* current flow control setting */ + int advertising; + + int id; + int type; + int mode; + int instance; + int phy_addr; + int frin_to_be_sent[8]; + int init_frin_desc; +}; + +struct rge_softc { + int unit; + int irq; + unsigned char dev_addr[6]; + unsigned long base_addr; + unsigned long mem_end; + struct ifnet *rge_ifp;/* interface info */ + device_t rge_dev; + int mtu; + int flags; + struct driver_data priv; + struct mtx rge_mtx; + device_t rge_miibus; + struct mii_data rge_mii;/* MII/media information */ + bus_space_handle_t rge_bhandle; + bus_space_tag_t rge_btag; + void *rge_intrhand; + struct resource rge_irq; + struct resource *rge_res; + struct ifmedia rge_ifmedia; /* TBI media info */ + int rge_if_flags; + int rge_link; /* link state */ + int rge_link_evt; /* pending link event */ + struct callout rge_stat_ch; + void (*xmit) (struct ifnet *); + void (*stop) (struct rge_softc *); + int (*ioctl) (struct ifnet *, u_long, caddr_t); + struct rge_softc_stats *(*get_stats) (struct rge_softc *); + int active; + int link_up; +}; + struct size_1_desc { uint64_t entry0; }; From f40c80b188a176be5cf134eba5bb95cab2b831cc Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Thu, 29 Oct 2009 21:14:10 +0000 Subject: [PATCH 292/380] White space changes --- sys/mips/rmi/board.c | 125 +++---- sys/mips/rmi/board.h | 57 +-- sys/mips/rmi/clock.c | 171 ++++----- sys/mips/rmi/clock.h | 2 +- sys/mips/rmi/debug.h | 92 ++--- sys/mips/rmi/ehcireg.h | 192 +++++----- sys/mips/rmi/ehcivar.h | 62 ++-- sys/mips/rmi/interrupt.h | 3 +- sys/mips/rmi/intr_machdep.c | 63 ++-- sys/mips/rmi/iodi.c | 153 ++++---- sys/mips/rmi/iomap.h | 4 +- sys/mips/rmi/msgring.c | 503 +++++++++++++------------- sys/mips/rmi/msgring.h | 281 +++++++------- sys/mips/rmi/msgring_xls.c | 373 ++++++++++--------- sys/mips/rmi/on_chip.c | 160 ++++---- sys/mips/rmi/pcibus.c | 122 ++++--- sys/mips/rmi/pcibus.h | 34 +- sys/mips/rmi/perfmon.h | 77 ++-- sys/mips/rmi/perfmon_kern.c | 63 ++-- sys/mips/rmi/perfmon_percpu.c | 199 ++++++---- sys/mips/rmi/perfmon_utils.h | 57 +-- sys/mips/rmi/perfmon_xlrconfig.h | 2 +- sys/mips/rmi/pic.h | 87 +++-- sys/mips/rmi/shared_structs.h | 90 ++--- sys/mips/rmi/shared_structs_func.h | 4 +- sys/mips/rmi/shared_structs_offsets.h | 4 +- sys/mips/rmi/tick.c | 10 +- sys/mips/rmi/uart_bus_xlr_iodi.c | 14 +- sys/mips/rmi/uart_cpu_mips_xlr.c | 58 +-- sys/mips/rmi/xlr_boot1_console.c | 16 +- sys/mips/rmi/xlr_i2c.c | 447 ++++++++++++----------- sys/mips/rmi/xlr_machdep.c | 345 +++++++++--------- sys/mips/rmi/xlr_pci.c | 264 +++++++------- sys/mips/rmi/xlrconfig.h | 219 +++++------ sys/mips/rmi/xls_ehci.c | 17 +- 35 files changed, 2290 insertions(+), 2080 deletions(-) diff --git a/sys/mips/rmi/board.c b/sys/mips/rmi/board.c index e50101eb968..cf90f6cccc1 100644 --- a/sys/mips/rmi/board.c +++ b/sys/mips/rmi/board.c @@ -41,68 +41,69 @@ #include static int xlr_rxstn_to_txstn_map[128] = { - [0 ... 7] = TX_STN_CPU_0, - [8 ... 15] = TX_STN_CPU_1, - [16 ... 23] = TX_STN_CPU_2, - [24 ... 31] = TX_STN_CPU_3, - [32 ... 39] = TX_STN_CPU_4, - [40 ... 47] = TX_STN_CPU_5, - [48 ... 55] = TX_STN_CPU_6, - [56 ... 63] = TX_STN_CPU_7, - [64 ... 95] = TX_STN_INVALID, - [96 ... 103] = TX_STN_GMAC, - [104 ... 107] = TX_STN_DMA, - [108 ... 111] = TX_STN_INVALID, - [112 ... 113] = TX_STN_XGS_0, - [114 ... 115] = TX_STN_XGS_1, - [116 ... 119] = TX_STN_INVALID, - [120 ... 127] = TX_STN_SAE + [0...7] = TX_STN_CPU_0, + [8...15] = TX_STN_CPU_1, + [16...23] = TX_STN_CPU_2, + [24...31] = TX_STN_CPU_3, + [32...39] = TX_STN_CPU_4, + [40...47] = TX_STN_CPU_5, + [48...55] = TX_STN_CPU_6, + [56...63] = TX_STN_CPU_7, + [64...95] = TX_STN_INVALID, + [96...103] = TX_STN_GMAC, + [104...107] = TX_STN_DMA, + [108...111] = TX_STN_INVALID, + [112...113] = TX_STN_XGS_0, + [114...115] = TX_STN_XGS_1, + [116...119] = TX_STN_INVALID, + [120...127] = TX_STN_SAE }; static int xls_rxstn_to_txstn_map[128] = { - [0 ... 7] = TX_STN_CPU_0, - [8 ... 15] = TX_STN_CPU_1, - [16 ... 23] = TX_STN_CPU_2, - [24 ... 31] = TX_STN_CPU_3, - [32 ... 63] = TX_STN_INVALID, - [64 ... 71] = TX_STN_PCIE, - [72 ... 79] = TX_STN_INVALID, - [80 ... 87] = TX_STN_GMAC1, - [88 ... 95] = TX_STN_INVALID, - [96 ... 103] = TX_STN_GMAC0, - [104 ... 107] = TX_STN_DMA, - [108 ... 111] = TX_STN_CDE, - [112 ... 119] = TX_STN_INVALID, - [120 ... 127] = TX_STN_SAE + [0...7] = TX_STN_CPU_0, + [8...15] = TX_STN_CPU_1, + [16...23] = TX_STN_CPU_2, + [24...31] = TX_STN_CPU_3, + [32...63] = TX_STN_INVALID, + [64...71] = TX_STN_PCIE, + [72...79] = TX_STN_INVALID, + [80...87] = TX_STN_GMAC1, + [88...95] = TX_STN_INVALID, + [96...103] = TX_STN_GMAC0, + [104...107] = TX_STN_DMA, + [108...111] = TX_STN_CDE, + [112...119] = TX_STN_INVALID, + [120...127] = TX_STN_SAE }; struct stn_cc *xlr_core_cc_configs[] = {&cc_table_cpu_0, &cc_table_cpu_1, - &cc_table_cpu_2, &cc_table_cpu_3, - &cc_table_cpu_4, &cc_table_cpu_5, - &cc_table_cpu_6, &cc_table_cpu_7 }; + &cc_table_cpu_2, &cc_table_cpu_3, + &cc_table_cpu_4, &cc_table_cpu_5, +&cc_table_cpu_6, &cc_table_cpu_7}; -struct stn_cc *xls_core_cc_configs[] = {&xls_cc_table_cpu_0, &xls_cc_table_cpu_1, - &xls_cc_table_cpu_2, &xls_cc_table_cpu_3}; +struct stn_cc *xls_core_cc_configs[] = {&xls_cc_table_cpu_0, &xls_cc_table_cpu_1, +&xls_cc_table_cpu_2, &xls_cc_table_cpu_3}; struct xlr_board_info xlr_board_info; /* - * All our knowledge of chip and board that cannot be detected by probing + * All our knowledge of chip and board that cannot be detected by probing * at run-time goes here */ -int xlr_board_info_setup() +int +xlr_board_info_setup() { if (xlr_is_xls()) { xlr_board_info.is_xls = 1; xlr_board_info.nr_cpus = 8; xlr_board_info.usb = 1; xlr_board_info.cfi = - (xlr_boot1_info.board_major_version != RMI_XLR_BOARD_ARIZONA_VIII); + (xlr_boot1_info.board_major_version != RMI_XLR_BOARD_ARIZONA_VIII); xlr_board_info.pci_irq = 0; xlr_board_info.credit_configs = xls_core_cc_configs; - xlr_board_info.bucket_sizes = &xls_bucket_sizes; - xlr_board_info.msgmap = xls_rxstn_to_txstn_map; - xlr_board_info.gmacports = 8; + xlr_board_info.bucket_sizes = &xls_bucket_sizes; + xlr_board_info.msgmap = xls_rxstn_to_txstn_map; + xlr_board_info.gmacports = 8; /* network block 0 */ xlr_board_info.gmac_block[0].type = XLR_GMAC; @@ -110,13 +111,13 @@ int xlr_board_info_setup() xlr_board_info.gmac_block[0].credit_config = &xls_cc_table_gmac0; xlr_board_info.gmac_block[0].station_txbase = MSGRNG_STNID_GMACTX0; xlr_board_info.gmac_block[0].station_rfr = MSGRNG_STNID_GMACRFR_0; - if (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_VI) + if (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_VI) xlr_board_info.gmac_block[0].mode = XLR_PORT0_RGMII; else xlr_board_info.gmac_block[0].mode = XLR_SGMII; - xlr_board_info.gmac_block[0].baseaddr = XLR_IO_GMAC_0_OFFSET; - xlr_board_info.gmac_block[0].baseirq = PIC_GMAC_0_IRQ; - xlr_board_info.gmac_block[0].baseinst = 0; + xlr_board_info.gmac_block[0].baseaddr = XLR_IO_GMAC_0_OFFSET; + xlr_board_info.gmac_block[0].baseirq = PIC_GMAC_0_IRQ; + xlr_board_info.gmac_block[0].baseinst = 0; /* network block 1 */ xlr_board_info.gmac_block[1].type = XLR_GMAC; @@ -124,13 +125,13 @@ int xlr_board_info_setup() xlr_board_info.gmac_block[1].credit_config = &xls_cc_table_gmac1; xlr_board_info.gmac_block[1].station_txbase = MSGRNG_STNID_GMAC1_TX0; xlr_board_info.gmac_block[1].station_rfr = MSGRNG_STNID_GMAC1_FR_0; - xlr_board_info.gmac_block[1].mode = XLR_SGMII; - xlr_board_info.gmac_block[1].baseaddr = XLR_IO_GMAC_4_OFFSET; - xlr_board_info.gmac_block[1].baseirq = PIC_XGS_0_IRQ; - xlr_board_info.gmac_block[1].baseinst = 4; + xlr_board_info.gmac_block[1].mode = XLR_SGMII; + xlr_board_info.gmac_block[1].baseaddr = XLR_IO_GMAC_4_OFFSET; + xlr_board_info.gmac_block[1].baseirq = PIC_XGS_0_IRQ; + xlr_board_info.gmac_block[1].baseinst = 4; /* network block 2 */ - xlr_board_info.gmac_block[2].enabled = 0; /* disabled on XLS */ + xlr_board_info.gmac_block[2].enabled = 0; /* disabled on XLS */ } else { xlr_board_info.is_xls = 0; xlr_board_info.nr_cpus = 32; @@ -138,9 +139,9 @@ int xlr_board_info_setup() xlr_board_info.cfi = 1; xlr_board_info.pci_irq = 0; xlr_board_info.credit_configs = xlr_core_cc_configs; - xlr_board_info.bucket_sizes = &bucket_sizes; - xlr_board_info.msgmap = xlr_rxstn_to_txstn_map; - xlr_board_info.gmacports = 4; + xlr_board_info.bucket_sizes = &bucket_sizes; + xlr_board_info.msgmap = xlr_rxstn_to_txstn_map; + xlr_board_info.gmacports = 4; /* GMAC0 */ xlr_board_info.gmac_block[0].type = XLR_GMAC; @@ -149,9 +150,9 @@ int xlr_board_info_setup() xlr_board_info.gmac_block[0].station_txbase = MSGRNG_STNID_GMACTX0; xlr_board_info.gmac_block[0].station_rfr = MSGRNG_STNID_GMACRFR_0; xlr_board_info.gmac_block[0].mode = XLR_RGMII; - xlr_board_info.gmac_block[0].baseaddr = XLR_IO_GMAC_0_OFFSET; - xlr_board_info.gmac_block[0].baseirq = PIC_GMAC_0_IRQ; - xlr_board_info.gmac_block[0].baseinst = 0; + xlr_board_info.gmac_block[0].baseaddr = XLR_IO_GMAC_0_OFFSET; + xlr_board_info.gmac_block[0].baseirq = PIC_GMAC_0_IRQ; + xlr_board_info.gmac_block[0].baseinst = 0; /* XGMAC0 */ xlr_board_info.gmac_block[1].type = XLR_XGMAC; @@ -160,9 +161,9 @@ int xlr_board_info_setup() xlr_board_info.gmac_block[1].station_txbase = MSGRNG_STNID_XGS0_TX; xlr_board_info.gmac_block[1].station_rfr = MSGRNG_STNID_XGS0FR; xlr_board_info.gmac_block[1].mode = -1; - xlr_board_info.gmac_block[1].baseaddr = XLR_IO_XGMAC_0_OFFSET; - xlr_board_info.gmac_block[1].baseirq = PIC_XGS_0_IRQ; - xlr_board_info.gmac_block[1].baseinst = 4; + xlr_board_info.gmac_block[1].baseaddr = XLR_IO_XGMAC_0_OFFSET; + xlr_board_info.gmac_block[1].baseirq = PIC_XGS_0_IRQ; + xlr_board_info.gmac_block[1].baseinst = 4; /* XGMAC1 */ xlr_board_info.gmac_block[2].type = XLR_XGMAC; @@ -171,9 +172,9 @@ int xlr_board_info_setup() xlr_board_info.gmac_block[2].station_txbase = MSGRNG_STNID_XGS1_TX; xlr_board_info.gmac_block[2].station_rfr = MSGRNG_STNID_XGS1FR; xlr_board_info.gmac_block[2].mode = -1; - xlr_board_info.gmac_block[2].baseaddr = XLR_IO_XGMAC_1_OFFSET; - xlr_board_info.gmac_block[2].baseirq = PIC_XGS_1_IRQ; - xlr_board_info.gmac_block[2].baseinst = 5; + xlr_board_info.gmac_block[2].baseaddr = XLR_IO_XGMAC_1_OFFSET; + xlr_board_info.gmac_block[2].baseirq = PIC_XGS_1_IRQ; + xlr_board_info.gmac_block[2].baseinst = 5; } return 0; } diff --git a/sys/mips/rmi/board.h b/sys/mips/rmi/board.h index b296d14804a..f47654e2a6c 100644 --- a/sys/mips/rmi/board.h +++ b/sys/mips/rmi/board.h @@ -150,7 +150,7 @@ xlr_revision_b0(void) static __inline__ int xlr_revision_b1(void) { - return xlr_revision() == 0x0c0003; + return xlr_revision() == 0x0c0003; } static __inline__ int @@ -182,7 +182,8 @@ static __inline__ int xlr_board_atx_iv(void) { return (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_IV) - && (xlr_boot1_info.board_minor_version == 0); } + && (xlr_boot1_info.board_minor_version == 0); +} static __inline__ int xlr_board_atx_iv_b(void) { @@ -225,48 +226,54 @@ static __inline__ int xlr_board_pci(void) { return (xlr_board_atx_iii_256() || xlr_board_atx_iii_512() - || xlr_board_atx_v_512()); + || xlr_board_atx_v_512()); } static __inline__ int xlr_is_xls2xx(void) { - uint32_t chipid = mips_rd_prid() & 0xffffff00U; + uint32_t chipid = mips_rd_prid() & 0xffffff00U; - return chipid == 0x0c8e00 || chipid == 0x0c8f00; + return chipid == 0x0c8e00 || chipid == 0x0c8f00; } static __inline__ int xlr_is_xls4xx(void) { - uint32_t chipid = mips_rd_prid() & 0xffffff00U; + uint32_t chipid = mips_rd_prid() & 0xffffff00U; - return chipid == 0x0c8800 || chipid == 0x0c8c00; + return chipid == 0x0c8800 || chipid == 0x0c8c00; } /* all our knowledge of chip and board that cannot be detected run-time goes here */ -enum gmac_block_types { XLR_GMAC, XLR_XGMAC, XLR_SPI4}; -enum gmac_block_modes { XLR_RGMII, XLR_SGMII, XLR_PORT0_RGMII }; +enum gmac_block_types { + XLR_GMAC, XLR_XGMAC, XLR_SPI4 +}; +enum gmac_block_modes { + XLR_RGMII, XLR_SGMII, XLR_PORT0_RGMII +}; struct xlr_board_info { int is_xls; int nr_cpus; - int usb; /* usb enabled ? */ - int cfi; /* compact flash driver for NOR? */ + int usb; /* usb enabled ? */ + int cfi; /* compact flash driver for NOR? */ int pci_irq; - struct stn_cc **credit_configs; /* pointer to Core station credits */ - struct bucket_size *bucket_sizes; /* pointer to Core station bucket */ - int *msgmap; /* mapping of message station to devices */ - int gmacports; /* number of gmac ports on the board */ + struct stn_cc **credit_configs; /* pointer to Core station credits */ + struct bucket_size *bucket_sizes; /* pointer to Core station + * bucket */ + int *msgmap; /* mapping of message station to devices */ + int gmacports; /* number of gmac ports on the board */ struct xlr_gmac_block_t { - int type; /* see enum gmac_block_types */ - unsigned int enabled; /* mask of ports enabled */ - struct stn_cc *credit_config; /* credit configuration */ - int station_txbase; /* station id for tx */ - int station_rfr; /* free desc bucket */ - int mode; /* see gmac_block_modes */ - uint32_t baseaddr; /* IO base */ - int baseirq; /* first irq for this block, the rest are in sequence */ - int baseinst; /* the first rge unit for this block */ - } gmac_block [3]; + int type; /* see enum gmac_block_types */ + unsigned int enabled; /* mask of ports enabled */ + struct stn_cc *credit_config; /* credit configuration */ + int station_txbase; /* station id for tx */ + int station_rfr;/* free desc bucket */ + int mode; /* see gmac_block_modes */ + uint32_t baseaddr; /* IO base */ + int baseirq; /* first irq for this block, the rest are in + * sequence */ + int baseinst; /* the first rge unit for this block */ + } gmac_block[3]; }; extern struct xlr_board_info xlr_board_info; diff --git a/sys/mips/rmi/clock.c b/sys/mips/rmi/clock.c index 2e5e0486b94..93c2fa1cae0 100644 --- a/sys/mips/rmi/clock.c +++ b/sys/mips/rmi/clock.c @@ -28,7 +28,7 @@ * * RMI_BSD */ -#include /* RCS ID & Copyright macro defns */ +#include /* RCS ID & Copyright macro defns */ #include #include @@ -77,12 +77,13 @@ u_int32_t counter_lower_last = 0; static int scale_factor; static int count_scale_factor[32]; -uint64_t platform_get_frequency() +uint64_t +platform_get_frequency() { return XLR_PIC_HZ; } -void +void mips_timer_early_init(uint64_t clock_hz) { /* Initialize clock early so that we can use DELAY sooner */ @@ -94,7 +95,7 @@ mips_timer_early_init(uint64_t clock_hz) /* * count_compare_clockhandler: * -* Handle the clock interrupt when count becomes equal to +* Handle the clock interrupt when count becomes equal to * compare. */ void @@ -107,23 +108,21 @@ count_compare_clockhandler(struct trapframe *tf) if (cpu == 0) { mips_wr_compare(0); - } - else { + } else { count_scale_factor[cpu]++; cycles = mips_rd_count(); - cycles += XLR_CPU_HZ/hz; + cycles += XLR_CPU_HZ / hz; mips_wr_compare(cycles); hardclock_cpu(USERMODE(tf->sr)); if (count_scale_factor[cpu] == STAT_PROF_CLOCK_SCALE_FACTOR) { statclock(USERMODE(tf->sr)); - if(profprocs != 0) { + if (profprocs != 0) { profclock(USERMODE(tf->sr), tf->pc); } count_scale_factor[cpu] = 0; } - - /* If needed , handle count compare tick skew here */ + /* If needed , handle count compare tick skew here */ } critical_exit(); @@ -141,18 +140,17 @@ pic_hardclockhandler(struct trapframe *tf) hardclock(USERMODE(tf->sr), tf->pc); if (scale_factor == STAT_PROF_CLOCK_SCALE_FACTOR) { statclock(USERMODE(tf->sr)); - if(profprocs != 0) { + if (profprocs != 0) { profclock(USERMODE(tf->sr), tf->pc); } scale_factor = 0; } #ifdef XLR_PERFMON if (xlr_perfmon_started) - xlr_perfmon_clockhandler(); + xlr_perfmon_clockhandler(); #endif - } - else { + } else { /* If needed , handle count compare tick skew here */ } critical_exit(); @@ -161,75 +159,77 @@ pic_hardclockhandler(struct trapframe *tf) int pic_timecounthandler(struct trapframe *tf) { - return (FILTER_HANDLED); + return (FILTER_HANDLED); } void platform_initclocks(void) { - int cpu = PCPU_GET(cpuid); - void *cookie; + int cpu = PCPU_GET(cpuid); + void *cookie; - /* Note: Passing #3 as NULL ensures that clockhandler - * gets called with trapframe - */ - /* profiling/process accounting timer interrupt for non-zero cpus */ - cpu_establish_hardintr("compare", - NULL, - (driver_intr_t *)count_compare_clockhandler, - NULL, - IRQ_TIMER, - INTR_TYPE_CLK|INTR_FAST, &cookie); + /* + * Note: Passing #3 as NULL ensures that clockhandler gets called + * with trapframe + */ + /* profiling/process accounting timer interrupt for non-zero cpus */ + cpu_establish_hardintr("compare", + NULL, + (driver_intr_t *) count_compare_clockhandler, + NULL, + IRQ_TIMER, + INTR_TYPE_CLK | INTR_FAST, &cookie); - /* timekeeping timer interrupt for cpu 0 */ - cpu_establish_hardintr("hardclk", - NULL, - (driver_intr_t *)pic_hardclockhandler, - NULL, - PIC_TIMER_7_IRQ, - INTR_TYPE_CLK|INTR_FAST, - &cookie); + /* timekeeping timer interrupt for cpu 0 */ + cpu_establish_hardintr("hardclk", + NULL, + (driver_intr_t *) pic_hardclockhandler, + NULL, + PIC_TIMER_7_IRQ, + INTR_TYPE_CLK | INTR_FAST, + &cookie); - /* this is used by timecounter */ - cpu_establish_hardintr("timecount", - (driver_filter_t *)pic_timecounthandler, NULL, - NULL, PIC_TIMER_6_IRQ, INTR_TYPE_CLK|INTR_FAST, - &cookie); - - if (cpu == 0) { - __uint64_t maxval = XLR_PIC_HZ/hz; - xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + /* this is used by timecounter */ + cpu_establish_hardintr("timecount", + (driver_filter_t *) pic_timecounthandler, NULL, + NULL, PIC_TIMER_6_IRQ, INTR_TYPE_CLK | INTR_FAST, + &cookie); - stathz = hz / STAT_PROF_CLOCK_SCALE_FACTOR; - profhz = stathz; + if (cpu == 0) { + __uint64_t maxval = XLR_PIC_HZ / hz; + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); - /* Setup PIC Interrupt */ + stathz = hz / STAT_PROF_CLOCK_SCALE_FACTOR; + profhz = stathz; - mtx_lock_spin(&xlr_pic_lock); - xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_0, (maxval & 0xffffffff)); /* 0x100 + 7*/ - xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_1, (maxval >> 32) & 0xffffffff);/* 0x110 + 7 */ - /* 0x40 + 8 */ - /* reg 40 is lower bits 31-0 and holds CPU mask */ - xlr_write_reg(mmio, PIC_IRT_0_TIMER_7, (1 << cpu)); - /* 0x80 + 8 */ - /* Reg 80 is upper bits 63-32 and holds */ - /* Valid Edge Local IRQ */ - xlr_write_reg(mmio, PIC_IRT_1_TIMER_7, (1<<31)|(0<<30)|(1<<6)|(PIC_TIMER_7_IRQ)); - pic_update_control(1<<(8+7)); + /* Setup PIC Interrupt */ - xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_0, (0xffffffff & 0xffffffff)); - xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_1, (0xffffffff & 0xffffffff)); - xlr_write_reg(mmio, PIC_IRT_0_TIMER_6, (1 << cpu)); - xlr_write_reg(mmio, PIC_IRT_1_TIMER_6, (1<<31)|(0<<30)|(1<<6)|(PIC_TIMER_6_IRQ)); - pic_update_control(1<<(8+6)); - mtx_unlock_spin(&xlr_pic_lock); - } else { - /* Setup count-compare interrupt for vcpu[1-31] */ - mips_wr_compare((xlr_boot1_info.cpu_frequency)/hz); - } + mtx_lock_spin(&xlr_pic_lock); + xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_0, (maxval & 0xffffffff)); /* 0x100 + 7 */ + xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_1, (maxval >> 32) & 0xffffffff); /* 0x110 + 7 */ + /* 0x40 + 8 */ + /* reg 40 is lower bits 31-0 and holds CPU mask */ + xlr_write_reg(mmio, PIC_IRT_0_TIMER_7, (1 << cpu)); + /* 0x80 + 8 */ + /* Reg 80 is upper bits 63-32 and holds */ + /* Valid Edge Local IRQ */ + xlr_write_reg(mmio, PIC_IRT_1_TIMER_7, (1 << 31) | (0 << 30) | (1 << 6) | (PIC_TIMER_7_IRQ)); + pic_update_control(1 << (8 + 7)); + + xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_0, (0xffffffff & 0xffffffff)); + xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_1, (0xffffffff & 0xffffffff)); + xlr_write_reg(mmio, PIC_IRT_0_TIMER_6, (1 << cpu)); + xlr_write_reg(mmio, PIC_IRT_1_TIMER_6, (1 << 31) | (0 << 30) | (1 << 6) | (PIC_TIMER_6_IRQ)); + pic_update_control(1 << (8 + 6)); + mtx_unlock_spin(&xlr_pic_lock); + } else { + /* Setup count-compare interrupt for vcpu[1-31] */ + mips_wr_compare((xlr_boot1_info.cpu_frequency) / hz); + } } -unsigned __attribute__((no_instrument_function)) +unsigned +__attribute__((no_instrument_function)) platform_get_timecount(struct timecounter *tc __unused) { xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); @@ -268,18 +268,21 @@ DELAY(int n) } static -uint64_t read_pic_counter(void) +uint64_t +read_pic_counter(void) { xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); uint32_t lower, upper; uint64_t tc; - /* Pull the value of the 64 bit counter which is stored in - * PIC register 120+N and 130+N + + /* + * Pull the value of the 64 bit counter which is stored in PIC + * register 120+N and 130+N */ - upper = 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_1); + upper = 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_1); lower = 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_0); - tc = (((uint64_t)upper << 32) | (uint64_t)lower); - return(tc); + tc = (((uint64_t) upper << 32) | (uint64_t) lower); + return (tc); } extern struct timecounter counter_timecounter; @@ -303,16 +306,16 @@ mips_timer_init_params(uint64_t platform_counter_freq, int double_count) cycles_per_tick = counter_freq / 1000; cycles_per_hz = counter_freq / hz; cycles_per_usec = counter_freq / (1 * 1000 * 1000); - cycles_per_sec = counter_freq ; - + cycles_per_sec = counter_freq; + counter_timecounter.tc_frequency = counter_freq; printf("hz=%d cyl_per_hz:%jd cyl_per_usec:%jd freq:%jd cyl_per_hz:%jd cyl_per_sec:%jd\n", - hz, - cycles_per_tick, - cycles_per_usec, - counter_freq, - cycles_per_hz, - cycles_per_sec - ); + hz, + cycles_per_tick, + cycles_per_usec, + counter_freq, + cycles_per_hz, + cycles_per_sec + ); set_cputicker(read_pic_counter, counter_freq, 1); } diff --git a/sys/mips/rmi/clock.h b/sys/mips/rmi/clock.h index 750c3dae127..a5d67a6011d 100644 --- a/sys/mips/rmi/clock.h +++ b/sys/mips/rmi/clock.h @@ -37,4 +37,4 @@ void count_compare_clockhandler(struct trapframe *); void pic_hardclockhandler(struct trapframe *); int pic_timecounthandler(struct trapframe *); -#endif /* _RMI_CLOCK_H_ */ +#endif /* _RMI_CLOCK_H_ */ diff --git a/sys/mips/rmi/debug.h b/sys/mips/rmi/debug.h index 2507a0478de..b5ec144cc2c 100755 --- a/sys/mips/rmi/debug.h +++ b/sys/mips/rmi/debug.h @@ -33,51 +33,51 @@ #include enum { - //cacheline 0 - MSGRNG_INT, - MSGRNG_PIC_INT, - MSGRNG_MSG, - MSGRNG_EXIT_STATUS, - MSGRNG_MSG_CYCLES, - //cacheline 1 - NETIF_TX = 8, - NETIF_RX, - NETIF_TX_COMPLETE, - NETIF_TX_COMPLETE_TX, - NETIF_RX_CYCLES, - NETIF_TX_COMPLETE_CYCLES, - NETIF_TX_CYCLES, - NETIF_TIMER_START_Q, - //NETIF_REG_FRIN, - //NETIF_INT_REG, - //cacheline 2 - REPLENISH_ENTER = 16, - REPLENISH_ENTER_COUNT, - REPLENISH_CPU, - REPLENISH_FRIN, - REPLENISH_CYCLES, - NETIF_STACK_TX, - NETIF_START_Q, - NETIF_STOP_Q, - //cacheline 3 - USER_MAC_START = 24, - USER_MAC_INT = 24, - USER_MAC_TX_COMPLETE, - USER_MAC_RX, - USER_MAC_POLL, - USER_MAC_TX, - USER_MAC_TX_FAIL, - USER_MAC_TX_COUNT, - USER_MAC_FRIN, - //cacheline 4 - USER_MAC_TX_FAIL_GMAC_CREDITS = 32, - USER_MAC_DO_PAGE_FAULT, - USER_MAC_UPDATE_TLB, - USER_MAC_UPDATE_BIGTLB, - USER_MAC_UPDATE_TLB_PFN0, - USER_MAC_UPDATE_TLB_PFN1, - - XLR_MAX_COUNTERS = 40 + //cacheline 0 + MSGRNG_INT, + MSGRNG_PIC_INT, + MSGRNG_MSG, + MSGRNG_EXIT_STATUS, + MSGRNG_MSG_CYCLES, + //cacheline 1 + NETIF_TX = 8, + NETIF_RX, + NETIF_TX_COMPLETE, + NETIF_TX_COMPLETE_TX, + NETIF_RX_CYCLES, + NETIF_TX_COMPLETE_CYCLES, + NETIF_TX_CYCLES, + NETIF_TIMER_START_Q, + //NETIF_REG_FRIN, + //NETIF_INT_REG, + //cacheline 2 + REPLENISH_ENTER = 16, + REPLENISH_ENTER_COUNT, + REPLENISH_CPU, + REPLENISH_FRIN, + REPLENISH_CYCLES, + NETIF_STACK_TX, + NETIF_START_Q, + NETIF_STOP_Q, + //cacheline 3 + USER_MAC_START = 24, + USER_MAC_INT = 24, + USER_MAC_TX_COMPLETE, + USER_MAC_RX, + USER_MAC_POLL, + USER_MAC_TX, + USER_MAC_TX_FAIL, + USER_MAC_TX_COUNT, + USER_MAC_FRIN, + //cacheline 4 + USER_MAC_TX_FAIL_GMAC_CREDITS = 32, + USER_MAC_DO_PAGE_FAULT, + USER_MAC_UPDATE_TLB, + USER_MAC_UPDATE_BIGTLB, + USER_MAC_UPDATE_TLB_PFN0, + USER_MAC_UPDATE_TLB_PFN1, + + XLR_MAX_COUNTERS = 40 }; extern int xlr_counters[MAXCPU][XLR_MAX_COUNTERS]; extern __uint32_t msgrng_msg_cycles; @@ -88,7 +88,7 @@ extern __uint32_t msgrng_msg_cycles; #define xlr_set_counter(x, value) atomic_set_int(&xlr_counters[PCPU_GET(cpuid)][(x)], (value)) #define xlr_get_counter(x) (&xlr_counters[0][(x)]) -#else /* default mode */ +#else /* default mode */ #define xlr_inc_counter(x) #define xlr_dec_counter(x) diff --git a/sys/mips/rmi/ehcireg.h b/sys/mips/rmi/ehcireg.h index e1e7dc3a19e..9c2540c20f8 100644 --- a/sys/mips/rmi/ehcireg.h +++ b/sys/mips/rmi/ehcireg.h @@ -60,7 +60,7 @@ #define PCI_USBREV_1_1 0x11 #define PCI_USBREV_2_0 0x20 -#define PCI_EHCI_FLADJ 0x61 /*RW Frame len adj, SOF=59488+6*fladj */ +#define PCI_EHCI_FLADJ 0x61 /* RW Frame len adj, SOF=59488+6*fladj */ #define PCI_EHCI_PORTWAKECAP 0x62 /* RW Port wake caps (opt) */ @@ -77,30 +77,30 @@ /*** EHCI capability registers ***/ -#define EHCI_CAPLENGTH 0x00 /*RO Capability register length field */ +#define EHCI_CAPLENGTH 0x00 /* RO Capability register length field */ /* reserved 0x01 */ #define EHCI_HCIVERSION 0x02 /* RO Interface version number */ #define EHCI_HCSPARAMS 0x04 /* RO Structural parameters */ #define EHCI_HCS_DEBUGPORT(x) (((x) >> 20) & 0xf) #define EHCI_HCS_P_INDICATOR(x) ((x) & 0x10000) -#define EHCI_HCS_N_CC(x) (((x) >> 12) & 0xf) /* # of companion ctlrs */ -#define EHCI_HCS_N_PCC(x) (((x) >> 8) & 0xf) /* # of ports per comp. */ -#define EHCI_HCS_PPC(x) ((x) & 0x10) /* port power control */ -#define EHCI_HCS_N_PORTS(x) ((x) & 0xf) /* # of ports */ +#define EHCI_HCS_N_CC(x) (((x) >> 12) & 0xf) /* # of companion ctlrs */ +#define EHCI_HCS_N_PCC(x) (((x) >> 8) & 0xf) /* # of ports per comp. */ +#define EHCI_HCS_PPC(x) ((x) & 0x10) /* port power control */ +#define EHCI_HCS_N_PORTS(x) ((x) & 0xf) /* # of ports */ #define EHCI_HCCPARAMS 0x08 /* RO Capability parameters */ -#define EHCI_HCC_EECP(x) (((x) >> 8) & 0xff) /* extended ports caps */ -#define EHCI_HCC_IST(x) (((x) >> 4) & 0xf) /* isoc sched threshold */ -#define EHCI_HCC_ASPC(x) ((x) & 0x4) /* async sched park cap */ -#define EHCI_HCC_PFLF(x) ((x) & 0x2) /* prog frame list flag */ -#define EHCI_HCC_64BIT(x) ((x) & 0x1) /* 64 bit address cap */ +#define EHCI_HCC_EECP(x) (((x) >> 8) & 0xff) /* extended ports caps */ +#define EHCI_HCC_IST(x) (((x) >> 4) & 0xf) /* isoc sched threshold */ +#define EHCI_HCC_ASPC(x) ((x) & 0x4) /* async sched park cap */ +#define EHCI_HCC_PFLF(x) ((x) & 0x2) /* prog frame list flag */ +#define EHCI_HCC_64BIT(x) ((x) & 0x1) /* 64 bit address cap */ -#define EHCI_HCSP_PORTROUTE 0x0c /*RO Companion port route description */ +#define EHCI_HCSP_PORTROUTE 0x0c /* RO Companion port route description */ /* EHCI operational registers. Offset given by EHCI_CAPLENGTH register */ #define EHCI_USBCMD 0x00 /* RO, RW, WO Command register */ -#define EHCI_CMD_ITC_M 0x00ff0000 /* RW interrupt threshold ctrl */ +#define EHCI_CMD_ITC_M 0x00ff0000 /* RW interrupt threshold ctrl */ #define EHCI_CMD_ITC_1 0x00010000 #define EHCI_CMD_ITC_2 0x00020000 #define EHCI_CMD_ITC_4 0x00040000 @@ -108,39 +108,41 @@ #define EHCI_CMD_ITC_16 0x00100000 #define EHCI_CMD_ITC_32 0x00200000 #define EHCI_CMD_ITC_64 0x00400000 -#define EHCI_CMD_ASPME 0x00000800 /* RW/RO async park enable */ -#define EHCI_CMD_ASPMC 0x00000300 /* RW/RO async park count */ -#define EHCI_CMD_LHCR 0x00000080 /* RW light host ctrl reset */ -#define EHCI_CMD_IAAD 0x00000040 /* RW intr on async adv door bell */ -#define EHCI_CMD_ASE 0x00000020 /* RW async sched enable */ -#define EHCI_CMD_PSE 0x00000010 /* RW periodic sched enable */ -#define EHCI_CMD_FLS_M 0x0000000c /* RW/RO frame list size */ -#define EHCI_CMD_FLS(x) (((x) >> 2) & 3) /* RW/RO frame list size */ -#define EHCI_CMD_HCRESET 0x00000002 /* RW reset */ -#define EHCI_CMD_RS 0x00000001 /* RW run/stop */ +#define EHCI_CMD_ASPME 0x00000800 /* RW/RO async park enable */ +#define EHCI_CMD_ASPMC 0x00000300 /* RW/RO async park count */ +#define EHCI_CMD_LHCR 0x00000080 /* RW light host ctrl reset */ +#define EHCI_CMD_IAAD 0x00000040 /* RW intr on async adv door + * bell */ +#define EHCI_CMD_ASE 0x00000020 /* RW async sched enable */ +#define EHCI_CMD_PSE 0x00000010 /* RW periodic sched enable */ +#define EHCI_CMD_FLS_M 0x0000000c /* RW/RO frame list size */ +#define EHCI_CMD_FLS(x) (((x) >> 2) & 3) /* RW/RO frame list size */ +#define EHCI_CMD_HCRESET 0x00000002 /* RW reset */ +#define EHCI_CMD_RS 0x00000001 /* RW run/stop */ #define EHCI_USBSTS 0x04 /* RO, RW, RWC Status register */ -#define EHCI_STS_ASS 0x00008000 /* RO async sched status */ -#define EHCI_STS_PSS 0x00004000 /* RO periodic sched status */ -#define EHCI_STS_REC 0x00002000 /* RO reclamation */ -#define EHCI_STS_HCH 0x00001000 /* RO host controller halted */ -#define EHCI_STS_IAA 0x00000020 /* RWC interrupt on async adv */ -#define EHCI_STS_HSE 0x00000010 /* RWC host system error */ -#define EHCI_STS_FLR 0x00000008 /* RWC frame list rollover */ -#define EHCI_STS_PCD 0x00000004 /* RWC port change detect */ -#define EHCI_STS_ERRINT 0x00000002 /* RWC error interrupt */ -#define EHCI_STS_INT 0x00000001 /* RWC interrupt */ +#define EHCI_STS_ASS 0x00008000 /* RO async sched status */ +#define EHCI_STS_PSS 0x00004000 /* RO periodic sched status */ +#define EHCI_STS_REC 0x00002000 /* RO reclamation */ +#define EHCI_STS_HCH 0x00001000 /* RO host controller halted */ +#define EHCI_STS_IAA 0x00000020 /* RWC interrupt on async adv */ +#define EHCI_STS_HSE 0x00000010 /* RWC host system error */ +#define EHCI_STS_FLR 0x00000008 /* RWC frame list rollover */ +#define EHCI_STS_PCD 0x00000004 /* RWC port change detect */ +#define EHCI_STS_ERRINT 0x00000002 /* RWC error interrupt */ +#define EHCI_STS_INT 0x00000001 /* RWC interrupt */ #define EHCI_STS_INTRS(x) ((x) & 0x3f) #define EHCI_NORMAL_INTRS (EHCI_STS_IAA | EHCI_STS_HSE | EHCI_STS_PCD | EHCI_STS_ERRINT | EHCI_STS_INT) #define EHCI_USBINTR 0x08 /* RW Interrupt register */ -#define EHCI_INTR_IAAE 0x00000020 /* interrupt on async advance ena */ -#define EHCI_INTR_HSEE 0x00000010 /* host system error ena */ -#define EHCI_INTR_FLRE 0x00000008 /* frame list rollover ena */ -#define EHCI_INTR_PCIE 0x00000004 /* port change ena */ -#define EHCI_INTR_UEIE 0x00000002 /* USB error intr ena */ -#define EHCI_INTR_UIE 0x00000001 /* USB intr ena */ +#define EHCI_INTR_IAAE 0x00000020 /* interrupt on async advance + * ena */ +#define EHCI_INTR_HSEE 0x00000010 /* host system error ena */ +#define EHCI_INTR_FLRE 0x00000008 /* frame list rollover ena */ +#define EHCI_INTR_PCIE 0x00000004 /* port change ena */ +#define EHCI_INTR_UEIE 0x00000002 /* USB error intr ena */ +#define EHCI_INTR_UIE 0x00000001 /* USB intr ena */ #define EHCI_FRINDEX 0x0c /* RW Frame Index register */ @@ -150,30 +152,30 @@ #define EHCI_ASYNCLISTADDR 0x18 /* RW Async List Base */ #define EHCI_CONFIGFLAG 0x40 /* RW Configure Flag register */ -#define EHCI_CONF_CF 0x00000001 /* RW configure flag */ +#define EHCI_CONF_CF 0x00000001 /* RW configure flag */ -#define EHCI_PORTSC(n) (0x40+4*(n)) /* RO, RW, RWC Port Status reg */ -#define EHCI_PS_WKOC_E 0x00400000 /* RW wake on over current ena */ -#define EHCI_PS_WKDSCNNT_E 0x00200000 /* RW wake on disconnect ena */ -#define EHCI_PS_WKCNNT_E 0x00100000 /* RW wake on connect ena */ -#define EHCI_PS_PTC 0x000f0000 /* RW port test control */ -#define EHCI_PS_PIC 0x0000c000 /* RW port indicator control */ -#define EHCI_PS_PO 0x00002000 /* RW port owner */ -#define EHCI_PS_PP 0x00001000 /* RW,RO port power */ -#define EHCI_PS_LS 0x00000c00 /* RO line status */ +#define EHCI_PORTSC(n) (0x40+4*(n)) /* RO, RW, RWC Port Status reg */ +#define EHCI_PS_WKOC_E 0x00400000 /* RW wake on over current ena */ +#define EHCI_PS_WKDSCNNT_E 0x00200000 /* RW wake on disconnect ena */ +#define EHCI_PS_WKCNNT_E 0x00100000 /* RW wake on connect ena */ +#define EHCI_PS_PTC 0x000f0000 /* RW port test control */ +#define EHCI_PS_PIC 0x0000c000 /* RW port indicator control */ +#define EHCI_PS_PO 0x00002000 /* RW port owner */ +#define EHCI_PS_PP 0x00001000 /* RW,RO port power */ +#define EHCI_PS_LS 0x00000c00 /* RO line status */ #define EHCI_PS_IS_LOWSPEED(x) (((x) & EHCI_PS_LS) == 0x00000400) -#define EHCI_PS_PR 0x00000100 /* RW port reset */ -#define EHCI_PS_SUSP 0x00000080 /* RW suspend */ -#define EHCI_PS_FPR 0x00000040 /* RW force port resume */ -#define EHCI_PS_OCC 0x00000020 /* RWC over current change */ -#define EHCI_PS_OCA 0x00000010 /* RO over current active */ -#define EHCI_PS_PEC 0x00000008 /* RWC port enable change */ -#define EHCI_PS_PE 0x00000004 /* RW port enable */ -#define EHCI_PS_CSC 0x00000002 /* RWC connect status change */ -#define EHCI_PS_CS 0x00000001 /* RO connect status */ +#define EHCI_PS_PR 0x00000100 /* RW port reset */ +#define EHCI_PS_SUSP 0x00000080 /* RW suspend */ +#define EHCI_PS_FPR 0x00000040 /* RW force port resume */ +#define EHCI_PS_OCC 0x00000020 /* RWC over current change */ +#define EHCI_PS_OCA 0x00000010 /* RO over current active */ +#define EHCI_PS_PEC 0x00000008 /* RWC port enable change */ +#define EHCI_PS_PE 0x00000004 /* RW port enable */ +#define EHCI_PS_CSC 0x00000002 /* RWC connect status change */ +#define EHCI_PS_CS 0x00000001 /* RO connect status */ #define EHCI_PS_CLEAR (EHCI_PS_OCC|EHCI_PS_PEC|EHCI_PS_CSC) -#define EHCI_PORT_RESET_COMPLETE 2 /* ms */ +#define EHCI_PORT_RESET_COMPLETE 2 /* ms */ #define EHCI_FLALIGN_ALIGN 0x1000 @@ -186,6 +188,7 @@ #endif typedef u_int32_t ehci_link_t; + #define EHCI_LINK_TERMINATE 0x00000001 #define EHCI_LINK_TYPE(x) ((x) & 0x00000006) #define EHCI_LINK_ITD 0x0 @@ -198,24 +201,26 @@ typedef u_int32_t ehci_physaddr_t; /* Isochronous Transfer Descriptor */ typedef struct { - ehci_link_t itd_next; + ehci_link_t itd_next; /* XXX many more */ -} ehci_itd_t; +} ehci_itd_t; + #define EHCI_ITD_ALIGN 32 /* Split Transaction Isochronous Transfer Descriptor */ typedef struct { - ehci_link_t sitd_next; + ehci_link_t sitd_next; /* XXX many more */ -} ehci_sitd_t; +} ehci_sitd_t; + #define EHCI_SITD_ALIGN 32 /* Queue Element Transfer Descriptor */ #define EHCI_QTD_NBUFFERS 5 typedef struct { - ehci_link_t qtd_next; - ehci_link_t qtd_altnext; - u_int32_t qtd_status; + ehci_link_t qtd_next; + ehci_link_t qtd_altnext; + u_int32_t qtd_status; #define EHCI_QTD_GET_STATUS(x) (((x) >> 0) & 0xff) #define EHCI_QTD_SET_STATUS(x) ((x) << 0) #define EHCI_QTD_ACTIVE 0x80 @@ -243,59 +248,62 @@ typedef struct { #define EHCI_QTD_GET_TOGGLE(x) (((x) >> 31) & 0x1) #define EHCI_QTD_SET_TOGGLE(x) ((x) << 31) #define EHCI_QTD_TOGGLE_MASK 0x80000000 - ehci_physaddr_t qtd_buffer[EHCI_QTD_NBUFFERS]; + ehci_physaddr_t qtd_buffer[EHCI_QTD_NBUFFERS]; ehci_physaddr_t qtd_buffer_hi[EHCI_QTD_NBUFFERS]; -} ehci_qtd_t; +} ehci_qtd_t; + #define EHCI_QTD_ALIGN 32 /* Queue Head */ typedef struct { - ehci_link_t qh_link; - u_int32_t qh_endp; -#define EHCI_QH_GET_ADDR(x) (((x) >> 0) & 0x7f) /* endpoint addr */ + ehci_link_t qh_link; + u_int32_t qh_endp; +#define EHCI_QH_GET_ADDR(x) (((x) >> 0) & 0x7f) /* endpoint addr */ #define EHCI_QH_SET_ADDR(x) (x) #define EHCI_QH_ADDRMASK 0x0000007f -#define EHCI_QH_GET_INACT(x) (((x) >> 7) & 0x01) /* inactivate on next */ +#define EHCI_QH_GET_INACT(x) (((x) >> 7) & 0x01) /* inactivate on next */ #define EHCI_QH_INACT 0x00000080 -#define EHCI_QH_GET_ENDPT(x) (((x) >> 8) & 0x0f) /* endpoint no */ +#define EHCI_QH_GET_ENDPT(x) (((x) >> 8) & 0x0f) /* endpoint no */ #define EHCI_QH_SET_ENDPT(x) ((x) << 8) -#define EHCI_QH_GET_EPS(x) (((x) >> 12) & 0x03) /* endpoint speed */ +#define EHCI_QH_GET_EPS(x) (((x) >> 12) & 0x03) /* endpoint speed */ #define EHCI_QH_SET_EPS(x) ((x) << 12) #define EHCI_QH_SPEED_FULL 0x0 #define EHCI_QH_SPEED_LOW 0x1 #define EHCI_QH_SPEED_HIGH 0x2 -#define EHCI_QH_GET_DTC(x) (((x) >> 14) & 0x01) /* data toggle control */ +#define EHCI_QH_GET_DTC(x) (((x) >> 14) & 0x01) /* data toggle control */ #define EHCI_QH_DTC 0x00004000 -#define EHCI_QH_GET_HRECL(x) (((x) >> 15) & 0x01) /* head of reclamation */ +#define EHCI_QH_GET_HRECL(x) (((x) >> 15) & 0x01) /* head of reclamation */ #define EHCI_QH_HRECL 0x00008000 -#define EHCI_QH_GET_MPL(x) (((x) >> 16) & 0x7ff) /* max packet len */ +#define EHCI_QH_GET_MPL(x) (((x) >> 16) & 0x7ff) /* max packet len */ #define EHCI_QH_SET_MPL(x) ((x) << 16) #define EHCI_QH_MPLMASK 0x07ff0000 -#define EHCI_QH_GET_CTL(x) (((x) >> 27) & 0x01) /* control endpoint */ +#define EHCI_QH_GET_CTL(x) (((x) >> 27) & 0x01) /* control endpoint */ #define EHCI_QH_CTL 0x08000000 -#define EHCI_QH_GET_NRL(x) (((x) >> 28) & 0x0f) /* NAK reload */ +#define EHCI_QH_GET_NRL(x) (((x) >> 28) & 0x0f) /* NAK reload */ #define EHCI_QH_SET_NRL(x) ((x) << 28) - u_int32_t qh_endphub; -#define EHCI_QH_GET_SMASK(x) (((x) >> 0) & 0xff) /* intr sched mask */ + u_int32_t qh_endphub; +#define EHCI_QH_GET_SMASK(x) (((x) >> 0) & 0xff) /* intr sched mask */ #define EHCI_QH_SET_SMASK(x) ((x) << 0) -#define EHCI_QH_GET_CMASK(x) (((x) >> 8) & 0xff) /* split completion mask */ +#define EHCI_QH_GET_CMASK(x) (((x) >> 8) & 0xff) /* split completion mask */ #define EHCI_QH_SET_CMASK(x) ((x) << 8) -#define EHCI_QH_GET_HUBA(x) (((x) >> 16) & 0x7f) /* hub address */ +#define EHCI_QH_GET_HUBA(x) (((x) >> 16) & 0x7f) /* hub address */ #define EHCI_QH_SET_HUBA(x) ((x) << 16) -#define EHCI_QH_GET_PORT(x) (((x) >> 23) & 0x7f) /* hub port */ +#define EHCI_QH_GET_PORT(x) (((x) >> 23) & 0x7f) /* hub port */ #define EHCI_QH_SET_PORT(x) ((x) << 23) -#define EHCI_QH_GET_MULT(x) (((x) >> 30) & 0x03) /* pipe multiplier */ +#define EHCI_QH_GET_MULT(x) (((x) >> 30) & 0x03) /* pipe multiplier */ #define EHCI_QH_SET_MULT(x) ((x) << 30) - ehci_link_t qh_curqtd; - ehci_qtd_t qh_qtd; -} ehci_qh_t; + ehci_link_t qh_curqtd; + ehci_qtd_t qh_qtd; +} ehci_qh_t; + #define EHCI_QH_ALIGN 32 /* Periodic Frame Span Traversal Node */ typedef struct { - ehci_link_t fstn_link; - ehci_link_t fstn_back; -} ehci_fstn_t; + ehci_link_t fstn_link; + ehci_link_t fstn_back; +} ehci_fstn_t; + #define EHCI_FSTN_ALIGN 32 -#endif /* _DEV_PCI_EHCIREG_H_ */ +#endif /* _DEV_PCI_EHCIREG_H_ */ diff --git a/sys/mips/rmi/ehcivar.h b/sys/mips/rmi/ehcivar.h index eb318ad03c2..b1b80be83b9 100644 --- a/sys/mips/rmi/ehcivar.h +++ b/sys/mips/rmi/ehcivar.h @@ -39,12 +39,13 @@ typedef struct ehci_soft_qtd { ehci_qtd_t qtd; - struct ehci_soft_qtd *nextqtd; /* mirrors nextqtd in TD */ + struct ehci_soft_qtd *nextqtd; /* mirrors nextqtd in TD */ ehci_physaddr_t physaddr; usbd_xfer_handle xfer; - LIST_ENTRY(ehci_soft_qtd) hnext; + LIST_ENTRY(ehci_soft_qtd) hnext; u_int16_t len; -} ehci_soft_qtd_t; +} ehci_soft_qtd_t; + #define EHCI_SQTD_SIZE ((sizeof (struct ehci_soft_qtd) + EHCI_QTD_ALIGN - 1) / EHCI_QTD_ALIGN * EHCI_QTD_ALIGN) #define EHCI_SQTD_CHUNK (EHCI_PAGE_SIZE / EHCI_SQTD_SIZE) @@ -55,14 +56,15 @@ typedef struct ehci_soft_qh { struct ehci_soft_qtd *sqtd; ehci_physaddr_t physaddr; int islot; /* Interrupt list slot. */ -} ehci_soft_qh_t; +} ehci_soft_qh_t; + #define EHCI_SQH_SIZE ((sizeof (struct ehci_soft_qh) + EHCI_QH_ALIGN - 1) / EHCI_QH_ALIGN * EHCI_QH_ALIGN) #define EHCI_SQH_CHUNK (EHCI_PAGE_SIZE / EHCI_SQH_SIZE) struct ehci_xfer { struct usbd_xfer xfer; - struct usb_task abort_task; - LIST_ENTRY(ehci_xfer) inext; /* list of active xfers */ + struct usb_task abort_task; + LIST_ENTRY(ehci_xfer) inext; /* list of active xfers */ ehci_soft_qtd_t *sqtdstart; ehci_soft_qtd_t *sqtdend; u_int32_t ehci_xfer_flags; @@ -70,6 +72,7 @@ struct ehci_xfer { int isdone; #endif }; + #define EHCI_XFER_ABORTING 0x0001 /* xfer is aborting. */ #define EHCI_XFER_ABORTWAIT 0x0002 /* abort completion is being awaited. */ @@ -79,7 +82,7 @@ struct ehci_xfer { * Information about an entry in the interrupt list. */ struct ehci_soft_islot { - ehci_soft_qh_t *sqh; /* Queue Head. */ + ehci_soft_qh_t *sqh; /* Queue Head. */ }; #define EHCI_FRAMELIST_MAXCOUNT 1024 @@ -97,7 +100,7 @@ struct ehci_soft_islot { #define EHCI_SCFLG_LOSTINTRBUG 0x0002 /* workaround for VIA / ATI chipsets */ typedef struct ehci_softc { - struct usbd_bus sc_bus; /* base device */ + struct usbd_bus sc_bus; /* base device */ int sc_flags; bus_space_tag_t iot; bus_space_handle_t ioh; @@ -108,15 +111,15 @@ typedef struct ehci_softc { struct resource *io_res; struct resource *irq_res; #endif - u_int sc_offs; /* offset to operational regs */ + u_int sc_offs; /* offset to operational regs */ - char sc_vendor[32]; /* vendor string for root hub */ - int sc_id_vendor; /* vendor ID for root hub */ + char sc_vendor[32]; /* vendor string for root hub */ + int sc_id_vendor; /* vendor ID for root hub */ - u_int32_t sc_cmd; /* shadow of cmd reg during suspend */ + u_int32_t sc_cmd; /* shadow of cmd reg during suspend */ #if defined(__NetBSD__) || defined(__OpenBSD__) - void *sc_powerhook; /* cookie from power hook */ - void *sc_shutdownhook; /* cookie from shutdown hook */ + void *sc_powerhook; /* cookie from power hook */ + void *sc_shutdownhook; /* cookie from shutdown hook */ #endif u_int sc_ncomp; @@ -127,29 +130,29 @@ typedef struct ehci_softc { ehci_link_t *sc_flist; u_int sc_flsize; #ifndef __FreeBSD__ - u_int sc_rand; /* XXX need proper intr scheduling */ + u_int sc_rand; /* XXX need proper intr scheduling */ #endif struct ehci_soft_islot sc_islots[EHCI_INTRQHS]; - LIST_HEAD(, ehci_xfer) sc_intrhead; + LIST_HEAD(, ehci_xfer) sc_intrhead; ehci_soft_qh_t *sc_freeqhs; ehci_soft_qtd_t *sc_freeqtds; int sc_noport; - u_int8_t sc_addr; /* device address */ - u_int8_t sc_conf; /* device configuration */ + u_int8_t sc_addr; /* device address */ + u_int8_t sc_conf; /* device configuration */ usbd_xfer_handle sc_intrxfer; char sc_isreset; #ifdef USB_USE_SOFTINTR char sc_softwake; -#endif /* USB_USE_SOFTINTR */ +#endif /* USB_USE_SOFTINTR */ u_int32_t sc_eintrs; ehci_soft_qh_t *sc_async_head; - SIMPLEQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */ + SIMPLEQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */ struct lock sc_doorbell_lock; @@ -157,13 +160,13 @@ typedef struct ehci_softc { usb_callout_t sc_tmo_intrlist; #if defined(__NetBSD__) || defined(__OpenBSD__) - device_ptr_t sc_child; /* /dev/usb# device */ + device_ptr_t sc_child; /* /dev/usb# device */ #endif char sc_dying; #if defined(__NetBSD__) struct usb_dma_reserve sc_dma_reserve; #endif -} ehci_softc_t; +} ehci_softc_t; #define EREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (a)) #define EREAD2(sc, a) bus_space_read_2((sc)->iot, (sc)->ioh, (a)) @@ -178,14 +181,15 @@ typedef struct ehci_softc { #define EOWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x)) #define EOWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x)) -usbd_status ehci_init(ehci_softc_t *); -int ehci_intr(void *); -int ehci_detach(ehci_softc_t *, int); +usbd_status ehci_init(ehci_softc_t *); +int ehci_intr(void *); +int ehci_detach(ehci_softc_t *, int); + #if defined(__NetBSD__) || defined(__OpenBSD__) -int ehci_activate(device_ptr_t, enum devact); +int ehci_activate(device_ptr_t, enum devact); + #endif -void ehci_power(int state, void *priv); -void ehci_shutdown(void *v); +void ehci_power(int state, void *priv); +void ehci_shutdown(void *v); #define MS_TO_TICKS(ms) ((ms) * hz / 1000) - diff --git a/sys/mips/rmi/interrupt.h b/sys/mips/rmi/interrupt.h index c13a27c756c..013a8e9f97c 100644 --- a/sys/mips/rmi/interrupt.h +++ b/sys/mips/rmi/interrupt.h @@ -39,5 +39,4 @@ #define IRQ_MSGRING 6 #define IRQ_TIMER 7 -#endif /* _RMI_INTERRUPT_H_ */ - +#endif /* _RMI_INTERRUPT_H_ */ diff --git a/sys/mips/rmi/intr_machdep.c b/sys/mips/rmi/intr_machdep.c index 3245ea7e2ac..9c1b8f818b3 100644 --- a/sys/mips/rmi/intr_machdep.c +++ b/sys/mips/rmi/intr_machdep.c @@ -55,40 +55,42 @@ struct mips_intrhand mips_intr_handlers[XLR_MAX_INTR]; static void mips_mask_hard_irq(void *source) { - uintptr_t irq = (uintptr_t)source; + uintptr_t irq = (uintptr_t) source; - write_c0_eimr64(read_c0_eimr64() & ~(1ULL< XLR_MAX_INTR) panic("%s called for unknown hard intr %d", __func__, irq); - /* FIXME locking - not needed now, because we do this only on startup from - CPU0 */ + /* + * FIXME locking - not needed now, because we do this only on + * startup from CPU0 + */ mih = &mips_intr_handlers[irq]; - /*mih->cntp = &intrcnt[irq]; */ + /* mih->cntp = &intrcnt[irq]; */ ie = mih->mih_event; if (ie == NULL) { - errcode = intr_event_create(&ie, (void *)(uintptr_t)irq, 0, + errcode = intr_event_create(&ie, (void *)(uintptr_t) irq, 0, irq, mips_mask_hard_irq, mips_unmask_hard_irq, NULL, NULL, "hard intr%d:", irq); - + if (errcode) { printf("Could not create event for intr %d\n", irq); return; @@ -97,17 +99,17 @@ cpu_establish_hardintr(const char *name, driver_filter_t *filt, intr_event_add_handler(ie, name, filt, handler, arg, intr_priority(flags), flags, cookiep); mih->mih_event = ie; - mips_unmask_hard_irq((void*)(uintptr_t)irq); + mips_unmask_hard_irq((void *)(uintptr_t) irq); } void -cpu_establish_softintr(const char *name, driver_filter_t *filt, - void (*handler)(void*), void *arg, int irq, int flags, +cpu_establish_softintr(const char *name, driver_filter_t * filt, + void (*handler) (void *), void *arg, int irq, int flags, void **cookiep) { - /* we don't separate them into soft/hard like other mips */ - cpu_establish_hardintr(name, filt, handler, arg, irq, flags, cookiep); + /* we don't separate them into soft/hard like other mips */ + cpu_establish_hardintr(name, filt, handler, arg, irq, flags, cookiep); } @@ -126,24 +128,23 @@ cpu_intr(struct trapframe *tf) critical_exit(); return; } - - /* No need to clear the EIRR here. the handler is gonna - * write to compare which clears eirr also + /* + * No need to clear the EIRR here. the handler is gonna write to + * compare which clears eirr also */ if (eirr & (1 << IRQ_TIMER)) { count_compare_clockhandler(tf); critical_exit(); return; } - /* FIXME sched pin >? LOCK>? */ - for(i = sizeof(eirr)*8 - 1; i>=0; i--) { - if ((eirr & 1ULL<= 0; i--) { + if ((eirr & 1ULL << i) == 0) continue; #ifdef SMP /* These are reserved interrupts */ - if((i == IPI_AST) || (i == IPI_RENDEZVOUS) || (i == IPI_STOP) - || (i == IPI_SMP_CALL_FUNCTION)) { + if ((i == IPI_AST) || (i == IPI_RENDEZVOUS) || (i == IPI_STOP) + || (i == IPI_SMP_CALL_FUNCTION)) { write_c0_eirr64(1ULL << i); pic_ack(i); smp_handle_ipi(tf, i); @@ -161,19 +162,17 @@ cpu_intr(struct trapframe *tf) #endif #endif mih = &mips_intr_handlers[i]; - /*atomic_add_long(mih->cntp, 1);*/ - ie = mih->mih_event; + /* atomic_add_long(mih->cntp, 1); */ + ie = mih->mih_event; write_c0_eirr64(1ULL << i); if (!ie || TAILQ_EMPTY(&ie->ie_handlers)) { printf("stray interrupt %d\n", i); continue; } - if (intr_event_handle(ie, tf) != 0) { - printf("stray interrupt %d\n",i); + printf("stray interrupt %d\n", i); } - } critical_exit(); } diff --git a/sys/mips/rmi/iodi.c b/sys/mips/rmi/iodi.c index 256d1bb8f3c..2dc2b2b6773 100644 --- a/sys/mips/rmi/iodi.c +++ b/sys/mips/rmi/iodi.c @@ -74,15 +74,18 @@ extern void iodi_activateirqs(void); extern bus_space_tag_t uart_bus_space_mem; -static struct resource *iodi_alloc_resource(device_t, device_t, int, int *, - u_long, u_long, u_long, u_int); +static struct resource * +iodi_alloc_resource(device_t, device_t, int, int *, + u_long, u_long, u_long, u_int); -static int iodi_activate_resource(device_t, device_t, int, int, - struct resource *); -static int iodi_setup_intr(device_t, device_t, struct resource *, int, - driver_filter_t *, driver_intr_t *, void *, void **); +static int +iodi_activate_resource(device_t, device_t, int, int, + struct resource *); +static int +iodi_setup_intr(device_t, device_t, struct resource *, int, + driver_filter_t *, driver_intr_t *, void *, void **); -struct iodi_softc *iodi_softc; /* There can be only one. */ +struct iodi_softc *iodi_softc; /* There can be only one. */ /* static void pic_usb_ack(void *arg) @@ -98,56 +101,56 @@ static void pic_usb_ack(void *arg) static int iodi_setup_intr(device_t dev, device_t child, - struct resource *ires, int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, - void **cookiep) + struct resource *ires, int flags, driver_filter_t * filt, driver_intr_t * intr, void *arg, + void **cookiep) { - int level; - xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); - xlr_reg_t reg; + int level; + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + xlr_reg_t reg; - /* FIXME is this the right place to fiddle with PIC? */ - if (strcmp(device_get_name(child),"uart") == 0) { - /* FIXME uart 1? */ - mtx_lock_spin(&xlr_pic_lock); - level = PIC_IRQ_IS_EDGE_TRIGGERED(PIC_IRT_UART_0_INDEX); - xlr_write_reg(mmio, PIC_IRT_0_UART_0, 0x01); - xlr_write_reg(mmio, PIC_IRT_1_UART_0, ((1 << 31) | (level<<30)|(1<<6)|(PIC_UART_0_IRQ))); - mtx_unlock_spin(&xlr_pic_lock); - cpu_establish_hardintr("uart", NULL, - (driver_intr_t *)intr, (void *)arg, PIC_UART_0_IRQ, flags, cookiep); + /* FIXME is this the right place to fiddle with PIC? */ + if (strcmp(device_get_name(child), "uart") == 0) { + /* FIXME uart 1? */ + mtx_lock_spin(&xlr_pic_lock); + level = PIC_IRQ_IS_EDGE_TRIGGERED(PIC_IRT_UART_0_INDEX); + xlr_write_reg(mmio, PIC_IRT_0_UART_0, 0x01); + xlr_write_reg(mmio, PIC_IRT_1_UART_0, ((1 << 31) | (level << 30) | (1 << 6) | (PIC_UART_0_IRQ))); + mtx_unlock_spin(&xlr_pic_lock); + cpu_establish_hardintr("uart", NULL, + (driver_intr_t *) intr, (void *)arg, PIC_UART_0_IRQ, flags, cookiep); - } else if (strcmp(device_get_name(child),"rge") == 0) { - int irq; - irq = rman_get_rid(ires); - mtx_lock_spin(&xlr_pic_lock); - reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE); - xlr_write_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE, reg | (1<<6)|(1<<30)| (1<<31)); - mtx_unlock_spin(&xlr_pic_lock); - cpu_establish_hardintr("rge", NULL, (driver_intr_t *)intr, (void *)arg, irq, flags, cookiep); + } else if (strcmp(device_get_name(child), "rge") == 0) { + int irq; - } else if (strcmp(device_get_name(child),"ehci") == 0) { - mtx_lock_spin(&xlr_pic_lock); - reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + PIC_USB_IRQ - PIC_IRQ_BASE); - xlr_write_reg(mmio, PIC_IRT_1_BASE + PIC_USB_IRQ - PIC_IRQ_BASE, reg | (1<<6)|(1<<30)| (1<<31)); - mtx_unlock_spin(&xlr_pic_lock); - cpu_establish_hardintr("ehci", NULL, (driver_intr_t *)intr, (void *)arg, PIC_USB_IRQ, flags, cookiep); - } + irq = rman_get_rid(ires); + mtx_lock_spin(&xlr_pic_lock); + reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE); + xlr_write_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE, reg | (1 << 6) | (1 << 30) | (1 << 31)); + mtx_unlock_spin(&xlr_pic_lock); + cpu_establish_hardintr("rge", NULL, (driver_intr_t *) intr, (void *)arg, irq, flags, cookiep); - BUS_SETUP_INTR(device_get_parent(dev), - child, ires, flags, filt, intr, arg, cookiep); + } else if (strcmp(device_get_name(child), "ehci") == 0) { + mtx_lock_spin(&xlr_pic_lock); + reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + PIC_USB_IRQ - PIC_IRQ_BASE); + xlr_write_reg(mmio, PIC_IRT_1_BASE + PIC_USB_IRQ - PIC_IRQ_BASE, reg | (1 << 6) | (1 << 30) | (1 << 31)); + mtx_unlock_spin(&xlr_pic_lock); + cpu_establish_hardintr("ehci", NULL, (driver_intr_t *) intr, (void *)arg, PIC_USB_IRQ, flags, cookiep); + } + BUS_SETUP_INTR(device_get_parent(dev), + child, ires, flags, filt, intr, arg, cookiep); - return (0); + return (0); } /* Strange hook found in mips/include/bus.h */ #ifndef MIPS_BUS_SPACE_PCI -#define MIPS_BUS_SPACE_PCI 10 +#define MIPS_BUS_SPACE_PCI 10 #endif static struct resource * iodi_alloc_resource(device_t bus, device_t child, int type, int *rid, - u_long start, u_long end, u_long count, u_int flags) + u_long start, u_long end, u_long count, u_int flags) { struct resource *res = malloc(sizeof(*res), M_DEVBUF, M_WAITOK); int unit; @@ -156,53 +159,52 @@ iodi_alloc_resource(device_t bus, device_t child, int type, int *rid, switch (type) { case SYS_RES_IRQ: device_printf(bus, "IRQ resource - for %s %lx-%lx\n", - device_get_nameunit(child), start, end); - break; + device_get_nameunit(child), start, end); + break; - case SYS_RES_IOPORT: + case SYS_RES_IOPORT: device_printf(bus, "IOPORT resource - for %s %lx-%lx\n", - device_get_nameunit(child), start, end); - break; + device_get_nameunit(child), start, end); + break; - case SYS_RES_MEMORY: + case SYS_RES_MEMORY: device_printf(bus, "MEMORY resource - for %s %lx-%lx\n", - device_get_nameunit(child), start, end); - break; - } + device_get_nameunit(child), start, end); + break; + } #endif - if (strcmp(device_get_name(child),"uart") == 0) { - if ((unit=device_get_unit(child)) == 0) { /* uart 0 */ + if (strcmp(device_get_name(child), "uart") == 0) { + if ((unit = device_get_unit(child)) == 0) { /* uart 0 */ res->r_bushandle = (xlr_io_base + XLR_IO_UART_0_OFFSET); - } - else if ( unit == 1) { + } else if (unit == 1) { res->r_bushandle = (xlr_io_base + XLR_IO_UART_1_OFFSET); - } - else + } else printf("%s: Unknown uart unit\n", __FUNCTION__); res->r_bustag = uart_bus_space_mem; - } else if (strcmp(device_get_name(child),"ehci") == 0) { + } else if (strcmp(device_get_name(child), "ehci") == 0) { res->r_bushandle = 0xbef24000; - res->r_bustag = (bus_space_tag_t)MIPS_BUS_SPACE_PCI; - } else if (strcmp(device_get_name(child),"cfi") == 0) { + res->r_bustag = (bus_space_tag_t) MIPS_BUS_SPACE_PCI; + } else if (strcmp(device_get_name(child), "cfi") == 0) { res->r_bushandle = 0xbc000000; res->r_bustag = 0; } - /*res->r_start = *rid;*/ + /* res->r_start = *rid; */ return (res); } static int iodi_activate_resource(device_t bus, device_t child, int type, int rid, - struct resource *r) + struct resource *r) { return (0); } + /* prototypes */ -static int iodi_probe(device_t); -static int iodi_attach(device_t); -static void iodi_identify(driver_t *, device_t); +static int iodi_probe(device_t); +static int iodi_attach(device_t); +static void iodi_identify(driver_t *, device_t); int iodi_probe(device_t dev) @@ -211,9 +213,9 @@ iodi_probe(device_t dev) } void -iodi_identify(driver_t *driver, device_t parent) +iodi_identify(driver_t * driver, device_t parent) { - + BUS_ADD_CHILD(parent, 0, "iodi", 0); } @@ -221,15 +223,16 @@ int iodi_attach(device_t dev) { device_t tmpd; + /* - * Attach each devices + * Attach each devices */ device_add_child(dev, "uart", 0); device_add_child(dev, "xlr_i2c", 0); - + if (xlr_board_info.usb) device_add_child(dev, "ehci", 0); - + if (xlr_board_info.cfi) device_add_child(dev, "cfi", 0); @@ -246,7 +249,6 @@ iodi_attach(device_t dev) tmpd = device_add_child(dev, "rge", 3); device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]); } - if (xlr_board_info.gmac_block[1].enabled) { if (xlr_board_info.gmac_block[1].type == XLR_GMAC) { tmpd = device_add_child(dev, "rge", 4); @@ -261,17 +263,16 @@ iodi_attach(device_t dev) tmpd = device_add_child(dev, "rge", 7); device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]); } else if (xlr_board_info.gmac_block[1].type == XLR_XGMAC) { -#if 0 /* XGMAC not yet */ +#if 0 /* XGMAC not yet */ tmpd = device_add_child(dev, "rge", 4); device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]); tmpd = device_add_child(dev, "rge", 5); device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]); #endif - } else - device_printf(dev, "Unknown type of gmac 1\n"); + } else + device_printf(dev, "Unknown type of gmac 1\n"); } - bus_generic_probe(dev); bus_generic_attach(dev); return 0; @@ -290,7 +291,7 @@ static device_method_t iodi_methods[] = { static driver_t iodi_driver = { "iodi", iodi_methods, - 1 /* no softc */ + 1 /* no softc */ }; static devclass_t iodi_devclass; diff --git a/sys/mips/rmi/iomap.h b/sys/mips/rmi/iomap.h index 4aa8f70b3a0..1d1e8ee814e 100644 --- a/sys/mips/rmi/iomap.h +++ b/sys/mips/rmi/iomap.h @@ -92,7 +92,7 @@ * For now, choose 256M phys in kseg1 = 0xA0000000 + (1<<28) * Config space spans 256 (num of buses) * 256 (num functions) * 256 bytes * ie 1<<24 = 16M - */ + */ #define DEFAULT_PCI_CONFIG_BASE 0x18000000 #define DEFAULT_HT_TYPE0_CFG_BASE 0x16000000 #define DEFAULT_HT_TYPE1_CFG_BASE 0x17000000 @@ -107,4 +107,4 @@ extern unsigned long xlr_io_base; extern void on_chip_init(void); -#endif /* _RMI_IOMAP_H_ */ +#endif /* _RMI_IOMAP_H_ */ diff --git a/sys/mips/rmi/msgring.c b/sys/mips/rmi/msgring.c index 860cd72a394..77d964c71b4 100644 --- a/sys/mips/rmi/msgring.c +++ b/sys/mips/rmi/msgring.c @@ -30,289 +30,288 @@ /********************************************************** * -----------------DO NOT EDIT THIS FILE------------------ * This file has been autogenerated by the build process - * from "msgring.cfg" + * from "msgring.cfg" **********************************************************/ -#include +#include struct bucket_size bucket_sizes = { { - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 0, - 32, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 0, - 0, 32, 32, 32, 32, 32, 0, 32, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 32, 0, 32, 0, 0, 0, 0, - 128, 0, 0, 0, 128, 0, 0, 0, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 0, + 32, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 0, + 0, 32, 32, 32, 32, 32, 0, 32, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 0, 32, 0, 0, 0, 0, + 128, 0, 0, 0, 128, 0, 0, 0, } }; struct stn_cc cc_table_cpu_0 = {{ - - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 4 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, - {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, - {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, - {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, - {0, 2 , 4 , 4 , 4 , 4 , 0 , 2 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 2 , 0 , 2 , 0 , 0 , 0 , 0 }, - {16, 0 , 0 , 0 , 16 , 0 , 0 , 0 }, - }}; + + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 4, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {4, 2, 2, 2, 2, 2, 2, 2}, + {2, 2, 2, 2, 2, 2, 2, 0}, + {4, 2, 2, 2, 2, 2, 2, 2}, + {2, 2, 2, 2, 2, 2, 2, 0}, + {0, 2, 4, 4, 4, 4, 0, 2}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 2, 0, 2, 0, 0, 0, 0}, + {16, 0, 0, 0, 16, 0, 0, 0}, +}}; struct stn_cc cc_table_cpu_1 = {{ - - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, - {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, - {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, - {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, - {0, 2 , 4 , 4 , 4 , 4 , 0 , 2 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 2 , 0 , 2 , 0 , 0 , 0 , 0 }, - {16, 0 , 0 , 0 , 16 , 0 , 0 , 0 }, - }}; + + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {4, 2, 2, 2, 2, 2, 2, 2}, + {2, 2, 2, 2, 2, 2, 2, 0}, + {4, 2, 2, 2, 2, 2, 2, 2}, + {2, 2, 2, 2, 2, 2, 2, 0}, + {0, 2, 4, 4, 4, 4, 0, 2}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 2, 0, 2, 0, 0, 0, 0}, + {16, 0, 0, 0, 16, 0, 0, 0}, +}}; struct stn_cc cc_table_cpu_2 = {{ - - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, - {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, - {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, - {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, - {0, 4 , 4 , 4 , 4 , 4 , 0 , 4 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 4 , 0 , 4 , 0 , 0 , 0 , 0 }, - {16, 0 , 0 , 0 , 16 , 0 , 0 , 0 }, - }}; + + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {4, 2, 2, 2, 2, 2, 2, 2}, + {2, 2, 2, 2, 2, 2, 2, 0}, + {4, 2, 2, 2, 2, 2, 2, 2}, + {2, 2, 2, 2, 2, 2, 2, 0}, + {0, 4, 4, 4, 4, 4, 0, 4}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 4, 0, 4, 0, 0, 0, 0}, + {16, 0, 0, 0, 16, 0, 0, 0}, +}}; struct stn_cc cc_table_cpu_3 = {{ - - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, - {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, - {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, - {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, - {0, 4 , 4 , 4 , 4 , 4 , 0 , 4 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 4 , 0 , 4 , 0 , 0 , 0 , 0 }, - {16, 0 , 0 , 0 , 16 , 0 , 0 , 0 }, - }}; + + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {4, 2, 2, 2, 2, 2, 2, 2}, + {2, 2, 2, 2, 2, 2, 2, 0}, + {4, 2, 2, 2, 2, 2, 2, 2}, + {2, 2, 2, 2, 2, 2, 2, 0}, + {0, 4, 4, 4, 4, 4, 0, 4}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 4, 0, 4, 0, 0, 0, 0}, + {16, 0, 0, 0, 16, 0, 0, 0}, +}}; struct stn_cc cc_table_cpu_4 = {{ - - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, - {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, - {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, - {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, - {0, 4 , 4 , 4 , 4 , 4 , 0 , 4 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 4 , 0 , 4 , 0 , 0 , 0 , 0 }, - {16, 0 , 0 , 0 , 16 , 0 , 0 , 0 }, - }}; + + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {4, 2, 2, 2, 2, 2, 2, 2}, + {2, 2, 2, 2, 2, 2, 2, 0}, + {4, 2, 2, 2, 2, 2, 2, 2}, + {2, 2, 2, 2, 2, 2, 2, 0}, + {0, 4, 4, 4, 4, 4, 0, 4}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 4, 0, 4, 0, 0, 0, 0}, + {16, 0, 0, 0, 16, 0, 0, 0}, +}}; struct stn_cc cc_table_cpu_5 = {{ - - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, - {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, - {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, - {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, - {0, 4 , 4 , 4 , 4 , 4 , 0 , 4 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 4 , 0 , 4 , 0 , 0 , 0 , 0 }, - {16, 0 , 0 , 0 , 16 , 0 , 0 , 0 }, - }}; + + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {4, 2, 2, 2, 2, 2, 2, 2}, + {2, 2, 2, 2, 2, 2, 2, 0}, + {4, 2, 2, 2, 2, 2, 2, 2}, + {2, 2, 2, 2, 2, 2, 2, 0}, + {0, 4, 4, 4, 4, 4, 0, 4}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 4, 0, 4, 0, 0, 0, 0}, + {16, 0, 0, 0, 16, 0, 0, 0}, +}}; struct stn_cc cc_table_cpu_6 = {{ - - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, - {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, - {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, - {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, - {0, 4 , 4 , 4 , 4 , 4 , 0 , 4 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 4 , 0 , 4 , 0 , 0 , 0 , 0 }, - {16, 0 , 0 , 0 , 16 , 0 , 0 , 0 }, - }}; + + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {4, 2, 2, 2, 2, 2, 2, 2}, + {2, 2, 2, 2, 2, 2, 2, 0}, + {4, 2, 2, 2, 2, 2, 2, 2}, + {2, 2, 2, 2, 2, 2, 2, 0}, + {0, 4, 4, 4, 4, 4, 0, 4}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 4, 0, 4, 0, 0, 0, 0}, + {16, 0, 0, 0, 16, 0, 0, 0}, +}}; struct stn_cc cc_table_cpu_7 = {{ - - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, - {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, - {4, 2 , 2 , 2 , 2 , 2 , 2 , 2 }, - {2, 2 , 2 , 2 , 2 , 2 , 2 , 0 }, - {0, 4 , 4 , 4 , 4 , 4 , 0 , 4 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 4 , 0 , 4 , 0 , 0 , 0 , 0 }, - {16, 0 , 0 , 0 , 16 , 0 , 0 , 0 }, - }}; + + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {4, 2, 2, 2, 2, 2, 2, 2}, + {2, 2, 2, 2, 2, 2, 2, 0}, + {4, 2, 2, 2, 2, 2, 2, 2}, + {2, 2, 2, 2, 2, 2, 2, 0}, + {0, 4, 4, 4, 4, 4, 0, 4}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 4, 0, 4, 0, 0, 0, 0}, + {16, 0, 0, 0, 16, 0, 0, 0}, +}}; struct stn_cc cc_table_xgs_0 = {{ - - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 4 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - }}; + + {8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 4, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, +}}; struct stn_cc cc_table_xgs_1 = {{ - - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 4 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - }}; + + {8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 4, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, +}}; struct stn_cc cc_table_gmac = {{ - - {8, 8 , 8 , 8 , 16 , 16 , 16 , 16 }, - {8, 8 , 8 , 8 , 16 , 16 , 16 , 16 }, - {8, 8 , 8 , 8 , 16 , 16 , 16 , 16 }, - {8, 8 , 8 , 8 , 16 , 16 , 16 , 16 }, - {8, 8 , 8 , 8 , 16 , 16 , 16 , 16 }, - {8, 8 , 8 , 8 , 16 , 16 , 16 , 16 }, - {8, 8 , 8 , 8 , 16 , 16 , 16 , 16 }, - {8, 8 , 8 , 8 , 16 , 16 , 16 , 16 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 4 , 0 , 0 , 0 , 0 , 0 , 4 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - }}; + + {8, 8, 8, 8, 16, 16, 16, 16}, + {8, 8, 8, 8, 16, 16, 16, 16}, + {8, 8, 8, 8, 16, 16, 16, 16}, + {8, 8, 8, 8, 16, 16, 16, 16}, + {8, 8, 8, 8, 16, 16, 16, 16}, + {8, 8, 8, 8, 16, 16, 16, 16}, + {8, 8, 8, 8, 16, 16, 16, 16}, + {8, 8, 8, 8, 16, 16, 16, 16}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 4, 0, 0, 0, 0, 0, 4}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, +}}; struct stn_cc cc_table_dma = {{ - - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - }}; + + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, +}}; struct stn_cc cc_table_sec = {{ - - {8, 8 , 8 , 8 , 0 , 0 , 0 , 0 }, - {8, 8 , 8 , 4 , 0 , 0 , 0 , 0 }, - {8, 8 , 8 , 8 , 0 , 0 , 0 , 0 }, - {8, 8 , 8 , 8 , 0 , 0 , 0 , 0 }, - {8, 8 , 8 , 8 , 0 , 0 , 0 , 0 }, - {8, 8 , 8 , 8 , 0 , 0 , 0 , 0 }, - {8, 8 , 8 , 8 , 0 , 0 , 0 , 0 }, - {8, 8 , 8 , 8 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - }}; + {8, 8, 8, 8, 0, 0, 0, 0}, + {8, 8, 8, 4, 0, 0, 0, 0}, + {8, 8, 8, 8, 0, 0, 0, 0}, + {8, 8, 8, 8, 0, 0, 0, 0}, + {8, 8, 8, 8, 0, 0, 0, 0}, + {8, 8, 8, 8, 0, 0, 0, 0}, + {8, 8, 8, 8, 0, 0, 0, 0}, + {8, 8, 8, 8, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, +}}; diff --git a/sys/mips/rmi/msgring.h b/sys/mips/rmi/msgring.h index 8cc6898b54a..c841413a87d 100755 --- a/sys/mips/rmi/msgring.h +++ b/sys/mips/rmi/msgring.h @@ -187,83 +187,94 @@ #define MSGRNG_CODE_BOOT_WAKEUP 200 #define MSGRNG_CODE_SPI4 3 -static inline int msgrng_xgmac_stid_rfr(int id) +static inline int +msgrng_xgmac_stid_rfr(int id) { - return !id ? MSGRNG_STNID_XMAC0RFR : MSGRNG_STNID_XMAC1RFR; + return !id ? MSGRNG_STNID_XMAC0RFR : MSGRNG_STNID_XMAC1RFR; } -static inline int msgrng_xgmac_stid_jfr(int id) +static inline int +msgrng_xgmac_stid_jfr(int id) { - return !id ? MSGRNG_STNID_XMAC0JFR : MSGRNG_STNID_XMAC1JFR; + return !id ? MSGRNG_STNID_XMAC0JFR : MSGRNG_STNID_XMAC1JFR; } -static inline int msgrng_xgmac_stid_tx(int id) +static inline int +msgrng_xgmac_stid_tx(int id) { - return !id ? MSGRNG_STNID_XMAC0_00_TX : MSGRNG_STNID_XMAC1_00_TX; + return !id ? MSGRNG_STNID_XMAC0_00_TX : MSGRNG_STNID_XMAC1_00_TX; } -static inline int msgrng_gmac_stid_rfr(int id) +static inline int +msgrng_gmac_stid_rfr(int id) { - return (MSGRNG_STNID_GMACRFR_0); + return (MSGRNG_STNID_GMACRFR_0); } -static inline int msgrng_gmac_stid_rfr_split_mode(int id) +static inline int +msgrng_gmac_stid_rfr_split_mode(int id) { - return ((id>>1)?MSGRNG_STNID_GMACRFR_1:MSGRNG_STNID_GMACRFR_0); + return ((id >> 1) ? MSGRNG_STNID_GMACRFR_1 : MSGRNG_STNID_GMACRFR_0); } -static inline int msgrng_gmac_stid_jfr(int id) +static inline int +msgrng_gmac_stid_jfr(int id) { - return MSGRNG_STNID_GMACJFR_0; + return MSGRNG_STNID_GMACJFR_0; } -static inline int msgrng_gmac_stid_jfr_split_mode(int id) +static inline int +msgrng_gmac_stid_jfr_split_mode(int id) { - return ((id>>1)?MSGRNG_STNID_GMACJFR_1:MSGRNG_STNID_GMACJFR_0); + return ((id >> 1) ? MSGRNG_STNID_GMACJFR_1 : MSGRNG_STNID_GMACJFR_0); } -static inline int msgrng_gmac_stid_tx(int id) +static inline int +msgrng_gmac_stid_tx(int id) { - return (MSGRNG_STNID_GMACTX0 + id); + return (MSGRNG_STNID_GMACTX0 + id); } -static inline void msgrng_send(unsigned int stid) +static inline void +msgrng_send(unsigned int stid) { - __asm__ volatile ( - ".set push\n" - ".set noreorder\n" - "sync\n" - // "msgsnd %0\n" - "move $8, %0\n" - "c2 0x80001\n" - ".set pop\n" - : : "r" (stid) : "$8" - ); + __asm__ volatile ( + ".set push\n" + ".set noreorder\n" + "sync\n" + // "msgsnd %0\n" + "move $8, %0\n" + "c2 0x80001\n" + ".set pop\n" + :: "r" (stid):"$8" + ); } -static inline void msgrng_receive(unsigned int pri) +static inline void +msgrng_receive(unsigned int pri) { - __asm__ volatile ( - ".set push\n" - ".set noreorder\n" - // "msgld %0\n" - "move $8, %0\n" - "c2 0x80002\n" - ".set pop\n" - : : "r" (pri) : "$8" - ); + __asm__ volatile ( + ".set push\n" + ".set noreorder\n" + // "msgld %0\n" + "move $8, %0\n" + "c2 0x80002\n" + ".set pop\n" + :: "r" (pri):"$8" + ); } -static inline void msgrng_wait(unsigned int mask) +static inline void +msgrng_wait(unsigned int mask) { - __asm__ volatile ( - ".set push\n" - ".set noreorder\n" - // "msgwait %0\n" - "move $8, %0\n" - "c2 0x80003\n" - ".set pop\n" - : :"r" (mask) : "$8" - ); + __asm__ volatile ( + ".set push\n" + ".set noreorder\n" + // "msgwait %0\n" + "move $8, %0\n" + "c2 0x80003\n" + ".set pop\n" + :: "r" (mask):"$8" + ); } #define msgrng_enable(flags) \ @@ -292,34 +303,35 @@ do { \ #define msgrng_flags_restore(flags) msgrng_disable(flags) struct msgrng_msg { - __uint64_t msg0; - __uint64_t msg1; - __uint64_t msg2; - __uint64_t msg3; + __uint64_t msg0; + __uint64_t msg1; + __uint64_t msg2; + __uint64_t msg3; }; -static inline void message_send_block_fast(int size, unsigned int code, unsigned int stid, - unsigned long long msg0, unsigned long long msg1, - unsigned long long msg2, unsigned long long msg3) +static inline void +message_send_block_fast(int size, unsigned int code, unsigned int stid, + unsigned long long msg0, unsigned long long msg1, + unsigned long long msg2, unsigned long long msg3) { - __asm__ __volatile__ (".set push\n" - ".set noreorder\n" - ".set mips64\n" - "dmtc2 %1, $0, 0\n" - "dmtc2 %2, $0, 1\n" - "dmtc2 %3, $0, 2\n" - "dmtc2 %4, $0, 3\n" - "move $8, %0\n" - "1: c2 0x80001\n" - "mfc2 $8, $2\n" - "andi $8, $8, 0x6\n" - "bnez $8, 1b\n" - "move $8, %0\n" - ".set pop\n" - : - : "r"(((size-1)<<16)|(code<<8)|stid), "r" (msg0), "r" (msg1), "r"(msg2), "r"(msg3) - : "$8" - ); + __asm__ __volatile__(".set push\n" + ".set noreorder\n" + ".set mips64\n" + "dmtc2 %1, $0, 0\n" + "dmtc2 %2, $0, 1\n" + "dmtc2 %3, $0, 2\n" + "dmtc2 %4, $0, 3\n" + "move $8, %0\n" + "1: c2 0x80001\n" + "mfc2 $8, $2\n" + "andi $8, $8, 0x6\n" + "bnez $8, 1b\n" + "move $8, %0\n" + ".set pop\n" + : + : "r"(((size - 1) << 16) | (code << 8) | stid), "r"(msg0), "r"(msg1), "r"(msg2), "r"(msg3) + : "$8" + ); } #define message_receive_fast(bucket, size, code, stid, msg0, msg1, msg2, msg3) \ @@ -338,86 +350,94 @@ static inline void message_send_block_fast(int size, unsigned int code, unsigned _tmp=0; \ } \ _tmp; \ - } ) + } ) -static __inline__ int message_send(unsigned int size, unsigned int code, - unsigned int stid, struct msgrng_msg *msg) +static __inline__ int +message_send(unsigned int size, unsigned int code, + unsigned int stid, struct msgrng_msg *msg) { - unsigned int dest = 0; - unsigned long long status=0; - int i=0; + unsigned int dest = 0; + unsigned long long status = 0; + int i = 0; - msgrng_load_tx_msg0(msg->msg0); - msgrng_load_tx_msg1(msg->msg1); - msgrng_load_tx_msg2(msg->msg2); - msgrng_load_tx_msg3(msg->msg3); + msgrng_load_tx_msg0(msg->msg0); + msgrng_load_tx_msg1(msg->msg1); + msgrng_load_tx_msg2(msg->msg2); + msgrng_load_tx_msg3(msg->msg3); - dest = ((size-1)<<16)|(code<<8)|(stid); + dest = ((size - 1) << 16) | (code << 8) | (stid); - //dbg_msg("Sending msg<%Lx,%Lx,%Lx,%Lx> to dest = %x\n", - //msg->msg0, msg->msg1, msg->msg2, msg->msg3, dest); + //dbg_msg("Sending msg<%Lx,%Lx,%Lx,%Lx> to dest = %x\n", + //msg->msg0, msg->msg1, msg->msg2, msg->msg3, dest); - msgrng_send(dest); + msgrng_send(dest); - for(i=0;i<16;i++) { - status = msgrng_read_status(); -// dbg_msg("status = %Lx\n", status); + for (i = 0; i < 16; i++) { + status = msgrng_read_status(); + //dbg_msg("status = %Lx\n", status); - if (status & 0x6) { - continue; + if (status & 0x6) { + continue; + } else + break; } - else break; + if (i == 16) { + if (dest == 0x61) + //dbg_msg("Processor %x: Unable to send msg to %llx\n", processor_id(), dest); + return status & 0x6; } - if (i==16) { - if (dest == 0x61) - //dbg_msg("Processor %x: Unable to send msg to %llx\n", processor_id(), dest); - return status & 0x6; - } - return msgrng_read_status() & 0x06; + return msgrng_read_status() & 0x06; } -static __inline__ int message_send_retry(unsigned int size, unsigned int code, - unsigned int stid, struct msgrng_msg *msg) +static __inline__ int +message_send_retry(unsigned int size, unsigned int code, + unsigned int stid, struct msgrng_msg *msg) { - int res = 0; - int retry = 0; + int res = 0; + int retry = 0; - for(;;) { - res = message_send(size, code, stid, msg); - /* retry a pending fail */ - if (res & 0x02) continue; - /* credit fail */ - if (res & 0x04) retry++; - else break; - if (retry == 4) return res & 0x06; - } + for (;;) { + res = message_send(size, code, stid, msg); + /* retry a pending fail */ + if (res & 0x02) + continue; + /* credit fail */ + if (res & 0x04) + retry++; + else + break; + if (retry == 4) + return res & 0x06; + } - return 0; + return 0; } -static __inline__ int message_receive(int pri, int *size, int *code, int *src_id, - struct msgrng_msg *msg) +static __inline__ int +message_receive(int pri, int *size, int *code, int *src_id, + struct msgrng_msg *msg) { - int res = message_receive_fast(pri, *size, *code, *src_id, msg->msg0, msg->msg1, msg->msg2, msg->msg3); - + int res = message_receive_fast(pri, *size, *code, *src_id, msg->msg0, msg->msg1, msg->msg2, msg->msg3); + #ifdef MSGRING_DUMP_MESSAGES - if (!res) { - dbg_msg("Received msg <%llx, %llx, %llx, %llx> <%d,%d,%d>\n", - msg->msg0, msg->msg1, msg->msg2, msg->msg3, - *size, *code, *src_id); - } + if (!res) { + dbg_msg("Received msg <%llx, %llx, %llx, %llx> <%d,%d,%d>\n", + msg->msg0, msg->msg1, msg->msg2, msg->msg3, + *size, *code, *src_id); + } #endif - - return res; + + return res; } + #define MSGRNG_STN_RX_QSIZE 256 struct stn_cc { - unsigned short counters[16][8]; + unsigned short counters[16][8]; }; struct bucket_size { - unsigned short bucket[128]; + unsigned short bucket[128]; }; extern struct bucket_size bucket_sizes; @@ -495,12 +515,13 @@ enum { MAX_TX_STNS }; -extern int register_msgring_handler(int major, - void (*action)(int, int,int,int,struct msgrng_msg *, void *), - void *dev_id); -extern void xlr_msgring_cpu_init(void); +extern int +register_msgring_handler(int major, + void (*action) (int, int, int, int, struct msgrng_msg *, void *), + void *dev_id); + extern void xlr_msgring_cpu_init(void); -extern void xlr_msgring_config(void); + extern void xlr_msgring_config(void); #define cpu_to_msgring_bucket(cpu) ((((cpu) >> 2)<<3)|((cpu) & 0x03)) diff --git a/sys/mips/rmi/msgring_xls.c b/sys/mips/rmi/msgring_xls.c index 2171f1404bf..bd86187f0c9 100644 --- a/sys/mips/rmi/msgring_xls.c +++ b/sys/mips/rmi/msgring_xls.c @@ -7,212 +7,211 @@ #include struct bucket_size xls_bucket_sizes = { - { 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 32, 32, 32, 32, 32, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 32, 32, 32, 32, 32, 0, 0, - 64, 64, 64, 64, 32, 32, 32, 32, - 0, 0, 0, 0, 0, 0, 0, 0, - 128, 128, 0, 0, 0, 0, 0, 0, + {32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 32, 32, 32, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 32, 32, 32, 32, 0, 0, + 64, 64, 64, 64, 32, 32, 32, 32, + 0, 0, 0, 0, 0, 0, 0, 0, + 128, 128, 0, 0, 0, 0, 0, 0, } }; struct stn_cc xls_cc_table_cpu_0 = {{ - {1, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 8 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 8 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 8 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 4 , 8 , 8 , 8 , 8 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 4 , 8 , 8 , 8 , 8 , 0 , 0 }, - {16, 16 , 16 , 16 , 16 , 16 , 16 , 16 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {32, 32 , 0 , 0 , 0 , 0 , 0 , 0 }, - }}; + {1, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 8, 0, 0, 0, 0}, + {0, 0, 0, 8, 0, 0, 0, 0}, + {0, 0, 0, 8, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 4, 8, 8, 8, 8, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 4, 8, 8, 8, 8, 0, 0}, + {16, 16, 16, 16, 16, 16, 16, 16}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {32, 32, 0, 0, 0, 0, 0, 0}, +}}; struct stn_cc xls_cc_table_cpu_1 = {{ - {1, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 4 , 8 , 8 , 8 , 8 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 4 , 8 , 8 , 8 , 8 , 0 , 0 }, - {16, 16 , 16 , 16 , 16 , 16 , 16 , 16 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {32, 32 , 0 , 0 , 0 , 0 , 0 , 0 }, - }}; + {1, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 4, 8, 8, 8, 8, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 4, 8, 8, 8, 8, 0, 0}, + {16, 16, 16, 16, 16, 16, 16, 16}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {32, 32, 0, 0, 0, 0, 0, 0}, +}}; struct stn_cc xls_cc_table_cpu_2 = {{ - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 4 , 8 , 8 , 8 , 8 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 4 , 8 , 8 , 8 , 8 , 0 , 0 }, - {16, 16 , 16 , 16 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {32, 32 , 0 , 0 , 0 , 0 , 0 , 0 }, - }}; + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 4, 8, 8, 8, 8, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 4, 8, 8, 8, 8, 0, 0}, + {16, 16, 16, 16, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {32, 32, 0, 0, 0, 0, 0, 0}, +}}; struct stn_cc xls_cc_table_cpu_3 = {{ - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 4 , 8 , 8 , 8 , 8 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 4 , 8 , 8 , 8 , 8 , 0 , 0 }, - {16, 16 , 16 , 16 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {32, 32 , 0 , 0 , 0 , 0 , 0 , 0 }, - }}; + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 4, 8, 8, 8, 8, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 4, 8, 8, 8, 8, 0, 0}, + {16, 16, 16, 16, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {32, 32, 0, 0, 0, 0, 0, 0}, +}}; struct stn_cc xls_cc_table_gmac0 = {{ - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 8 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 8 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - }}; + {8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 8, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 8, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, +}}; struct stn_cc xls_cc_table_gmac1 = {{ - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {8, 8 , 8 , 8 , 8 , 8 , 8 , 8 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 8 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 8 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - }}; + {8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 8, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 8, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, +}}; struct stn_cc xls_cc_table_dma = {{ - {4, 4 , 4 , 4 , 4 , 4 , 4 , 4 }, - {4, 4 , 4 , 2 , 4 , 4 , 4 , 4 }, - {4, 4 , 4 , 2 , 4 , 4 , 4 , 4 }, - {4, 4 , 4 , 2 , 4 , 4 , 4 , 4 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - }}; + {4, 4, 4, 4, 4, 4, 4, 4}, + {4, 4, 4, 2, 4, 4, 4, 4}, + {4, 4, 4, 2, 4, 4, 4, 4}, + {4, 4, 4, 2, 4, 4, 4, 4}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, +}}; struct stn_cc xls_cc_table_cmp = {{ - {4, 4 , 4 , 4 , 4 , 4 , 4 , 4 }, - {4, 4 , 4 , 2 , 4 , 4 , 4 , 4 }, - {4, 4 , 4 , 2 , 4 , 4 , 4 , 4 }, - {4, 4 , 4 , 2 , 4 , 4 , 4 , 4 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - }}; + {4, 4, 4, 4, 4, 4, 4, 4}, + {4, 4, 4, 2, 4, 4, 4, 4}, + {4, 4, 4, 2, 4, 4, 4, 4}, + {4, 4, 4, 2, 4, 4, 4, 4}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, +}}; struct stn_cc xls_cc_table_pcie = {{ - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - }}; + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, +}}; struct stn_cc xls_cc_table_sec = {{ - {6, 8 , 8 , 8 , 0 , 0 , 0 , 0 }, - {8, 8 , 8 , 4 , 0 , 0 , 0 , 0 }, - {8, 8 , 8 , 4 , 0 , 0 , 0 , 0 }, - {8, 8 , 8 , 4 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - {0, 0 , 0 , 0 , 0 , 0 , 0 , 0 }, - }}; - + {6, 8, 8, 8, 0, 0, 0, 0}, + {8, 8, 8, 4, 0, 0, 0, 0}, + {8, 8, 8, 4, 0, 0, 0, 0}, + {8, 8, 8, 4, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, +}}; diff --git a/sys/mips/rmi/on_chip.c b/sys/mips/rmi/on_chip.c index 1a3d67e17fe..79f30fb9fff 100644 --- a/sys/mips/rmi/on_chip.c +++ b/sys/mips/rmi/on_chip.c @@ -49,11 +49,14 @@ #include #include -void disable_msgring_int(void *arg) ; -void enable_msgring_int(void *arg) ; +void +disable_msgring_int(void *arg); +void +enable_msgring_int(void *arg); + /* definitions */ struct tx_stn_handler { - void (*action)(int, int, int, int, struct msgrng_msg *, void *); + void (*action) (int, int, int, int, struct msgrng_msg *, void *); void *dev_id; }; @@ -78,11 +81,11 @@ static struct mtx msgrng_lock; static int msgring_int_enabled; struct mtx xlr_pic_lock; -static int msgring_pop_num_buckets; -static uint32_t msgring_pop_bucket_mask; -static int msgring_int_type; -static int msgring_watermark_count; -static uint32_t msgring_thread_mask; +static int msgring_pop_num_buckets; +static uint32_t msgring_pop_bucket_mask; +static int msgring_int_type; +static int msgring_watermark_count; +static uint32_t msgring_thread_mask; uint32_t msgrng_msg_cycles = 0; @@ -90,7 +93,8 @@ int xlr_counters[MAXCPU][XLR_MAX_COUNTERS] __aligned(XLR_CACHELINE_SIZE); void xlr_msgring_handler(struct trapframe *); -void xlr_msgring_cpu_init(void) +void +xlr_msgring_cpu_init(void) { struct stn_cc *cc_config; struct bucket_size *bucket_sizes; @@ -106,19 +110,20 @@ void xlr_msgring_cpu_init(void) cc_config = xlr_board_info.credit_configs[id]; msgrng_flags_save(flags); - - /* Message Stations are shared among all threads in a cpu core - * Assume, thread 0 on all cores are always active when more than - * 1 thread is active in a core + + /* + * Message Stations are shared among all threads in a cpu core + * Assume, thread 0 on all cores are always active when more than 1 + * thread is active in a core */ - msgrng_write_bucksize(0, bucket_sizes->bucket[id*8 + 0]); - msgrng_write_bucksize(1, bucket_sizes->bucket[id*8 + 1]); - msgrng_write_bucksize(2, bucket_sizes->bucket[id*8 + 2]); - msgrng_write_bucksize(3, bucket_sizes->bucket[id*8 + 3]); - msgrng_write_bucksize(4, bucket_sizes->bucket[id*8 + 4]); - msgrng_write_bucksize(5, bucket_sizes->bucket[id*8 + 5]); - msgrng_write_bucksize(6, bucket_sizes->bucket[id*8 + 6]); - msgrng_write_bucksize(7, bucket_sizes->bucket[id*8 + 7]); + msgrng_write_bucksize(0, bucket_sizes->bucket[id * 8 + 0]); + msgrng_write_bucksize(1, bucket_sizes->bucket[id * 8 + 1]); + msgrng_write_bucksize(2, bucket_sizes->bucket[id * 8 + 2]); + msgrng_write_bucksize(3, bucket_sizes->bucket[id * 8 + 3]); + msgrng_write_bucksize(4, bucket_sizes->bucket[id * 8 + 4]); + msgrng_write_bucksize(5, bucket_sizes->bucket[id * 8 + 5]); + msgrng_write_bucksize(6, bucket_sizes->bucket[id * 8 + 6]); + msgrng_write_bucksize(7, bucket_sizes->bucket[id * 8 + 7]); MSGRNG_CC_INIT_CPU_DEST(0, cc_config->counters); MSGRNG_CC_INIT_CPU_DEST(1, cc_config->counters); @@ -140,7 +145,8 @@ void xlr_msgring_cpu_init(void) msgrng_flags_restore(flags); } -void xlr_msgring_config(void) +void +xlr_msgring_config(void) { msgring_int_type = 0x02; msgring_pop_num_buckets = 8; @@ -154,34 +160,38 @@ void xlr_msgring_config(void) /* msgring_watermark_count, msgring_thread_mask); */ } -void xlr_msgring_handler(struct trapframe *tf) +void +xlr_msgring_handler(struct trapframe *tf) { unsigned long mflags; - int bucket=0; - int size=0, code=0, rx_stid=0, tx_stid=0; + int bucket = 0; + int size = 0, code = 0, rx_stid = 0, tx_stid = 0; struct msgrng_msg msg; unsigned int bucket_empty_bm = 0; - unsigned int status=0; + unsigned int status = 0; xlr_inc_counter(MSGRNG_INT); /* TODO: not necessary to disable preemption */ msgrng_flags_save(mflags); /* First Drain all the high priority messages */ - for(;;) { + for (;;) { bucket_empty_bm = (msgrng_read_status() >> 24) & msgring_pop_bucket_mask; - /* all buckets empty, break*/ - if ( bucket_empty_bm == msgring_pop_bucket_mask) break; + /* all buckets empty, break */ + if (bucket_empty_bm == msgring_pop_bucket_mask) + break; - for(bucket=0; bucket < msgring_pop_num_buckets; bucket++) { + for (bucket = 0; bucket < msgring_pop_num_buckets; bucket++) { uint32_t cycles = 0; - if ((bucket_empty_bm & (1 << bucket))/*empty*/) continue; - + if ((bucket_empty_bm & (1 << bucket)) /* empty */ ) + continue; + status = message_receive(bucket, &size, &code, &rx_stid, &msg); - if (status) continue; - + if (status) + continue; + xlr_inc_counter(MSGRNG_MSG); msgrng_msg_cycles = mips_rd_count(); cycles = msgrng_msg_cycles; @@ -190,20 +200,19 @@ void xlr_msgring_handler(struct trapframe *tf) if (!tx_stn_handlers[tx_stid].action) { printf("[%s]: No Handler for message from stn_id=%d, bucket=%d, " - "size=%d, msg0=%llx, dropping message\n", - __FUNCTION__, tx_stid, bucket, size, msg.msg0); - } - else { + "size=%d, msg0=%llx, dropping message\n", + __FUNCTION__, tx_stid, bucket, size, msg.msg0); + } else { //printf("[%s]: rx_stid = %d\n", __FUNCTION__, rx_stid); msgrng_flags_restore(mflags); - (*tx_stn_handlers[tx_stid].action)(bucket, size, code, rx_stid, - &msg, tx_stn_handlers[tx_stid].dev_id); + (*tx_stn_handlers[tx_stid].action) (bucket, size, code, rx_stid, + &msg, tx_stn_handlers[tx_stid].dev_id); msgrng_flags_save(mflags); - } - xlr_set_counter(MSGRNG_MSG_CYCLES, (read_c0_count()-cycles)); + } + xlr_set_counter(MSGRNG_MSG_CYCLES, (read_c0_count() - cycles)); } } - + xlr_set_counter(MSGRNG_EXIT_STATUS, msgrng_read_status()); msgrng_flags_restore(mflags); @@ -213,39 +222,42 @@ void xlr_msgring_handler(struct trapframe *tf) /* Call the msg callback */ } -void enable_msgring_int(void *arg) +void +enable_msgring_int(void *arg) { - unsigned long mflags=0; + unsigned long mflags = 0; msgrng_access_save(&msgrng_lock, mflags); /* enable the message ring interrupts */ - msgrng_write_config((msgring_watermark_count<<24)|(IRQ_MSGRING<<16) - |(msgring_thread_mask<<8)|msgring_int_type); - msgrng_access_restore(&msgrng_lock, mflags); + msgrng_write_config((msgring_watermark_count << 24) | (IRQ_MSGRING << 16) + | (msgring_thread_mask << 8) | msgring_int_type); + msgrng_access_restore(&msgrng_lock, mflags); } -void disable_msgring_int(void *arg) +void +disable_msgring_int(void *arg) { - unsigned long mflags=0; + unsigned long mflags = 0; uint32_t config; msgrng_access_save(&msgrng_lock, mflags); config = msgrng_read_config(); config &= ~0x3; msgrng_write_config(config); - msgrng_access_restore(&msgrng_lock, mflags); + msgrng_access_restore(&msgrng_lock, mflags); } extern void platform_prep_smp_launch(void); extern void msgring_process_fast_intr(void *arg); -int register_msgring_handler(int major, - void (*action)(int, int,int,int,struct msgrng_msg *, void *), - void *dev_id) +int +register_msgring_handler(int major, + void (*action) (int, int, int, int, struct msgrng_msg *, void *), + void *dev_id) { - void *cookie; /* FIXME - use? */ + void *cookie; /* FIXME - use? */ - if (major >= MAX_TX_STNS) + if (major >= MAX_TX_STNS) return 1; //dbg_msg("major=%d, action=%p, dev_id=%p\n", major, action, dev_id); @@ -254,47 +266,49 @@ int register_msgring_handler(int major, tx_stn_handlers[major].action = action; tx_stn_handlers[major].dev_id = dev_id; mtx_unlock_spin(&msgrng_lock); - + if (xlr_test_and_set(&msgring_int_enabled)) { platform_prep_smp_launch(); - cpu_establish_hardintr("msgring", (driver_filter_t *)NULL, - (driver_intr_t *)msgring_process_fast_intr, - NULL, IRQ_MSGRING, INTR_TYPE_NET|INTR_FAST, &cookie); + cpu_establish_hardintr("msgring", (driver_filter_t *) NULL, + (driver_intr_t *) msgring_process_fast_intr, + NULL, IRQ_MSGRING, INTR_TYPE_NET | INTR_FAST, &cookie); /* configure the msgring interrupt on cpu 0 */ enable_msgring_int(NULL); } - return 0; } -static void pic_init(void) +static void +pic_init(void) { xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); - int i=0; + int i = 0; int level; dbg_msg("Initializing PIC...\n"); - for(i=0; i 4)) - return(255); + return (255); if (xlr_board_info.is_xls) { switch (pin) { - case 1: return PIC_PCIE_LINK0_IRQ; - case 2: return PIC_PCIE_LINK1_IRQ; - case 3: return PIC_PCIE_LINK2_IRQ; - case 4: return PIC_PCIE_LINK3_IRQ; + case 1: + return PIC_PCIE_LINK0_IRQ; + case 2: + return PIC_PCIE_LINK1_IRQ; + case 3: + return PIC_PCIE_LINK2_IRQ; + case 4: + return PIC_PCIE_LINK3_IRQ; } - } else { + } else { if (pin == 1) { return (16); } } - - return(255); + + return (255); } static struct rman irq_rman, port_rman, mem_rman; @@ -101,7 +105,7 @@ static void bridge_pcix_ack(void *arg) { xlr_read_reg(xlr_io_mmio(XLR_IO_PCIX_OFFSET), 0x140 >> 2); } -*/ +*/ /* static void bridge_pcie_ack(void *arg) { @@ -147,10 +151,10 @@ static void pic_pcie_ack(void *arg) int mips_platform_pci_setup_intr(device_t dev, device_t child, - struct resource *irq, int flags, - driver_filter_t *filt, - driver_intr_t *intr, void *arg, - void **cookiep) + struct resource *irq, int flags, + driver_filter_t * filt, + driver_intr_t * intr, void *arg, + void **cookiep) { int level; xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); @@ -162,59 +166,58 @@ mips_platform_pci_setup_intr(device_t dev, device_t child, return error; if (rman_get_start(irq) != rman_get_end(irq)) { device_printf(dev, "Interrupt allocation %lu != %lu\n", - rman_get_start(irq), rman_get_end(irq)); + rman_get_start(irq), rman_get_end(irq)); return EINVAL; } - xlrirq = rman_get_start(irq); - if (strcmp(device_get_name(dev),"pcib") != 0) + if (strcmp(device_get_name(dev), "pcib") != 0) return 0; if (xlr_board_info.is_xls == 0) { mtx_lock_spin(&xlr_pic_lock); level = PIC_IRQ_IS_EDGE_TRIGGERED(PIC_IRT_PCIX_INDEX); xlr_write_reg(mmio, PIC_IRT_0_PCIX, 0x01); - xlr_write_reg(mmio, PIC_IRT_1_PCIX, ((1 << 31) | (level<<30)| - (1<<6)|(PIC_PCIX_IRQ))); + xlr_write_reg(mmio, PIC_IRT_1_PCIX, ((1 << 31) | (level << 30) | + (1 << 6) | (PIC_PCIX_IRQ))); mtx_unlock_spin(&xlr_pic_lock); cpu_establish_hardintr(device_get_name(child), filt, - (driver_intr_t *)intr, (void *)arg, PIC_PCIX_IRQ, flags, cookiep); + (driver_intr_t *) intr, (void *)arg, PIC_PCIX_IRQ, flags, cookiep); } else { mtx_lock_spin(&xlr_pic_lock); xlr_write_reg(mmio, PIC_IRT_0_BASE + xlrirq - PIC_IRQ_BASE, 0x01); xlr_write_reg(mmio, PIC_IRT_1_BASE + xlrirq - PIC_IRQ_BASE, - ((1 << 31) | (1<<30) | (1<<6) | xlrirq)); + ((1 << 31) | (1 << 30) | (1 << 6) | xlrirq)); mtx_unlock_spin(&xlr_pic_lock); - if (flags & INTR_FAST) - cpu_establish_hardintr(device_get_name(child), filt, - (driver_intr_t *)intr, (void *)arg, xlrirq, flags, cookiep); + if (flags & INTR_FAST) + cpu_establish_hardintr(device_get_name(child), filt, + (driver_intr_t *) intr, (void *)arg, xlrirq, flags, cookiep); else - cpu_establish_hardintr(device_get_name(child), filt, - (driver_intr_t *)intr, (void *)arg, xlrirq, flags, cookiep); + cpu_establish_hardintr(device_get_name(child), filt, + (driver_intr_t *) intr, (void *)arg, xlrirq, flags, cookiep); + - } return bus_generic_setup_intr(dev, child, irq, flags, filt, intr, - arg, cookiep); + arg, cookiep); } int mips_platform_pci_teardown_intr(device_t dev, device_t child, - struct resource *irq, void *cookie); + struct resource *irq, void *cookie); int mips_platform_pci_teardown_intr(device_t dev, device_t child, - struct resource *irq, void *cookie) + struct resource *irq, void *cookie) { - if (strcmp(device_get_name(child),"pci") == 0) { + if (strcmp(device_get_name(child), "pci") == 0) { /* if needed reprogram the pic to clear pcix related entry */ } return bus_generic_teardown_intr(dev, child, irq, cookie); } -void +void pci_init_resources(void) { irq_rman.rm_start = 0; @@ -249,29 +252,29 @@ pci_init_resources(void) struct resource * xlr_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, - u_long start, u_long end, u_long count, u_int flags) + u_long start, u_long end, u_long count, u_int flags) { - struct rman *rm; - struct resource *rv; + struct rman *rm; + struct resource *rv; vm_offset_t va; - int needactivate = flags & RF_ACTIVE; + int needactivate = flags & RF_ACTIVE; #if 0 device_printf(bus, "xlr_pci_alloc_resource : child %s, type %d, start %lx end %lx, count %lx, flags %x\n", - device_get_nameunit(child), type, start, end, count, flags); + device_get_nameunit(child), type, start, end, count, flags); #endif switch (type) { case SYS_RES_IRQ: - rm = &irq_rman; + rm = &irq_rman; break; case SYS_RES_IOPORT: - rm = &port_rman; + rm = &port_rman; break; case SYS_RES_MEMORY: - rm = &mem_rman; + rm = &mem_rman; break; default: @@ -282,43 +285,44 @@ xlr_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, if (rv == 0) return 0; - rman_set_bustag(rv, (bus_space_tag_t)MIPS_BUS_SPACE_PCI); + rman_set_bustag(rv, (bus_space_tag_t) MIPS_BUS_SPACE_PCI); rman_set_rid(rv, *rid); if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) { - /* if ((start + count) > (2 << 28)) { - va_start = kmem_alloc_nofault(kernel_map, count); - }*/ - /* This called for pmap_map_uncached, but the pmap_map - * calls pmap_kenter which does a is_cacheable_mem() check and + /* + * if ((start + count) > (2 << 28)) { va_start = + * kmem_alloc_nofault(kernel_map, count); } + */ + /* + * This called for pmap_map_uncached, but the pmap_map calls + * pmap_kenter which does a is_cacheable_mem() check and * thus sets the PTE_UNCACHED bit. Hopefully this will work * for this guy... RRS */ - /* va = pmap_map(&va_start, start, start + count, 0);*/ - va = (vm_offset_t)pmap_mapdev(start, start + count); + /* va = pmap_map(&va_start, start, start + count, 0); */ + va = (vm_offset_t)pmap_mapdev(start, start + count); rman_set_bushandle(rv, va); /* bushandle is same as virtual addr */ rman_set_virtual(rv, (void *)va); - rman_set_bustag(rv, (bus_space_tag_t)MIPS_BUS_SPACE_PCI); + rman_set_bustag(rv, (bus_space_tag_t) MIPS_BUS_SPACE_PCI); + } + if (needactivate) { + if (bus_activate_resource(child, type, *rid, rv)) { + rman_release_resource(rv); + return (NULL); + } } - - if (needactivate) { - if (bus_activate_resource(child, type, *rid, rv)) { - rman_release_resource(rv); - return (NULL); - } - } - return rv; } int pci_deactivate_resource(device_t bus, device_t child, int type, int rid, - struct resource *r) + struct resource *r) { return (rman_deactivate_resource(r)); } + /* now in pci.c int pci_activate_resource(device_t bus, device_t child, int type, int rid, @@ -339,7 +343,7 @@ struct rman * pci_get_rman(device_t dev, int type) { switch (type) { - case SYS_RES_IOPORT: + case SYS_RES_IOPORT: return &port_rman; case SYS_RES_MEMORY: diff --git a/sys/mips/rmi/pcibus.h b/sys/mips/rmi/pcibus.h index 2f4fda8ccdb..deea39c03fc 100644 --- a/sys/mips/rmi/pcibus.h +++ b/sys/mips/rmi/pcibus.h @@ -36,23 +36,27 @@ #define PCIE_LINK3_MSI_STATUS 0x194 void pci_init_resources(void); -struct resource *xlr_pci_alloc_resource(device_t bus, device_t child, - int type, int *rid, - u_long start, u_long end, u_long count, - u_int flags); -int pci_activate_resource(device_t bus, device_t child, int type, int rid, - struct resource *r); -int pci_deactivate_resource(device_t bus, device_t child, int type, int rid, - struct resource *r); -int pci_release_resource(device_t bus, device_t child, int type, int rid, - struct resource *r); +struct resource * +xlr_pci_alloc_resource(device_t bus, device_t child, + int type, int *rid, + u_long start, u_long end, u_long count, + u_int flags); +int +pci_activate_resource(device_t bus, device_t child, int type, int rid, + struct resource *r); +int +pci_deactivate_resource(device_t bus, device_t child, int type, int rid, + struct resource *r); +int +pci_release_resource(device_t bus, device_t child, int type, int rid, + struct resource *r); struct rman *pci_get_rman(device_t dev, int type); int mips_platform_pci_setup_intr(device_t dev, device_t child, - struct resource *irq, int flags, - driver_filter_t *filt, - driver_intr_t *intr, void *arg, - void **cookiep); + struct resource *irq, int flags, + driver_filter_t * filt, + driver_intr_t * intr, void *arg, + void **cookiep); int -mips_pci_route_interrupt(device_t bus, device_t dev, int pin); + mips_pci_route_interrupt(device_t bus, device_t dev, int pin); diff --git a/sys/mips/rmi/perfmon.h b/sys/mips/rmi/perfmon.h index 23523caab6f..555b1818cd3 100644 --- a/sys/mips/rmi/perfmon.h +++ b/sys/mips/rmi/perfmon.h @@ -33,18 +33,21 @@ #include -/* +/* * category events reported by the perfmon library */ -enum event_category_t { PERF_CP0_COUNTER=1, PERF_CP2_CREDITS, PERF_L2_COUNTER, - PERF_SBC_COUNTER, PERF_SBC_CREDITS, PERF_GMAC0_COUNTER, PERF_GMAC1_COUNTER, - PERF_GMAC2_COUNTER, PERF_GMAC_STAT_COM, PERF_GMAC_STAT_TX, - PERF_GMAC_STAT_RX, PERF_DRAM_COUNTER, PERF_PARAMETER_CONF=127}; +enum event_category_t { + PERF_CP0_COUNTER = 1, PERF_CP2_CREDITS, PERF_L2_COUNTER, + PERF_SBC_COUNTER, PERF_SBC_CREDITS, PERF_GMAC0_COUNTER, PERF_GMAC1_COUNTER, + PERF_GMAC2_COUNTER, PERF_GMAC_STAT_COM, PERF_GMAC_STAT_TX, +PERF_GMAC_STAT_RX, PERF_DRAM_COUNTER, PERF_PARAMETER_CONF = 127}; -enum perf_param_t { PERF_CPU_SAMPLING_INTERVAL, PERF_SYS_SAMPLING_INTERVAL, PERF_CC_SAMPLE_RATE, PERF_CP0_FLAGS}; +enum perf_param_t { + PERF_CPU_SAMPLING_INTERVAL, PERF_SYS_SAMPLING_INTERVAL, PERF_CC_SAMPLE_RATE, PERF_CP0_FLAGS +}; -#define CPO_EVENTS_TEMPLATE 0x06 /* enable kernel and user events */ +#define CPO_EVENTS_TEMPLATE 0x06 /* enable kernel and user events */ #define PERFMON_ACTIVE_MAGIC 0xc001 #define PERFMON_ENABLED_MAGIC 0xb007 @@ -52,17 +55,20 @@ enum perf_param_t { PERF_CPU_SAMPLING_INTERVAL, PERF_SYS_SAMPLING_INTERVAL, PERF #define PERFMON_SERVER_PORT 7007 -enum system_bridge_credits_t {PCIX_CREDITS, HT_CREDITS, GIO_CREDITS, OTHER_CREDITS}; +enum system_bridge_credits_t { + PCIX_CREDITS, HT_CREDITS, GIO_CREDITS, OTHER_CREDITS +}; struct perf_config_data { - uint16_t magic; /* monitor start when this is initialized */ - uint16_t generation; /* incremented when the config changes */ + uint16_t magic; /* monitor start when this is initialized */ + uint16_t generation; /* incremented when the config changes */ uint16_t flags; - uint16_t cc_sample_rate; /* rate at which credit counters are sampled - relative to sampling_rate */ - uint32_t sampling_rate; /* rate at which events are sampled */ - uint32_t cc_register_mask; /* credit counters registers to be sampled */ - uint64_t events[NTHREADS]; /* events bitmap for each thread */ + uint16_t cc_sample_rate;/* rate at which credit counters are sampled + * relative to sampling_rate */ + uint32_t sampling_rate; /* rate at which events are sampled */ + uint32_t cc_register_mask; /* credit counters registers to be + * sampled */ + uint64_t events[NTHREADS]; /* events bitmap for each thread */ }; struct perf_sample { @@ -78,34 +84,39 @@ struct sample_q { uint32_t overflows; }; -struct perf_area { +struct perf_area { struct perf_config_data perf_config; struct sample_q sample_fifo; }; /* - * We have a shared location to keep a global tick counter for all the + * We have a shared location to keep a global tick counter for all the * CPUS - TODO is this optimal? effect on cache? */ extern uint32_t *xlr_perfmon_timer_loc; + #define PERFMON_TIMESTAMP_LOC (xlr_perfmon_timer_loc) -static __inline__ uint32_t perfmon_timestamp_get(void) +static __inline__ uint32_t +perfmon_timestamp_get(void) { return *PERFMON_TIMESTAMP_LOC; } -static __inline__ void perfmon_timestamp_set(uint32_t val) +static __inline__ void +perfmon_timestamp_set(uint32_t val) { *PERFMON_TIMESTAMP_LOC = val; } -static __inline__ void perfmon_timestamp_incr(int val) +static __inline__ void +perfmon_timestamp_incr(int val) { (*PERFMON_TIMESTAMP_LOC) += val; } -static __inline__ void send_sample_gts(uint32_t tag, uint32_t value, uint32_t td) +static __inline__ void +send_sample_gts(uint32_t tag, uint32_t value, uint32_t td) { xlr_send_sample(tag, value, perfmon_timestamp_get(), td); } @@ -114,21 +125,23 @@ static __inline__ void send_sample_gts(uint32_t tag, uint32_t value, uint32_t td * Simple FIFO, one producer - one consumer - circlar queue - no locking */ -static __inline__ void init_fifo(struct sample_q *q) +static __inline__ void +init_fifo(struct sample_q *q) { q->head = q->tail = 0; } -static __inline__ void put_sample(struct sample_q *q, uint32_t sample_tag, uint32_t counter, - uint32_t duration) +static __inline__ void +put_sample(struct sample_q *q, uint32_t sample_tag, uint32_t counter, + uint32_t duration) { uint32_t timestamp = perfmon_timestamp_get(); int new_tail = (q->tail + 1) % PERF_SAMPLE_BUFSZ; + if (q->head == new_tail) { q->overflows++; return; } - q->samples[new_tail].sample_tag = sample_tag; q->samples[new_tail].counter = counter; q->samples[new_tail].timestamp = timestamp; @@ -137,8 +150,9 @@ static __inline__ void put_sample(struct sample_q *q, uint32_t sample_tag, uint3 q->tail = new_tail; } -static __inline__ int get_sample(struct sample_q *q, uint32_t *sample_tag, uint32_t *counter, - uint32_t *timestamp, uint32_t *duration) +static __inline__ int +get_sample(struct sample_q *q, uint32_t * sample_tag, uint32_t * counter, + uint32_t * timestamp, uint32_t * duration) { int head = q->head; @@ -149,11 +163,12 @@ static __inline__ int get_sample(struct sample_q *q, uint32_t *sample_tag, uint3 *timestamp = q->samples[head].timestamp; *duration = q->samples[head].duration; - q->head = (head+1) % PERF_SAMPLE_BUFSZ; + q->head = (head + 1) % PERF_SAMPLE_BUFSZ; return 1; } -static __inline__ void clear_queue(struct sample_q *q) +static __inline__ void +clear_queue(struct sample_q *q) { q->head = q->tail; } @@ -162,7 +177,7 @@ void xlr_perfmon_sampler(void *); void log_active_core(int core); int get_start_generation(void); -void xlr_perfmon_clockhandler (void); +void xlr_perfmon_clockhandler(void); extern int xlr_perfmon_started; -#endif /* PERFMON_H */ +#endif /* PERFMON_H */ diff --git a/sys/mips/rmi/perfmon_kern.c b/sys/mips/rmi/perfmon_kern.c index 6b74f72bec3..363bbb2037d 100644 --- a/sys/mips/rmi/perfmon_kern.c +++ b/sys/mips/rmi/perfmon_kern.c @@ -46,53 +46,56 @@ int xlr_perfmon_started = 0; struct perf_area *xlr_shared_config_area = NULL; uint32_t *xlr_perfmon_timer_loc; -uint32_t *xlr_cpu_sampling_interval; -uint32_t xlr_perfmon_kernel_version = 1; /* Future use */ +uint32_t *xlr_cpu_sampling_interval; +uint32_t xlr_perfmon_kernel_version = 1; /* Future use */ uint32_t xlr_perfmon_ticks; extern int mips_cpu_online_mask; extern uint32_t cpu_ltop_map[MAXCPU]; #ifdef SMP -static __inline__ void pic_send_perfmon_ipi(int cpu) +static __inline__ void +pic_send_perfmon_ipi(int cpu) { - xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); - int tid, pid; - uint32_t ipi; + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + int tid, pid; + uint32_t ipi; - tid = cpu & 0x3; - pid = (cpu >> 2) & 0x7; - ipi = (pid << 20) | (tid << 16) | IPI_PERFMON; + tid = cpu & 0x3; + pid = (cpu >> 2) & 0x7; + ipi = (pid << 20) | (tid << 16) | IPI_PERFMON; - mtx_lock_spin(&xlr_pic_lock); - xlr_write_reg(mmio, PIC_IPI, ipi); - mtx_unlock_spin(&xlr_pic_lock); + mtx_lock_spin(&xlr_pic_lock); + xlr_write_reg(mmio, PIC_IPI, ipi); + mtx_unlock_spin(&xlr_pic_lock); } -#endif + +#endif -void +void xlr_perfmon_clockhandler(void) { #ifdef SMP int cpu; int i; + #endif - if (xlr_perfmon_ticks++ >= (*xlr_cpu_sampling_interval)/(XLR_PIC_HZ/(hz * 1024))) { + if (xlr_perfmon_ticks++ >= (*xlr_cpu_sampling_interval) / (XLR_PIC_HZ / (hz * 1024))) { /* update timer */ *xlr_perfmon_timer_loc += *xlr_cpu_sampling_interval; xlr_perfmon_ticks = 0; xlr_perfmon_sampler(NULL); #ifdef SMP - for (i=0; inewptr == NULL) + if (error != 0 || req->newptr == NULL) return (error); if (!xlr_perfmon_started && val != 0) @@ -157,6 +159,5 @@ sysctl_xlr_perfmon_start_stop(SYSCTL_HANDLER_ARGS) SYSCTL_NODE(_debug, OID_AUTO, xlrperf, CTLFLAG_RW, NULL, "XLR PERF Nodes"); SYSCTL_PROC(_debug_xlrperf, OID_AUTO, start, CTLTYPE_INT | CTLFLAG_RW, - &xlr_perfmon_started, 0, sysctl_xlr_perfmon_start_stop, "I", "set/unset to start/stop " - "performance monitoring"); - + &xlr_perfmon_started, 0, sysctl_xlr_perfmon_start_stop, "I", "set/unset to start/stop " + "performance monitoring"); diff --git a/sys/mips/rmi/perfmon_percpu.c b/sys/mips/rmi/perfmon_percpu.c index 44ba3567111..fc0f06246bb 100644 --- a/sys/mips/rmi/perfmon_percpu.c +++ b/sys/mips/rmi/perfmon_percpu.c @@ -62,27 +62,32 @@ extern uint32_t cpu_ltop_map[MAXCPU]; extern struct perf_area *xlr_shared_config_area; -static __inline__ uint32_t make_cpu_tag(uint32_t val) +static __inline__ uint32_t +make_cpu_tag(uint32_t val) { - return PERF_CP0_COUNTER<<24 | (val & 0xffff); + return PERF_CP0_COUNTER << 24 | (val & 0xffff); } -static __inline__ uint32_t make_cp0_perf_control(uint32_t flags, uint32_t thread, uint32_t event) +static __inline__ uint32_t +make_cp0_perf_control(uint32_t flags, uint32_t thread, uint32_t event) { - return (flags & 0x1f) | (thread & 0x03)<<11 | (event & 0x3f)<<5 | 0x01; + return (flags & 0x1f) | (thread & 0x03) << 11 | (event & 0x3f) << 5 | 0x01; } -static __inline__ uint32_t cp0_perf_control_get_thread(uint32_t control_word) +static __inline__ uint32_t +cp0_perf_control_get_thread(uint32_t control_word) { - return (control_word & 0x1800)>>11; + return (control_word & 0x1800) >> 11; } -static __inline__ uint32_t cp0_perf_control_get_event(uint32_t control_word) +static __inline__ uint32_t +cp0_perf_control_get_event(uint32_t control_word) { - return (control_word & 0x7e0)>>5; + return (control_word & 0x7e0) >> 5; } -static __inline__ uint32_t read_pic_6_timer_count(void) +static __inline__ uint32_t +read_pic_6_timer_count(void) { xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); @@ -91,12 +96,13 @@ static __inline__ uint32_t read_pic_6_timer_count(void) } -static uint32_t get_num_events(const uint64_t *events) +static uint32_t +get_num_events(const uint64_t * events) { int total = 0; int thread; - for(thread = 0; thread 1) { cntr_cntrl = get_next_control_word(cntr_cntrl, saved_config.events); write_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL1, cntr_cntrl); - write_c0_register(CP0_PERF_COUNTER, PERFCNTR1, 0); /* reset count */ + write_c0_register(CP0_PERF_COUNTER, PERFCNTR1, 0); /* reset count */ } saved_timestamp = read_pic_6_timer_count(); } @@ -221,51 +264,50 @@ int xlr_perfmon_no_event_count = 0; int xlr_perfmon_sample_count; /* timer callback routine */ -void xlr_perfmon_sampler(void *dummy) +void +xlr_perfmon_sampler(void *dummy) { uint32_t current_ts; - uint32_t cntr_cntrl=0; + uint32_t cntr_cntrl = 0; /* xlr_ack_interrupt(XLR_PERFMON_IPI_VECTOR); */ if (my_perf_area->perf_config.magic != PERFMON_ACTIVE_MAGIC) return; /* - * If there has been a change in configuation, update the configuration - */ + * If there has been a change in configuation, update the + * configuration + */ if (saved_config.generation != my_perf_area->perf_config.generation) { reconfigure(); return; } - /* credit counter samples if reqd */ - if(saved_config.cc_register_mask && --cc_sample == 0) { + if (saved_config.cc_register_mask && --cc_sample == 0) { cc_sample = saved_config.cc_sample_rate; - do_sample_cc_registers(&my_perf_area->sample_fifo, - my_perf_area->perf_config.cc_register_mask); + do_sample_cc_registers(&my_perf_area->sample_fifo, + my_perf_area->perf_config.cc_register_mask); } - if (num_events == 0) { xlr_perfmon_no_event_count++; return; } - /* put samples in the queue */ current_ts = read_pic_6_timer_count(); cntr_cntrl = read_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL0); put_sample(&my_perf_area->sample_fifo, make_cpu_tag(cntr_cntrl), - read_c0_register(CP0_PERF_COUNTER, PERFCNTR0), current_ts - saved_timestamp); + read_c0_register(CP0_PERF_COUNTER, PERFCNTR0), current_ts - saved_timestamp); xlr_perfmon_sample_count++; - write_c0_register(CP0_PERF_COUNTER, PERFCNTR0, 0); /* reset count */ + write_c0_register(CP0_PERF_COUNTER, PERFCNTR0, 0); /* reset count */ - if(num_events > 1) { + if (num_events > 1) { cntr_cntrl = read_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL1); put_sample(&my_perf_area->sample_fifo, make_cpu_tag(cntr_cntrl), - read_c0_register(CP0_PERF_COUNTER, PERFCNTR1), current_ts - saved_timestamp); + read_c0_register(CP0_PERF_COUNTER, PERFCNTR1), current_ts - saved_timestamp); xlr_perfmon_sample_count++; - write_c0_register(CP0_PERF_COUNTER, PERFCNTR1, 0); /* reset count */ + write_c0_register(CP0_PERF_COUNTER, PERFCNTR1, 0); /* reset count */ - if(num_events > 2) { + if (num_events > 2) { /* multiplex events */ cntr_cntrl = get_next_control_word(cntr_cntrl, saved_config.events); write_c0_register(CP0_PERF_COUNTER, PERFCNTRCTL0, cntr_cntrl); @@ -280,12 +322,13 @@ void xlr_perfmon_sampler(void *dummy) /* * Initializes time to gather CPU performance counters and credit counters */ -void xlr_perfmon_init_cpu(void *dummy) +void +xlr_perfmon_init_cpu(void *dummy) { int processor = cpu_ltop_map[PCPU_GET(cpuid)]; /* run on just one thread per core */ - if(processor % 4) + if (processor % 4) return; DPRINT("%d : configure with %p", processor, my_perf_area); @@ -295,5 +338,5 @@ void xlr_perfmon_init_cpu(void *dummy) my_perf_area->perf_config.generation = PERFMON_INITIAL_GENERATION; DPRINT("%d : Initialize", processor); - return ; + return; } diff --git a/sys/mips/rmi/perfmon_utils.h b/sys/mips/rmi/perfmon_utils.h index 7d86184ff30..bafcb546526 100644 --- a/sys/mips/rmi/perfmon_utils.h +++ b/sys/mips/rmi/perfmon_utils.h @@ -31,74 +31,87 @@ #ifndef UTILS_H #define UTILS_H -#include /* variable args */ - +#include /* variable args */ + /* TODO optimize of mips, even i & (i-1) is better */ -static int __inline__ get_set_bit_count64(uint64_t value) +static int __inline__ +get_set_bit_count64(uint64_t value) { - int i, result=0; + int i, result = 0; - for(i=0; i /* for DPRINT */ +#include /* for DPRINT */ #define NCPUS 32 #define NCORES 8 diff --git a/sys/mips/rmi/pic.h b/sys/mips/rmi/pic.h index eee251e6dda..7cdf9052f7a 100644 --- a/sys/mips/rmi/pic.h +++ b/sys/mips/rmi/pic.h @@ -200,58 +200,69 @@ extern struct mtx xlr_pic_lock; -static __inline__ __uint32_t pic_read_control(void) +static __inline__ __uint32_t +pic_read_control(void) { - xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); - __uint32_t reg; - mtx_lock_spin(&xlr_pic_lock); - xlr_read_reg(mmio, PIC_CTRL); - mtx_unlock_spin(&xlr_pic_lock); - return reg; + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + __uint32_t reg; + + mtx_lock_spin(&xlr_pic_lock); + xlr_read_reg(mmio, PIC_CTRL); + mtx_unlock_spin(&xlr_pic_lock); + return reg; } -static __inline__ void pic_write_control(__uint32_t control) +static __inline__ void +pic_write_control(__uint32_t control) { - xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); - mtx_lock_spin(&xlr_pic_lock); - xlr_write_reg(mmio, PIC_CTRL, control); - mtx_unlock_spin(&xlr_pic_lock); + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + + mtx_lock_spin(&xlr_pic_lock); + xlr_write_reg(mmio, PIC_CTRL, control); + mtx_unlock_spin(&xlr_pic_lock); } -static __inline__ void pic_update_control(__uint32_t control) +static __inline__ void +pic_update_control(__uint32_t control) { - xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); - mtx_lock_spin(&xlr_pic_lock); - xlr_write_reg(mmio, PIC_CTRL, (control | xlr_read_reg(mmio, PIC_CTRL))); - mtx_unlock_spin(&xlr_pic_lock); + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + + mtx_lock_spin(&xlr_pic_lock); + xlr_write_reg(mmio, PIC_CTRL, (control | xlr_read_reg(mmio, PIC_CTRL))); + mtx_unlock_spin(&xlr_pic_lock); } -static __inline__ void pic_ack(int irq) +static __inline__ void +pic_ack(int irq) { - xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); - /* ack the pic, if needed */ - if (!PIC_IRQ_IS_IRT(irq)) return; + /* ack the pic, if needed */ + if (!PIC_IRQ_IS_IRT(irq)) + return; - if(PIC_IRQ_IS_EDGE_TRIGGERED(irq)) { - mtx_lock_spin(&xlr_pic_lock); - xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE) )); - mtx_unlock_spin(&xlr_pic_lock); - return; - } - return; + if (PIC_IRQ_IS_EDGE_TRIGGERED(irq)) { + mtx_lock_spin(&xlr_pic_lock); + xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE))); + mtx_unlock_spin(&xlr_pic_lock); + return; + } + return; } -static inline void pic_delayed_ack(int irq) +static inline void +pic_delayed_ack(int irq) { - xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); - if (!PIC_IRQ_IS_IRT(irq)) return; + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); - if(!PIC_IRQ_IS_EDGE_TRIGGERED(irq)) { - mtx_lock_spin(&xlr_pic_lock); - xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE) )); - mtx_unlock_spin(&xlr_pic_lock); - return; - } + if (!PIC_IRQ_IS_IRT(irq)) + return; + + if (!PIC_IRQ_IS_EDGE_TRIGGERED(irq)) { + mtx_lock_spin(&xlr_pic_lock); + xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE))); + mtx_unlock_spin(&xlr_pic_lock); + return; + } } -#endif /* _RMI_PIC_H_ */ +#endif /* _RMI_PIC_H_ */ diff --git a/sys/mips/rmi/shared_structs.h b/sys/mips/rmi/shared_structs.h index fb9505f0a41..6e5ecd43cea 100755 --- a/sys/mips/rmi/shared_structs.h +++ b/sys/mips/rmi/shared_structs.h @@ -36,42 +36,42 @@ #define BOOT1_INFO_VERSION 0x0001 struct boot1_info { - uint64_t boot_level; - uint64_t io_base; - uint64_t output_device; - uint64_t uart_print; - uint64_t led_output; - uint64_t init; - uint64_t exit; - uint64_t warm_reset; - uint64_t wakeup; - uint64_t cpu_online_map; - uint64_t master_reentry_sp; - uint64_t master_reentry_gp; - uint64_t master_reentry_fn; - uint64_t slave_reentry_fn; - uint64_t magic_dword; - uint64_t uart_putchar; - uint64_t size; - uint64_t uart_getchar; - uint64_t nmi_handler; - uint64_t psb_version; - uint64_t mac_addr; - uint64_t cpu_frequency; - uint64_t board_version; - uint64_t malloc; - uint64_t free; - uint64_t alloc_pbuf; - uint64_t free_pbuf; - uint64_t psb_os_cpu_map; - uint64_t userapp_cpu_map; - uint64_t wakeup_os; - uint64_t psb_mem_map; - uint64_t board_major_version; - uint64_t board_minor_version; - uint64_t board_manf_revision; - uint64_t board_serial_number; - uint64_t psb_physaddr_map; + uint64_t boot_level; + uint64_t io_base; + uint64_t output_device; + uint64_t uart_print; + uint64_t led_output; + uint64_t init; + uint64_t exit; + uint64_t warm_reset; + uint64_t wakeup; + uint64_t cpu_online_map; + uint64_t master_reentry_sp; + uint64_t master_reentry_gp; + uint64_t master_reentry_fn; + uint64_t slave_reentry_fn; + uint64_t magic_dword; + uint64_t uart_putchar; + uint64_t size; + uint64_t uart_getchar; + uint64_t nmi_handler; + uint64_t psb_version; + uint64_t mac_addr; + uint64_t cpu_frequency; + uint64_t board_version; + uint64_t malloc; + uint64_t free; + uint64_t alloc_pbuf; + uint64_t free_pbuf; + uint64_t psb_os_cpu_map; + uint64_t userapp_cpu_map; + uint64_t wakeup_os; + uint64_t psb_mem_map; + uint64_t board_major_version; + uint64_t board_minor_version; + uint64_t board_manf_revision; + uint64_t board_serial_number; + uint64_t psb_physaddr_map; }; extern struct boot1_info xlr_boot1_info; @@ -92,16 +92,18 @@ struct xlr_loader_info { /* Boot loader uses the linux mips convention */ #define BOOT1_MEMMAP_MAX 32 -enum xlr_phys_memmap_t { BOOT1_MEM_RAM=1, BOOT1_MEM_ROM_DATA, BOOT1_MEM_RESERVED}; +enum xlr_phys_memmap_t { + BOOT1_MEM_RAM = 1, BOOT1_MEM_ROM_DATA, BOOT1_MEM_RESERVED +}; struct xlr_boot1_mem_map { - uint32_t num_entries; - struct { - uint64_t addr; - uint64_t size; - uint32_t type; - uint32_t pad; - } physmem_map[BOOT1_MEMMAP_MAX]; + uint32_t num_entries; + struct { + uint64_t addr; + uint64_t size; + uint32_t type; + uint32_t pad; + } physmem_map[BOOT1_MEMMAP_MAX]; }; diff --git a/sys/mips/rmi/shared_structs_func.h b/sys/mips/rmi/shared_structs_func.h index 54320757b1f..be964140835 100755 --- a/sys/mips/rmi/shared_structs_func.h +++ b/sys/mips/rmi/shared_structs_func.h @@ -27,8 +27,8 @@ * SUCH DAMAGE. * * RMI_BSD */ -/* DO NOT EDIT THIS FILE - * This file has been autogenerated by ./gen_struct_offsets +/* DO NOT EDIT THIS FILE + * This file has been autogenerated by ./gen_struct_offsets */ #ifndef _SHARED_STRUCTS_FUNC_H #define _SHARED_STRUCTS_FUNC_H diff --git a/sys/mips/rmi/shared_structs_offsets.h b/sys/mips/rmi/shared_structs_offsets.h index 6cbabd8aa73..605c735356c 100755 --- a/sys/mips/rmi/shared_structs_offsets.h +++ b/sys/mips/rmi/shared_structs_offsets.h @@ -27,8 +27,8 @@ * SUCH DAMAGE. * * RMI_BSD */ -/* DO NOT EDIT THIS FILE - * This file has been autogenerated by ./gen_struct_offsets +/* DO NOT EDIT THIS FILE + * This file has been autogenerated by ./gen_struct_offsets */ #ifndef _SHARED_STRUCTS_OFFSETS_H #define _SHARED_STRUCTS_OFFSETS_H diff --git a/sys/mips/rmi/tick.c b/sys/mips/rmi/tick.c index 1f4fcbea2d4..aaeb0e94d60 100644 --- a/sys/mips/rmi/tick.c +++ b/sys/mips/rmi/tick.c @@ -91,13 +91,13 @@ sysctl_machdep_counter_freq(SYSCTL_HANDLER_ARGS) { int error; uint64_t freq; + /* - * RRS wonders if this will really work. You don't - * change the req of the system here, it would require - * changes to the RMI PIC in order to get the TC to - * run at a differrent frequency. + * RRS wonders if this will really work. You don't change the req of + * the system here, it would require changes to the RMI PIC in order + * to get the TC to run at a differrent frequency. */ - + if (counter_timecounter.tc_frequency == 0) return (EOPNOTSUPP); freq = counter_freq; diff --git a/sys/mips/rmi/uart_bus_xlr_iodi.c b/sys/mips/rmi/uart_bus_xlr_iodi.c index 20415f4136d..110029835ff 100644 --- a/sys/mips/rmi/uart_bus_xlr_iodi.c +++ b/sys/mips/rmi/uart_bus_xlr_iodi.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2006 Raza Microelectronics + * Copyright (c) 2006 Raza Microelectronics * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -46,10 +46,10 @@ static int uart_iodi_probe(device_t dev); static device_method_t uart_iodi_methods[] = { /* Device interface */ - DEVMETHOD(device_probe, uart_iodi_probe), - DEVMETHOD(device_attach, uart_bus_attach), - DEVMETHOD(device_detach, uart_bus_detach), - { 0, 0 } + DEVMETHOD(device_probe, uart_iodi_probe), + DEVMETHOD(device_attach, uart_bus_attach), + DEVMETHOD(device_detach, uart_bus_detach), + {0, 0} }; static driver_t uart_iodi_driver = { @@ -64,9 +64,9 @@ uart_iodi_probe(device_t dev) struct uart_softc *sc; sc = device_get_softc(dev); - sc->sc_class = &uart_ns8250_class; + sc->sc_class = &uart_ns8250_class; - /* regshft = 2, rclk = 66000000, rid = 0, chan = 0 */ + /* regshft = 2, rclk = 66000000, rid = 0, chan = 0 */ return (uart_bus_probe(dev, 2, 66000000, 0, 0)); } diff --git a/sys/mips/rmi/uart_cpu_mips_xlr.c b/sys/mips/rmi/uart_cpu_mips_xlr.c index 6cbea14a303..221f4115390 100644 --- a/sys/mips/rmi/uart_cpu_mips_xlr.c +++ b/sys/mips/rmi/uart_cpu_mips_xlr.c @@ -30,7 +30,7 @@ * code written by Olivier Houchard. */ /* - * XLRMIPS: This file is hacked from arm/... + * XLRMIPS: This file is hacked from arm/... */ #include "opt_uart.h" @@ -55,9 +55,10 @@ static int xlr_uart_probe(struct uart_bas *bas); static void xlr_uart_init(struct uart_bas *bas, int, int, int, int); static void xlr_uart_term(struct uart_bas *bas); static void xlr_uart_putc(struct uart_bas *bas, int); + /*static int xlr_uart_poll(struct uart_bas *bas);*/ static int xlr_uart_getc(struct uart_bas *bas, struct mtx *hwmtx); -struct mtx xlr_uart_mtx; /*UartLock*/ +struct mtx xlr_uart_mtx; /* UartLock */ extern struct uart_ops uart_ns8250_ops; @@ -66,61 +67,68 @@ struct uart_ops xlr_uart_ns8250_ops = { .init = xlr_uart_init, .term = xlr_uart_term, .putc = xlr_uart_putc, - /* .poll = xlr_uart_poll, ?? */ + /* .poll = xlr_uart_poll, ?? */ .getc = xlr_uart_getc, }; bus_space_tag_t uart_bus_space_io; bus_space_tag_t uart_bus_space_mem; -static __inline void xlr_uart_lock(struct mtx *hwmtx) +static __inline void +xlr_uart_lock(struct mtx *hwmtx) { - if(!mtx_initialized(hwmtx)) + if (!mtx_initialized(hwmtx)) return; - if(!kdb_active && hwmtx != NULL) - mtx_lock_spin(hwmtx); + if (!kdb_active && hwmtx != NULL) + mtx_lock_spin(hwmtx); } -static __inline void xlr_uart_unlock(struct mtx *hwmtx) +static __inline void +xlr_uart_unlock(struct mtx *hwmtx) { - if(!mtx_initialized(hwmtx)) + if (!mtx_initialized(hwmtx)) return; - if(!kdb_active && hwmtx != NULL) - mtx_unlock_spin(hwmtx); + if (!kdb_active && hwmtx != NULL) + mtx_unlock_spin(hwmtx); } -static int xlr_uart_probe(struct uart_bas *bas) +static int +xlr_uart_probe(struct uart_bas *bas) { int res; + xlr_uart_lock(&xlr_uart_mtx); res = uart_ns8250_ops.probe(bas); xlr_uart_unlock(&xlr_uart_mtx); return res; } -static void xlr_uart_init(struct uart_bas *bas, int baudrate, int databits, - int stopbits, int parity) - +static void +xlr_uart_init(struct uart_bas *bas, int baudrate, int databits, + int stopbits, int parity) { xlr_uart_lock(&xlr_uart_mtx); - uart_ns8250_ops.init(bas,baudrate,databits,stopbits,parity); + uart_ns8250_ops.init(bas, baudrate, databits, stopbits, parity); xlr_uart_unlock(&xlr_uart_mtx); } -static void xlr_uart_term(struct uart_bas *bas) +static void +xlr_uart_term(struct uart_bas *bas) { xlr_uart_lock(&xlr_uart_mtx); uart_ns8250_ops.term(bas); xlr_uart_unlock(&xlr_uart_mtx); } -static void xlr_uart_putc(struct uart_bas *bas, int c) +static void +xlr_uart_putc(struct uart_bas *bas, int c) { xlr_uart_lock(&xlr_uart_mtx); - uart_ns8250_ops.putc(bas,c); + uart_ns8250_ops.putc(bas, c); xlr_uart_unlock(&xlr_uart_mtx); } + /* static int xlr_uart_poll(struct uart_bas *bas) { @@ -132,7 +140,8 @@ static int xlr_uart_poll(struct uart_bas *bas) } */ -static int xlr_uart_getc(struct uart_bas *bas, struct mtx *hwmtx) +static int +xlr_uart_getc(struct uart_bas *bas, struct mtx *hwmtx) { return uart_ns8250_ops.getc(bas, hwmtx); } @@ -151,7 +160,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) di->bas.chan = 0; di->bas.bst = uart_bus_space_mem; /* TODO Need to call bus_space_map() here */ - di->bas.bsh = 0xbef14000; /* Try with UART0 */ + di->bas.bsh = 0xbef14000; /* Try with UART0 */ di->bas.regshft = 2; /* divisor = rclk / (baudrate * 16); */ di->bas.rclk = 66000000; @@ -166,9 +175,10 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) return (0); } -static void xlr_uart_mtx_init(void *dummy __unused) +static void +xlr_uart_mtx_init(void *dummy __unused) { - mtx_init(&xlr_uart_mtx, "uart lock",NULL,MTX_SPIN); + mtx_init(&xlr_uart_mtx, "uart lock", NULL, MTX_SPIN); } -SYSINIT(xlr_init_uart_mtx, SI_SUB_LOCK, SI_ORDER_ANY, xlr_uart_mtx_init, NULL); +SYSINIT(xlr_init_uart_mtx, SI_SUB_LOCK, SI_ORDER_ANY, xlr_uart_mtx_init, NULL); diff --git a/sys/mips/rmi/xlr_boot1_console.c b/sys/mips/rmi/xlr_boot1_console.c index 10b650eefd5..88cefcfa52d 100644 --- a/sys/mips/rmi/xlr_boot1_console.c +++ b/sys/mips/rmi/xlr_boot1_console.c @@ -52,12 +52,12 @@ __FBSDID("$FreeBSD$"); #include #if 0 -static cn_probe_t xlr_boot1_cnprobe; -static cn_init_t xlr_boot1_cninit; -static cn_term_t xlr_boot1_cnterm; -static cn_getc_t xlr_boot1_cngetc; -static cn_checkc_t xlr_boot1_cncheckc; -static cn_putc_t xlr_boot1_cnputc; +static cn_probe_t xlr_boot1_cnprobe; +static cn_init_t xlr_boot1_cninit; +static cn_term_t xlr_boot1_cnterm; +static cn_getc_t xlr_boot1_cngetc; +static cn_checkc_t xlr_boot1_cncheckc; +static cn_putc_t xlr_boot1_cnputc; CONS_DRIVER(xlrboot, xlr_boot1_cnprobe, xlr_boot1_cninit, xlr_boot1_cnterm, xlr_boot1_cngetc, xlr_boot1_cncheckc, xlr_boot1_cnputc, NULL); @@ -70,8 +70,8 @@ xlr_boot1_cnprobe(struct consdev *cp) { cp->cn_pri = CN_NORMAL; cp->cn_tp = NULL; - cp->cn_arg = NULL; /* softc */ - cp->cn_unit = -1; /* ? */ + cp->cn_arg = NULL; /* softc */ + cp->cn_unit = -1; /* ? */ cp->cn_flags = 0; } diff --git a/sys/mips/rmi/xlr_i2c.c b/sys/mips/rmi/xlr_i2c.c index 5f36f7cd797..d05345ee723 100644 --- a/sys/mips/rmi/xlr_i2c.c +++ b/sys/mips/rmi/xlr_i2c.c @@ -39,7 +39,7 @@ __FBSDID("$FreeBSD: src/sys/mips/xlr/xlr_i2c.c,v 1.20.8.1 2008/08/25 23:17:51 co #include #include #include -#include +#include #include @@ -65,7 +65,7 @@ __FBSDID("$FreeBSD: src/sys/mips/xlr/xlr_i2c.c,v 1.20.8.1 2008/08/25 23:17:51 co #define I2C_PALM_HDSTATIM 0x09 /* TEST Values!! Change as required */ -#define I2C_PALM_CFG_DEF 0x000000F8 /* 8-Bit Addr + POR Values */ +#define I2C_PALM_CFG_DEF 0x000000F8 /* 8-Bit Addr + POR Values */ #define I2C_PALM_CLKDIV_DEF 0x14A //0x00000052 #define I2C_PALM_HDSTATIM_DEF 0x107 //0x00000000 @@ -78,12 +78,12 @@ __FBSDID("$FreeBSD: src/sys/mips/xlr/xlr_i2c.c,v 1.20.8.1 2008/08/25 23:17:51 co #define ARIZONA_I2c_BUS 1 -int bus =1; +int bus = 1; uint8_t current_slave; uint8_t read_address; -static xlr_reg_t* iobase_i2c_regs; +static xlr_reg_t *iobase_i2c_regs; static devclass_t xlr_i2c_devclass; @@ -96,20 +96,19 @@ static int xlr_i2c_detach(device_t); static int xlr_i2c_start(device_t dev, u_char slave, int timeout); static int xlr_i2c_stop(device_t dev); -static int xlr_i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay ); -static int xlr_i2c_write(device_t dev, char *buf, int len, int *sent, int timeout ); +static int xlr_i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay); +static int xlr_i2c_write(device_t dev, char *buf, int len, int *sent, int timeout); -struct xlr_i2c_softc -{ - device_t dev; /* Myself */ - struct resource *mem_res; /* Memory resource */ - volatile int flags; +struct xlr_i2c_softc { + device_t dev; /* Myself */ + struct resource *mem_res; /* Memory resource */ + volatile int flags; #define RXRDY 4 #define TXRDY 0x10 - int sc_started; - int twi_addr; - device_t iicbus; + int sc_started; + int twi_addr; + device_t iicbus; }; @@ -118,164 +117,176 @@ struct xlr_i2c_softc while(local_loop--); \ }\ -static void get_i2c_base(void) +static void +get_i2c_base(void) { - if(bus == 0) - iobase_i2c_regs = xlr_io_mmio(PHOENIX_IO_I2C_0_OFFSET); - else - iobase_i2c_regs = xlr_io_mmio(PHOENIX_IO_I2C_1_OFFSET); - return; + if (bus == 0) + iobase_i2c_regs = xlr_io_mmio(PHOENIX_IO_I2C_0_OFFSET); + else + iobase_i2c_regs = xlr_io_mmio(PHOENIX_IO_I2C_1_OFFSET); + return; } -static void palm_write(int reg, int value) +static void +palm_write(int reg, int value) { - get_i2c_base(); - xlr_write_reg(iobase_i2c_regs, reg, value); - return; + get_i2c_base(); + xlr_write_reg(iobase_i2c_regs, reg, value); + return; } -static int palm_read(int reg) +static int +palm_read(int reg) { - uint32_t val; - get_i2c_base(); - val = xlr_read_reg(iobase_i2c_regs, reg); - return ((int) val); + uint32_t val; + + get_i2c_base(); + val = xlr_read_reg(iobase_i2c_regs, reg); + return ((int)val); } -static int palm_addr_only(uint8_t addr, uint8_t offset) +static int +palm_addr_only(uint8_t addr, uint8_t offset) { - volatile uint32_t regVal=0x00; + volatile uint32_t regVal = 0x00; - palm_write(I2C_PALM_ADDR, offset); - palm_write(I2C_PALM_DEVADDR, addr); - palm_write(I2C_PALM_CFG, 0xfa); - palm_write(I2C_PALM_STARTXFR,0x02); - regVal = palm_read(I2C_PALM_STATUS); - if (regVal & 0x0008) { - printf("palm_addr_only: ACKERR. Aborting...\n"); - return -1; - } - return 0; + palm_write(I2C_PALM_ADDR, offset); + palm_write(I2C_PALM_DEVADDR, addr); + palm_write(I2C_PALM_CFG, 0xfa); + palm_write(I2C_PALM_STARTXFR, 0x02); + regVal = palm_read(I2C_PALM_STATUS); + if (regVal & 0x0008) { + printf("palm_addr_only: ACKERR. Aborting...\n"); + return -1; + } + return 0; } -static int palm_rx(uint8_t addr, uint8_t offset, uint8_t len, - uint8_t *buf) +static int +palm_rx(uint8_t addr, uint8_t offset, uint8_t len, + uint8_t * buf) { - volatile uint32_t regVal=0x00, ctr=0x00; - int timeOut, numBytes=0x00; + volatile uint32_t regVal = 0x00, ctr = 0x00; + int timeOut, numBytes = 0x00; - palm_write(I2C_PALM_CFG, 0xfa); - palm_write(I2C_PALM_BYTECNT, len); - palm_write(I2C_PALM_DEVADDR, addr); //DEVADDR=0x4c, 0x68 - MDELAY(1); + palm_write(I2C_PALM_CFG, 0xfa); + palm_write(I2C_PALM_BYTECNT, len); + palm_write(I2C_PALM_DEVADDR, addr); + //DEVADDR = 0x4c, 0x68 + MDELAY(1); - for (numBytes=0x00; numBytes < len; numBytes++) { - palm_write(I2C_PALM_ADDR, offset+numBytes);//I2C_PALM_ADDR:offset - MDELAY(1); - if (!ctr) { - /* Trigger a READ Transaction */ - palm_write(I2C_PALM_STARTXFR, I2C_PALM_STARTXFR_RD); - ctr++; - } - - /* Error Conditions [Begin] */ - regVal = palm_read(I2C_PALM_STATUS); - MDELAY(1); - if (regVal & 0x0008) { - printf("palm_rx: ACKERR. Aborting...\n"); - return -1; - } - timeOut=10; - while ((regVal & 0x0030) && timeOut--) { - palm_write(I2C_PALM_STARTXFR, I2C_PALM_STARTXFR_RD); - regVal = palm_read(I2C_PALM_STATUS); - } - if (timeOut==0x00) { - printf("palm_rx: TimedOut on Valid STARTXFR/Arbitration\n"); - return -1; - } - timeOut=10; - /* Do we have valid data from the device yet..? */ - regVal &= 0x0004; - while (!regVal && timeOut--) { - regVal = palm_read(I2C_PALM_STATUS) & 0x0004; - } - if (timeOut==0x00) { - printf("palm_rx: TimedOut Waiting for Valid Data\n"); - return -1; - } - /* Error Conditions [End] */ - /* Read the data */ - buf[numBytes] = (uint8_t)palm_read(I2C_PALM_DATAIN); - } - return 0; + for (numBytes = 0x00; numBytes < len; numBytes++) { + palm_write(I2C_PALM_ADDR, offset + numBytes); +//I2C_PALM_ADDR:offset + MDELAY(1); + if (!ctr) { + /* Trigger a READ Transaction */ + palm_write(I2C_PALM_STARTXFR, I2C_PALM_STARTXFR_RD); + ctr++; + } + /* Error Conditions [Begin] */ + regVal = palm_read(I2C_PALM_STATUS); + MDELAY(1); + if (regVal & 0x0008) { + printf("palm_rx: ACKERR. Aborting...\n"); + return -1; + } + timeOut = 10; + while ((regVal & 0x0030) && timeOut--) { + palm_write(I2C_PALM_STARTXFR, I2C_PALM_STARTXFR_RD); + regVal = palm_read(I2C_PALM_STATUS); + } + if (timeOut == 0x00) { + printf("palm_rx: TimedOut on Valid STARTXFR/Arbitration\n"); + return -1; + } + timeOut = 10; + /* Do we have valid data from the device yet..? */ + regVal &= 0x0004; + while (!regVal && timeOut--) { + regVal = palm_read(I2C_PALM_STATUS) & 0x0004; + } + if (timeOut == 0x00) { + printf("palm_rx: TimedOut Waiting for Valid Data\n"); + return -1; + } + /* Error Conditions [End] */ + /* Read the data */ + buf[numBytes] = (uint8_t) palm_read(I2C_PALM_DATAIN); + } + return 0; } -static int wait_for_idle(void) +static int +wait_for_idle(void) { - int timeOut=0x1000; - volatile uint32_t regVal=0x00; - regVal = palm_read(I2C_PALM_STATUS) & 0x0001; - while (regVal && timeOut--) { - regVal = palm_read(I2C_PALM_STATUS) & 0x0001; - } - if (timeOut == 0x00) - return -1; /* Timed Out */ - else - return 0; + int timeOut = 0x1000; + volatile uint32_t regVal = 0x00; + + regVal = palm_read(I2C_PALM_STATUS) & 0x0001; + while (regVal && timeOut--) { + regVal = palm_read(I2C_PALM_STATUS) & 0x0001; + } + if (timeOut == 0x00) + return -1; /* Timed Out */ + else + return 0; } -static int palm_tx(uint8_t addr, uint8_t offset, uint8_t* buf, uint8_t len) +static int +palm_tx(uint8_t addr, uint8_t offset, uint8_t * buf, uint8_t len) { - volatile uint32_t regVal=0x00; - int timeOut, ctr=0x00, numBytes=len; + volatile uint32_t regVal = 0x00; + int timeOut, ctr = 0x00, numBytes = len; - for (ctr=0x00; ctrmem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - if (sc->mem_res == NULL) - { - printf("not able to allocate the bus resource\n"); - } - - if((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL) - printf("could not allocate iicbus instance\n"); + sc = device_get_softc(dev); + sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (sc->mem_res == NULL) { + printf("not able to allocate the bus resource\n"); + } + if ((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL) + printf("could not allocate iicbus instance\n"); bus_generic_attach(dev); - return (0); + return (0); } - + static int xlr_i2c_detach(device_t dev) { bus_generic_detach(dev); - + return (0); } -/* +/* static int xlr_i2c_add_child(device_t dev, int order, const char *name, int unit) { @@ -338,105 +347,109 @@ xlr_i2c_add_child(device_t dev, int order, const char *name, int unit) } */ -static int xlr_i2c_start(device_t dev, u_char slave, int timeout) +static int +xlr_i2c_start(device_t dev, u_char slave, int timeout) { - int error =0; - struct xlr_i2c_softc *sc; + int error = 0; + struct xlr_i2c_softc *sc; - sc = device_get_softc(dev); - sc->sc_started = 1; + sc = device_get_softc(dev); + sc->sc_started = 1; - current_slave = (slave >> 1); - return error; + current_slave = (slave >> 1); + return error; } -static int xlr_i2c_stop(device_t dev) +static int +xlr_i2c_stop(device_t dev) { - int error =0; + int error = 0; - return error; + return error; } -static int xlr_i2c_read(device_t dev, char *buf, int len, int *read, int last, - int delay ) +static int +xlr_i2c_read(device_t dev, char *buf, int len, int *read, int last, + int delay) { - int error =0; + int error = 0; - if(palm_addr_only(current_slave,read_address) == -1){ - printf("I2C ADDRONLY Phase Fail.\n"); - return -1; - } - - - if(palm_rx(current_slave,read_address,len,buf)== -1){ - printf("I2C Read Fail.\n"); - return -1; - } - *read = len; - return error; + if (palm_addr_only(current_slave, read_address) == -1) { + printf("I2C ADDRONLY Phase Fail.\n"); + return -1; + } + if (palm_rx(current_slave, read_address, len, buf) == -1) { + printf("I2C Read Fail.\n"); + return -1; + } + *read = len; + return error; } -static int xlr_i2c_write(device_t dev, char *buf, int len, int *sent, int timeout /* us */) +static int +xlr_i2c_write(device_t dev, char *buf, int len, int *sent, int timeout /* us */ ) { - int error =0; - uint8_t write_address; + int error = 0; + uint8_t write_address; - if(len == 1){ - /* address for the next read*/ - read_address=buf[0]; - return error; - } - if(len < 2) - return (-1); + if (len == 1) { + /* address for the next read */ + read_address = buf[0]; + return error; + } + if (len < 2) + return (-1); - write_address = buf[0]; + write_address = buf[0]; - /*for write operation, buf[0] contains the register offset and - buf[1] onwards contains the value*/ - palm_tx(current_slave,write_address, &buf[1], len-1); - - return error; + /* + * for write operation, buf[0] contains the register offset and + * buf[1] onwards contains the value + */ + palm_tx(current_slave, write_address, &buf[1], len - 1); + + return error; } static int xlr_i2c_callback(device_t dev, int index, caddr_t *data) { - return 0; + return 0; } static int xlr_i2c_repeated_start(device_t dev, u_char slave, int timeout) { - return 0; + return 0; } static device_method_t xlr_i2c_methods[] = { - /* device interface */ - DEVMETHOD(device_probe, xlr_i2c_probe), - DEVMETHOD(device_attach, xlr_i2c_attach), - DEVMETHOD(device_detach, xlr_i2c_detach), + /* device interface */ + DEVMETHOD(device_probe, xlr_i2c_probe), + DEVMETHOD(device_attach, xlr_i2c_attach), + DEVMETHOD(device_detach, xlr_i2c_detach), - /* iicbus interface */ - DEVMETHOD(iicbus_callback, xlr_i2c_callback), - DEVMETHOD(iicbus_repeated_start, xlr_i2c_repeated_start), - DEVMETHOD(iicbus_start, xlr_i2c_start), - DEVMETHOD(iicbus_stop, xlr_i2c_stop), - DEVMETHOD(iicbus_write, xlr_i2c_write), - DEVMETHOD(iicbus_read, xlr_i2c_read), - { 0, 0 } + /* iicbus interface */ + DEVMETHOD(iicbus_callback, xlr_i2c_callback), + DEVMETHOD(iicbus_repeated_start, xlr_i2c_repeated_start), + DEVMETHOD(iicbus_start, xlr_i2c_start), + DEVMETHOD(iicbus_stop, xlr_i2c_stop), + DEVMETHOD(iicbus_write, xlr_i2c_write), + DEVMETHOD(iicbus_read, xlr_i2c_read), + {0, 0} }; static driver_t xlr_i2c_driver = { - "xlr_i2c", - xlr_i2c_methods, - sizeof(struct xlr_i2c_softc), + "xlr_i2c", + xlr_i2c_methods, + sizeof(struct xlr_i2c_softc), }; DRIVER_MODULE(xlr_i2c, iodi, xlr_i2c_driver, xlr_i2c_devclass, 0, 0); diff --git a/sys/mips/rmi/xlr_machdep.c b/sys/mips/rmi/xlr_machdep.c index e909b38c10d..5839b437cac 100644 --- a/sys/mips/rmi/xlr_machdep.c +++ b/sys/mips/rmi/xlr_machdep.c @@ -46,7 +46,7 @@ #include #include -#include /* cinit() */ +#include /* cinit() */ #include #include #include @@ -88,7 +88,7 @@ void platform_prep_smp_launch(void); unsigned long xlr_io_base = (unsigned long)(DEFAULT_XLR_IO_BASE); -/* 4KB static data aread to keep a copy of the bootload env until +/* 4KB static data aread to keep a copy of the bootload env until the dynamic kenv is setup */ char boot1_env[4096]; extern unsigned long _gp; @@ -96,34 +96,37 @@ extern unsigned long _gp; /* * Parameters from boot loader */ -struct boot1_info xlr_boot1_info; -struct xlr_loader_info xlr_loader_info; /* FIXME : Unused */ -int xlr_run_mode; -int xlr_argc; -char **xlr_argv, **xlr_envp; -uint64_t cpu_mask_info; -uint32_t xlr_online_cpumask; +struct boot1_info xlr_boot1_info; +struct xlr_loader_info xlr_loader_info; /* FIXME : Unused */ +int xlr_run_mode; +int xlr_argc; +char **xlr_argv, **xlr_envp; +uint64_t cpu_mask_info; +uint32_t xlr_online_cpumask; + #ifdef SMP static unsigned long xlr_secondary_gp[MAXCPU]; static unsigned long xlr_secondary_sp[MAXCPU]; + #endif extern int mips_cpu_online_mask; extern int mips_cpu_logical_mask; uint32_t cpu_ltop_map[MAXCPU]; uint32_t cpu_ptol_map[MAXCPU]; -uint32_t xlr_core_cpu_mask=0x1; /* Core 0 thread 0 is always there */ +uint32_t xlr_core_cpu_mask = 0x1; /* Core 0 thread 0 is always there */ void platform_reset(void) { /* FIXME : use proper define */ - u_int32_t *mmio = (u_int32_t *)0xbef18000; + u_int32_t *mmio = (u_int32_t *) 0xbef18000; printf("Rebooting the system now\n"); mmio[8] = 0x1; } -void platform_secondary_init(void) +void +platform_secondary_init(void) { #ifdef SMP xlr_msgring_cpu_init(); @@ -143,8 +146,9 @@ void platform_secondary_init(void) } -int xlr_asid_pcpu=256; /* This the default */ -int xlr_shtlb_enabled=0; +int xlr_asid_pcpu = 256; /* This the default */ +int xlr_shtlb_enabled = 0; + /* This function sets up the number of tlb entries available to the kernel based on the number of threads brought up. The ASID range also gets divided similarly. @@ -153,7 +157,8 @@ NOTE: This function will mark all 64TLB entries as available to the threads brought up in the core. If kernel is brought with say mask 0x33333333, no TLBs will be available to the threads in each core. */ -static void setup_tlb_resource(void) +static void +setup_tlb_resource(void) { int mmu_setup; int value = 0; @@ -161,18 +166,18 @@ static void setup_tlb_resource(void) uint32_t thr_mask = cpu_map >> (xlr_cpu_id() << 2); uint8_t core0 = xlr_boot1_info.cpu_online_map & 0xf; uint8_t core_thr_mask; - int i=0, count=0; + int i = 0, count = 0; /* If CPU0 did not enable shared TLB, other cores need to follow */ - if((xlr_cpu_id() != 0) && (xlr_shtlb_enabled == 0)) + if ((xlr_cpu_id() != 0) && (xlr_shtlb_enabled == 0)) return; /* First check if each core is brought up with the same mask */ - for(i=1; i < 8; i++) { + for (i = 1; i < 8; i++) { core_thr_mask = cpu_map >> (i << 2); core_thr_mask &= 0xf; - if(core_thr_mask && core_thr_mask != core0){ + if (core_thr_mask && core_thr_mask != core0) { printf - ("Each core must be brought with same cpu mask\n"); + ("Each core must be brought with same cpu mask\n"); printf("Cannot enabled shared TLB. "); printf("Falling back to split TLB mode\n"); return; @@ -180,19 +185,21 @@ static void setup_tlb_resource(void) } xlr_shtlb_enabled = 1; - for(i=0;i<4;i++) if (thr_mask & (1<pc_curthread); + write_c0_register32(MIPS_COP_0_OSSCRATCH, 7, pcpup->pc_curthread); mutex_init(); @@ -349,8 +357,8 @@ mips_init(void) #ifdef DDB #ifdef SMP - setup_nmi(); -#endif /* SMP */ + setup_nmi(); +#endif /* SMP */ kdb_init(); if (boothowto & RB_KDB) { kdb_enter("Boot flags requested debugger"); @@ -362,23 +370,25 @@ void tick_init(void); void platform_start(__register_t a0 __unused, - __register_t a1 __unused, - __register_t a2 __unused, - __register_t a3 __unused) + __register_t a1 __unused, + __register_t a2 __unused, + __register_t a3 __unused) { vm_size_t physsz = 0; int i, j; struct xlr_boot1_mem_map *boot_map; + #ifdef SMP uint32_t tmp; - void (*wakeup)(void *, void *, unsigned int); + void (*wakeup) (void *, void *, unsigned int); + #endif /* XXX FIXME the code below is not 64 bit clean */ /* Save boot loader and other stuff from scratch regs */ xlr_boot1_info = *(struct boot1_info *)read_c0_register32(MIPS_COP_0_OSSCRATCH, 0); - cpu_mask_info = read_c0_register64(MIPS_COP_0_OSSCRATCH, 1); + cpu_mask_info = read_c0_register64(MIPS_COP_0_OSSCRATCH, 1); xlr_online_cpumask = read_c0_register32(MIPS_COP_0_OSSCRATCH, 2); xlr_run_mode = read_c0_register32(MIPS_COP_0_OSSCRATCH, 3); xlr_argc = read_c0_register32(MIPS_COP_0_OSSCRATCH, 4); @@ -386,28 +396,29 @@ platform_start(__register_t a0 __unused, xlr_envp = (char **)read_c0_register32(MIPS_COP_0_OSSCRATCH, 6); /* TODO: Verify the magic number here */ - /*FIXMELATER: xlr_boot1_info.magic_number */ + /* FIXMELATER: xlr_boot1_info.magic_number */ /* initialize console so that we have printf */ - boothowto |= (RB_SERIAL | RB_MULTIPLE); /* Use multiple consoles */ - - /* clockrate used by delay, so initialize it here */ - cpu_clock = xlr_boot1_info.cpu_frequency/1000000 ; + boothowto |= (RB_SERIAL | RB_MULTIPLE); /* Use multiple consoles */ - /* Note the time counter on CPU0 runs not at system - * clock speed, but at PIC time counter speed (which is - * returned by platform_get_frequency(). Thus we do not - * use xlr_boot1_info.cpu_frequency here. + /* clockrate used by delay, so initialize it here */ + cpu_clock = xlr_boot1_info.cpu_frequency / 1000000; + + /* + * Note the time counter on CPU0 runs not at system clock speed, but + * at PIC time counter speed (which is returned by + * platform_get_frequency(). Thus we do not use + * xlr_boot1_info.cpu_frequency here. */ mips_timer_early_init(platform_get_frequency()); mips_timer_init_params(platform_get_frequency(), 0); cninit(); init_static_kenv(boot1_env, sizeof(boot1_env)); - printf("Environment (from %d args):\n", xlr_argc-1); + printf("Environment (from %d args):\n", xlr_argc - 1); if (xlr_argc == 1) printf("\tNone\n"); - for(i=1; inum_entries; i++, j+=2) { + (unsigned long)xlr_boot1_info.psb_mem_map; + for (i = 0, j = 0; i < boot_map->num_entries; i++, j += 2) { if (boot_map->physmem_map[i].type == BOOT1_MEM_RAM) { if (j == 14) { - printf("*** ERROR *** memory map too large ***\n"); + printf("*** ERROR *** memory map too large ***\n"); break; } if (j == 0) { - /*TODO FIXME */ + /* TODO FIXME */ /* start after kernel end */ phys_avail[0] = (vm_paddr_t) - MIPS_KSEG0_TO_PHYS(&_end) + 0x20000; + MIPS_KSEG0_TO_PHYS(&_end) + 0x20000; /* boot loader start */ /* HACK to Use bootloaders memory region */ - /*TODO FIXME */ - if(boot_map->physmem_map[0].size == 0x0c000000) { + /* TODO FIXME */ + if (boot_map->physmem_map[0].size == 0x0c000000) { boot_map->physmem_map[0].size = 0x0ff00000; } phys_avail[1] = boot_map->physmem_map[0].addr + - boot_map->physmem_map[0].size; + boot_map->physmem_map[0].size; } else { /* @@ -450,11 +461,11 @@ platform_start(__register_t a0 __unused, * to map from the second are which is not in KSEG0 and not mapped */ phys_avail[j] = (vm_paddr_t) - boot_map->physmem_map[i].addr; - phys_avail[j+1] = phys_avail[j] + - boot_map->physmem_map[i].size; -#if 0 /* FIXME TOD0 */ - phys_avail[j] = phys_avail[j+1] = 0; + boot_map->physmem_map[i].addr; + phys_avail[j + 1] = phys_avail[j] + + boot_map->physmem_map[i].size; +#if 0 /* FIXME TOD0 */ + phys_avail[j] = phys_avail[j + 1] = 0; #endif } physsz += boot_map->physmem_map[i].size; @@ -462,67 +473,71 @@ platform_start(__register_t a0 __unused, } /* FIXME XLR TODO */ - phys_avail[j] = phys_avail[j+1] = 0; + phys_avail[j] = phys_avail[j + 1] = 0; realmem = physmem = btoc(physsz); - /*Store pcpu in scratch 5*/ - write_c0_register32(MIPS_COP_0_OSSCRATCH,5,pcpup); + /* Store pcpu in scratch 5 */ + write_c0_register32(MIPS_COP_0_OSSCRATCH, 5, pcpup); /* Set up hz, among others. */ mips_init(); - pcpup = (struct pcpu *)NULL; /* TODO To be removed */ + pcpup = (struct pcpu *)NULL; /* TODO To be removed */ #ifdef SMP - /*If thread 0 of any core is not available then mark whole core as - not available*/ + /* + * If thread 0 of any core is not available then mark whole core as + * not available + */ tmp = xlr_boot1_info.cpu_online_map; - for(i=4; ii_thread; p = td->td_proc; - /* Interrupt thread will enable the interrupts after processing - all messages - */ + /* + * Interrupt thread will enable the interrupts after processing all + * messages + */ disable_msgring_int(NULL); it->i_pending = 1; if (TD_AWAITING_INTR(td)) { - thread_lock(td); + thread_lock(td); CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, p->p_pid, - p->p_comm); + p->p_comm); TD_CLR_IWAIT(td); sched_add(td, SRQ_INTR); - thread_unlock(td); + thread_unlock(td); } else { CTR4(KTR_INTR, "%s: pid %d (%s): state %d", - __func__, p->p_pid, p->p_comm, td->td_state); + __func__, p->p_pid, p->p_comm, td->td_state); } } + #define MIT_DEAD 4 static void -msgring_process(void * arg) +msgring_process(void *arg) { volatile struct msgring_ithread *ithd; struct thread *td; @@ -615,43 +635,43 @@ msgring_process(void * arg) p = td->td_proc; ithd = (volatile struct msgring_ithread *)arg; KASSERT(ithd->i_thread == td, - ("%s:msg_ithread and proc linkage out of sync", __func__)); + ("%s:msg_ithread and proc linkage out of sync", __func__)); /* First bind this thread to the right CPU */ thread_lock(td); sched_bind(td, ithd->i_cpu); thread_unlock(td); -// printf("Started %s on CPU %d\n", __FUNCTION__, ithd->i_cpu); + //printf("Started %s on CPU %d\n", __FUNCTION__, ithd->i_cpu); - while(1) { + while (1) { if (ithd->i_flags & MIT_DEAD) { CTR3(KTR_INTR, "%s: pid %d (%s) exiting", __func__, - p->p_pid, p->p_comm); + p->p_pid, p->p_comm); kthread_exit(); } while (ithd->i_pending) { /* - * This might need a full read and write barrier - * to make sure that this write posts before any - * of the memory or device accesses in the - * handlers. + * This might need a full read and write barrier to + * make sure that this write posts before any of the + * memory or device accesses in the handlers. */ atomic_store_rel_int(&ithd->i_pending, 0); xlr_msgring_handler(NULL); } if (!ithd->i_pending && !(ithd->i_flags & MIT_DEAD)) { - thread_lock(td); + thread_lock(td); sched_class(td, PRI_ITHD); TD_SET_IWAIT(td); - thread_unlock(td); + thread_unlock(td); enable_msgring_int(NULL); mi_switch(SW_VOL, NULL); } } } -void platform_prep_smp_launch(void) +void +platform_prep_smp_launch(void) { int cpu; uint32_t cpu_mask; @@ -664,26 +684,26 @@ void platform_prep_smp_launch(void) /* Create kernel threads for message ring interrupt processing */ /* Currently create one task for thread 0 of each core */ - for(cpu=0; cpu < MAXCPU; cpu+=1) { + for (cpu = 0; cpu < MAXCPU; cpu += 1) { - if(!((1 << cpu) & cpu_mask)) + if (!((1 << cpu) & cpu_mask)) continue; - if((cpu_ltop_map[cpu]%4) != 0) + if ((cpu_ltop_map[cpu] % 4) != 0) continue; ithd = &msgring_ithreads[cpu]; sprintf(ithd_name[cpu], "msg_intr%d", cpu); error = kproc_create(msgring_process, - (void *)ithd, - &p, - (RFSTOPPED | RFHIGHPID), - 2, - ithd_name[cpu]); + (void *)ithd, + &p, + (RFSTOPPED | RFHIGHPID), + 2, + ithd_name[cpu]); if (error) panic("kproc_create() failed with %d", error); - td = FIRST_THREAD_IN_PROC(p); /* XXXKSE */ + td = FIRST_THREAD_IN_PROC(p); /* XXXKSE */ thread_lock(td); sched_class(td, PRI_ITHD); @@ -695,4 +715,3 @@ void platform_prep_smp_launch(void) CTR2(KTR_INTR, "%s: created %s", __func__, ithd_name[cpu]); } } - diff --git a/sys/mips/rmi/xlr_pci.c b/sys/mips/rmi/xlr_pci.c index 3b11bf19e10..a3cfa5220f7 100644 --- a/sys/mips/rmi/xlr_pci.c +++ b/sys/mips/rmi/xlr_pci.c @@ -71,24 +71,24 @@ #define MSI_MIPS_ADDR_DEST 0x000ff000 #define MSI_MIPS_ADDR_RH 0x00000008 -# define MSI_MIPS_ADDR_RH_OFF 0x00000000 -# define MSI_MIPS_ADDR_RH_ON 0x00000008 +#define MSI_MIPS_ADDR_RH_OFF 0x00000000 +#define MSI_MIPS_ADDR_RH_ON 0x00000008 #define MSI_MIPS_ADDR_DM 0x00000004 -# define MSI_MIPS_ADDR_DM_PHYSICAL 0x00000000 -# define MSI_MIPS_ADDR_DM_LOGICAL 0x00000004 +#define MSI_MIPS_ADDR_DM_PHYSICAL 0x00000000 +#define MSI_MIPS_ADDR_DM_LOGICAL 0x00000004 /* Fields in data for Intel MSI messages. */ -#define MSI_MIPS_DATA_TRGRMOD 0x00008000 /* Trigger mode */ -# define MSI_MIPS_DATA_TRGREDG 0x00000000 /* edge */ -# define MSI_MIPS_DATA_TRGRLVL 0x00008000 /* level */ +#define MSI_MIPS_DATA_TRGRMOD 0x00008000 /* Trigger mode */ +#define MSI_MIPS_DATA_TRGREDG 0x00000000 /* edge */ +#define MSI_MIPS_DATA_TRGRLVL 0x00008000 /* level */ -#define MSI_MIPS_DATA_LEVEL 0x00004000 /* Polarity. */ -# define MSI_MIPS_DATA_DEASSERT 0x00000000 -# define MSI_MIPS_DATA_ASSERT 0x00004000 +#define MSI_MIPS_DATA_LEVEL 0x00004000 /* Polarity. */ +#define MSI_MIPS_DATA_DEASSERT 0x00000000 +#define MSI_MIPS_DATA_ASSERT 0x00004000 -#define MSI_MIPS_DATA_DELMOD 0x00000700 /* Delivery Mode */ -# define MSI_MIPS_DATA_DELFIXED 0x00000000 /* fixed */ -# define MSI_MIPS_DATA_DELLOPRI 0x00000100 /* lowest priority */ +#define MSI_MIPS_DATA_DELMOD 0x00000700 /* Delivery Mode */ +#define MSI_MIPS_DATA_DELFIXED 0x00000000 /* fixed */ +#define MSI_MIPS_DATA_DELLOPRI 0x00000100 /* lowest priority */ #define MSI_MIPS_DATA_INTVEC 0x000000ff @@ -105,9 +105,9 @@ MSI_MIPS_DATA_ASSERT | (irq)) struct xlr_hose_softc { - int junk; /* no softc */ + int junk; /* no softc */ }; -static devclass_t pcib_devclass; +static devclass_t pcib_devclass; static int pci_bus_status = 0; static void *pci_config_base; @@ -127,13 +127,13 @@ xlr_pcib_probe(device_t dev) } static int -xlr_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) +xlr_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t * result) { #if 0 device_printf(dev, "xlr_pcib_read_ivar : read ivar %d for child %s\n", which, device_get_nameunit(child)); #endif switch (which) { - case PCIB_IVAR_BUS: + case PCIB_IVAR_BUS: *result = 0; return 0; } @@ -151,33 +151,37 @@ xlr_pcib_maxslots(device_t dev) #define pci_cfg_offset(bus,slot,devfn,where) (((bus)<<16) + ((slot) << 11)+((devfn)<<8)+(where)) -static __inline__ void disable_and_clear_cache_error(void) -{ - uint64_t lsu_cfg0 = read_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID); - lsu_cfg0 = lsu_cfg0 & ~0x2e; - write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID, lsu_cfg0); - /* Clear cache error log */ - write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID, 0); -} - -static __inline__ void clear_and_enable_cache_error(void) -{ - uint64_t lsu_cfg0 = 0; - - /* first clear the cache error logging register */ - write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID, 0); - write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERROVF_REGID, 0); - write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRINT_REGID, 0); - - lsu_cfg0 = read_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID); - lsu_cfg0 = lsu_cfg0 | 0x2e; - write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID, lsu_cfg0); -} - -static uint32_t phoenix_pciread(u_int b, u_int s, u_int f, - u_int reg, int width) +static __inline__ void +disable_and_clear_cache_error(void) { - uint32_t data = 0; + uint64_t lsu_cfg0 = read_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID); + + lsu_cfg0 = lsu_cfg0 & ~0x2e; + write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID, lsu_cfg0); + /* Clear cache error log */ + write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID, 0); +} + +static __inline__ void +clear_and_enable_cache_error(void) +{ + uint64_t lsu_cfg0 = 0; + + /* first clear the cache error logging register */ + write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID, 0); + write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERROVF_REGID, 0); + write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRINT_REGID, 0); + + lsu_cfg0 = read_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID); + lsu_cfg0 = lsu_cfg0 | 0x2e; + write_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CFG0_REGID, lsu_cfg0); +} + +static uint32_t +phoenix_pciread(u_int b, u_int s, u_int f, + u_int reg, int width) +{ + uint32_t data = 0; if ((width == 2) && (reg & 1)) return 0xFFFFFFFF; @@ -197,19 +201,20 @@ static uint32_t phoenix_pciread(u_int b, u_int s, u_int f, return data; } -static void phoenix_pciwrite(u_int b, u_int s, u_int f, - u_int reg, u_int val, int width) -{ +static void +phoenix_pciwrite(u_int b, u_int s, u_int f, + u_int reg, u_int val, int width) +{ uint32_t cfgaddr = pci_cfg_offset(b, s, f, reg); uint32_t data = 0; if ((width == 2) && (reg & 1)) - return ; + return; else if ((width == 4) && (reg & 3)) - return ; + return; if (!pci_bus_status) - return ; + return; if (width == 1) { data = pci_cfg_read_32bit(cfgaddr); @@ -220,88 +225,89 @@ static void phoenix_pciwrite(u_int b, u_int s, u_int f, data = (data & ~(0xffff << ((reg & 3) << 3))) | (val << ((reg & 3) << 3)); } else { - data = val; + data = val; } pci_cfg_write_32bit(cfgaddr, data); - return ; + return; } -static uint32_t pci_cfg_read_32bit(uint32_t addr) +static uint32_t +pci_cfg_read_32bit(uint32_t addr) { - uint32_t temp = 0; - uint32_t *p = (uint32_t *) ((uint32_t)pci_config_base + (addr & ~3)); - uint64_t cerr_cpu_log = 0; + uint32_t temp = 0; + uint32_t *p = (uint32_t *) ((uint32_t) pci_config_base + (addr & ~3)); + uint64_t cerr_cpu_log = 0; disable_and_clear_cache_error(); - temp = SWAP32(*p); + temp = SWAP32(*p); - /* Read cache err log */ - cerr_cpu_log = read_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID); + /* Read cache err log */ + cerr_cpu_log = read_64bit_phnx_ctrl_reg(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID); - if(cerr_cpu_log) - { - /* Device don't exist. */ - temp = ~0x0; - } + if (cerr_cpu_log) { + /* Device don't exist. */ + temp = ~0x0; + } clear_and_enable_cache_error(); - return temp; + return temp; } -static void pci_cfg_write_32bit(uint32_t addr, uint32_t data) +static void +pci_cfg_write_32bit(uint32_t addr, uint32_t data) { - unsigned int *p = (unsigned int *)((uint32_t)pci_config_base + (addr & ~3)); + unsigned int *p = (unsigned int *)((uint32_t) pci_config_base + (addr & ~3)); - *p = SWAP32(data); + *p = SWAP32(data); } static u_int32_t xlr_pcib_read_config(device_t dev, u_int b, u_int s, u_int f, - u_int reg, int width) + u_int reg, int width) { return phoenix_pciread(b, s, f, reg, width); } static void xlr_pcib_write_config(device_t dev, u_int b, u_int s, u_int f, - u_int reg, u_int32_t val, int width) + u_int reg, u_int32_t val, int width) { phoenix_pciwrite(b, s, f, reg, val, width); } -static int xlr_pcib_attach(device_t dev) +static int +xlr_pcib_attach(device_t dev) { device_add_child(dev, "pci", 0); bus_generic_attach(dev); return 0; } -#define PCIE_LINK_STATE 0x4000 +#define PCIE_LINK_STATE 0x4000 static void -xlr_pcib_identify(driver_t *driver, device_t parent) +xlr_pcib_identify(driver_t * driver, device_t parent) { xlr_reg_t *pcie_mmio_le = xlr_io_mmio(XLR_IO_PCIE_1_OFFSET); - xlr_reg_t reg_link0 = xlr_read_reg(pcie_mmio_le, (0x80 >> 2)); - xlr_reg_t reg_link1 = xlr_read_reg(pcie_mmio_le, (0x84 >> 2)); + xlr_reg_t reg_link0 = xlr_read_reg(pcie_mmio_le, (0x80 >> 2)); + xlr_reg_t reg_link1 = xlr_read_reg(pcie_mmio_le, (0x84 >> 2)); - if ((uint16_t)reg_link0 & PCIE_LINK_STATE) { + if ((uint16_t) reg_link0 & PCIE_LINK_STATE) { device_printf(parent, "Link 0 up\n"); } - if ((uint16_t)reg_link1 & PCIE_LINK_STATE) { + if ((uint16_t) reg_link1 & PCIE_LINK_STATE) { device_printf(parent, "Link 1 up\n"); } - BUS_ADD_CHILD(parent, 0, "pcib", 0); - + } static int -xlr_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs); + xlr_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs); static int -xlr_release_msi(device_t pcib, device_t dev, int count, int *irqs); + xlr_release_msi(device_t pcib, device_t dev, int count, int *irqs); static int xlr_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs) @@ -310,13 +316,13 @@ xlr_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs) int i; device_t parent, tmp; - + /* find the lane on which the slot is connected to */ tmp = dev; while (1) { - parent = device_get_parent(tmp); + parent = device_get_parent(tmp); if (parent == NULL || parent == pcib) { - device_printf(dev, "Cannot find parent bus\n"); + device_printf(dev, "Cannot find parent bus\n"); return ENXIO; } if (strcmp(device_get_nameunit(parent), "pci0") == 0) @@ -324,49 +330,58 @@ xlr_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs) tmp = parent; } - switch (pci_get_slot(tmp)) { - case 0: pciirq = PIC_PCIE_LINK0_IRQ; break; - case 1: pciirq = PIC_PCIE_LINK1_IRQ; break; - case 2: pciirq = PIC_PCIE_LINK2_IRQ; break; - case 3: pciirq = PIC_PCIE_LINK3_IRQ; break; - default: return ENXIO; + switch (pci_get_slot(tmp)) { + case 0: + pciirq = PIC_PCIE_LINK0_IRQ; + break; + case 1: + pciirq = PIC_PCIE_LINK1_IRQ; + break; + case 2: + pciirq = PIC_PCIE_LINK2_IRQ; + break; + case 3: + pciirq = PIC_PCIE_LINK3_IRQ; + break; + default: + return ENXIO; } - irqs[0] = pciirq; - /* - For now put in some fixed values for the other requested MSI, - TODO handle multiple messages - */ - for (i=1; i> 32; - low = value & 0xffffffff; - - __asm__ __volatile__ ( - ".set push\n" - ".set noreorder\n" - ".set noat\n" - ".set mips4\n\t" - - "dsll32 $2, %1, 0 \n\t" - "dsll32 $1, %0, 0 \n\t" - "dsrl32 $2, $2, 0 \n\t" - "or $1, $1, $2 \n\t" - ".word 0x40a14806 \n\t" - "nop \n\t" - - ".set pop\n" - - : - : "r" (high), "r" (low) - : "$1", "$2"); -} - -static inline void write_c0_eimr64(__uint64_t value) +static inline void +write_c0_eirr64(__uint64_t value) { - __uint32_t low, high; + __uint32_t low, high; - high = value >> 32; - low = value & 0xffffffff; + high = value >> 32; + low = value & 0xffffffff; - __asm__ __volatile__ ( - ".set push\n" - ".set noreorder\n" - ".set noat\n" - ".set mips4\n\t" + __asm__ __volatile__( + ".set push\n" + ".set noreorder\n" + ".set noat\n" + ".set mips4\n\t" - "dsll32 $2, %1, 0 \n\t" - "dsll32 $1, %0, 0 \n\t" - "dsrl32 $2, $2, 0 \n\t" - "or $1, $1, $2 \n\t" - ".word 0x40a14807 \n\t" - "nop \n\t" + "dsll32 $2, %1, 0 \n\t" + "dsll32 $1, %0, 0 \n\t" + "dsrl32 $2, $2, 0 \n\t" + "or $1, $1, $2 \n\t" + ".word 0x40a14806 \n\t" + "nop \n\t" - ".set pop\n" + ".set pop\n" - : - : "r" (high), "r" (low) - : "$1", "$2"); + : + : "r"(high), "r"(low) + : "$1", "$2"); } -static __inline__ int xlr_test_and_set(int *lock) +static inline void +write_c0_eimr64(__uint64_t value) { - int oldval = 0; + __uint32_t low, high; - __asm__ __volatile__ (".set push\n" - ".set noreorder\n" - "move $9, %2\n" - "li $8, 1\n" - //"swapw $8, $9\n" - ".word 0x71280014\n" - "move %1, $8\n" - ".set pop\n" - : "+m" (*lock), "=r" (oldval) - : "r" ((unsigned long)lock) - : "$8", "$9" - ); - return (oldval == 0 ? 1/*success*/ : 0/*failure*/); + high = value >> 32; + low = value & 0xffffffff; + + __asm__ __volatile__( + ".set push\n" + ".set noreorder\n" + ".set noat\n" + ".set mips4\n\t" + + "dsll32 $2, %1, 0 \n\t" + "dsll32 $1, %0, 0 \n\t" + "dsrl32 $2, $2, 0 \n\t" + "or $1, $1, $2 \n\t" + ".word 0x40a14807 \n\t" + "nop \n\t" + + ".set pop\n" + + : + : "r"(high), "r"(low) + : "$1", "$2"); } -static __inline__ uint32_t xlr_mfcr(uint32_t reg) +static __inline__ int +xlr_test_and_set(int *lock) +{ + int oldval = 0; + + __asm__ __volatile__(".set push\n" + ".set noreorder\n" + "move $9, %2\n" + "li $8, 1\n" + // "swapw $8, $9\n" + ".word 0x71280014\n" + "move %1, $8\n" + ".set pop\n" + : "+m"(*lock), "=r"(oldval) + : "r"((unsigned long)lock) + : "$8", "$9" + ); + + return (oldval == 0 ? 1 /* success */ : 0 /* failure */ ); +} + +static __inline__ uint32_t +xlr_mfcr(uint32_t reg) { uint32_t val; - __asm__ __volatile__ ( - "move $8, %1\n" - ".word 0x71090018\n" - "move %0, $9\n" - : "=r"(val) - : "r"(reg) : "$8", "$9"); + __asm__ __volatile__( + "move $8, %1\n" + ".word 0x71090018\n" + "move %0, $9\n" + : "=r"(val) + : "r"(reg):"$8", "$9"); return val; } -static __inline__ void xlr_mtcr(uint32_t reg, uint32_t val) +static __inline__ void +xlr_mtcr(uint32_t reg, uint32_t val) { - __asm__ __volatile__ ( - "move $8, %1\n" - "move $9, %0\n" - ".word 0x71090019\n" - ::"r"(val), "r"(reg) - : "$8", "$9"); + __asm__ __volatile__( + "move $8, %1\n" + "move $9, %0\n" + ".word 0x71090019\n" + :: "r"(val), "r"(reg) + : "$8", "$9"); } + #endif diff --git a/sys/mips/rmi/xls_ehci.c b/sys/mips/rmi/xls_ehci.c index c351bb6ecca..a270507a131 100644 --- a/sys/mips/rmi/xls_ehci.c +++ b/sys/mips/rmi/xls_ehci.c @@ -72,12 +72,13 @@ __FBSDID("$FreeBSD: src/sys/dev/usb/ehci_pci.c,v 1.18.2.4 2008/04/23 18:54:51 jh /*#include */ #include -#include +#include #ifdef USB_DEBUG #define EHCI_DEBUG USB_DEBUG #define DPRINTF(x) do { if (ehcidebug) logprintf x; } while (0) extern int ehcidebug; + #else #define DPRINTF(x) #endif @@ -158,8 +159,8 @@ ehci_xls_attach(device_t self) sc->sc_bus.usbrev = USBREV_2_0; rid = 0; - sc->io_res = bus_alloc_resource(self, SYS_RES_MEMORY, &rid, - 0ul, ~0ul, 0x400, RF_ACTIVE); + sc->io_res = bus_alloc_resource(self, SYS_RES_MEMORY, &rid, + 0ul, ~0ul, 0x400, RF_ACTIVE); if (!sc->io_res) { device_printf(self, "Could not map memory\n"); return ENXIO; @@ -169,7 +170,7 @@ ehci_xls_attach(device_t self) rid = 0; sc->irq_res = bus_alloc_resource(self, SYS_RES_IRQ, &rid, - 39, 39, 1, RF_SHAREABLE | RF_ACTIVE); + 39, 39, 1, RF_SHAREABLE | RF_ACTIVE); if (sc->irq_res == NULL) { device_printf(self, "Could not allocate irq\n"); ehci_xls_detach(self); @@ -195,7 +196,6 @@ ehci_xls_attach(device_t self) ehci_xls_detach(self); return ENXIO; } - /* * Find companion controllers. According to the spec they always * have lower function numbers so they should be enumerated already. @@ -207,7 +207,6 @@ ehci_xls_attach(device_t self) ehci_xls_detach(self); return ENXIO; } - sc->sc_ncomp = 0; ehci_xls_takecontroller(self); @@ -216,7 +215,6 @@ ehci_xls_attach(device_t self) sc->sc_flags |= EHCI_SCFLG_DONEINIT; err = device_probe_and_attach(sc->sc_bus.bdev); } - if (err) { device_printf(self, "USB init failed err=%d\n", err); ehci_xls_detach(self); @@ -234,7 +232,6 @@ ehci_xls_detach(device_t self) ehci_detach(sc, 0); sc->sc_flags &= ~EHCI_SCFLG_DONEINIT; } - /* * disable interrupts that might have been switched on in ehci_init */ @@ -270,13 +267,13 @@ ehci_xls_detach(device_t self) static void ehci_xls_takecontroller(device_t self) { - //device_printf(self, "In func %s\n", __func__); + //device_printf(self, "In func %s\n", __func__); } static void ehci_xls_givecontroller(device_t self) { - //device_printf(self, "In func %s\n", __func__); + //device_printf(self, "In func %s\n", __func__); } static device_method_t ehci_methods[] = { From ebe8d22e40d6d62eb74ff560ee77e4d87a0dd209 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Thu, 29 Oct 2009 21:21:01 +0000 Subject: [PATCH 293/380] white space changes --- sys/dev/rmi/xlr/rge.c | 1221 +++++++++++++++++----------------- sys/dev/rmi/xlr/rge.h | 134 ++-- sys/dev/rmi/xlr/xgmac_mdio.h | 62 +- 3 files changed, 718 insertions(+), 699 deletions(-) diff --git a/sys/dev/rmi/xlr/rge.c b/sys/dev/rmi/xlr/rge.c index fa9807602a9..ef2288e852c 100644 --- a/sys/dev/rmi/xlr/rge.c +++ b/sys/dev/rmi/xlr/rge.c @@ -79,7 +79,7 @@ #include #include #include /* for DELAY */ -#include /* */ +#include /* */ #include #include #include @@ -117,7 +117,8 @@ MODULE_DEPEND(rge, miibus, 1, 1, 1); #ifdef DEBUG #undef dbg_msg -int mac_debug = 1; +int mac_debug = 1; + #define dbg_msg(fmt, args...) \ do {\ if (mac_debug) {\ @@ -130,7 +131,8 @@ int mac_debug = 1; #else #undef dbg_msg #define dbg_msg(fmt, args...) -int mac_debug = 0; +int mac_debug = 0; + #endif #define MAC_B2B_IPG 88 @@ -165,12 +167,13 @@ int mac_debug = 0; extern uint32_t cpu_ltop_map[32]; #ifdef ENABLED_DEBUG -static int port_counters[4][8] __aligned(XLR_CACHELINE_SIZE); +static int port_counters[4][8] __aligned(XLR_CACHELINE_SIZE); + #define port_inc_counter(port, counter) atomic_add_int(&port_counters[port][(counter)], 1) #define port_set_counter(port, counter, value) atomic_set_int(&port_counters[port][(counter)], (value)) #else -#define port_inc_counter(port, counter) /*Nothing*/ -#define port_set_counter(port, counter, value) /*Nothing*/ +#define port_inc_counter(port, counter) /* Nothing */ +#define port_set_counter(port, counter, value) /* Nothing */ #endif int xlr_rge_tx_prepend[MAXCPU]; @@ -181,20 +184,21 @@ int xlr_rge_tx_ok_done[MAXCPU]; int xlr_rge_rx_done[MAXCPU]; int xlr_rge_repl_done[MAXCPU]; -static __inline__ unsigned int +static __inline__ unsigned int ldadd_wu(unsigned int value, unsigned long *addr) { - __asm__ __volatile__( ".set push\n" - ".set noreorder\n" - "move $8, %2\n" - "move $9, %3\n" - /* "ldaddwu $8, $9\n" */ - ".word 0x71280011\n" - "move %0, $8\n" - ".set pop\n" - : "=&r"(value), "+m"(*addr) - : "0"(value), "r" ((unsigned long)addr) - : "$8", "$9"); + __asm__ __volatile__(".set push\n" + ".set noreorder\n" + "move $8, %2\n" + "move $9, %3\n" + /* "ldaddwu $8, $9\n" */ + ".word 0x71280011\n" + "move %0, $8\n" + ".set pop\n" + : "=&r"(value), "+m"(*addr) + : "0"(value), "r"((unsigned long)addr) + : "$8", "$9"); + return value; } @@ -212,85 +216,86 @@ ldadd_wu(unsigned int value, unsigned long *addr) #define XLR_MAX_MACS 8 #define XLR_MAX_TX_FRAGS 14 -#define MAX_P2D_DESC_PER_PORT 512 +#define MAX_P2D_DESC_PER_PORT 512 struct p2d_tx_desc { - uint64_t frag [XLR_MAX_TX_FRAGS + 2]; + uint64_t frag[XLR_MAX_TX_FRAGS + 2]; }; + #define MAX_TX_RING_SIZE (XLR_MAX_MACS * MAX_P2D_DESC_PER_PORT * sizeof(struct p2d_tx_desc)) struct rge_softc *dev_mac[XLR_MAX_MACS]; -static int dev_mac_xgs0; -static int dev_mac_gmac0; +static int dev_mac_xgs0; +static int dev_mac_gmac0; -static int gmac_common_init_done; +static int gmac_common_init_done; -static int rge_probe(device_t); -static int rge_attach(device_t); -static int rge_detach(device_t); -static int rge_suspend(device_t); -static int rge_resume(device_t); -static void rge_release_resources(struct rge_softc *); -static void rge_rx(struct rge_softc *, vm_paddr_t paddr, int); -static void rge_intr(void *); -static void rge_start_locked(struct ifnet *, int); -static void rge_start(struct ifnet *); -static int rge_ioctl(struct ifnet *, u_long, caddr_t); -static void rge_init(void *); -static void rge_stop(struct rge_softc *); -static void rge_watchdog(struct ifnet *); -static int rge_shutdown(device_t); -static void rge_reset(struct rge_softc *); +static int rge_probe(device_t); +static int rge_attach(device_t); +static int rge_detach(device_t); +static int rge_suspend(device_t); +static int rge_resume(device_t); +static void rge_release_resources(struct rge_softc *); +static void rge_rx(struct rge_softc *, vm_paddr_t paddr, int); +static void rge_intr(void *); +static void rge_start_locked(struct ifnet *, int); +static void rge_start(struct ifnet *); +static int rge_ioctl(struct ifnet *, u_long, caddr_t); +static void rge_init(void *); +static void rge_stop(struct rge_softc *); +static void rge_watchdog(struct ifnet *); +static int rge_shutdown(device_t); +static void rge_reset(struct rge_softc *); static struct mbuf *get_mbuf(void); -static void free_buf(vm_paddr_t paddr); -static void *get_buf(void); +static void free_buf(vm_paddr_t paddr); +static void *get_buf(void); -static void xlr_mac_get_hwaddr(struct rge_softc *); -static void xlr_mac_setup_hwaddr(struct driver_data *); -static void rmi_xlr_mac_set_enable(struct driver_data *priv, int flag); -static void rmi_xlr_xgmac_init(struct driver_data *priv); -static void rmi_xlr_gmac_init(struct driver_data *priv); -static void mac_common_init(void); -static int rge_mii_write(device_t, int, int, int); -static int rge_mii_read(device_t, int, int); -static void rmi_xlr_mac_mii_statchg(device_t); -static int rmi_xlr_mac_mediachange(struct ifnet *); -static void rmi_xlr_mac_mediastatus(struct ifnet *, struct ifmediareq *); -static void xlr_mac_set_rx_mode(struct rge_softc *sc); -void +static void xlr_mac_get_hwaddr(struct rge_softc *); +static void xlr_mac_setup_hwaddr(struct driver_data *); +static void rmi_xlr_mac_set_enable(struct driver_data *priv, int flag); +static void rmi_xlr_xgmac_init(struct driver_data *priv); +static void rmi_xlr_gmac_init(struct driver_data *priv); +static void mac_common_init(void); +static int rge_mii_write(device_t, int, int, int); +static int rge_mii_read(device_t, int, int); +static void rmi_xlr_mac_mii_statchg(device_t); +static int rmi_xlr_mac_mediachange(struct ifnet *); +static void rmi_xlr_mac_mediastatus(struct ifnet *, struct ifmediareq *); +static void xlr_mac_set_rx_mode(struct rge_softc *sc); +void rmi_xlr_mac_msgring_handler(int bucket, int size, int code, - int stid, struct msgrng_msg *msg, - void *data); -static void mac_frin_replenish(void *); -static int rmi_xlr_mac_open(struct rge_softc *); -static int rmi_xlr_mac_close(struct rge_softc *); -static int + int stid, struct msgrng_msg *msg, + void *data); +static void mac_frin_replenish(void *); +static int rmi_xlr_mac_open(struct rge_softc *); +static int rmi_xlr_mac_close(struct rge_softc *); +static int mac_xmit(struct mbuf *, struct rge_softc *, - struct driver_data *, int, struct p2d_tx_desc *); -static int rmi_xlr_mac_xmit(struct mbuf *, struct rge_softc *, int, struct p2d_tx_desc *); + struct driver_data *, int, struct p2d_tx_desc *); +static int rmi_xlr_mac_xmit(struct mbuf *, struct rge_softc *, int, struct p2d_tx_desc *); static struct rge_softc_stats *rmi_xlr_mac_get_stats(struct rge_softc *sc); -static void rmi_xlr_mac_set_multicast_list(struct rge_softc *sc); -static int rmi_xlr_mac_change_mtu(struct rge_softc *sc, int new_mtu); -static int rmi_xlr_mac_fill_rxfr(struct rge_softc *sc); -static void rmi_xlr_config_spill_area(struct driver_data *priv); -static int rmi_xlr_mac_set_speed(struct driver_data *s, xlr_mac_speed_t speed); -static int +static void rmi_xlr_mac_set_multicast_list(struct rge_softc *sc); +static int rmi_xlr_mac_change_mtu(struct rge_softc *sc, int new_mtu); +static int rmi_xlr_mac_fill_rxfr(struct rge_softc *sc); +static void rmi_xlr_config_spill_area(struct driver_data *priv); +static int rmi_xlr_mac_set_speed(struct driver_data *s, xlr_mac_speed_t speed); +static int rmi_xlr_mac_set_duplex(struct driver_data *s, - xlr_mac_duplex_t duplex, xlr_mac_fc_t fc); + xlr_mac_duplex_t duplex, xlr_mac_fc_t fc); static void serdes_regs_init(struct driver_data *priv); static int rmi_xlr_gmac_reset(struct driver_data *priv); /*Statistics...*/ static int get_p2d_desc_failed = 0; -static int msg_snd_failed =0; +static int msg_snd_failed = 0; SYSCTL_INT(_hw, OID_AUTO, get_p2d_failed, CTLFLAG_RW, - &get_p2d_desc_failed, 0, "p2d desc failed"); + &get_p2d_desc_failed, 0, "p2d desc failed"); SYSCTL_INT(_hw, OID_AUTO, msg_snd_failed, CTLFLAG_RW, - &msg_snd_failed, 0, "msg snd failed"); + &msg_snd_failed, 0, "msg snd failed"); -struct callout xlr_tx_stop_bkp; +struct callout xlr_tx_stop_bkp; static device_method_t rge_methods[] = { /* Device interface */ @@ -308,7 +313,7 @@ static device_method_t rge_methods[] = { {0, 0} }; -static driver_t rge_driver = { +static driver_t rge_driver = { "rge", rge_methods, sizeof(struct rge_softc) @@ -328,60 +333,61 @@ DRIVER_MODULE(miibus, rge, miibus_driver, miibus_devclass, 0, 0); #define XKPHYS 0x8000000000000000 -static __inline__ uint32_t +static __inline__ uint32_t lw_40bit_phys(uint64_t phys, int cca) { - uint64_t addr; - uint32_t value = 0; - unsigned long flags; + uint64_t addr; + uint32_t value = 0; + unsigned long flags; + + addr = XKPHYS | ((uint64_t) cca << 59) | (phys & 0xfffffffffcULL); - addr = XKPHYS | ((uint64_t)cca << 59) | (phys & 0xfffffffffcULL); - enable_KX(flags); - __asm__ __volatile__( - ".set push\n" - ".set noreorder\n" - ".set mips64\n" - "lw %0, 0(%1) \n" - ".set pop\n" - : "=r" (value) - : "r" (addr) ); + __asm__ __volatile__( + ".set push\n" + ".set noreorder\n" + ".set mips64\n" + "lw %0, 0(%1) \n" + ".set pop\n" + : "=r"(value) + : "r"(addr)); disable_KX(flags); return value; } -static __inline__ uint64_t +static __inline__ uint64_t ld_40bit_phys(uint64_t phys, int cca) { - uint64_t addr; - uint64_t value = 0; - unsigned long flags; + uint64_t addr; + uint64_t value = 0; + unsigned long flags; - addr = XKPHYS | ((uint64_t)cca << 59) | (phys & 0xfffffffffcULL); + addr = XKPHYS | ((uint64_t) cca << 59) | (phys & 0xfffffffffcULL); enable_KX(flags); - __asm__ __volatile__( - ".set push\n" - ".set noreorder\n" - ".set mips64\n" - "ld %0, 0(%1) \n" - ".set pop\n" - : "=r" (value) - : "r" (addr)); + __asm__ __volatile__( + ".set push\n" + ".set noreorder\n" + ".set mips64\n" + "ld %0, 0(%1) \n" + ".set pop\n" + : "=r"(value) + : "r"(addr)); disable_KX(flags); return value; } -void *xlr_tx_ring_mem; +void *xlr_tx_ring_mem; struct tx_desc_node { struct p2d_tx_desc *ptr; - TAILQ_ENTRY (tx_desc_node) list; + TAILQ_ENTRY(tx_desc_node) list; }; + #define XLR_MAX_TX_DESC_NODES (XLR_MAX_MACS * MAX_P2D_DESC_PER_PORT) struct tx_desc_node tx_desc_nodes[XLR_MAX_TX_DESC_NODES]; static volatile int xlr_tot_avail_p2d[XLR_MAX_CORE]; @@ -391,37 +397,38 @@ static int xlr_total_active_core = 0; * This should contain the list of all free tx frag desc nodes pointing to tx * p2d arrays */ -static +static TAILQ_HEAD(, tx_desc_node) tx_frag_desc[XLR_MAX_CORE] = - { - TAILQ_HEAD_INITIALIZER(tx_frag_desc[0]), - TAILQ_HEAD_INITIALIZER(tx_frag_desc[1]), - TAILQ_HEAD_INITIALIZER(tx_frag_desc[2]), - TAILQ_HEAD_INITIALIZER(tx_frag_desc[3]), - TAILQ_HEAD_INITIALIZER(tx_frag_desc[4]), - TAILQ_HEAD_INITIALIZER(tx_frag_desc[5]), - TAILQ_HEAD_INITIALIZER(tx_frag_desc[6]), - TAILQ_HEAD_INITIALIZER(tx_frag_desc[7]), - }; +{ + TAILQ_HEAD_INITIALIZER(tx_frag_desc[0]), + TAILQ_HEAD_INITIALIZER(tx_frag_desc[1]), + TAILQ_HEAD_INITIALIZER(tx_frag_desc[2]), + TAILQ_HEAD_INITIALIZER(tx_frag_desc[3]), + TAILQ_HEAD_INITIALIZER(tx_frag_desc[4]), + TAILQ_HEAD_INITIALIZER(tx_frag_desc[5]), + TAILQ_HEAD_INITIALIZER(tx_frag_desc[6]), + TAILQ_HEAD_INITIALIZER(tx_frag_desc[7]), +}; /* This contains a list of free tx frag node descriptors */ -static TAILQ_HEAD(, tx_desc_node) free_tx_frag_desc[XLR_MAX_CORE] = - { - TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[0]), - TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[1]), - TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[2]), - TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[3]), - TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[4]), - TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[5]), - TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[6]), - TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[7]), - }; +static +TAILQ_HEAD(, tx_desc_node) free_tx_frag_desc[XLR_MAX_CORE] = +{ + TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[0]), + TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[1]), + TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[2]), + TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[3]), + TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[4]), + TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[5]), + TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[6]), + TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[7]), +}; static struct mtx tx_desc_lock[XLR_MAX_CORE]; static inline void -mac_make_desc_rfr(struct msgrng_msg *msg, - vm_paddr_t addr) +mac_make_desc_rfr(struct msgrng_msg *msg, + vm_paddr_t addr) { msg->msg0 = (uint64_t) addr & 0xffffffffe0ULL; msg->msg1 = msg->msg2 = msg->msg3 = 0; @@ -432,8 +439,8 @@ mac_make_desc_rfr(struct msgrng_msg *msg, static void init_p2d_allocation(void) { - int active_core[8]= {0}; - int i=0; + int active_core[8] = {0}; + int i = 0; uint32_t cpumask; int cpu; @@ -442,43 +449,43 @@ init_p2d_allocation(void) for (i = 0; i < 32; i++) { if (cpumask & (1 << i)) { cpu = cpu_ltop_map[i]; - if(!active_core[cpu/4]){ - active_core[cpu/4] = 1; + if (!active_core[cpu / 4]) { + active_core[cpu / 4] = 1; xlr_total_active_core++; } } } - for(i=0; iptr = tx_desc; tx_desc++; TAILQ_INSERT_HEAD(&tx_frag_desc[j], node, list); - j = (i / (XLR_MAX_TX_DESC_NODES/xlr_total_active_core)); + j = (i / (XLR_MAX_TX_DESC_NODES / xlr_total_active_core)); } } @@ -508,14 +515,14 @@ get_p2d_desc(void) TAILQ_REMOVE(&tx_frag_desc[cpu], node, list); tx_desc = node->ptr; TAILQ_INSERT_HEAD(&free_tx_frag_desc[cpu], node, list); - }else{ - /*Increment p2d desc fail count*/ + } else { + /* Increment p2d desc fail count */ get_p2d_desc_failed++; } mtx_unlock_spin(&tx_desc_lock[cpu]); return tx_desc; } -static void +static void free_p2d_desc(struct p2d_tx_desc *tx_desc) { struct tx_desc_node *node; @@ -533,17 +540,18 @@ free_p2d_desc(struct p2d_tx_desc *tx_desc) } -static int +static int build_frag_list(struct mbuf *m_head, struct msgrng_msg *p2p_msg, struct p2d_tx_desc *tx_desc) { - struct mbuf *m; - vm_paddr_t paddr; - uint64_t p2d_len; - int nfrag; - vm_paddr_t p1 , p2; - uint32_t len1 , len2; - vm_offset_t taddr; - uint64_t fr_stid; + struct mbuf *m; + vm_paddr_t paddr; + uint64_t p2d_len; + int nfrag; + vm_paddr_t p1, p2; + uint32_t len1, len2; + vm_offset_t taddr; + uint64_t fr_stid; + fr_stid = (xlr_cpu_id() << 3) + xlr_thr_id() + 4; if (tx_desc == NULL) @@ -558,21 +566,21 @@ build_frag_list(struct mbuf *m_head, struct msgrng_msg *p2p_msg, struct p2d_tx_d if (m->m_len != 0) { paddr = vtophys(mtod(m, vm_offset_t)); p1 = paddr + m->m_len; - p2 = vtophys(((vm_offset_t) m->m_data + m->m_len)); + p2 = vtophys(((vm_offset_t)m->m_data + m->m_len)); if (p1 != p2) { len1 = (uint32_t) - (PAGE_SIZE - (paddr & PAGE_MASK)); + (PAGE_SIZE - (paddr & PAGE_MASK)); tx_desc->frag[nfrag] = (127ULL << 54) | - ((uint64_t) len1 << 40) | paddr; + ((uint64_t) len1 << 40) | paddr; nfrag++; - taddr = (vm_offset_t) m->m_data + len1; + taddr = (vm_offset_t)m->m_data + len1; p2 = vtophys(taddr); len2 = m->m_len - len1; if (nfrag >= XLR_MAX_TX_FRAGS) panic("TX frags exceeded"); tx_desc->frag[nfrag] = (127ULL << 54) | - ((uint64_t) len2 << 40) | p2; + ((uint64_t) len2 << 40) | p2; taddr += len2; p1 = vtophys(taddr); @@ -580,76 +588,76 @@ build_frag_list(struct mbuf *m_head, struct msgrng_msg *p2p_msg, struct p2d_tx_d if ((p2 + len2) != p1) { printf("p1 = %p p2 = %p\n", (void *)p1, (void *)p2); printf("len1 = %x len2 = %x\n", len1, - len2); + len2); printf("m_data %p\n", m->m_data); DELAY(1000000); panic("Multiple Mbuf segment discontiguous\n"); } } else { tx_desc->frag[nfrag] = (127ULL << 54) | - ((uint64_t) m->m_len << 40) | paddr; + ((uint64_t) m->m_len << 40) | paddr; } nfrag++; } } /* set eop in the last tx p2d desc */ tx_desc->frag[nfrag - 1] |= (1ULL << 63); - paddr = vtophys((vm_offset_t) tx_desc); + paddr = vtophys((vm_offset_t)tx_desc); tx_desc->frag[nfrag] = (1ULL << 63) | (fr_stid << 54) | paddr; nfrag++; - tx_desc->frag[XLR_MAX_TX_FRAGS] = (uint64_t) (vm_offset_t) tx_desc; - tx_desc->frag[XLR_MAX_TX_FRAGS + 1] = (uint64_t) (vm_offset_t) m_head; + tx_desc->frag[XLR_MAX_TX_FRAGS] = (uint64_t) (vm_offset_t)tx_desc; + tx_desc->frag[XLR_MAX_TX_FRAGS + 1] = (uint64_t) (vm_offset_t)m_head; p2d_len = (nfrag * 8); p2p_msg->msg0 = (1ULL << 63) | (1ULL << 62) | (127ULL << 54) | - (p2d_len << 40) | paddr; + (p2d_len << 40) | paddr; return 0; } -static void +static void release_tx_desc(struct msgrng_msg *msg, int rel_buf) { - vm_paddr_t paddr = msg->msg0 & 0xffffffffffULL; - uint64_t temp; + vm_paddr_t paddr = msg->msg0 & 0xffffffffffULL; + uint64_t temp; struct p2d_tx_desc *tx_desc; - struct mbuf *m; + struct mbuf *m; paddr += (XLR_MAX_TX_FRAGS * sizeof(uint64_t)); temp = ld_40bit_phys(paddr, 3); - tx_desc = (struct p2d_tx_desc *)((vm_offset_t) temp); + tx_desc = (struct p2d_tx_desc *)((vm_offset_t)temp); if (rel_buf) { paddr += sizeof(uint64_t); temp = ld_40bit_phys(paddr, 3); - m = (struct mbuf *)((vm_offset_t) temp); + m = (struct mbuf *)((vm_offset_t)temp); m_freem(m); } - free_p2d_desc(tx_desc); } #ifdef RX_COPY #define RGE_MAX_NUM_DESC (6 * MAX_NUM_DESC) -uint8_t *rge_rx_buffers[RGE_MAX_NUM_DESC]; +uint8_t *rge_rx_buffers[RGE_MAX_NUM_DESC]; static struct mtx rge_rx_mtx; -int g_rx_buf_head; +int g_rx_buf_head; -static void +static void init_rx_buf(void) { - int i; - uint8_t *buf, *start; - uint32_t size , *ptr; + int i; + uint8_t *buf, *start; + uint32_t size, *ptr; + mtx_init(&rge_rx_mtx, "xlr rx_desc", NULL, MTX_SPIN); size = (RGE_MAX_NUM_DESC * (MAX_FRAME_SIZE + XLR_CACHELINE_SIZE)); start = (uint8_t *) contigmalloc(size, M_DEVBUF, M_NOWAIT | M_ZERO, - 0, 0xffffffff, XLR_CACHELINE_SIZE, 0); + 0, 0xffffffff, XLR_CACHELINE_SIZE, 0); if (start == NULL) panic("NO RX BUFFERS"); buf = start; @@ -662,10 +670,11 @@ init_rx_buf(void) } } -static void * +static void * get_rx_buf(void) { - void *ptr = NULL; + void *ptr = NULL; + mtx_lock_spin(&rge_rx_mtx); if (g_rx_buf_head < RGE_MAX_NUM_DESC) { ptr = (void *)rge_rx_buffers[g_rx_buf_head]; @@ -674,12 +683,13 @@ get_rx_buf(void) mtx_unlock_spin(&rge_rx_mtx); return ptr; } + #endif -static struct mbuf * +static struct mbuf * get_mbuf(void) { - struct mbuf *m_new = NULL; + struct mbuf *m_new = NULL; if ((m_new = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR)) == NULL) return NULL; @@ -689,11 +699,11 @@ get_mbuf(void) return m_new; } -static void +static void free_buf(vm_paddr_t paddr) { - struct mbuf *m; - vm_offset_t temp; + struct mbuf *m; + vm_offset_t temp; temp = lw_40bit_phys((paddr - XLR_CACHELINE_SIZE), 3); m = (struct mbuf *)temp; @@ -707,9 +717,11 @@ get_buf(void) #ifdef RX_COPY return get_rx_buf(); #else - struct mbuf *m_new = NULL; + struct mbuf *m_new = NULL; + #ifdef INVARIANTS - vm_paddr_t temp1, temp2; + vm_paddr_t temp1, temp2; + #endif unsigned int *md; @@ -727,8 +739,8 @@ get_buf(void) /* return (void *)m_new; */ #ifdef INVARIANTS - temp1 = vtophys((vm_offset_t) m_new->m_data); - temp2 = vtophys((vm_offset_t) m_new->m_data + 1536); + temp1 = vtophys((vm_offset_t)m_new->m_data); + temp2 = vtophys((vm_offset_t)m_new->m_data + 1536); if ((temp1 + 1536) != temp2) panic("ALLOCED BUFFER IS NOT CONTIGUOUS\n"); #endif @@ -738,16 +750,16 @@ get_buf(void) /********************************************************************** **********************************************************************/ -static void +static void rmi_xlr_mac_set_enable(struct driver_data *priv, int flag) { - uint32_t regval; - int tx_threshold = 1518; + uint32_t regval; + int tx_threshold = 1518; if (flag) { regval = xlr_read_reg(priv->mmio, R_TX_CONTROL); regval |= (1 << O_TX_CONTROL__TxEnable) | - (tx_threshold << O_TX_CONTROL__TxThreshold); + (tx_threshold << O_TX_CONTROL__TxThreshold); xlr_write_reg(priv->mmio, R_TX_CONTROL, regval); @@ -763,7 +775,7 @@ rmi_xlr_mac_set_enable(struct driver_data *priv, int flag) } else { regval = xlr_read_reg(priv->mmio, R_TX_CONTROL); regval &= ~((1 << O_TX_CONTROL__TxEnable) | - (tx_threshold << O_TX_CONTROL__TxThreshold)); + (tx_threshold << O_TX_CONTROL__TxThreshold)); xlr_write_reg(priv->mmio, R_TX_CONTROL, regval); @@ -779,19 +791,19 @@ rmi_xlr_mac_set_enable(struct driver_data *priv, int flag) /********************************************************************** **********************************************************************/ -static __inline__ int +static __inline__ int xlr_mac_send_fr(struct driver_data *priv, - vm_paddr_t addr, int len) + vm_paddr_t addr, int len) { - int stid = priv->rfrbucket; + int stid = priv->rfrbucket; struct msgrng_msg msg; - int vcpu = (xlr_cpu_id()<<2)+xlr_thr_id(); + int vcpu = (xlr_cpu_id() << 2) + xlr_thr_id(); - mac_make_desc_rfr(&msg, addr); + mac_make_desc_rfr(&msg, addr); /* Send the packet to MAC */ dbg_msg("mac_%d: Sending free packet %llx to stid %d\n", - priv->instance, addr, stid); + priv->instance, addr, stid); if (priv->type == XLR_XGMAC) { while (message_send(1, MSGRNG_CODE_XGMAC, stid, &msg)); } else { @@ -804,11 +816,12 @@ xlr_mac_send_fr(struct driver_data *priv, /**************************************************************/ -static void +static void xgmac_mdio_setup(volatile unsigned int *_mmio) { - int i; - uint32_t rd_data; + int i; + uint32_t rd_data; + for (i = 0; i < 4; i++) { rd_data = xmdio_read(_mmio, 1, 0x8000 + i); rd_data = rd_data & 0xffffdfff; /* clear isolate bit */ @@ -824,10 +837,10 @@ xgmac_mdio_setup(volatile unsigned int *_mmio) ********************************************************************* */ #define PHY_STATUS_RETRIES 25000 -static void +static void rmi_xlr_mac_mii_init(struct driver_data *priv) { - xlr_reg_t *mii_mmio = priv->mii_mmio; + xlr_reg_t *mii_mmio = priv->mii_mmio; /* use the lowest clock divisor - divisor 28 */ xlr_write_reg(mii_mmio, R_MII_MGMT_CONFIG, 0x07); @@ -845,17 +858,17 @@ rmi_xlr_mac_mii_init(struct driver_data *priv) * value read, or 0 if an error occurred. ********************************************************************* */ -static int -rge_mii_read_internal(xlr_reg_t *mii_mmio, int phyaddr, int regidx) +static int +rge_mii_read_internal(xlr_reg_t * mii_mmio, int phyaddr, int regidx) { - int i = 0; + int i = 0; /* setup the phy reg to be used */ xlr_write_reg(mii_mmio, R_MII_MGMT_ADDRESS, - (phyaddr << 8) | (regidx << 0)); + (phyaddr << 8) | (regidx << 0)); /* Issue the read command */ xlr_write_reg(mii_mmio, R_MII_MGMT_COMMAND, - (1 << O_MII_MGMT_COMMAND__rstat)); + (1 << O_MII_MGMT_COMMAND__rstat)); /* poll for the read cycle to complete */ for (i = 0; i < PHY_STATUS_RETRIES; i++) { @@ -873,10 +886,11 @@ rge_mii_read_internal(xlr_reg_t *mii_mmio, int phyaddr, int regidx) return xlr_read_reg(mii_mmio, R_MII_MGMT_STATUS); } -static int +static int rge_mii_read(device_t dev, int phyaddr, int regidx) { struct rge_softc *sc = device_get_softc(dev); + return rge_mii_read_internal(sc->priv.mii_mmio, phyaddr, regidx); } @@ -889,7 +903,7 @@ rge_mii_read(device_t dev, int phyaddr, int regidx) * Return value: * nothing ********************************************************************* */ -static int +static int rmi_xlr_mac_mediachange(struct ifnet *ifp) { struct rge_softc *sc = ifp->if_softc; @@ -915,11 +929,11 @@ rmi_xlr_mac_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) { struct rge_softc *sc = ifp->if_softc; - /*Check whether this is interface is active or not.*/ + /* Check whether this is interface is active or not. */ ifmr->ifm_status = IFM_AVALID; - if(sc->link_up){ + if (sc->link_up) { ifmr->ifm_status |= IFM_ACTIVE; - }else{ + } else { ifmr->ifm_active = IFM_ETHER; } } @@ -937,12 +951,12 @@ rmi_xlr_mac_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) * nothing ********************************************************************* */ static void -rge_mii_write_internal(xlr_reg_t *mii_mmio, int phyaddr, int regidx, int regval) +rge_mii_write_internal(xlr_reg_t * mii_mmio, int phyaddr, int regidx, int regval) { - int i = 0; + int i = 0; xlr_write_reg(mii_mmio, R_MII_MGMT_ADDRESS, - (phyaddr << 8) | (regidx << 0)); + (phyaddr << 8) | (regidx << 0)); /* Write the data which starts the write cycle */ xlr_write_reg(mii_mmio, R_MII_MGMT_WRITE_DATA, regval); @@ -965,7 +979,7 @@ rge_mii_write(device_t dev, int phyaddr, int regidx, int regval) return (0); } -static void +static void rmi_xlr_mac_mii_statchg(struct device *dev) { } @@ -973,12 +987,12 @@ rmi_xlr_mac_mii_statchg(struct device *dev) static void serdes_regs_init(struct driver_data *priv) { - xlr_reg_t *mmio_gpio = (xlr_reg_t *)(xlr_io_base + XLR_IO_GPIO_OFFSET); + xlr_reg_t *mmio_gpio = (xlr_reg_t *) (xlr_io_base + XLR_IO_GPIO_OFFSET); int i; /* Initialize SERDES CONTROL Registers */ rge_mii_write_internal(priv->serdes_mmio, 26, 0, 0x6DB0); - rge_mii_write_internal(priv->serdes_mmio, 26, 1, 0xFFFF); + rge_mii_write_internal(priv->serdes_mmio, 26, 1, 0xFFFF); rge_mii_write_internal(priv->serdes_mmio, 26, 2, 0xB6D0); rge_mii_write_internal(priv->serdes_mmio, 26, 3, 0x00FF); rge_mii_write_internal(priv->serdes_mmio, 26, 4, 0x0000); @@ -987,87 +1001,92 @@ serdes_regs_init(struct driver_data *priv) rge_mii_write_internal(priv->serdes_mmio, 26, 7, 0x0001); rge_mii_write_internal(priv->serdes_mmio, 26, 8, 0x0000); rge_mii_write_internal(priv->serdes_mmio, 26, 9, 0x0000); - rge_mii_write_internal(priv->serdes_mmio, 26,10, 0x0000); + rge_mii_write_internal(priv->serdes_mmio, 26, 10, 0x0000); - /* + /* * For loop delay and GPIO programming crud from Linux driver, */ - for(i=0;i<10000000;i++){} + for (i = 0; i < 10000000; i++) { + } mmio_gpio[0x20] = 0x7e6802; mmio_gpio[0x10] = 0x7104; - for(i=0;i<100000000;i++){} + for (i = 0; i < 100000000; i++) { + } return; -} +} -static void serdes_autoconfig(struct driver_data *priv) +static void +serdes_autoconfig(struct driver_data *priv) { - int delay = 100000; + int delay = 100000; - /* Enable Auto negotiation in the PCS Layer*/ - rge_mii_write_internal(priv->pcs_mmio, 27, 0, 0x1000); - DELAY(delay); - rge_mii_write_internal(priv->pcs_mmio, 27, 0, 0x0200); - DELAY(delay); + /* Enable Auto negotiation in the PCS Layer */ + rge_mii_write_internal(priv->pcs_mmio, 27, 0, 0x1000); + DELAY(delay); + rge_mii_write_internal(priv->pcs_mmio, 27, 0, 0x0200); + DELAY(delay); - rge_mii_write_internal(priv->pcs_mmio, 28, 0, 0x1000); - DELAY(delay); - rge_mii_write_internal(priv->pcs_mmio, 28, 0, 0x0200); - DELAY(delay); + rge_mii_write_internal(priv->pcs_mmio, 28, 0, 0x1000); + DELAY(delay); + rge_mii_write_internal(priv->pcs_mmio, 28, 0, 0x0200); + DELAY(delay); - rge_mii_write_internal(priv->pcs_mmio, 29, 0, 0x1000); - DELAY(delay); - rge_mii_write_internal(priv->pcs_mmio, 29, 0, 0x0200); - DELAY(delay); + rge_mii_write_internal(priv->pcs_mmio, 29, 0, 0x1000); + DELAY(delay); + rge_mii_write_internal(priv->pcs_mmio, 29, 0, 0x0200); + DELAY(delay); - rge_mii_write_internal(priv->pcs_mmio, 30, 0, 0x1000); - DELAY(delay); - rge_mii_write_internal(priv->pcs_mmio, 30, 0, 0x0200); - DELAY(delay); + rge_mii_write_internal(priv->pcs_mmio, 30, 0, 0x1000); + DELAY(delay); + rge_mii_write_internal(priv->pcs_mmio, 30, 0, 0x0200); + DELAY(delay); } /***************************************************************** * Initialize GMAC *****************************************************************/ -static void +static void rmi_xlr_config_pde(struct driver_data *priv) { - int i = 0, cpu = 0, bucket = 0; - uint64_t bucket_map = 0; + int i = 0, cpu = 0, bucket = 0; + uint64_t bucket_map = 0; + /* uint32_t desc_pack_ctrl = 0; */ - uint32_t cpumask; + uint32_t cpumask; cpumask = PCPU_GET(cpumask) | PCPU_GET(other_cpus); for (i = 0; i < 32; i++) { if (cpumask & (1 << i)) { cpu = cpu_ltop_map[i]; - bucket = ((cpu >> 2) << 3);//| (cpu & 0x03); + bucket = ((cpu >> 2) << 3); + //|(cpu & 0x03); bucket_map |= (1ULL << bucket); dbg_msg("i=%d, cpu=%d, bucket = %d, bucket_map=%llx\n", - i, cpu, bucket, bucket_map); + i, cpu, bucket, bucket_map); } } /* bucket_map = 0x1; */ xlr_write_reg(priv->mmio, R_PDE_CLASS_0, (bucket_map & 0xffffffff)); xlr_write_reg(priv->mmio, R_PDE_CLASS_0 + 1, - ((bucket_map >> 32) & 0xffffffff)); + ((bucket_map >> 32) & 0xffffffff)); xlr_write_reg(priv->mmio, R_PDE_CLASS_1, (bucket_map & 0xffffffff)); xlr_write_reg(priv->mmio, R_PDE_CLASS_1 + 1, - ((bucket_map >> 32) & 0xffffffff)); + ((bucket_map >> 32) & 0xffffffff)); xlr_write_reg(priv->mmio, R_PDE_CLASS_2, (bucket_map & 0xffffffff)); xlr_write_reg(priv->mmio, R_PDE_CLASS_2 + 1, - ((bucket_map >> 32) & 0xffffffff)); + ((bucket_map >> 32) & 0xffffffff)); xlr_write_reg(priv->mmio, R_PDE_CLASS_3, (bucket_map & 0xffffffff)); xlr_write_reg(priv->mmio, R_PDE_CLASS_3 + 1, - ((bucket_map >> 32) & 0xffffffff)); + ((bucket_map >> 32) & 0xffffffff)); } -static void +static void rmi_xlr_config_parser(struct driver_data *priv) { /* @@ -1081,17 +1100,17 @@ rmi_xlr_config_parser(struct driver_data *priv) /* configure the parser : L2 Type is configured in the bootloader */ /* extract IP: src, dest protocol */ xlr_write_reg(priv->mmio, R_L3CTABLE, - (9 << 20) | (1 << 19) | (1 << 18) | (0x01 << 16) | - (0x0800 << 0)); + (9 << 20) | (1 << 19) | (1 << 18) | (0x01 << 16) | + (0x0800 << 0)); xlr_write_reg(priv->mmio, R_L3CTABLE + 1, - (12 << 25) | (4 << 21) | (16 << 14) | (4 << 10)); + (12 << 25) | (4 << 21) | (16 << 14) | (4 << 10)); } -static void +static void rmi_xlr_config_classifier(struct driver_data *priv) { - int i = 0; + int i = 0; if (priv->type == XLR_XGMAC) { /* xgmac translation table doesn't have sane values on reset */ @@ -1107,16 +1126,16 @@ rmi_xlr_config_classifier(struct driver_data *priv) } enum { - SGMII_SPEED_10 = 0x00000000, - SGMII_SPEED_100 = 0x02000000, - SGMII_SPEED_1000 = 0x04000000, + SGMII_SPEED_10 = 0x00000000, + SGMII_SPEED_100 = 0x02000000, + SGMII_SPEED_1000 = 0x04000000, }; -static void +static void rmi_xlr_gmac_config_speed(struct driver_data *priv) { int phy_addr = priv->phy_addr; - xlr_reg_t *mmio = priv->mmio; + xlr_reg_t *mmio = priv->mmio; struct rge_softc *sc = priv->sc; priv->speed = rge_mii_read_internal(priv->mii_mmio, phy_addr, 28); @@ -1129,9 +1148,9 @@ rmi_xlr_gmac_config_speed(struct driver_data *priv) xlr_write_reg(mmio, R_MAC_CONFIG_2, 0x7137); xlr_write_reg(mmio, R_CORECONTROL, 0x02); printf("%s: [10Mbps]\n", device_get_nameunit(sc->rge_dev)); - sc->rge_mii.mii_media.ifm_media = IFM_ETHER | IFM_AUTO | IFM_10_T | IFM_FDX; + sc->rge_mii.mii_media.ifm_media = IFM_ETHER | IFM_AUTO | IFM_10_T | IFM_FDX; sc->rge_mii.mii_media.ifm_cur->ifm_media = IFM_ETHER | IFM_AUTO | IFM_10_T | IFM_FDX; - sc->rge_mii.mii_media_active = IFM_ETHER | IFM_AUTO | IFM_10_T | IFM_FDX; + sc->rge_mii.mii_media_active = IFM_ETHER | IFM_AUTO | IFM_10_T | IFM_FDX; } else if (priv->speed == xlr_mac_speed_100) { if (priv->mode != XLR_RGMII) xlr_write_reg(mmio, R_INTERFACE_CONTROL, SGMII_SPEED_100); @@ -1162,7 +1181,7 @@ rmi_xlr_gmac_config_speed(struct driver_data *priv) sc->rge_mii.mii_media_active = IFM_ETHER | IFM_AUTO | IFM_1000_T | IFM_FDX; } } - + if (!priv->link) { sc->rge_mii.mii_media.ifm_cur->ifm_media = IFM_ETHER; sc->link_up = 0; @@ -1174,19 +1193,19 @@ rmi_xlr_gmac_config_speed(struct driver_data *priv) /***************************************************************** * Initialize XGMAC *****************************************************************/ -static void +static void rmi_xlr_xgmac_init(struct driver_data *priv) { - int i = 0; - xlr_reg_t *mmio = priv->mmio; - int id = priv->instance; + int i = 0; + xlr_reg_t *mmio = priv->mmio; + int id = priv->instance; struct rge_softc *sc = priv->sc; volatile unsigned short *cpld; cpld = (volatile unsigned short *)0xBD840000; xlr_write_reg(priv->mmio, R_DESC_PACK_CTRL, - (MAX_FRAME_SIZE << O_DESC_PACK_CTRL__RegularSize) | (4 << 20)); + (MAX_FRAME_SIZE << O_DESC_PACK_CTRL__RegularSize) | (4 << 20)); xlr_write_reg(priv->mmio, R_BYTEOFFSET0, BYTE_OFFSET); rmi_xlr_config_pde(priv); rmi_xlr_config_parser(priv); @@ -1228,36 +1247,36 @@ rmi_xlr_xgmac_init(struct driver_data *priv) if (id == 0) { for (i = 0; i < 16; i++) { xlr_write_reg(mmio, R_XGS_TX0_BUCKET_SIZE + i, - bucket_sizes. - bucket[MSGRNG_STNID_XGS0_TX + i]); + bucket_sizes. + bucket[MSGRNG_STNID_XGS0_TX + i]); } xlr_write_reg(mmio, R_XGS_JFR_BUCKET_SIZE, - bucket_sizes.bucket[MSGRNG_STNID_XMAC0JFR]); + bucket_sizes.bucket[MSGRNG_STNID_XMAC0JFR]); xlr_write_reg(mmio, R_XGS_RFR_BUCKET_SIZE, - bucket_sizes.bucket[MSGRNG_STNID_XMAC0RFR]); + bucket_sizes.bucket[MSGRNG_STNID_XMAC0RFR]); for (i = 0; i < MAX_NUM_MSGRNG_STN_CC; i++) { xlr_write_reg(mmio, R_CC_CPU0_0 + i, - cc_table_xgs_0. - counters[i >> 3][i & 0x07]); + cc_table_xgs_0. + counters[i >> 3][i & 0x07]); } } else if (id == 1) { for (i = 0; i < 16; i++) { xlr_write_reg(mmio, R_XGS_TX0_BUCKET_SIZE + i, - bucket_sizes. - bucket[MSGRNG_STNID_XGS1_TX + i]); + bucket_sizes. + bucket[MSGRNG_STNID_XGS1_TX + i]); } xlr_write_reg(mmio, R_XGS_JFR_BUCKET_SIZE, - bucket_sizes.bucket[MSGRNG_STNID_XMAC1JFR]); + bucket_sizes.bucket[MSGRNG_STNID_XMAC1JFR]); xlr_write_reg(mmio, R_XGS_RFR_BUCKET_SIZE, - bucket_sizes.bucket[MSGRNG_STNID_XMAC1RFR]); + bucket_sizes.bucket[MSGRNG_STNID_XMAC1RFR]); for (i = 0; i < MAX_NUM_MSGRNG_STN_CC; i++) { xlr_write_reg(mmio, R_CC_CPU0_0 + i, - cc_table_xgs_1. - counters[i >> 3][i & 0x07]); + cc_table_xgs_1. + counters[i >> 3][i & 0x07]); } } sc->rge_mii.mii_media.ifm_media = IFM_ETHER | IFM_AUTO | IFM_10G_SR | IFM_FDX; @@ -1279,66 +1298,66 @@ rmi_xlr_gmac_reset(struct driver_data *priv) xlr_reg_t *mmio = priv->mmio; int i, maxloops = 100; - /* Disable MAC RX */ - val = xlr_read_reg(mmio, R_MAC_CONFIG_1); - val &= ~0x4; - xlr_write_reg(mmio, R_MAC_CONFIG_1, val); + /* Disable MAC RX */ + val = xlr_read_reg(mmio, R_MAC_CONFIG_1); + val &= ~0x4; + xlr_write_reg(mmio, R_MAC_CONFIG_1, val); - /* Disable Core RX */ - val = xlr_read_reg(mmio, R_RX_CONTROL); - val &= ~0x1; - xlr_write_reg(mmio, R_RX_CONTROL, val); + /* Disable Core RX */ + val = xlr_read_reg(mmio, R_RX_CONTROL); + val &= ~0x1; + xlr_write_reg(mmio, R_RX_CONTROL, val); - /* wait for rx to halt */ - for (i=0; immio; - int id = priv->instance; + int i = 0; + xlr_reg_t *mmio = priv->mmio; + int id = priv->instance; struct stn_cc *gmac_cc_config; - uint32_t value = 0; - int blk = id/4, port = id % 4; + uint32_t value = 0; + int blk = id / 4, port = id % 4; rmi_xlr_mac_set_enable(priv, 0); rmi_xlr_config_spill_area(priv); xlr_write_reg(mmio, R_DESC_PACK_CTRL, - (BYTE_OFFSET << O_DESC_PACK_CTRL__ByteOffset) | - (1 << O_DESC_PACK_CTRL__MaxEntry) | - (MAX_FRAME_SIZE << O_DESC_PACK_CTRL__RegularSize)); + (BYTE_OFFSET << O_DESC_PACK_CTRL__ByteOffset) | + (1 << O_DESC_PACK_CTRL__MaxEntry) | + (MAX_FRAME_SIZE << O_DESC_PACK_CTRL__RegularSize)); rmi_xlr_config_pde(priv); rmi_xlr_config_parser(priv); @@ -1346,23 +1365,22 @@ rmi_xlr_gmac_init(struct driver_data *priv) xlr_write_reg(mmio, R_MSG_TX_THRESHOLD, 3); xlr_write_reg(mmio, R_MAC_CONFIG_1, 0x35); - xlr_write_reg(mmio, R_RX_CONTROL, (0x7<<6)); + xlr_write_reg(mmio, R_RX_CONTROL, (0x7 << 6)); - if(priv->mode == XLR_PORT0_RGMII) { + if (priv->mode == XLR_PORT0_RGMII) { printf("Port 0 set in RGMII mode\n"); value = xlr_read_reg(mmio, R_RX_CONTROL); value |= 1 << O_RX_CONTROL__RGMII; xlr_write_reg(mmio, R_RX_CONTROL, value); } - rmi_xlr_mac_mii_init(priv); - + #if 0 priv->advertising = ADVERTISED_10baseT_Full | ADVERTISED_10baseT_Half | - ADVERTISED_100baseT_Full | ADVERTISED_100baseT_Half | - ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg | - ADVERTISED_MII; + ADVERTISED_100baseT_Full | ADVERTISED_100baseT_Half | + ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg | + ADVERTISED_MII; #endif /* @@ -1371,13 +1389,12 @@ rmi_xlr_gmac_init(struct driver_data *priv) */ rge_mii_write_internal(priv->mii_mmio, priv->phy_addr, 25, 0xfffffffe); - if (priv->mode != XLR_RGMII){ + if (priv->mode != XLR_RGMII) { serdes_regs_init(priv); serdes_autoconfig(priv); } - rmi_xlr_gmac_config_speed(priv); - + value = xlr_read_reg(mmio, R_IPG_IFG); xlr_write_reg(mmio, R_IPG_IFG, ((value & ~0x7f) | MAC_B2B_IPG)); xlr_write_reg(mmio, R_DMACR0, 0xffffffff); @@ -1390,25 +1407,25 @@ rmi_xlr_gmac_init(struct driver_data *priv) xlr_write_reg(mmio, R_FREEQCARVE, 0); xlr_write_reg(mmio, R_GMAC_TX0_BUCKET_SIZE + port, - xlr_board_info.bucket_sizes->bucket[priv->txbucket]); + xlr_board_info.bucket_sizes->bucket[priv->txbucket]); xlr_write_reg(mmio, R_GMAC_JFR0_BUCKET_SIZE, - xlr_board_info.bucket_sizes->bucket[MSGRNG_STNID_GMACJFR_0]); + xlr_board_info.bucket_sizes->bucket[MSGRNG_STNID_GMACJFR_0]); xlr_write_reg(mmio, R_GMAC_RFR0_BUCKET_SIZE, - xlr_board_info.bucket_sizes->bucket[MSGRNG_STNID_GMACRFR_0]); + xlr_board_info.bucket_sizes->bucket[MSGRNG_STNID_GMACRFR_0]); xlr_write_reg(mmio, R_GMAC_JFR1_BUCKET_SIZE, - xlr_board_info.bucket_sizes->bucket[MSGRNG_STNID_GMACJFR_1]); + xlr_board_info.bucket_sizes->bucket[MSGRNG_STNID_GMACJFR_1]); xlr_write_reg(mmio, R_GMAC_RFR1_BUCKET_SIZE, - xlr_board_info.bucket_sizes->bucket[MSGRNG_STNID_GMACRFR_1]); + xlr_board_info.bucket_sizes->bucket[MSGRNG_STNID_GMACRFR_1]); dbg_msg("Programming credit counter %d : %d -> %d\n", blk, R_GMAC_TX0_BUCKET_SIZE + port, - xlr_board_info.bucket_sizes->bucket[priv->txbucket]); + xlr_board_info.bucket_sizes->bucket[priv->txbucket]); gmac_cc_config = xlr_board_info.gmac_block[blk].credit_config; for (i = 0; i < MAX_NUM_MSGRNG_STN_CC; i++) { xlr_write_reg(mmio, R_CC_CPU0_0 + i, - gmac_cc_config->counters[i >> 3][i & 0x07]); + gmac_cc_config->counters[i >> 3][i & 0x07]); dbg_msg("%d: %d -> %d\n", priv->instance, - R_CC_CPU0_0 + i, gmac_cc_config->counters[i >> 3][i & 0x07]); + R_CC_CPU0_0 + i, gmac_cc_config->counters[i >> 3][i & 0x07]); } priv->init_frin_desc = 1; } @@ -1416,22 +1433,22 @@ rmi_xlr_gmac_init(struct driver_data *priv) /********************************************************************** * Set promiscuous mode **********************************************************************/ -static void +static void xlr_mac_set_rx_mode(struct rge_softc *sc) { struct driver_data *priv = &(sc->priv); - uint32_t regval; + uint32_t regval; regval = xlr_read_reg(priv->mmio, R_MAC_FILTER_CONFIG); - + if (sc->flags & IFF_PROMISC) { regval |= (1 << O_MAC_FILTER_CONFIG__BROADCAST_EN) | - (1 << O_MAC_FILTER_CONFIG__PAUSE_FRAME_EN) | - (1 << O_MAC_FILTER_CONFIG__ALL_MCAST_EN) | - (1 << O_MAC_FILTER_CONFIG__ALL_UCAST_EN); + (1 << O_MAC_FILTER_CONFIG__PAUSE_FRAME_EN) | + (1 << O_MAC_FILTER_CONFIG__ALL_MCAST_EN) | + (1 << O_MAC_FILTER_CONFIG__ALL_UCAST_EN); } else { regval &= ~((1 << O_MAC_FILTER_CONFIG__PAUSE_FRAME_EN) | - (1 << O_MAC_FILTER_CONFIG__ALL_UCAST_EN)); + (1 << O_MAC_FILTER_CONFIG__ALL_UCAST_EN)); } xlr_write_reg(priv->mmio, R_MAC_FILTER_CONFIG, regval); @@ -1440,7 +1457,7 @@ xlr_mac_set_rx_mode(struct rge_softc *sc) /********************************************************************** * Configure LAN speed for the specified MAC. ********************************************************************* */ -static int +static int rmi_xlr_mac_set_speed(struct driver_data *s, xlr_mac_speed_t speed) { return 0; @@ -1449,9 +1466,9 @@ rmi_xlr_mac_set_speed(struct driver_data *s, xlr_mac_speed_t speed) /********************************************************************** * Set Ethernet duplex and flow control options for this MAC ********************************************************************* */ -static int +static int rmi_xlr_mac_set_duplex(struct driver_data *s, - xlr_mac_duplex_t duplex, xlr_mac_fc_t fc) + xlr_mac_duplex_t duplex, xlr_mac_fc_t fc) { return 0; } @@ -1465,11 +1482,11 @@ rmi_xlr_mac_set_duplex(struct driver_data *s, #define MAC_TX_PASS 0 #define MAC_TX_RETRY 1 -static __inline__ void +static __inline__ void message_send_block(unsigned int size, unsigned int code, - unsigned int stid, struct msgrng_msg *msg) + unsigned int stid, struct msgrng_msg *msg) { - unsigned int dest = 0; + unsigned int dest = 0; unsigned long long status = 0; msgrng_load_tx_msg0(msg->msg0); @@ -1486,16 +1503,16 @@ message_send_block(unsigned int size, unsigned int code, } -int xlr_dev_queue_xmit_hack = 0; +int xlr_dev_queue_xmit_hack = 0; -static int +static int mac_xmit(struct mbuf *m, struct rge_softc *sc, - struct driver_data *priv, int len, struct p2d_tx_desc *tx_desc) + struct driver_data *priv, int len, struct p2d_tx_desc *tx_desc) { struct msgrng_msg msg; - int stid = priv->txbucket; - uint32_t tx_cycles = 0; - unsigned long mflags = 0; + int stid = priv->txbucket; + uint32_t tx_cycles = 0; + unsigned long mflags = 0; int vcpu = PCPU_GET(cpuid); int rv; @@ -1511,8 +1528,8 @@ mac_xmit(struct mbuf *m, struct rge_softc *sc, msgrng_access_disable(mflags); release_tx_desc(&msg, 0); xlr_rge_msg_snd_failed[vcpu]++; - dbg_msg("Failed packet to cpu %d, rv = %d, stid %d, msg0=%llx\n", - vcpu, rv, stid, msg.msg0); + dbg_msg("Failed packet to cpu %d, rv = %d, stid %d, msg0=%llx\n", + vcpu, rv, stid, msg.msg0); return MAC_TX_FAIL; } msgrng_access_disable(mflags); @@ -1523,8 +1540,9 @@ mac_xmit(struct mbuf *m, struct rge_softc *sc, dbg_msg("Sent tx packet to stid %d, msg0=%llx, msg1=%llx \n", stid, msg.msg0, msg.msg1); #ifdef DUMP_PACKETS { - int i = 0; - unsigned char *buf = (char *)m->m_data; + int i = 0; + unsigned char *buf = (char *)m->m_data; + printf("Tx Packet: length=%d\n", len); for (i = 0; i < 64; i++) { if (i && (i % 16) == 0) @@ -1538,11 +1556,11 @@ mac_xmit(struct mbuf *m, struct rge_softc *sc, return MAC_TX_PASS; } -static int +static int rmi_xlr_mac_xmit(struct mbuf *m, struct rge_softc *sc, int len, struct p2d_tx_desc *tx_desc) { struct driver_data *priv = &(sc->priv); - int ret = -ENOSPC; + int ret = -ENOSPC; dbg_msg("IN\n"); @@ -1563,15 +1581,15 @@ retry: return ret; } -static void +static void mac_frin_replenish(void *args /* ignored */ ) { #ifdef RX_COPY return; #else - int cpu = xlr_cpu_id(); - int done = 0; - int i = 0; + int cpu = xlr_cpu_id(); + int done = 0; + int i = 0; xlr_inc_counter(REPLENISH_ENTER); /* @@ -1586,12 +1604,12 @@ mac_frin_replenish(void *args /* ignored */ ) for (i = 0; i < XLR_MAX_MACS; i++) { /* int offset = 0; */ - unsigned long msgrng_flags; - void *m; - uint32_t cycles; + unsigned long msgrng_flags; + void *m; + uint32_t cycles; struct rge_softc *sc; struct driver_data *priv; - int frin_to_be_sent; + int frin_to_be_sent; sc = dev_mac[i]; if (!sc) @@ -1602,9 +1620,9 @@ mac_frin_replenish(void *args /* ignored */ ) /* if (atomic_read(frin_to_be_sent) < 0) */ if (frin_to_be_sent < 0) { - panic ("BUG?: [%s]: gmac_%d illegal value for frin_to_be_sent=%d\n", - __FUNCTION__, i, - frin_to_be_sent); + panic("BUG?: [%s]: gmac_%d illegal value for frin_to_be_sent=%d\n", + __FUNCTION__, i, + frin_to_be_sent); } /* if (!atomic_read(frin_to_be_sent)) */ if (!frin_to_be_sent) @@ -1628,7 +1646,7 @@ mac_frin_replenish(void *args /* ignored */ ) } msgrng_access_disable(msgrng_flags); xlr_set_counter(REPLENISH_CYCLES, - (read_c0_count() - cycles)); + (read_c0_count() - cycles)); atomic_subtract_int((&priv->frin_to_be_sent[cpu]), 1); continue; @@ -1643,11 +1661,12 @@ mac_frin_replenish(void *args /* ignored */ ) static volatile uint32_t g_tx_frm_tx_ok; -static void +static void rge_tx_bkp_func(void *arg, int npending) { - int i=0; - for(i=0; iactive) continue; rge_start_locked(dev_mac[i]->rge_ifp, RGE_TX_THRESHOLD); @@ -1656,23 +1675,23 @@ rge_tx_bkp_func(void *arg, int npending) } /* This function is called from an interrupt handler */ -void +void rmi_xlr_mac_msgring_handler(int bucket, int size, int code, - int stid, struct msgrng_msg *msg, - void *data /* ignored */ ) + int stid, struct msgrng_msg *msg, + void *data /* ignored */ ) { - uint64_t phys_addr = 0; - unsigned long addr = 0; - uint32_t length = 0; - int ctrl = 0, port = 0; + uint64_t phys_addr = 0; + unsigned long addr = 0; + uint32_t length = 0; + int ctrl = 0, port = 0; struct rge_softc *sc = NULL; struct driver_data *priv = 0; - struct ifnet *ifp; - int cpu = xlr_cpu_id(); - int vcpu=(cpu<<2)+xlr_thr_id(); + struct ifnet *ifp; + int cpu = xlr_cpu_id(); + int vcpu = (cpu << 2) + xlr_thr_id(); dbg_msg("mac: bucket=%d, size=%d, code=%d, stid=%d, msg0=%llx msg1=%llx\n", - bucket, size, code, stid, msg->msg0, msg->msg1); + bucket, size, code, stid, msg->msg0, msg->msg1); phys_addr = (uint64_t) (msg->msg0 & 0xffffffffe0ULL); length = (msg->msg0 >> 40) & 0x3fff; @@ -1696,7 +1715,7 @@ rmi_xlr_mac_msgring_handler(int bucket, int size, int code, sc = dev_mac[dev_mac_xgs0]; else if (stid == MSGRNG_STNID_XGS1FR) sc = dev_mac[dev_mac_xgs0 + 1]; - else + else sc = dev_mac[dev_mac_gmac0 + port]; } if (sc == NULL) @@ -1704,19 +1723,19 @@ rmi_xlr_mac_msgring_handler(int bucket, int size, int code, priv = &(sc->priv); dbg_msg("msg0 = %llx, stid = %d, port = %d, addr=%lx, length=%d, ctrl=%d\n", - msg->msg0, stid, port, addr, length, ctrl); + msg->msg0, stid, port, addr, length, ctrl); if (ctrl == CTRL_REG_FREE || ctrl == CTRL_JUMBO_FREE) { xlr_rge_tx_ok_done[vcpu]++; release_tx_desc(msg, 1); ifp = sc->rge_ifp; - if (ifp->if_drv_flags & IFF_DRV_OACTIVE){ + if (ifp->if_drv_flags & IFF_DRV_OACTIVE) { ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; } - if(atomic_cmpset_int(&g_tx_frm_tx_ok, 0,1)) - rge_tx_bkp_func(NULL,0); + if (atomic_cmpset_int(&g_tx_frm_tx_ok, 0, 1)) + rge_tx_bkp_func(NULL, 0); xlr_set_counter(NETIF_TX_COMPLETE_CYCLES, - (read_c0_count() - msgrng_msg_cycles)); + (read_c0_count() - msgrng_msg_cycles)); } else if (ctrl == CTRL_SNGL || ctrl == CTRL_START) { /* Rx Packet */ /* struct mbuf *m = 0; */ @@ -1732,15 +1751,14 @@ rmi_xlr_mac_msgring_handler(int bucket, int size, int code, if ((priv->frin_to_be_sent[cpu]) > MAC_FRIN_TO_BE_SENT_THRESHOLD) { mac_frin_replenish(NULL); } - dbg_msg("gmac_%d: rx packet: phys_addr = %llx, length = %x\n", - priv->instance, phys_addr, length); + priv->instance, phys_addr, length); mac_stats_add(priv->stats.rx_packets, 1); mac_stats_add(priv->stats.rx_bytes, length); xlr_inc_counter(NETIF_RX); xlr_set_counter(NETIF_RX_CYCLES, - (read_c0_count() - msgrng_msg_cycles)); + (read_c0_count() - msgrng_msg_cycles)); rge_rx(sc, phys_addr, length); xlr_rge_rx_done[vcpu]++; } else { @@ -1753,51 +1771,55 @@ rmi_xlr_mac_msgring_handler(int bucket, int size, int code, **********************************************************************/ static int rge_probe(dev) - device_t dev; + device_t dev; { /* Always return 0 */ return 0; } volatile unsigned long xlr_debug_enabled; -struct callout rge_dbg_count; -static void xlr_debug_count(void *addr) +struct callout rge_dbg_count; +static void +xlr_debug_count(void *addr) { struct driver_data *priv = &dev_mac[0]->priv; - /*uint32_t crdt;*/ - if(xlr_debug_enabled){ - printf("\nAvailRxIn %#x\n",xlr_read_reg(priv->mmio,0x23e)); + + /* uint32_t crdt; */ + if (xlr_debug_enabled) { + printf("\nAvailRxIn %#x\n", xlr_read_reg(priv->mmio, 0x23e)); } callout_reset(&rge_dbg_count, hz, xlr_debug_count, NULL); } -static void xlr_tx_q_wakeup(void *addr) +static void +xlr_tx_q_wakeup(void *addr) { - int i=0; - int j=0; - for(i=0; iactive) continue; - if((dev_mac[i]->rge_ifp->if_drv_flags) & IFF_DRV_OACTIVE){ - for(j=0; jrge_ifp->if_drv_flags) & IFF_DRV_OACTIVE) { + for (j = 0; j < XLR_MAX_CORE; j++) { + if (xlr_tot_avail_p2d[j]) { dev_mac[i]->rge_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; break; } } } } - callout_reset(&xlr_tx_stop_bkp, 5*hz, xlr_tx_q_wakeup, NULL); + callout_reset(&xlr_tx_stop_bkp, 5 * hz, xlr_tx_q_wakeup, NULL); } static int rge_attach(device_t dev) { - struct ifnet *ifp; + struct ifnet *ifp; struct rge_softc *sc; struct driver_data *priv = 0; - int ret = 0; + int ret = 0; struct xlr_gmac_block_t *gmac_conf = device_get_ivars(dev); sc = device_get_softc(dev); @@ -1820,26 +1842,25 @@ rge_attach(device_t dev) priv->id = sc->unit; if (gmac_conf->type == XLR_GMAC) { priv->instance = priv->id; - priv->mmio = (xlr_reg_t *)(xlr_io_base + gmac_conf->baseaddr + - 0x1000 * (sc->unit % 4)); + priv->mmio = (xlr_reg_t *) (xlr_io_base + gmac_conf->baseaddr + + 0x1000 * (sc->unit % 4)); if ((ret = rmi_xlr_gmac_reset(priv)) == -1) goto out; } else if (gmac_conf->type == XLR_XGMAC) { priv->instance = priv->id - xlr_board_info.gmacports; priv->mmio = (xlr_reg_t *) (xlr_io_base + gmac_conf->baseaddr); } - if (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_VI) { dbg_msg("Arizona board - offset 4 \n"); - priv->mii_mmio = (xlr_reg_t *)(xlr_io_base + XLR_IO_GMAC_4_OFFSET); + priv->mii_mmio = (xlr_reg_t *) (xlr_io_base + XLR_IO_GMAC_4_OFFSET); } else - priv->mii_mmio = (xlr_reg_t *)(xlr_io_base + XLR_IO_GMAC_0_OFFSET); + priv->mii_mmio = (xlr_reg_t *) (xlr_io_base + XLR_IO_GMAC_0_OFFSET); - priv->pcs_mmio = (xlr_reg_t *)(xlr_io_base + gmac_conf->baseaddr); - priv->serdes_mmio = (xlr_reg_t *)(xlr_io_base + XLR_IO_GMAC_0_OFFSET); + priv->pcs_mmio = (xlr_reg_t *) (xlr_io_base + gmac_conf->baseaddr); + priv->serdes_mmio = (xlr_reg_t *) (xlr_io_base + XLR_IO_GMAC_0_OFFSET); - sc->base_addr = (unsigned long) priv->mmio; - sc->mem_end = (unsigned long) priv->mmio + XLR_IO_SIZE - 1; + sc->base_addr = (unsigned long)priv->mmio; + sc->mem_end = (unsigned long)priv->mmio + XLR_IO_SIZE - 1; sc->xmit = rge_start; sc->stop = rge_stop; @@ -1858,19 +1879,19 @@ rge_attach(device_t dev) else priv->phy_addr = priv->instance; priv->mode = XLR_RGMII; - } else { + } else { if (gmac_conf->mode == XLR_PORT0_RGMII && - priv->instance == 0) { - priv->mode = XLR_PORT0_RGMII; + priv->instance == 0) { + priv->mode = XLR_PORT0_RGMII; priv->phy_addr = 0; - } else { - priv->mode = XLR_SGMII; + } else { + priv->mode = XLR_SGMII; priv->phy_addr = priv->instance + 16; } } priv->txbucket = gmac_conf->station_txbase + priv->instance % 4; - priv->rfrbucket = gmac_conf->station_rfr; + priv->rfrbucket = gmac_conf->station_rfr; priv->spill_configured = 0; dbg_msg("priv->mmio=%p\n", priv->mmio); @@ -1896,8 +1917,8 @@ rge_attach(device_t dev) IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen); IFQ_SET_READY(&ifp->if_snd); sc->active = 1; - ifp->if_hwassist = 0; - ifp->if_capabilities = IFCAP_TXCSUM | IFCAP_VLAN_HWTAGGING; + ifp->if_hwassist = 0; + ifp->if_capabilities = IFCAP_TXCSUM | IFCAP_VLAN_HWTAGGING; ifp->if_capenable = ifp->if_capabilities; /* Initialize the rge_softc */ @@ -1907,7 +1928,7 @@ rge_attach(device_t dev) rman_set_rid(&sc->rge_irq, sc->irq); ret = bus_setup_intr(dev, &sc->rge_irq, INTR_FAST | INTR_TYPE_NET | INTR_MPSAFE, - NULL, rge_intr, sc, &sc->rge_intrhand); + NULL, rge_intr, sc, &sc->rge_intrhand); if (ret) { rge_detach(dev); @@ -1919,10 +1940,10 @@ rge_attach(device_t dev) xlr_mac_setup_hwaddr(priv); dbg_msg("MMIO %08lx, MII %08lx, PCS %08lx, base %08lx PHY %d IRQ %d\n", - (u_long) priv->mmio, (u_long) priv->mii_mmio, (u_long) priv->pcs_mmio, - (u_long) sc->base_addr, priv->phy_addr, sc->irq); - dbg_msg("HWADDR %02x:%02x tx %d rfr %d\n", (u_int)sc->dev_addr[4], - (u_int)sc->dev_addr[5], priv->txbucket, priv->rfrbucket); + (u_long)priv->mmio, (u_long)priv->mii_mmio, (u_long)priv->pcs_mmio, + (u_long)sc->base_addr, priv->phy_addr, sc->irq); + dbg_msg("HWADDR %02x:%02x tx %d rfr %d\n", (u_int)sc->dev_addr[4], + (u_int)sc->dev_addr[5], priv->txbucket, priv->rfrbucket); /* * Set up ifmedia support. @@ -1932,10 +1953,10 @@ rge_attach(device_t dev) */ sc->rge_mii.mii_ifp = ifp; sc->rge_mii.mii_readreg = rge_mii_read; - sc->rge_mii.mii_writereg = (mii_writereg_t)rge_mii_write; + sc->rge_mii.mii_writereg = (mii_writereg_t) rge_mii_write; sc->rge_mii.mii_statchg = rmi_xlr_mac_mii_statchg; ifmedia_init(&sc->rge_mii.mii_media, 0, rmi_xlr_mac_mediachange, - rmi_xlr_mac_mediastatus); + rmi_xlr_mac_mediastatus); ifmedia_add(&sc->rge_mii.mii_media, IFM_ETHER | IFM_AUTO, 0, NULL); ifmedia_set(&sc->rge_mii.mii_media, IFM_ETHER | IFM_AUTO); sc->rge_mii.mii_media.ifm_media = sc->rge_mii.mii_media.ifm_cur->ifm_media; @@ -1951,26 +1972,25 @@ rge_attach(device_t dev) rmi_xlr_xgmac_init(priv); } dbg_msg("rge_%d: Phoenix Mac at 0x%p (mtu=%d)\n", - sc->unit, priv->mmio, sc->mtu); + sc->unit, priv->mmio, sc->mtu); dev_mac[sc->unit] = sc; if (priv->type == XLR_XGMAC && priv->instance == 0) dev_mac_xgs0 = sc->unit; if (priv->type == XLR_GMAC && priv->instance == 0) dev_mac_gmac0 = sc->unit; - if (!gmac_common_init_done){ + if (!gmac_common_init_done) { mac_common_init(); gmac_common_init_done = 1; callout_init(&xlr_tx_stop_bkp, CALLOUT_MPSAFE); callout_reset(&xlr_tx_stop_bkp, hz, xlr_tx_q_wakeup, NULL); callout_init(&rge_dbg_count, CALLOUT_MPSAFE); -// callout_reset(&rge_dbg_count, hz, xlr_debug_count, NULL); + //callout_reset(&rge_dbg_count, hz, xlr_debug_count, NULL); } if ((ret = rmi_xlr_mac_open(sc)) == -1) { RGE_LOCK_DESTROY(sc); goto out; } - out: if (ret < 0) { device_printf(dev, "error - skipping\n"); @@ -1978,18 +1998,18 @@ out: return ret; } -static void +static void rge_reset(struct rge_softc *sc) { } static int rge_detach(dev) - device_t dev; + device_t dev; { #ifdef FREEBSD_MAC_NOT_YET struct rge_softc *sc; - struct ifnet *ifp; + struct ifnet *ifp; sc = device_get_softc(dev); ifp = sc->rge_ifp; @@ -2013,7 +2033,7 @@ rge_detach(dev) #endif /* FREEBSD_MAC_NOT_YET */ return (0); } -static int +static int rge_suspend(device_t dev) { struct rge_softc *sc; @@ -2026,14 +2046,14 @@ rge_suspend(device_t dev) return 0; } -static int +static int rge_resume(device_t dev) { panic("rge_resume(): unimplemented\n"); return 0; } -static void +static void rge_release_resources(struct rge_softc *sc) { @@ -2043,23 +2063,23 @@ rge_release_resources(struct rge_softc *sc) if (mtx_initialized(&sc->rge_mtx)) /* XXX */ RGE_LOCK_DESTROY(sc); } -uint32_t gmac_rx_fail[32]; -uint32_t gmac_rx_pass[32]; +uint32_t gmac_rx_fail[32]; +uint32_t gmac_rx_pass[32]; #ifdef RX_COPY -static void +static void rge_rx(struct rge_softc *sc, vm_paddr_t paddr, int len) { /* * struct mbuf *m = (struct mbuf *)*(unsigned int *)((char *)addr - * XLR_CACHELINE_SIZE); */ - struct mbuf *m; - void *ptr; - vm_offset_t temp; - struct ifnet *ifp = sc->rge_ifp; - unsigned long msgrng_flags; - int cpu = PCPU_GET(cpuid); + struct mbuf *m; + void *ptr; + vm_offset_t temp; + struct ifnet *ifp = sc->rge_ifp; + unsigned long msgrng_flags; + int cpu = PCPU_GET(cpuid); temp = lw_40bit_phys((paddr - XLR_CACHELINE_SIZE), 3); @@ -2082,8 +2102,9 @@ rge_rx(struct rge_softc *sc, vm_paddr_t paddr, int len) #ifdef DUMP_PACKETS { - int i = 0; - unsigned char *buf = (char *)m->m_data; + int i = 0; + unsigned char *buf = (char *)m->m_data; + printf("Rx Packet: length=%d\n", len); for (i = 0; i < 64; i++) { if (i && (i % 16) == 0) @@ -2100,30 +2121,30 @@ rge_rx(struct rge_softc *sc, vm_paddr_t paddr, int len) (*ifp->if_input) (ifp, m); } } + #else -static void +static void rge_rx(struct rge_softc *sc, vm_paddr_t paddr, int len) { /* * struct mbuf *m = (struct mbuf *)*(unsigned int *)((char *)addr - * XLR_CACHELINE_SIZE); */ - struct mbuf *m; - vm_offset_t temp; - unsigned int mag; - struct ifnet *ifp = sc->rge_ifp; + struct mbuf *m; + vm_offset_t temp; + unsigned int mag; + struct ifnet *ifp = sc->rge_ifp; temp = lw_40bit_phys((paddr - XLR_CACHELINE_SIZE), 3); - mag = lw_40bit_phys((paddr - XLR_CACHELINE_SIZE+4), 3); + mag = lw_40bit_phys((paddr - XLR_CACHELINE_SIZE + 4), 3); m = (struct mbuf *)temp; if (mag != 0xf00bad) { /* somebody else packet Error - FIXME in intialization */ - printf("cpu %d: *ERROR* Not my packet paddr %p\n", xlr_cpu_id(), (void *)paddr); + printf("cpu %d: *ERROR* Not my packet paddr %p\n", xlr_cpu_id(), (void *)paddr); return; } - /* align the data */ m->m_data += BYTE_OFFSET; m->m_pkthdr.len = m->m_len = len; @@ -2131,8 +2152,9 @@ rge_rx(struct rge_softc *sc, vm_paddr_t paddr, int len) #ifdef DUMP_PACKETS { - int i = 0; - unsigned char *buf = (char *)m->m_data; + int i = 0; + unsigned char *buf = (char *)m->m_data; + printf("Rx Packet: length=%d\n", len); for (i = 0; i < 64; i++) { if (i && (i % 16) == 0) @@ -2145,19 +2167,20 @@ rge_rx(struct rge_softc *sc, vm_paddr_t paddr, int len) ifp->if_ipackets++; (*ifp->if_input) (ifp, m); } + #endif -static void +static void rge_intr(void *arg) { struct rge_softc *sc = (struct rge_softc *)arg; struct driver_data *priv = &(sc->priv); - xlr_reg_t *mmio = priv->mmio; - uint32_t intreg = xlr_read_reg(mmio, R_INTREG); + xlr_reg_t *mmio = priv->mmio; + uint32_t intreg = xlr_read_reg(mmio, R_INTREG); if (intreg & (1 << O_INTREG__MDInt)) { - uint32_t phy_int_status = 0; - int i = 0; + uint32_t phy_int_status = 0; + int i = 0; for (i = 0; i < XLR_MAX_MACS; i++) { struct rge_softc *phy_dev = 0; @@ -2173,15 +2196,15 @@ rge_intr(void *arg) continue; phy_int_status = rge_mii_read_internal(phy_priv->mii_mmio, - phy_priv->phy_addr, 26); + phy_priv->phy_addr, 26); printf("rge%d: Phy addr %d, MII MMIO %lx status %x\n", phy_priv->instance, - (int) phy_priv->phy_addr, (u_long)phy_priv->mii_mmio, phy_int_status); + (int)phy_priv->phy_addr, (u_long)phy_priv->mii_mmio, phy_int_status); rmi_xlr_gmac_config_speed(phy_priv); } } else { printf("[%s]: mac type = %d, instance %d error " - "interrupt: INTREG = 0x%08x\n", - __FUNCTION__, priv->type, priv->instance, intreg); + "interrupt: INTREG = 0x%08x\n", + __FUNCTION__, priv->type, priv->instance, intreg); } /* clear all interrupts and hope to make progress */ @@ -2191,44 +2214,44 @@ rge_intr(void *arg) if ((xlr_revision_b0()) && (priv->type == XLR_XGMAC)) { struct rge_softc *xgs0_dev = dev_mac[dev_mac_xgs0]; struct driver_data *xgs0_priv = &xgs0_dev->priv; - xlr_reg_t *xgs0_mmio = xgs0_priv->mmio; - uint32_t xgs0_intreg = xlr_read_reg(xgs0_mmio, R_INTREG); + xlr_reg_t *xgs0_mmio = xgs0_priv->mmio; + uint32_t xgs0_intreg = xlr_read_reg(xgs0_mmio, R_INTREG); if (xgs0_intreg) { printf("[%s]: mac type = %d, instance %d error " - "interrupt: INTREG = 0x%08x\n", - __FUNCTION__, xgs0_priv->type, xgs0_priv->instance, xgs0_intreg); + "interrupt: INTREG = 0x%08x\n", + __FUNCTION__, xgs0_priv->type, xgs0_priv->instance, xgs0_intreg); xlr_write_reg(xgs0_mmio, R_INTREG, 0xffffffff); } } } -static void +static void rge_start_locked(struct ifnet *ifp, int threshold) { struct rge_softc *sc = ifp->if_softc; - struct mbuf *m = NULL; - int prepend_pkt = 0; - int i=0; - struct p2d_tx_desc *tx_desc=NULL; - int cpu = xlr_cpu_id(); - uint32_t vcpu = (cpu<<2)+xlr_thr_id(); + struct mbuf *m = NULL; + int prepend_pkt = 0; + int i = 0; + struct p2d_tx_desc *tx_desc = NULL; + int cpu = xlr_cpu_id(); + uint32_t vcpu = (cpu << 2) + xlr_thr_id(); if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) return; - for (i=0; iif_snd)) return; tx_desc = get_p2d_desc(); - if(!tx_desc){ + if (!tx_desc) { xlr_rge_get_p2d_failed[vcpu]++; return; } /* Grab a packet off the queue. */ IFQ_DEQUEUE(&ifp->if_snd, m); - if (m == NULL){ + if (m == NULL) { free_p2d_desc(tx_desc); return; } @@ -2246,18 +2269,19 @@ rge_start_locked(struct ifnet *ifp, int threshold) } } -static void +static void rge_start(struct ifnet *ifp) { rge_start_locked(ifp, RGE_TX_Q_SIZE); } -static int +static int rge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) { struct rge_softc *sc = ifp->if_softc; - struct ifreq *ifr = (struct ifreq *)data; - int mask , error = 0; + struct ifreq *ifr = (struct ifreq *)data; + int mask, error = 0; + /* struct mii_data *mii; */ switch (command) { case SIOCSIFMTU: @@ -2282,12 +2306,12 @@ rge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) sc->flags |= IFF_PROMISC; xlr_mac_set_rx_mode(sc); } else if (ifp->if_drv_flags & IFF_DRV_RUNNING && - !(ifp->if_flags & IFF_PROMISC) && - sc->flags & IFF_PROMISC) { + !(ifp->if_flags & IFF_PROMISC) && + sc->flags & IFF_PROMISC) { sc->flags &= IFF_PROMISC; xlr_mac_set_rx_mode(sc); } else if (ifp->if_drv_flags & IFF_DRV_RUNNING && - (ifp->if_flags ^ sc->flags) & IFF_ALLMULTI) { + (ifp->if_flags ^ sc->flags) & IFF_ALLMULTI) { rmi_xlr_mac_set_multicast_list(sc); } else xlr_mac_set_rx_mode(sc); @@ -2312,7 +2336,7 @@ rge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) case SIOCSIFMEDIA: case SIOCGIFMEDIA: error = ifmedia_ioctl(ifp, ifr, - &sc->rge_mii.mii_media, command); + &sc->rge_mii.mii_media, command); break; case SIOCSIFCAP: mask = ifr->ifr_reqcap ^ ifp->if_capenable; @@ -2326,11 +2350,11 @@ rge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) return (error); } -static void +static void rge_init(void *addr) { struct rge_softc *sc = (struct rge_softc *)addr; - struct ifnet *ifp; + struct ifnet *ifp; struct driver_data *priv = &(sc->priv); ifp = sc->rge_ifp; @@ -2343,13 +2367,13 @@ rge_init(void *addr) rmi_xlr_mac_set_enable(priv, 1); } -static void +static void rge_stop(struct rge_softc *sc) { rmi_xlr_mac_close(sc); } -static void +static void rge_watchdog(struct ifnet *sc) { } @@ -2358,6 +2382,7 @@ static int rge_shutdown(device_t dev) { struct rge_softc *sc; + sc = device_get_softc(dev); RGE_LOCK(sc); @@ -2365,10 +2390,10 @@ rge_shutdown(device_t dev) rge_reset(sc); RGE_UNLOCK(sc); - return(0); + return (0); } -static int +static int rmi_xlr_mac_open(struct rge_softc *sc) { struct driver_data *priv = &(sc->priv); @@ -2379,7 +2404,6 @@ rmi_xlr_mac_open(struct rge_softc *sc) if (rmi_xlr_mac_fill_rxfr(sc)) { return -1; } - mtx_lock_spin(&priv->lock); xlr_mac_set_rx_mode(sc); @@ -2387,14 +2411,14 @@ rmi_xlr_mac_open(struct rge_softc *sc) if (sc->unit == xlr_board_info.gmacports - 1) { printf("Enabling MDIO interrupts\n"); struct rge_softc *tmp = NULL; + for (i = 0; i < xlr_board_info.gmacports; i++) { tmp = dev_mac[i]; if (tmp) xlr_write_reg(tmp->priv.mmio, R_INTMASK, - ((tmp->priv.instance == 0) << O_INTMASK__MDInt)); + ((tmp->priv.instance == 0) << O_INTMASK__MDInt)); } } - /* * Configure the speed, duplex, and flow control */ @@ -2413,7 +2437,7 @@ rmi_xlr_mac_open(struct rge_softc *sc) /********************************************************************** **********************************************************************/ -static int +static int rmi_xlr_mac_close(struct rge_softc *sc) { struct driver_data *priv = &(sc->priv); @@ -2441,6 +2465,7 @@ static struct rge_softc_stats * rmi_xlr_mac_get_stats(struct rge_softc *sc) { struct driver_data *priv = &(sc->priv); + /* unsigned long flags; */ mtx_lock_spin(&priv->lock); @@ -2454,14 +2479,14 @@ rmi_xlr_mac_get_stats(struct rge_softc *sc) /********************************************************************** **********************************************************************/ -static void +static void rmi_xlr_mac_set_multicast_list(struct rge_softc *sc) { } /********************************************************************** **********************************************************************/ -static int +static int rmi_xlr_mac_change_mtu(struct rge_softc *sc, int new_mtu) { struct driver_data *priv = &(sc->priv); @@ -2486,14 +2511,14 @@ rmi_xlr_mac_change_mtu(struct rge_softc *sc, int new_mtu) /********************************************************************** **********************************************************************/ -static int +static int rmi_xlr_mac_fill_rxfr(struct rge_softc *sc) { struct driver_data *priv = &(sc->priv); - unsigned long msgrng_flags; - int i; - int ret = 0; - void *ptr; + unsigned long msgrng_flags; + int i; + int ret = 0; + void *ptr; dbg_msg("\n"); if (!priv->init_frin_desc) @@ -2507,7 +2532,6 @@ rmi_xlr_mac_fill_rxfr(struct rge_softc *sc) ret = -ENOMEM; break; } - /* Send the free Rx desc to the MAC */ msgrng_access_enable(msgrng_flags); xlr_mac_send_fr(priv, vtophys(ptr), MAX_FRAME_SIZE); @@ -2521,17 +2545,17 @@ rmi_xlr_mac_fill_rxfr(struct rge_softc *sc) **********************************************************************/ static __inline__ void * rmi_xlr_config_spill(xlr_reg_t * mmio, - int reg_start_0, int reg_start_1, - int reg_size, int size) + int reg_start_0, int reg_start_1, + int reg_size, int size) { - uint32_t spill_size = size; - void *spill = NULL; - uint64_t phys_addr = 0; + uint32_t spill_size = size; + void *spill = NULL; + uint64_t phys_addr = 0; spill = contigmalloc((spill_size + XLR_CACHELINE_SIZE), M_DEVBUF, - M_NOWAIT | M_ZERO, 0, 0xffffffff, XLR_CACHELINE_SIZE, 0); - if (!spill || ((vm_offset_t) spill & (XLR_CACHELINE_SIZE - 1))) { + M_NOWAIT | M_ZERO, 0, 0xffffffff, XLR_CACHELINE_SIZE, 0); + if (!spill || ((vm_offset_t)spill & (XLR_CACHELINE_SIZE - 1))) { panic("Unable to allocate memory for spill area!\n"); } phys_addr = vtophys(spill); @@ -2543,7 +2567,7 @@ rmi_xlr_config_spill(xlr_reg_t * mmio, return spill; } -static void +static void rmi_xlr_config_spill_area(struct driver_data *priv) { /* @@ -2557,53 +2581,52 @@ rmi_xlr_config_spill_area(struct driver_data *priv) priv->spill_configured = 1; return; } - priv->spill_configured = 1; priv->frin_spill = - rmi_xlr_config_spill(priv->mmio, - R_REG_FRIN_SPILL_MEM_START_0, - R_REG_FRIN_SPILL_MEM_START_1, - R_REG_FRIN_SPILL_MEM_SIZE, - MAX_FRIN_SPILL * - sizeof(struct fr_desc)); + rmi_xlr_config_spill(priv->mmio, + R_REG_FRIN_SPILL_MEM_START_0, + R_REG_FRIN_SPILL_MEM_START_1, + R_REG_FRIN_SPILL_MEM_SIZE, + MAX_FRIN_SPILL * + sizeof(struct fr_desc)); priv->class_0_spill = - rmi_xlr_config_spill(priv->mmio, - R_CLASS0_SPILL_MEM_START_0, - R_CLASS0_SPILL_MEM_START_1, - R_CLASS0_SPILL_MEM_SIZE, - MAX_CLASS_0_SPILL * - sizeof(union rx_tx_desc)); + rmi_xlr_config_spill(priv->mmio, + R_CLASS0_SPILL_MEM_START_0, + R_CLASS0_SPILL_MEM_START_1, + R_CLASS0_SPILL_MEM_SIZE, + MAX_CLASS_0_SPILL * + sizeof(union rx_tx_desc)); priv->class_1_spill = - rmi_xlr_config_spill(priv->mmio, - R_CLASS1_SPILL_MEM_START_0, - R_CLASS1_SPILL_MEM_START_1, - R_CLASS1_SPILL_MEM_SIZE, - MAX_CLASS_1_SPILL * - sizeof(union rx_tx_desc)); + rmi_xlr_config_spill(priv->mmio, + R_CLASS1_SPILL_MEM_START_0, + R_CLASS1_SPILL_MEM_START_1, + R_CLASS1_SPILL_MEM_SIZE, + MAX_CLASS_1_SPILL * + sizeof(union rx_tx_desc)); priv->frout_spill = - rmi_xlr_config_spill(priv->mmio, R_FROUT_SPILL_MEM_START_0, - R_FROUT_SPILL_MEM_START_1, - R_FROUT_SPILL_MEM_SIZE, - MAX_FROUT_SPILL * - sizeof(struct fr_desc)); + rmi_xlr_config_spill(priv->mmio, R_FROUT_SPILL_MEM_START_0, + R_FROUT_SPILL_MEM_START_1, + R_FROUT_SPILL_MEM_SIZE, + MAX_FROUT_SPILL * + sizeof(struct fr_desc)); priv->class_2_spill = - rmi_xlr_config_spill(priv->mmio, - R_CLASS2_SPILL_MEM_START_0, - R_CLASS2_SPILL_MEM_START_1, - R_CLASS2_SPILL_MEM_SIZE, - MAX_CLASS_2_SPILL * - sizeof(union rx_tx_desc)); + rmi_xlr_config_spill(priv->mmio, + R_CLASS2_SPILL_MEM_START_0, + R_CLASS2_SPILL_MEM_START_1, + R_CLASS2_SPILL_MEM_SIZE, + MAX_CLASS_2_SPILL * + sizeof(union rx_tx_desc)); priv->class_3_spill = - rmi_xlr_config_spill(priv->mmio, - R_CLASS3_SPILL_MEM_START_0, - R_CLASS3_SPILL_MEM_START_1, - R_CLASS3_SPILL_MEM_SIZE, - MAX_CLASS_3_SPILL * - sizeof(union rx_tx_desc)); + rmi_xlr_config_spill(priv->mmio, + R_CLASS3_SPILL_MEM_START_0, + R_CLASS3_SPILL_MEM_START_1, + R_CLASS3_SPILL_MEM_SIZE, + MAX_CLASS_3_SPILL * + sizeof(union rx_tx_desc)); priv->spill_configured = 1; } @@ -2611,19 +2634,19 @@ rmi_xlr_config_spill_area(struct driver_data *priv) * Write the MAC address to the XLR registers * All 4 addresses are the same for now *****************************************************************/ -static void +static void xlr_mac_setup_hwaddr(struct driver_data *priv) { struct rge_softc *sc = priv->sc; xlr_write_reg(priv->mmio, R_MAC_ADDR0, - ((sc->dev_addr[5] << 24) | (sc->dev_addr[4] << 16) - | (sc->dev_addr[3] << 8) | (sc->dev_addr[2])) - ); + ((sc->dev_addr[5] << 24) | (sc->dev_addr[4] << 16) + | (sc->dev_addr[3] << 8) | (sc->dev_addr[2])) + ); xlr_write_reg(priv->mmio, R_MAC_ADDR0 + 1, - ((sc->dev_addr[1] << 24) | (sc-> - dev_addr[0] << 16))); + ((sc->dev_addr[1] << 24) | (sc-> + dev_addr[0] << 16))); xlr_write_reg(priv->mmio, R_MAC_ADDR_MASK2, 0xffffffff); @@ -2634,17 +2657,17 @@ xlr_mac_setup_hwaddr(struct driver_data *priv) xlr_write_reg(priv->mmio, R_MAC_ADDR_MASK3 + 1, 0xffffffff); xlr_write_reg(priv->mmio, R_MAC_FILTER_CONFIG, - (1 << O_MAC_FILTER_CONFIG__BROADCAST_EN) | - (1 << O_MAC_FILTER_CONFIG__ALL_MCAST_EN) | - (1 << O_MAC_FILTER_CONFIG__MAC_ADDR0_VALID) - ); + (1 << O_MAC_FILTER_CONFIG__BROADCAST_EN) | + (1 << O_MAC_FILTER_CONFIG__ALL_MCAST_EN) | + (1 << O_MAC_FILTER_CONFIG__MAC_ADDR0_VALID) + ); } /***************************************************************** * Read the MAC address from the XLR registers * All 4 addresses are the same for now *****************************************************************/ -static void +static void xlr_mac_get_hwaddr(struct rge_softc *sc) { struct driver_data *priv = &(sc->priv); @@ -2660,7 +2683,7 @@ xlr_mac_get_hwaddr(struct rge_softc *sc) /***************************************************************** * Mac Module Initialization *****************************************************************/ -static void +static void mac_common_init(void) { init_p2d_allocation(); @@ -2670,31 +2693,27 @@ mac_common_init(void) #endif if (xlr_board_info.is_xls) { - if (register_msgring_handler (TX_STN_GMAC0, - rmi_xlr_mac_msgring_handler, NULL)) { + if (register_msgring_handler(TX_STN_GMAC0, + rmi_xlr_mac_msgring_handler, NULL)) { panic("Couldn't register msgring handler\n"); } - if (register_msgring_handler (TX_STN_GMAC1, - rmi_xlr_mac_msgring_handler, NULL)) { + if (register_msgring_handler(TX_STN_GMAC1, + rmi_xlr_mac_msgring_handler, NULL)) { panic("Couldn't register msgring handler\n"); } } else { - if (register_msgring_handler (TX_STN_GMAC, - rmi_xlr_mac_msgring_handler, NULL)) { + if (register_msgring_handler(TX_STN_GMAC, + rmi_xlr_mac_msgring_handler, NULL)) { panic("Couldn't register msgring handler\n"); } } - /* Not yet - if (xlr_board_atx_ii()) { - if (register_msgring_handler - (TX_STN_XGS_0, rmi_xlr_mac_msgring_handler, NULL)) { - panic("Couldn't register msgring handler for TX_STN_XGS_0\n"); - } - if (register_msgring_handler - (TX_STN_XGS_1, rmi_xlr_mac_msgring_handler, NULL)) { - panic("Couldn't register msgring handler for TX_STN_XGS_1\n"); - } - } - */ + /* + * Not yet if (xlr_board_atx_ii()) { if (register_msgring_handler + * (TX_STN_XGS_0, rmi_xlr_mac_msgring_handler, NULL)) { + * panic("Couldn't register msgring handler for TX_STN_XGS_0\n"); } + * if (register_msgring_handler (TX_STN_XGS_1, + * rmi_xlr_mac_msgring_handler, NULL)) { panic("Couldn't register + * msgring handler for TX_STN_XGS_1\n"); } } + */ } diff --git a/sys/dev/rmi/xlr/rge.h b/sys/dev/rmi/xlr/rge.h index 8ccc8a2ebb5..98b5847c6d8 100644 --- a/sys/dev/rmi/xlr/rge.h +++ b/sys/dev/rmi/xlr/rge.h @@ -943,22 +943,22 @@ typedef enum { xlr_mac_speed_10, xlr_mac_speed_100, xlr_mac_speed_1000, xlr_mac_speed_rsvd -} xlr_mac_speed_t; +} xlr_mac_speed_t; typedef enum { xlr_mac_duplex_auto, xlr_mac_duplex_half, xlr_mac_duplex_full -} xlr_mac_duplex_t; +} xlr_mac_duplex_t; typedef enum { xlr_mac_link_down, xlr_mac_link_up, -} xlr_mac_link_t; +} xlr_mac_link_t; typedef enum { xlr_mac_fc_auto, xlr_mac_fc_disabled, xlr_mac_fc_frame, xlr_mac_fc_collision, xlr_mac_fc_carrier -} xlr_mac_fc_t; +} xlr_mac_fc_t; /* static int mac_frin_to_be_sent_thr[8]; */ @@ -972,12 +972,12 @@ enum { }; struct rge_softc_stats { - unsigned long rx_frames; - unsigned long tx_frames; - unsigned long rx_packets; - unsigned long rx_bytes; - unsigned long tx_packets; - unsigned long tx_bytes; + unsigned long rx_frames; + unsigned long tx_frames; + unsigned long rx_packets; + unsigned long rx_bytes; + unsigned long tx_packets; + unsigned long tx_bytes; }; struct driver_data { @@ -992,93 +992,93 @@ struct driver_data { union rx_tx_desc *class_1_spill; union rx_tx_desc *class_2_spill; union rx_tx_desc *class_3_spill; - int spill_configured; + int spill_configured; struct rge_softc *sc; /* pointer to freebsd device soft-pointer */ struct rge_softc_stats stats; - struct mtx lock; + struct mtx lock; - xlr_reg_t *mmio; - xlr_reg_t *mii_mmio; - xlr_reg_t *pcs_mmio; - xlr_reg_t *serdes_mmio; + xlr_reg_t *mmio; + xlr_reg_t *mii_mmio; + xlr_reg_t *pcs_mmio; + xlr_reg_t *serdes_mmio; - int txbucket; - int rfrbucket; + int txbucket; + int rfrbucket; - int phy_oldbmsr; - int phy_oldanlpar; - int phy_oldk1stsr; - int phy_oldlinkstat; - unsigned char phys_addr[2]; + int phy_oldbmsr; + int phy_oldanlpar; + int phy_oldk1stsr; + int phy_oldlinkstat; + unsigned char phys_addr[2]; - xlr_mac_speed_t speed; /* current speed */ + xlr_mac_speed_t speed; /* current speed */ xlr_mac_duplex_t duplex;/* current duplex */ - xlr_mac_link_t link; /* current link */ - xlr_mac_fc_t flow_ctrl; /* current flow control setting */ - int advertising; + xlr_mac_link_t link; /* current link */ + xlr_mac_fc_t flow_ctrl; /* current flow control setting */ + int advertising; - int id; - int type; - int mode; - int instance; - int phy_addr; - int frin_to_be_sent[8]; - int init_frin_desc; + int id; + int type; + int mode; + int instance; + int phy_addr; + int frin_to_be_sent[8]; + int init_frin_desc; }; struct rge_softc { - int unit; - int irq; - unsigned char dev_addr[6]; - unsigned long base_addr; - unsigned long mem_end; - struct ifnet *rge_ifp;/* interface info */ - device_t rge_dev; - int mtu; - int flags; + int unit; + int irq; + unsigned char dev_addr[6]; + unsigned long base_addr; + unsigned long mem_end; + struct ifnet *rge_ifp; /* interface info */ + device_t rge_dev; + int mtu; + int flags; struct driver_data priv; - struct mtx rge_mtx; - device_t rge_miibus; - struct mii_data rge_mii;/* MII/media information */ + struct mtx rge_mtx; + device_t rge_miibus; + struct mii_data rge_mii;/* MII/media information */ bus_space_handle_t rge_bhandle; - bus_space_tag_t rge_btag; - void *rge_intrhand; - struct resource rge_irq; + bus_space_tag_t rge_btag; + void *rge_intrhand; + struct resource rge_irq; struct resource *rge_res; - struct ifmedia rge_ifmedia; /* TBI media info */ - int rge_if_flags; - int rge_link; /* link state */ - int rge_link_evt; /* pending link event */ - struct callout rge_stat_ch; - void (*xmit) (struct ifnet *); - void (*stop) (struct rge_softc *); - int (*ioctl) (struct ifnet *, u_long, caddr_t); + struct ifmedia rge_ifmedia; /* TBI media info */ + int rge_if_flags; + int rge_link; /* link state */ + int rge_link_evt; /* pending link event */ + struct callout rge_stat_ch; + void (*xmit) (struct ifnet *); + void (*stop) (struct rge_softc *); + int (*ioctl) (struct ifnet *, u_long, caddr_t); struct rge_softc_stats *(*get_stats) (struct rge_softc *); int active; int link_up; }; struct size_1_desc { - uint64_t entry0; + uint64_t entry0; }; struct size_2_desc { - uint64_t entry0; - uint64_t entry1; + uint64_t entry0; + uint64_t entry1; }; struct size_3_desc { - uint64_t entry0; - uint64_t entry1; - uint64_t entry2; + uint64_t entry0; + uint64_t entry1; + uint64_t entry2; }; struct size_4_desc { - uint64_t entry0; - uint64_t entry1; - uint64_t entry2; - uint64_t entry3; + uint64_t entry0; + uint64_t entry1; + uint64_t entry2; + uint64_t entry3; }; struct fr_desc { diff --git a/sys/dev/rmi/xlr/xgmac_mdio.h b/sys/dev/rmi/xlr/xgmac_mdio.h index 7a8208e1eb2..5d0a3d0cd53 100644 --- a/sys/dev/rmi/xlr/xgmac_mdio.h +++ b/sys/dev/rmi/xlr/xgmac_mdio.h @@ -35,28 +35,28 @@ static inline int xmdio_read(volatile unsigned int *_mmio, - uint32_t phy_addr, uint32_t address); + uint32_t phy_addr, uint32_t address); static inline void xmdio_write(volatile unsigned int *_mmio, - uint32_t phy_addr, uint32_t address, uint32_t data); + uint32_t phy_addr, uint32_t address, uint32_t data); static inline void xmdio_address(volatile unsigned int *_mmio, - uint32_t phy_addr, uint32_t dev_ad, uint32_t address); + uint32_t phy_addr, uint32_t dev_ad, uint32_t address); static inline void xmdio_address(volatile unsigned int *_mmio, - uint32_t phy_addr, uint32_t dev_ad, uint32_t address) + uint32_t phy_addr, uint32_t dev_ad, uint32_t address) { - uint32_t st_field = 0x0; - uint32_t op_type = 0x0; /* address operation */ - uint32_t ta_field = 0x2; /* ta field */ + uint32_t st_field = 0x0; + uint32_t op_type = 0x0; /* address operation */ + uint32_t ta_field = 0x2;/* ta field */ _mmio[0x11] = ((st_field & 0x3) << 30) | - ((op_type & 0x3) << 28) | - ((phy_addr & 0x1F) << 23) | - ((dev_ad & 0x1F) << 18) | - ((ta_field & 0x3) << 16) | - ((address & 0xffff) << 0); + ((op_type & 0x3) << 28) | + ((phy_addr & 0x1F) << 23) | + ((dev_ad & 0x1F) << 18) | + ((ta_field & 0x3) << 16) | + ((address & 0xffff) << 0); _mmio[0x10] = (0x0 << 3) | 0x5; _mmio[0x10] = (0x1 << 3) | 0x5; @@ -71,20 +71,20 @@ xmdio_address(volatile unsigned int *_mmio, /* function prototypes */ static inline int xmdio_read(volatile unsigned int *_mmio, - uint32_t phy_addr, uint32_t address) + uint32_t phy_addr, uint32_t address) { - uint32_t st_field = 0x0; - uint32_t op_type = 0x3; /* read operation */ - uint32_t ta_field = 0x2; /* ta field */ - uint32_t data = 0; + uint32_t st_field = 0x0; + uint32_t op_type = 0x3; /* read operation */ + uint32_t ta_field = 0x2;/* ta field */ + uint32_t data = 0; xmdio_address(_mmio, phy_addr, 5, address); _mmio[0x11] = ((st_field & 0x3) << 30) | - ((op_type & 0x3) << 28) | - ((phy_addr & 0x1F) << 23) | - ((5 & 0x1F) << 18) | - ((ta_field & 0x3) << 16) | - ((data & 0xffff) << 0); + ((op_type & 0x3) << 28) | + ((phy_addr & 0x1F) << 23) | + ((5 & 0x1F) << 18) | + ((ta_field & 0x3) << 16) | + ((data & 0xffff) << 0); _mmio[0x10] = (0x0 << 3) | 0x5; _mmio[0x10] = (0x1 << 3) | 0x5; @@ -100,19 +100,19 @@ xmdio_read(volatile unsigned int *_mmio, static inline void xmdio_write(volatile unsigned int *_mmio, - uint32_t phy_addr, uint32_t address, uint32_t data) + uint32_t phy_addr, uint32_t address, uint32_t data) { - uint32_t st_field = 0x0; - uint32_t op_type = 0x1; /* write operation */ - uint32_t ta_field = 0x2; /* ta field */ + uint32_t st_field = 0x0; + uint32_t op_type = 0x1; /* write operation */ + uint32_t ta_field = 0x2;/* ta field */ xmdio_address(_mmio, phy_addr, 5, address); _mmio[0x11] = ((st_field & 0x3) << 30) | - ((op_type & 0x3) << 28) | - ((phy_addr & 0x1F) << 23) | - ((5 & 0x1F) << 18) | - ((ta_field & 0x3) << 16) | - ((data & 0xffff) << 0); + ((op_type & 0x3) << 28) | + ((phy_addr & 0x1F) << 23) | + ((5 & 0x1F) << 18) | + ((ta_field & 0x3) << 16) | + ((data & 0xffff) << 0); _mmio[0x10] = (0x0 << 3) | 0x5; _mmio[0x10] = (0x1 << 3) | 0x5; From 733a780709917db6cac568340d9a95de5e200bb0 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Thu, 29 Oct 2009 21:23:44 +0000 Subject: [PATCH 294/380] white space changes --- sys/dev/rmi/sec/desc.h | 2065 +++++++------- sys/dev/rmi/sec/rmilib.c | 5627 +++++++++++++++++++------------------- sys/dev/rmi/sec/rmilib.h | 694 ++--- sys/dev/rmi/sec/rmisec.c | 800 +++--- 4 files changed, 4579 insertions(+), 4607 deletions(-) diff --git a/sys/dev/rmi/sec/desc.h b/sys/dev/rmi/sec/desc.h index cb76637805d..5757e13a765 100755 --- a/sys/dev/rmi/sec/desc.h +++ b/sys/dev/rmi/sec/desc.h @@ -70,7 +70,7 @@ (word) |= (((value) & (field ## _BITS)) << (field ## _LSB)); } /* - * NOTE: May be used to build value specific mask + * NOTE: May be used to build value specific mask * (e.g. GEN_MASK(CTL_DSC_CPHR_3DES,CTL_DSC_CPHR_LSB) */ #define GEN_MASK(bits,lsb) ((bits) << (lsb)) @@ -122,7 +122,7 @@ * | Ctrl | Destination Id | 2'b00 | Desc Ctrl | 1'b0 | Data Error | Address of packet descriptor data structure | * ---------------------------------------------------------------------------------------------------------------------------- * - * The Instruction and Data Error codes are enumerated in the + * The Instruction and Data Error codes are enumerated in the * ControlDescriptor and PacketDescriptor sections below * */ @@ -132,12 +132,12 @@ * Operating assumptions * ===================== * - * + * * -> For all IpSec ops, I assume that all the IP/IPSec/TCP headers * and the data are present at the specified source addresses. * I also assume that all necessary header data already exists * at the destination. Additionally, in AH I assume that all - * mutable fields (IP.{TOS, Flags, Offset, TTL, Header_Checksum}) + * mutable fields (IP.{TOS, Flags, Offset, TTL, Header_Checksum}) * and the AH.Authentication_Data have been zeroed by the client. * * @@ -183,9 +183,9 @@ * * A) Rebuilding packets from fragments on dword boundaries. The discussion * below is exemplified by tests memcpy_all_off_frags and memcpy_same_off_frags - * + * * 1) The Offset before data/iv on first fragment is ALWAYS written back - * Non-zero dst dword or global offsets may cause more data to be + * Non-zero dst dword or global offsets may cause more data to be * written than the user-specified length. * * @@ -217,7 +217,7 @@ * Cipher_Offset = 3 * IV_Offset = 3 * Use_IV = ANY - * + * * * * 3 2 1 0 3 2 1 0 @@ -228,7 +228,7 @@ * ----------------------- ----------------------- * | | | | D05 | | | | D05 | D04 | * ----------------------- ----------------------- - * + * * 2) On fragments following the first, IV_Offset is overloaded to mean data offset * (number of dwords to skip from beginning of cacheline before starting processing) * and Use_IV is overloaded to mean do writeback the offset (in the clear). @@ -253,7 +253,7 @@ * Packet_Legth = 104 Dst_dword_offset = 1 * IV_Offset = 1 * Use_IV = 0 - * + * * * * 3 2 1 0 3 2 1 0 @@ -275,7 +275,7 @@ * engine always writes full lines, therefore ADD1 + 0x20 will be re-written. Setting Use_IV to 0 * will allow the sec pipe write back buffer to preserve D04, D05 from previous frag and only * receive D10, D11 thereby preserving the integrity of the previous data. - * + * * 3) On fragments following the first, !UseIV in combination w/ Dst_dword_offset >= (4 - IV_Offset) * will cause a wraparound of the write thus achieving all 16 possible (Initial_Location, Final_Location) * combinations for the data. @@ -284,7 +284,7 @@ * Example: * -------- * - * Contiguously merging 2 data sets above with a third located at ADD3. If this is the last fragment, + * Contiguously merging 2 data sets above with a third located at ADD3. If this is the last fragment, * reset its Next bit. * * @@ -295,7 +295,7 @@ * Packet_Legth = 152 Dst_dword_offset = 3 * IV_Offset = 3 * Use_IV = 0 - * + * * * * 3 2 1 0 3 2 1 0 @@ -312,13 +312,13 @@ * ----------------------- ----------------------- * | D21 | D20 | D1b | D1a | <- ADD1 + 0x80 * ----------------------- - * | D25 | D24 | D23 | D22 | + * | D25 | D24 | D23 | D22 | * ----------------------- - * | D29 | D28 | D27 | D26 | + * | D29 | D28 | D27 | D26 | * ----------------------- - * | D2d | D2c | D2b | D2a | + * | D2d | D2c | D2b | D2a | * ----------------------- - * |(D2d)|(D2c)| D2f | D2e | + * |(D2d)|(D2c)| D2f | D2e | * ----------------------- * * It is worth noticing that always writing full-lines causes the last 2 dwords in the reconstituted @@ -327,7 +327,7 @@ * * * B) Implications of fragmentation on AES - * + * * 1) AES is a 128 bit block cipher; therefore it requires an even dword total data length * Data fragments (provided there are more than 1) are allowed to have odd dword * data lengths provided the total length (cumulated over fragments) is an even dword @@ -354,9 +354,9 @@ * Use_IV = 1 * Cipher = Any AES * Next = 1 - * * - * + * + * * * 3 2 1 0 3 2 1 0 * ----------------------- ----------------------- @@ -396,7 +396,7 @@ /* #define MSG_CMD_CTL_ADDR */ -#define MSG_CMD_CTL_ADDR_LSB 0 +#define MSG_CMD_CTL_ADDR_LSB 0 #define MSG_CMD_CTL_ADDR_BITS FOURTY_BITS #define MSG_CMD_CTL_ADDR_MASK (MSG_CMD_CTL_ADDR_BITS << MSG_CMD_CTL_ADDR_LSB) @@ -419,8 +419,8 @@ #define MSG_CMD_DATA_LEN_MASK (MSG_CMD_DATA_LEN_BITS << MSG_CMD_DATA_LEN_LSB) /* #define MSG_CMD_DATA_ADDR */ -#define MSG_CMD_DATA_ADDR_LSB 0 -#define MSG_CMD_DATA_ADDR_BITS FOURTY_BITS +#define MSG_CMD_DATA_ADDR_LSB 0 +#define MSG_CMD_DATA_ADDR_BITS FOURTY_BITS #define MSG_CMD_DATA_ADDR_MASK (MSG_CMD_DATA_ADDR_BITS << MSG_CMD_DATA_ADDR_LSB) #define MSG_CMD_DATA_MASK (MSG_CMD_DATA_CTL_MASK | \ @@ -620,7 +620,7 @@ * For ARC4, IFetch/IDecode will always read exactly 4 * consecutive dwords into its CipherKey{0,3} regardless * of this quantity; it will however only use the specified - * number of bytes. + * number of bytes. * Cipher = 3'b000 Bypass * 3'b001 DES * 3'b010 3DES @@ -642,7 +642,7 @@ * and recalculate the Arc4 Sbox if Arc4 Cipher chosen; * This overrides LoadArc4State setting. * HASH.HMAC = 1'b0 Hash without HMAC - * 1'b1 Hash with HMAC + * 1'b1 Hash with HMAC * Needs to be set to 0 for GCM and Kasumi F9 authenticators * otherwise unpredictable results will be generated * Hash = 2'b00 Hash NOP @@ -712,7 +712,7 @@ #define CTL_DSC_ARC4_KEYLEN_MASK (CTL_DSC_ARC4_KEYLEN_BITS << CTL_DSC_ARC4_KEYLEN_LSB) /* #define CTL_DSC_CPHR (cipher) */ -#define CTL_DSC_CPHR_BYPASS 0 /* undefined */ +#define CTL_DSC_CPHR_BYPASS 0 /* undefined */ #define CTL_DSC_CPHR_DES 1 #define CTL_DSC_CPHR_3DES 2 #define CTL_DSC_CPHR_AES128 3 @@ -736,8 +736,8 @@ #define CTL_DSC_MODE_MASK (CTL_DSC_MODE_BITS << CTL_DSC_MODE_LSB) /* #define CTL_DSC_ICPHR */ -#define CTL_DSC_ICPHR_OKY 0 /* Old Keys */ -#define CTL_DSC_ICPHR_NKY 1 /* New Keys */ +#define CTL_DSC_ICPHR_OKY 0 /* Old Keys */ +#define CTL_DSC_ICPHR_NKY 1 /* New Keys */ #define CTL_DSC_ICPHR_LSB 28 #define CTL_DSC_ICPHR_BITS ONE_BIT #define CTL_DSC_ICPHR_MASK (CTL_DSC_ICPHR_BITS << CTL_DSC_ICPHR_LSB) @@ -788,1075 +788,1075 @@ /* AES256, (ECB, CBC, OFB, CTR, CFB), HMAC (MD5, SHA-1, SHA-256) - 96 bytes */ typedef struct AES256HMAC_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKey3; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; -} AES256HMAC_t, *AES256HMAC_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} AES256HMAC_t, *AES256HMAC_pt; /* AES256, (ECB, CBC, OFB, CTR, CFB), HMAC (SHA-384, SHA-512) - 160 bytes */ typedef struct AES256HMAC2_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKey3; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; - uint64_t hmacKey8; - uint64_t hmacKey9; - uint64_t hmacKey10; - uint64_t hmacKey11; - uint64_t hmacKey12; - uint64_t hmacKey13; - uint64_t hmacKey14; - uint64_t hmacKey15; -} AES256HMAC2_t, *AES256HMAC2_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} AES256HMAC2_t, *AES256HMAC2_pt; /* AES256, (ECB, CBC, OFB, CTR, CFB), GCM - 56 bytes */ typedef struct AES256GCM_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKey3; - uint64_t GCMH0; - uint64_t GCMH1; - uint64_t GCMSCI; -} AES256GCM_t, *AES256GCM_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} AES256GCM_t, *AES256GCM_pt; /* AES256, (ECB, CBC, OFB, CTR, CFB), F9 - 56 bytes */ typedef struct AES256F9_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKey3; - uint64_t authKey0; - uint64_t authKey1; -} AES256F9_t, *AES256F9_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t authKey0; + uint64_t authKey1; +} AES256F9_t, *AES256F9_pt; /* AES256, (ECB, CBC, OFB, CTR, CFB), Non-HMAC (MD5, SHA-1, SHA-256) - 32 bytes */ typedef struct AES256_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKey3; -} AES256_t, *AES256_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; +} AES256_t, *AES256_pt; /* All AES192 possibilities */ /* AES192, (ECB, CBC, OFB, CTR, CFB), HMAC (MD5, SHA-1, SHA-192) - 88 bytes */ typedef struct AES192HMAC_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; -} AES192HMAC_t, *AES192HMAC_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} AES192HMAC_t, *AES192HMAC_pt; /* AES192, (ECB, CBC, OFB, CTR, CFB), HMAC (SHA-384, SHA-512) - 152 bytes */ typedef struct AES192HMAC2_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; - uint64_t hmacKey8; - uint64_t hmacKey9; - uint64_t hmacKey10; - uint64_t hmacKey11; - uint64_t hmacKey12; - uint64_t hmacKey13; - uint64_t hmacKey14; - uint64_t hmacKey15; -} AES192HMAC2_t, *AES192HMAC2_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} AES192HMAC2_t, *AES192HMAC2_pt; /* AES192, (ECB, CBC, OFB, CTR, CFB), GCM - 48 bytes */ typedef struct AES192GCM_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t GCMH0; - uint64_t GCMH1; - uint64_t GCMSCI; -} AES192GCM_t, *AES192GCM_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} AES192GCM_t, *AES192GCM_pt; /* AES192, (ECB, CBC, OFB, CTR, CFB), F9 - 48 bytes */ typedef struct AES192F9_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t authKey0; - uint64_t authKey1; -} AES192F9_t, *AES192F9_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t authKey0; + uint64_t authKey1; +} AES192F9_t, *AES192F9_pt; /* AES192, (ECB, CBC, OFB, CTR, CFB), Non-HMAC (MD5, SHA-1, SHA-192) - 24 bytes */ typedef struct AES192_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; -} AES192_t, *AES192_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; +} AES192_t, *AES192_pt; /* All AES128 possibilities */ /* AES128, (ECB, CBC, OFB, CTR, CFB), HMAC (MD5, SHA-1, SHA-128) - 80 bytes */ typedef struct AES128HMAC_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; -} AES128HMAC_t, *AES128HMAC_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} AES128HMAC_t, *AES128HMAC_pt; /* AES128, (ECB, CBC, OFB, CTR, CFB), HMAC (SHA-384, SHA-612) - 144 bytes */ typedef struct AES128HMAC2_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; - uint64_t hmacKey8; - uint64_t hmacKey9; - uint64_t hmacKey10; - uint64_t hmacKey11; - uint64_t hmacKey12; - uint64_t hmacKey13; - uint64_t hmacKey14; - uint64_t hmacKey15; -} AES128HMAC2_t, *AES128HMAC2_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} AES128HMAC2_t, *AES128HMAC2_pt; /* AES128, (ECB, CBC, OFB, CTR, CFB), GCM - 40 bytes */ typedef struct AES128GCM_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t GCMH0; - uint64_t GCMH1; - uint64_t GCMSCI; -} AES128GCM_t, *AES128GCM_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} AES128GCM_t, *AES128GCM_pt; /* AES128, (ECB, CBC, OFB, CTR, CFB), F9 - 48 bytes */ typedef struct AES128F9_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t authKey0; - uint64_t authKey1; -} AES128F9_t, *AES128F9_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t authKey0; + uint64_t authKey1; +} AES128F9_t, *AES128F9_pt; /* AES128, (ECB, CBC, OFB, CTR, CFB), Non-HMAC (MD5, SHA-1, SHA-128) - 16 bytes */ typedef struct AES128_s { - uint64_t cipherKey0; - uint64_t cipherKey1; -} AES128_t, *AES128_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; +} AES128_t, *AES128_pt; /* AES128, (OFB F8), Non-HMAC (MD5, SHA-1, SHA-256) - 32 bytes */ typedef struct AES128F8_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKeyMask0; - uint64_t cipherKeyMask1; -} AES128F8_t, *AES128F8_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKeyMask0; + uint64_t cipherKeyMask1; +} AES128F8_t, *AES128F8_pt; /* AES128, (OFB F8), HMAC (MD5, SHA-1, SHA-256) - 96 bytes */ typedef struct AES128F8HMAC_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKeyMask0; - uint64_t cipherKeyMask1; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; -} AES128F8HMAC_t, *AES128F8HMAC_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKeyMask0; + uint64_t cipherKeyMask1; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} AES128F8HMAC_t, *AES128F8HMAC_pt; /* AES128, (OFB F8), HMAC (SHA-384, SHA-512) - 160 bytes */ typedef struct AES128F8HMAC2_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKeyMask0; - uint64_t cipherKeyMask1; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; - uint64_t hmacKey8; - uint64_t hmacKey9; - uint64_t hmacKey10; - uint64_t hmacKey11; - uint64_t hmacKey12; - uint64_t hmacKey13; - uint64_t hmacKey14; - uint64_t hmacKey15; -} AES128F8HMAC2_t, *AES128F8HMAC2_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKeyMask0; + uint64_t cipherKeyMask1; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} AES128F8HMAC2_t, *AES128F8HMAC2_pt; /* AES192, (OFB F8), Non-HMAC (MD5, SHA-1, SHA-256) - 48 bytes */ typedef struct AES192F8_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKeyMask0; - uint64_t cipherKeyMask1; - uint64_t cipherKeyMask2; -} AES192F8_t, *AES192F8_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKeyMask0; + uint64_t cipherKeyMask1; + uint64_t cipherKeyMask2; +} AES192F8_t, *AES192F8_pt; /* AES192, (OFB F8), HMAC (MD5, SHA-1, SHA-256) - 112 bytes */ typedef struct AES192F8HMAC_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKeyMask0; - uint64_t cipherKeyMask1; - uint64_t cipherKeyMask2; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; -} AES192F8HMAC_t, *AES192F8HMAC_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKeyMask0; + uint64_t cipherKeyMask1; + uint64_t cipherKeyMask2; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} AES192F8HMAC_t, *AES192F8HMAC_pt; /* AES192, (OFB F8), HMAC (SHA-384, SHA-512) - 176 bytes */ typedef struct AES192F8HMAC2_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKeyMask0; - uint64_t cipherKeyMask1; - uint64_t cipherKeyMask2; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; - uint64_t hmacKey8; - uint64_t hmacKey9; - uint64_t hmacKey10; - uint64_t hmacKey11; - uint64_t hmacKey12; - uint64_t hmacKey13; - uint64_t hmacKey14; - uint64_t hmacKey15; -} AES192F8HMAC2_t, *AES192F8HMAC2_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKeyMask0; + uint64_t cipherKeyMask1; + uint64_t cipherKeyMask2; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} AES192F8HMAC2_t, *AES192F8HMAC2_pt; /* AES256, (OFB F8), Non-HMAC (MD5, SHA-1, SHA-256) - 64 bytes */ typedef struct AES256F8_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKey3; - uint64_t cipherKeyMask0; - uint64_t cipherKeyMask1; - uint64_t cipherKeyMask2; - uint64_t cipherKeyMask3; -} AES256F8_t, *AES256F8_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t cipherKeyMask0; + uint64_t cipherKeyMask1; + uint64_t cipherKeyMask2; + uint64_t cipherKeyMask3; +} AES256F8_t, *AES256F8_pt; /* AES256, (OFB F8), HMAC (MD5, SHA-1, SHA-256) - 128 bytes */ typedef struct AES256F8HMAC_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKey3; - uint64_t cipherKeyMask0; - uint64_t cipherKeyMask1; - uint64_t cipherKeyMask2; - uint64_t cipherKeyMask3; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; -} AES256F8HMAC_t, *AES256F8HMAC_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t cipherKeyMask0; + uint64_t cipherKeyMask1; + uint64_t cipherKeyMask2; + uint64_t cipherKeyMask3; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} AES256F8HMAC_t, *AES256F8HMAC_pt; /* AES256, (OFB F8), HMAC (SHA-384, SHA-512) - 192 bytes */ typedef struct AES256F8HMAC2_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKey3; - uint64_t cipherKeyMask0; - uint64_t cipherKeyMask1; - uint64_t cipherKeyMask2; - uint64_t cipherKeyMask3; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; - uint64_t hmacKey8; - uint64_t hmacKey9; - uint64_t hmacKey10; - uint64_t hmacKey11; - uint64_t hmacKey12; - uint64_t hmacKey13; - uint64_t hmacKey14; - uint64_t hmacKey15; -} AES256F8HMAC2_t, *AES256F8HMAC2_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t cipherKeyMask0; + uint64_t cipherKeyMask1; + uint64_t cipherKeyMask2; + uint64_t cipherKeyMask3; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} AES256F8HMAC2_t, *AES256F8HMAC2_pt; /* AES256, (F8), GCM - 40 bytes */ typedef struct AES128F8GCM_s { - uint64_t cipherKey0; - uint64_t cipherKey2; - uint64_t GCMH0; - uint64_t GCMH1; - uint64_t GCMSCI; -} AES128F8GCM_t, *AES128F8GCM_pt; + uint64_t cipherKey0; + uint64_t cipherKey2; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} AES128F8GCM_t, *AES128F8GCM_pt; /* AES256, (F8), GCM - 48 bytes */ typedef struct AES192F8GCM_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t GCMH0; - uint64_t GCMH1; - uint64_t GCMSCI; -} AES192F8GCM_t, *AES192F8GCM_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} AES192F8GCM_t, *AES192F8GCM_pt; /* AES256, (F8), GCM - 56 bytes */ typedef struct AES256F8GCM_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKey3; - uint64_t GCMH0; - uint64_t GCMH1; - uint64_t GCMSCI; -} AES256F8GCM_t, *AES256F8GCM_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} AES256F8GCM_t, *AES256F8GCM_pt; /* AES256, (F8), F9 - 40 bytes */ typedef struct AES128F8F9_s { - uint64_t cipherKey0; - uint64_t cipherKey2; - uint64_t authKey0; - uint64_t authKey1; -} AES128F8F9_t, *AES128F8F9_pt; + uint64_t cipherKey0; + uint64_t cipherKey2; + uint64_t authKey0; + uint64_t authKey1; +} AES128F8F9_t, *AES128F8F9_pt; /* AES256, (F8), F9 - 48 bytes */ typedef struct AES192F8F9_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t authKey0; - uint64_t authKey1; -} AES192F8F9_t, *AES192F8F9_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t authKey0; + uint64_t authKey1; +} AES192F8F9_t, *AES192F8F9_pt; /* AES256F8, (F8), F9 - 56 bytes */ typedef struct AES256F8F9_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKey3; - uint64_t authKey0; - uint64_t authKey1; -} AES256F8F9_t, *AES256F8F9_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t authKey0; + uint64_t authKey1; +} AES256F8F9_t, *AES256F8F9_pt; /* All DES possibilities */ /* DES, (ECB, CBC), HMAC (MD5, SHA-1, SHA-128) - 72 bytes */ typedef struct DESHMAC_s { - uint64_t cipherKey0; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; -} DESHMAC_t, *DESHMAC_pt; + uint64_t cipherKey0; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} DESHMAC_t, *DESHMAC_pt; /* DES, (ECB, CBC), HMAC (SHA-384, SHA-512) - 136 bytes */ typedef struct DESHMAC2_s { - uint64_t cipherKey0; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; - uint64_t hmacKey8; - uint64_t hmacKey9; - uint64_t hmacKey10; - uint64_t hmacKey11; - uint64_t hmacKey12; - uint64_t hmacKey13; - uint64_t hmacKey14; - uint64_t hmacKey15; -} DESHMAC2_t, *DESHMAC2_pt; + uint64_t cipherKey0; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} DESHMAC2_t, *DESHMAC2_pt; /* DES, (ECB, CBC), GCM - 32 bytes */ typedef struct DESGCM_s { - uint64_t cipherKey0; - uint64_t GCMH0; - uint64_t GCMH1; - uint64_t GCMSCI; -} DESGCM_t, *DESGCM_pt; + uint64_t cipherKey0; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} DESGCM_t, *DESGCM_pt; /* DES, (ECB, CBC), F9 - 32 bytes */ typedef struct DESF9_s { - uint64_t cipherKey0; - uint64_t authKey0; - uint64_t authKey1; -} DESF9_t, *DESF9_pt; + uint64_t cipherKey0; + uint64_t authKey0; + uint64_t authKey1; +} DESF9_t, *DESF9_pt; /* DES, (ECB, CBC), Non-HMAC (MD5, SHA-1, SHA-128) - 9 bytes */ typedef struct DES_s { - uint64_t cipherKey0; -} DES_t, *DES_pt; + uint64_t cipherKey0; +} DES_t, *DES_pt; /* All 3DES possibilities */ /* 3DES, (ECB, CBC), HMAC (MD5, SHA-1, SHA-128) - 88 bytes */ typedef struct DES3HMAC_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; -} DES3HMAC_t, *DES3HMAC_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} DES3HMAC_t, *DES3HMAC_pt; /* 3DES, (ECB, CBC), HMAC (SHA-384, SHA-512) - 152 bytes */ typedef struct DES3HMAC2_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; - uint64_t hmacKey8; - uint64_t hmacKey9; - uint64_t hmacKey10; - uint64_t hmacKey11; - uint64_t hmacKey12; - uint64_t hmacKey13; - uint64_t hmacKey14; - uint64_t hmacKey15; -} DES3HMAC2_t, *DES3HMAC2_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} DES3HMAC2_t, *DES3HMAC2_pt; /* 3DES, (ECB, CBC), GCM - 48 bytes */ typedef struct DES3GCM_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t GCMH0; - uint64_t GCMH1; - uint64_t GCMSCI; -} DES3GCM_t, *DES3GCM_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} DES3GCM_t, *DES3GCM_pt; /* 3DES, (ECB, CBC), GCM - 48 bytes */ typedef struct DES3F9_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t authKey0; - uint64_t authKey1; -} DES3F9_t, *DES3F9_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t authKey0; + uint64_t authKey1; +} DES3F9_t, *DES3F9_pt; /* 3DES, (ECB, CBC), Non-HMAC (MD5, SHA-1, SHA-128) - 24 bytes */ typedef struct DES3_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; -} DES3_t, *DES3_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; +} DES3_t, *DES3_pt; /* HMAC only - no cipher */ /* HMAC (MD5, SHA-1, SHA-128) - 64 bytes */ typedef struct HMAC_s { - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; -} HMAC_t, *HMAC_pt; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} HMAC_t, *HMAC_pt; /* HMAC (SHA-384, SHA-512) - 128 bytes */ typedef struct HMAC2_s { - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; - uint64_t hmacKey8; - uint64_t hmacKey9; - uint64_t hmacKey10; - uint64_t hmacKey11; - uint64_t hmacKey12; - uint64_t hmacKey13; - uint64_t hmacKey14; - uint64_t hmacKey15; -} HMAC2_t, *HMAC2_pt; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} HMAC2_t, *HMAC2_pt; /* GCM - 24 bytes */ typedef struct GCM_s { - uint64_t GCMH0; - uint64_t GCMH1; - uint64_t GCMSCI; -} GCM_t, *GCM_pt; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} GCM_t, *GCM_pt; /* F9 - 24 bytes */ typedef struct F9_s { - uint64_t authKey0; - uint64_t authKey1; -} F9_t, *F9_pt; + uint64_t authKey0; + uint64_t authKey1; +} F9_t, *F9_pt; /* All ARC4 possibilities */ /* ARC4, HMAC (MD5, SHA-1, SHA-256) - 96 bytes */ typedef struct ARC4HMAC_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKey3; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; -} ARC4HMAC_t, *ARC4HMAC_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} ARC4HMAC_t, *ARC4HMAC_pt; /* ARC4, HMAC (SHA-384, SHA-512) - 160 bytes */ typedef struct ARC4HMAC2_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKey3; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; - uint64_t hmacKey8; - uint64_t hmacKey9; - uint64_t hmacKey10; - uint64_t hmacKey11; - uint64_t hmacKey12; - uint64_t hmacKey13; - uint64_t hmacKey14; - uint64_t hmacKey15; -} ARC4HMAC2_t, *ARC4HMAC2_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} ARC4HMAC2_t, *ARC4HMAC2_pt; /* ARC4, GCM - 56 bytes */ typedef struct ARC4GCM_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKey3; - uint64_t GCMH0; - uint64_t GCMH1; - uint64_t GCMSCI; -} ARC4GCM_t, *ARC4GCM_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} ARC4GCM_t, *ARC4GCM_pt; /* ARC4, F9 - 56 bytes */ typedef struct ARC4F9_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKey3; - uint64_t authKey0; - uint64_t authKey1; -} ARC4F9_t, *ARC4F9_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t authKey0; + uint64_t authKey1; +} ARC4F9_t, *ARC4F9_pt; /* ARC4, HMAC (MD5, SHA-1, SHA-256) - 408 bytes (not including 8 bytes from instruction) */ typedef struct ARC4StateHMAC_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKey3; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; - uint64_t PAD0; - uint64_t PAD1; - uint64_t PAD2; - uint64_t Arc4SboxData0; - uint64_t Arc4SboxData1; - uint64_t Arc4SboxData2; - uint64_t Arc4SboxData3; - uint64_t Arc4SboxData4; - uint64_t Arc4SboxData5; - uint64_t Arc4SboxData6; - uint64_t Arc4SboxData7; - uint64_t Arc4SboxData8; - uint64_t Arc4SboxData9; - uint64_t Arc4SboxData10; - uint64_t Arc4SboxData11; - uint64_t Arc4SboxData12; - uint64_t Arc4SboxData13; - uint64_t Arc4SboxData14; - uint64_t Arc4SboxData15; - uint64_t Arc4SboxData16; - uint64_t Arc4SboxData17; - uint64_t Arc4SboxData18; - uint64_t Arc4SboxData19; - uint64_t Arc4SboxData20; - uint64_t Arc4SboxData21; - uint64_t Arc4SboxData22; - uint64_t Arc4SboxData23; - uint64_t Arc4SboxData24; - uint64_t Arc4SboxData25; - uint64_t Arc4SboxData26; - uint64_t Arc4SboxData27; - uint64_t Arc4SboxData28; - uint64_t Arc4SboxData29; - uint64_t Arc4SboxData30; - uint64_t Arc4SboxData31; - uint64_t Arc4IJData; - uint64_t PAD3; - uint64_t PAD4; - uint64_t PAD5; -} ARC4StateHMAC_t, *ARC4StateHMAC_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t PAD0; + uint64_t PAD1; + uint64_t PAD2; + uint64_t Arc4SboxData0; + uint64_t Arc4SboxData1; + uint64_t Arc4SboxData2; + uint64_t Arc4SboxData3; + uint64_t Arc4SboxData4; + uint64_t Arc4SboxData5; + uint64_t Arc4SboxData6; + uint64_t Arc4SboxData7; + uint64_t Arc4SboxData8; + uint64_t Arc4SboxData9; + uint64_t Arc4SboxData10; + uint64_t Arc4SboxData11; + uint64_t Arc4SboxData12; + uint64_t Arc4SboxData13; + uint64_t Arc4SboxData14; + uint64_t Arc4SboxData15; + uint64_t Arc4SboxData16; + uint64_t Arc4SboxData17; + uint64_t Arc4SboxData18; + uint64_t Arc4SboxData19; + uint64_t Arc4SboxData20; + uint64_t Arc4SboxData21; + uint64_t Arc4SboxData22; + uint64_t Arc4SboxData23; + uint64_t Arc4SboxData24; + uint64_t Arc4SboxData25; + uint64_t Arc4SboxData26; + uint64_t Arc4SboxData27; + uint64_t Arc4SboxData28; + uint64_t Arc4SboxData29; + uint64_t Arc4SboxData30; + uint64_t Arc4SboxData31; + uint64_t Arc4IJData; + uint64_t PAD3; + uint64_t PAD4; + uint64_t PAD5; +} ARC4StateHMAC_t, *ARC4StateHMAC_pt; /* ARC4, HMAC (SHA-384, SHA-512) - 480 bytes (not including 8 bytes from instruction) */ typedef struct ARC4StateHMAC2_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKey3; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; - uint64_t hmacKey8; - uint64_t hmacKey9; - uint64_t hmacKey10; - uint64_t hmacKey11; - uint64_t hmacKey12; - uint64_t hmacKey13; - uint64_t hmacKey14; - uint64_t hmacKey15; - uint64_t PAD0; - uint64_t PAD1; - uint64_t PAD2; - uint64_t Arc4SboxData0; - uint64_t Arc4SboxData1; - uint64_t Arc4SboxData2; - uint64_t Arc4SboxData3; - uint64_t Arc4SboxData4; - uint64_t Arc4SboxData5; - uint64_t Arc4SboxData6; - uint64_t Arc4SboxData7; - uint64_t Arc4SboxData8; - uint64_t Arc4SboxData9; - uint64_t Arc4SboxData10; - uint64_t Arc4SboxData11; - uint64_t Arc4SboxData12; - uint64_t Arc4SboxData13; - uint64_t Arc4SboxData14; - uint64_t Arc4SboxData15; - uint64_t Arc4SboxData16; - uint64_t Arc4SboxData17; - uint64_t Arc4SboxData18; - uint64_t Arc4SboxData19; - uint64_t Arc4SboxData20; - uint64_t Arc4SboxData21; - uint64_t Arc4SboxData22; - uint64_t Arc4SboxData23; - uint64_t Arc4SboxData24; - uint64_t Arc4SboxData25; - uint64_t Arc4SboxData26; - uint64_t Arc4SboxData27; - uint64_t Arc4SboxData28; - uint64_t Arc4SboxData29; - uint64_t Arc4SboxData30; - uint64_t Arc4SboxData31; - uint64_t Arc4IJData; - uint64_t PAD3; - uint64_t PAD4; - uint64_t PAD5; -} ARC4StateHMAC2_t, *ARC4StateHMAC2_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; + uint64_t PAD0; + uint64_t PAD1; + uint64_t PAD2; + uint64_t Arc4SboxData0; + uint64_t Arc4SboxData1; + uint64_t Arc4SboxData2; + uint64_t Arc4SboxData3; + uint64_t Arc4SboxData4; + uint64_t Arc4SboxData5; + uint64_t Arc4SboxData6; + uint64_t Arc4SboxData7; + uint64_t Arc4SboxData8; + uint64_t Arc4SboxData9; + uint64_t Arc4SboxData10; + uint64_t Arc4SboxData11; + uint64_t Arc4SboxData12; + uint64_t Arc4SboxData13; + uint64_t Arc4SboxData14; + uint64_t Arc4SboxData15; + uint64_t Arc4SboxData16; + uint64_t Arc4SboxData17; + uint64_t Arc4SboxData18; + uint64_t Arc4SboxData19; + uint64_t Arc4SboxData20; + uint64_t Arc4SboxData21; + uint64_t Arc4SboxData22; + uint64_t Arc4SboxData23; + uint64_t Arc4SboxData24; + uint64_t Arc4SboxData25; + uint64_t Arc4SboxData26; + uint64_t Arc4SboxData27; + uint64_t Arc4SboxData28; + uint64_t Arc4SboxData29; + uint64_t Arc4SboxData30; + uint64_t Arc4SboxData31; + uint64_t Arc4IJData; + uint64_t PAD3; + uint64_t PAD4; + uint64_t PAD5; +} ARC4StateHMAC2_t, *ARC4StateHMAC2_pt; /* ARC4, GCM - 408 bytes (not including 8 bytes from instruction) */ typedef struct ARC4StateGCM_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKey3; - uint64_t GCMH0; - uint64_t GCMH1; - uint64_t GCMSCI; - uint64_t PAD0; - uint64_t PAD1; - uint64_t PAD2; - uint64_t PAD3; - uint64_t PAD4; - uint64_t PAD5; - uint64_t PAD6; - uint64_t PAD7; - uint64_t Arc4SboxData0; - uint64_t Arc4SboxData1; - uint64_t Arc4SboxData2; - uint64_t Arc4SboxData3; - uint64_t Arc4SboxData4; - uint64_t Arc4SboxData5; - uint64_t Arc4SboxData6; - uint64_t Arc4SboxData7; - uint64_t Arc4SboxData8; - uint64_t Arc4SboxData9; - uint64_t Arc4SboxData10; - uint64_t Arc4SboxData11; - uint64_t Arc4SboxData12; - uint64_t Arc4SboxData13; - uint64_t Arc4SboxData14; - uint64_t Arc4SboxData15; - uint64_t Arc4SboxData16; - uint64_t Arc4SboxData17; - uint64_t Arc4SboxData18; - uint64_t Arc4SboxData19; - uint64_t Arc4SboxData20; - uint64_t Arc4SboxData21; - uint64_t Arc4SboxData22; - uint64_t Arc4SboxData23; - uint64_t Arc4SboxData24; - uint64_t Arc4SboxData25; - uint64_t Arc4SboxData26; - uint64_t Arc4SboxData27; - uint64_t Arc4SboxData28; - uint64_t Arc4SboxData29; - uint64_t Arc4SboxData30; - uint64_t Arc4SboxData31; - uint64_t Arc4IJData; - uint64_t PAD8; - uint64_t PAD9; - uint64_t PAD10; -} ARC4StateGCM_t, *ARC4StateGCM_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; + uint64_t PAD0; + uint64_t PAD1; + uint64_t PAD2; + uint64_t PAD3; + uint64_t PAD4; + uint64_t PAD5; + uint64_t PAD6; + uint64_t PAD7; + uint64_t Arc4SboxData0; + uint64_t Arc4SboxData1; + uint64_t Arc4SboxData2; + uint64_t Arc4SboxData3; + uint64_t Arc4SboxData4; + uint64_t Arc4SboxData5; + uint64_t Arc4SboxData6; + uint64_t Arc4SboxData7; + uint64_t Arc4SboxData8; + uint64_t Arc4SboxData9; + uint64_t Arc4SboxData10; + uint64_t Arc4SboxData11; + uint64_t Arc4SboxData12; + uint64_t Arc4SboxData13; + uint64_t Arc4SboxData14; + uint64_t Arc4SboxData15; + uint64_t Arc4SboxData16; + uint64_t Arc4SboxData17; + uint64_t Arc4SboxData18; + uint64_t Arc4SboxData19; + uint64_t Arc4SboxData20; + uint64_t Arc4SboxData21; + uint64_t Arc4SboxData22; + uint64_t Arc4SboxData23; + uint64_t Arc4SboxData24; + uint64_t Arc4SboxData25; + uint64_t Arc4SboxData26; + uint64_t Arc4SboxData27; + uint64_t Arc4SboxData28; + uint64_t Arc4SboxData29; + uint64_t Arc4SboxData30; + uint64_t Arc4SboxData31; + uint64_t Arc4IJData; + uint64_t PAD8; + uint64_t PAD9; + uint64_t PAD10; +} ARC4StateGCM_t, *ARC4StateGCM_pt; /* ARC4, F9 - 408 bytes (not including 8 bytes from instruction) */ typedef struct ARC4StateF9_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKey3; - uint64_t authKey0; - uint64_t authKey1; - uint64_t PAD0; - uint64_t PAD1; - uint64_t PAD2; - uint64_t PAD3; - uint64_t PAD4; - uint64_t PAD5; - uint64_t PAD6; - uint64_t PAD7; - uint64_t PAD8; - uint64_t Arc4SboxData0; - uint64_t Arc4SboxData1; - uint64_t Arc4SboxData2; - uint64_t Arc4SboxData3; - uint64_t Arc4SboxData4; - uint64_t Arc4SboxData5; - uint64_t Arc4SboxData6; - uint64_t Arc4SboxData7; - uint64_t Arc4SboxData8; - uint64_t Arc4SboxData9; - uint64_t Arc4SboxData10; - uint64_t Arc4SboxData11; - uint64_t Arc4SboxData12; - uint64_t Arc4SboxData13; - uint64_t Arc4SboxData14; - uint64_t Arc4SboxData15; - uint64_t Arc4SboxData16; - uint64_t Arc4SboxData17; - uint64_t Arc4SboxData18; - uint64_t Arc4SboxData19; - uint64_t Arc4SboxData20; - uint64_t Arc4SboxData21; - uint64_t Arc4SboxData22; - uint64_t Arc4SboxData23; - uint64_t Arc4SboxData24; - uint64_t Arc4SboxData25; - uint64_t Arc4SboxData26; - uint64_t Arc4SboxData27; - uint64_t Arc4SboxData28; - uint64_t Arc4SboxData29; - uint64_t Arc4SboxData30; - uint64_t Arc4SboxData31; - uint64_t Arc4IJData; - uint64_t PAD9; - uint64_t PAD10; - uint64_t PAD11; -} ARC4StateF9_t, *ARC4StateF9_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t authKey0; + uint64_t authKey1; + uint64_t PAD0; + uint64_t PAD1; + uint64_t PAD2; + uint64_t PAD3; + uint64_t PAD4; + uint64_t PAD5; + uint64_t PAD6; + uint64_t PAD7; + uint64_t PAD8; + uint64_t Arc4SboxData0; + uint64_t Arc4SboxData1; + uint64_t Arc4SboxData2; + uint64_t Arc4SboxData3; + uint64_t Arc4SboxData4; + uint64_t Arc4SboxData5; + uint64_t Arc4SboxData6; + uint64_t Arc4SboxData7; + uint64_t Arc4SboxData8; + uint64_t Arc4SboxData9; + uint64_t Arc4SboxData10; + uint64_t Arc4SboxData11; + uint64_t Arc4SboxData12; + uint64_t Arc4SboxData13; + uint64_t Arc4SboxData14; + uint64_t Arc4SboxData15; + uint64_t Arc4SboxData16; + uint64_t Arc4SboxData17; + uint64_t Arc4SboxData18; + uint64_t Arc4SboxData19; + uint64_t Arc4SboxData20; + uint64_t Arc4SboxData21; + uint64_t Arc4SboxData22; + uint64_t Arc4SboxData23; + uint64_t Arc4SboxData24; + uint64_t Arc4SboxData25; + uint64_t Arc4SboxData26; + uint64_t Arc4SboxData27; + uint64_t Arc4SboxData28; + uint64_t Arc4SboxData29; + uint64_t Arc4SboxData30; + uint64_t Arc4SboxData31; + uint64_t Arc4IJData; + uint64_t PAD9; + uint64_t PAD10; + uint64_t PAD11; +} ARC4StateF9_t, *ARC4StateF9_pt; /* ARC4, Non-HMAC (MD5, SHA-1, SHA-256) - 32 bytes */ typedef struct ARC4_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKey3; -} ARC4_t, *ARC4_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; +} ARC4_t, *ARC4_pt; /* ARC4, Non-HMAC (MD5, SHA-1, SHA-256) - 344 bytes (not including 8 bytes from instruction) */ typedef struct ARC4State_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t cipherKey2; - uint64_t cipherKey3; - uint64_t PAD0; - uint64_t PAD1; - uint64_t PAD2; - uint64_t Arc4SboxData0; - uint64_t Arc4SboxData1; - uint64_t Arc4SboxData2; - uint64_t Arc4SboxData3; - uint64_t Arc4SboxData4; - uint64_t Arc4SboxData5; - uint64_t Arc4SboxData6; - uint64_t Arc4SboxData7; - uint64_t Arc4SboxData8; - uint64_t Arc4SboxData9; - uint64_t Arc4SboxData10; - uint64_t Arc4SboxData11; - uint64_t Arc4SboxData12; - uint64_t Arc4SboxData13; - uint64_t Arc4SboxData14; - uint64_t Arc4SboxData15; - uint64_t Arc4SboxData16; - uint64_t Arc4SboxData17; - uint64_t Arc4SboxData18; - uint64_t Arc4SboxData19; - uint64_t Arc4SboxData20; - uint64_t Arc4SboxData21; - uint64_t Arc4SboxData22; - uint64_t Arc4SboxData23; - uint64_t Arc4SboxData24; - uint64_t Arc4SboxData25; - uint64_t Arc4SboxData26; - uint64_t Arc4SboxData27; - uint64_t Arc4SboxData28; - uint64_t Arc4SboxData29; - uint64_t Arc4SboxData30; - uint64_t Arc4SboxData31; - uint64_t Arc4IJData; - uint64_t PAD3; - uint64_t PAD4; - uint64_t PAD5; -} ARC4State_t, *ARC4State_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t cipherKey2; + uint64_t cipherKey3; + uint64_t PAD0; + uint64_t PAD1; + uint64_t PAD2; + uint64_t Arc4SboxData0; + uint64_t Arc4SboxData1; + uint64_t Arc4SboxData2; + uint64_t Arc4SboxData3; + uint64_t Arc4SboxData4; + uint64_t Arc4SboxData5; + uint64_t Arc4SboxData6; + uint64_t Arc4SboxData7; + uint64_t Arc4SboxData8; + uint64_t Arc4SboxData9; + uint64_t Arc4SboxData10; + uint64_t Arc4SboxData11; + uint64_t Arc4SboxData12; + uint64_t Arc4SboxData13; + uint64_t Arc4SboxData14; + uint64_t Arc4SboxData15; + uint64_t Arc4SboxData16; + uint64_t Arc4SboxData17; + uint64_t Arc4SboxData18; + uint64_t Arc4SboxData19; + uint64_t Arc4SboxData20; + uint64_t Arc4SboxData21; + uint64_t Arc4SboxData22; + uint64_t Arc4SboxData23; + uint64_t Arc4SboxData24; + uint64_t Arc4SboxData25; + uint64_t Arc4SboxData26; + uint64_t Arc4SboxData27; + uint64_t Arc4SboxData28; + uint64_t Arc4SboxData29; + uint64_t Arc4SboxData30; + uint64_t Arc4SboxData31; + uint64_t Arc4IJData; + uint64_t PAD3; + uint64_t PAD4; + uint64_t PAD5; +} ARC4State_t, *ARC4State_pt; /* Kasumi f8 - 32 bytes */ typedef struct KASUMIF8_s { - uint64_t cipherKey0; - uint64_t cipherKey1; -} KASUMIF8_t, *KASUMIF8_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; +} KASUMIF8_t, *KASUMIF8_pt; /* Kasumi f8 + HMAC (MD5, SHA-1, SHA-256) - 80 bytes */ typedef struct KASUMIF8HMAC_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; -} KASUMIF8HMAC_t, *KASUMIF8HMAC_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; +} KASUMIF8HMAC_t, *KASUMIF8HMAC_pt; /* Kasumi f8 + HMAC (SHA-384, SHA-512) - 144 bytes */ typedef struct KASUMIF8HMAC2_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t hmacKey0; - uint64_t hmacKey1; - uint64_t hmacKey2; - uint64_t hmacKey3; - uint64_t hmacKey4; - uint64_t hmacKey5; - uint64_t hmacKey6; - uint64_t hmacKey7; - uint64_t hmacKey8; - uint64_t hmacKey9; - uint64_t hmacKey10; - uint64_t hmacKey11; - uint64_t hmacKey12; - uint64_t hmacKey13; - uint64_t hmacKey14; - uint64_t hmacKey15; -} KASUMIF8HMAC2_t, *KASUMIF8HMAC2_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t hmacKey0; + uint64_t hmacKey1; + uint64_t hmacKey2; + uint64_t hmacKey3; + uint64_t hmacKey4; + uint64_t hmacKey5; + uint64_t hmacKey6; + uint64_t hmacKey7; + uint64_t hmacKey8; + uint64_t hmacKey9; + uint64_t hmacKey10; + uint64_t hmacKey11; + uint64_t hmacKey12; + uint64_t hmacKey13; + uint64_t hmacKey14; + uint64_t hmacKey15; +} KASUMIF8HMAC2_t, *KASUMIF8HMAC2_pt; /* Kasumi f8 + GCM - 144 bytes */ typedef struct KASUMIF8GCM_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t GCMH0; - uint64_t GCMH1; - uint64_t GCMSCI; -} KASUMIF8GCM_t, *KASUMIF8GCM_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t GCMH0; + uint64_t GCMH1; + uint64_t GCMSCI; +} KASUMIF8GCM_t, *KASUMIF8GCM_pt; /* Kasumi f8 + f9 - 32 bytes */ typedef struct KASUMIF8F9_s { - uint64_t cipherKey0; - uint64_t cipherKey1; - uint64_t authKey0; - uint64_t authKey1; -} KASUMIF8F9_t, *KASUMIF8F9_pt; + uint64_t cipherKey0; + uint64_t cipherKey1; + uint64_t authKey0; + uint64_t authKey1; +} KASUMIF8F9_t, *KASUMIF8F9_pt; typedef union CipherHashInfo_u { - AES256HMAC_t infoAES256HMAC; - AES256_t infoAES256; - AES192HMAC_t infoAES192HMAC; - AES192_t infoAES192; - AES128HMAC_t infoAES128HMAC; - AES128_t infoAES128; - DESHMAC_t infoDESHMAC; - DES_t infoDES; - DES3HMAC_t info3DESHMAC; - DES3_t info3DES; - HMAC_t infoHMAC; - /* ARC4 */ - ARC4HMAC_t infoARC4HMAC; - ARC4StateHMAC_t infoARC4StateHMAC; - ARC4_t infoARC4; - ARC4State_t infoARC4State; - /* AES mode F8 */ - AES256F8HMAC_t infoAES256F8HMAC; - AES256F8_t infoAES256F8; - AES192F8HMAC_t infoAES192F8HMAC; - AES192F8_t infoAES192F8; - AES128F8HMAC_t infoAES128F8HMAC; - AES128F8_t infoAES128F8; - /* KASUMI F8 */ - KASUMIF8HMAC_t infoKASUMIF8HMAC; - KASUMIF8_t infoKASUMIF8; - /* GCM */ - GCM_t infoGCM; - AES256F8GCM_t infoAES256F8GCM; - AES192F8GCM_t infoAES192F8GCM; - AES128F8GCM_t infoAES128F8GCM; - AES256GCM_t infoAES256GCM; - AES192GCM_t infoAES192GCM; - AES128GCM_t infoAES128GCM; - DESGCM_t infoDESGCM; - DES3GCM_t info3DESGCM; - ARC4GCM_t infoARC4GCM; - ARC4StateGCM_t infoARC4StateGCM; - KASUMIF8GCM_t infoKASUMIF8GCM; - /* HMAC2 */ - HMAC2_t infoHMAC2; - AES256F8HMAC2_t infoAES256F8HMAC2; - AES192F8HMAC2_t infoAES192F8HMAC2; - AES128F8HMAC2_t infoAES128F8HMAC2; - AES256HMAC2_t infoAES256HMAC2; - AES192HMAC2_t infoAES192HMAC2; - AES128HMAC2_t infoAES128HMAC2; - DESHMAC2_t infoDESHMAC2; - DES3HMAC2_t info3DESHMAC2; - ARC4HMAC2_t infoARC4HMAC2; - ARC4StateHMAC2_t infoARC4StateHMAC2; - KASUMIF8HMAC2_t infoKASUMIF8HMAC2; - /* F9 */ - F9_t infoF9; - AES256F8F9_t infoAES256F8F9; - AES192F8F9_t infoAES192F8F9; - AES128F8F9_t infoAES128F8F9; - AES256F9_t infoAES256F9; - AES192F9_t infoAES192F9; - AES128F9_t infoAES128F9; - DESF9_t infoDESF9; - DES3F9_t info3DESF9; - ARC4F9_t infoARC4F9; - ARC4StateF9_t infoARC4StateF9; - KASUMIF8F9_t infoKASUMIF8F9; -} CipherHashInfo_t, *CipherHashInfo_pt; + AES256HMAC_t infoAES256HMAC; + AES256_t infoAES256; + AES192HMAC_t infoAES192HMAC; + AES192_t infoAES192; + AES128HMAC_t infoAES128HMAC; + AES128_t infoAES128; + DESHMAC_t infoDESHMAC; + DES_t infoDES; + DES3HMAC_t info3DESHMAC; + DES3_t info3DES; + HMAC_t infoHMAC; + /* ARC4 */ + ARC4HMAC_t infoARC4HMAC; + ARC4StateHMAC_t infoARC4StateHMAC; + ARC4_t infoARC4; + ARC4State_t infoARC4State; + /* AES mode F8 */ + AES256F8HMAC_t infoAES256F8HMAC; + AES256F8_t infoAES256F8; + AES192F8HMAC_t infoAES192F8HMAC; + AES192F8_t infoAES192F8; + AES128F8HMAC_t infoAES128F8HMAC; + AES128F8_t infoAES128F8; + /* KASUMI F8 */ + KASUMIF8HMAC_t infoKASUMIF8HMAC; + KASUMIF8_t infoKASUMIF8; + /* GCM */ + GCM_t infoGCM; + AES256F8GCM_t infoAES256F8GCM; + AES192F8GCM_t infoAES192F8GCM; + AES128F8GCM_t infoAES128F8GCM; + AES256GCM_t infoAES256GCM; + AES192GCM_t infoAES192GCM; + AES128GCM_t infoAES128GCM; + DESGCM_t infoDESGCM; + DES3GCM_t info3DESGCM; + ARC4GCM_t infoARC4GCM; + ARC4StateGCM_t infoARC4StateGCM; + KASUMIF8GCM_t infoKASUMIF8GCM; + /* HMAC2 */ + HMAC2_t infoHMAC2; + AES256F8HMAC2_t infoAES256F8HMAC2; + AES192F8HMAC2_t infoAES192F8HMAC2; + AES128F8HMAC2_t infoAES128F8HMAC2; + AES256HMAC2_t infoAES256HMAC2; + AES192HMAC2_t infoAES192HMAC2; + AES128HMAC2_t infoAES128HMAC2; + DESHMAC2_t infoDESHMAC2; + DES3HMAC2_t info3DESHMAC2; + ARC4HMAC2_t infoARC4HMAC2; + ARC4StateHMAC2_t infoARC4StateHMAC2; + KASUMIF8HMAC2_t infoKASUMIF8HMAC2; + /* F9 */ + F9_t infoF9; + AES256F8F9_t infoAES256F8F9; + AES192F8F9_t infoAES192F8F9; + AES128F8F9_t infoAES128F8F9; + AES256F9_t infoAES256F9; + AES192F9_t infoAES192F9; + AES128F9_t infoAES128F9; + DESF9_t infoDESF9; + DES3F9_t info3DESF9; + ARC4F9_t infoARC4F9; + ARC4StateF9_t infoARC4StateF9; + KASUMIF8F9_t infoKASUMIF8F9; +} CipherHashInfo_t, *CipherHashInfo_pt; -/* - * - * ControlDescriptor_s datastructure - * +/* + * + * ControlDescriptor_s datastructure + * */ typedef struct ControlDescriptor_s { - uint64_t instruction; - CipherHashInfo_t cipherHashInfo; -} ControlDescriptor_t, *ControlDescriptor_pt; + uint64_t instruction; + CipherHashInfo_t cipherHashInfo; +} ControlDescriptor_t, *ControlDescriptor_pt; @@ -1877,7 +1877,7 @@ typedef struct ControlDescriptor_s { * PacketDescriptor_t.srcLengthIVOffUseIVNext * ------------------------------------------ * - * 63 62 61 59 58 57 56 54 53 43 + * 63 62 61 59 58 57 56 54 53 43 * ------------------------------------------------------------------------------------------------ * || Load HMAC key || Pad Hash || Hash Byte Count || Next || Use IV || IV Offset || Packet length || ... CONT ... * ------------------------------------------------------------------------------------------------ @@ -1920,7 +1920,7 @@ typedef struct ControlDescriptor_s { * On subsequent frags: Do write out to DST the (dword) offset data * IV Offset = On first frag: Offset IN NB OF 8 BYTE WORDS (dwords) from beginning of packet * (i.e. (Potentially byte-shifted) Segment address) to cipher IV - * On subsequent frags: Offset to beginning of data to process; data to offset won't + * On subsequent frags: Offset to beginning of data to process; data to offset won't * be given to engines and will be written out to dst in the clear. * ON SUBSEQUENT FRAGS, IV_Offset MAY NOT EXCEED 3; LARGER VALUES WILL CAUSE AN ERROR * SEE ERROR CONDITIONS BELOW @@ -1977,17 +1977,17 @@ typedef struct ControlDescriptor_s { * E/D = 1'b0 Decrypt * 1'b1 Encrypt * Overloaded to also mean IV byte offset for first frag - * Cipher_Offset = Nb of words between the first data segment + * Cipher_Offset = Nb of words between the first data segment * and word on which to start cipher operation * (64 BIT WORDS !!!) * Hash_Offset = Nb of words between the first data segment - * and word on which to start hashing + * and word on which to start hashing * (64 bit words) * Hash_Src = 1'b0 DMA channel - * 1'b1 Cipher if word count exceeded Cipher_Offset; + * 1'b1 Cipher if word count exceeded Cipher_Offset; * DMA channel otherwise - * CkSum_Offset = Nb of words between the first data segment - * and word on which to start + * CkSum_Offset = Nb of words between the first data segment + * and word on which to start * checksum calculation (32 BIT WORDS !!!) * CkSum_Src = 1'b0 DMA channel * 1'b1 Cipher if word count exceeded Cipher_Offset @@ -2000,7 +2000,7 @@ typedef struct ControlDescriptor_s { * PacketDescriptor_t.authDstNonceLow * ---------------------------------- * - * 63 40 39 5 4 0 + * 63 40 39 5 4 0 * ----------------------------------------------------- * || Nonce_Low || Auth_dst_address || Cipher_Offset_Hi || * ----------------------------------------------------- @@ -2070,7 +2070,7 @@ ected) regular CTR /* #define PKT_DSC_PADHASH */ #define PKT_DSC_PADHASH_PADDED 0 -#define PKT_DSC_PADHASH_PAD 1 /* requires padding */ +#define PKT_DSC_PADHASH_PAD 1 /* requires padding */ #define PKT_DSC_PADHASH_LSB 62 #define PKT_DSC_PADHASH_BITS ONE_BIT #define PKT_DSC_PADHASH_MASK (PKT_DSC_PADHASH_BITS << PKT_DSC_PADHASH_LSB) @@ -2128,7 +2128,7 @@ ected) regular CTR #define PKT_DSC_WAIT_MASK (PKT_DSC_WAIT_BITS << PKT_DSC_WAIT_LSB) /* #define PKT_DSC_SEGADDR */ -#define PKT_DSC_SEGADDR_LSB 5 +#define PKT_DSC_SEGADDR_LSB 5 #define PKT_DSC_SEGADDR_BITS FOURTY_BITS #define PKT_DSC_SEGADDR_MASK \ (PKT_DSC_SEGADDR_BITS << PKT_DSC_SEGADDR_LSB) @@ -2156,24 +2156,24 @@ ected) regular CTR #define PKT_DSC_ARC4BYTECOUNT_LSB 60 #define PKT_DSC_ARC4BYTECOUNT_BITS THREE_BITS #define PKT_DSC_ARC4BYTECOUNT_MASK (PKT_DSC_ARC4BYTECOUNT_BITS << PKT_DSC_ARC4BYTECOUNT_LSB) - + /* #define PKT_DSC_SYM_OP (symmetric key operation) */ #define PKT_DSC_SYM_OP_DECRYPT 0 #define PKT_DSC_SYM_OP_ENCRYPT 1 #define PKT_DSC_SYM_OP_LSB 59 #define PKT_DSC_SYM_OP_BITS ONE_BIT #define PKT_DSC_SYM_OP_MASK (PKT_DSC_SYM_OP_BITS << PKT_DSC_SYM_OP_LSB) - + /* #define PKT_DSC_CPHROFF */ #define PKT_DSC_CPHROFF_LSB 56 #define PKT_DSC_CPHROFF_BITS THREE_BITS #define PKT_DSC_CPHROFF_MASK (PKT_DSC_CPHROFF_BITS << PKT_DSC_CPHROFF_LSB) - + /* #define PKT_DSC_HASHOFF */ #define PKT_DSC_HASHOFF_LSB 54 #define PKT_DSC_HASHOFF_BITS TWO_BITS #define PKT_DSC_HASHOFF_MASK (PKT_DSC_HASHOFF_BITS << PKT_DSC_HASHOFF_LSB) - + /* #define PKT_DSC_HASHSRC */ #define PKT_DSC_HASHSRC_DMA 0 #define PKT_DSC_HASHSRC_CIPHER 1 @@ -2185,7 +2185,7 @@ ected) regular CTR #define PKT_DSC_CKSUMOFF_LSB 41 #define PKT_DSC_CKSUMOFF_BITS TWELVE_BITS #define PKT_DSC_CKSUMOFF_MASK (PKT_DSC_CKSUMOFF_BITS << PKT_DSC_CKSUMOFF_LSB) - + /* #define PKT_DSC_CKSUMSRC */ #define PKT_DSC_CKSUMSRC_DMA 0 #define PKT_DSC_CKSUMSRC_CIPHER 1 @@ -2254,12 +2254,12 @@ ected) regular CTR #define PKT_DSC_LASTWORD_LSB 56 #define PKT_DSC_LASTWORD_BITS TWO_BITS #define PKT_DSC_LASTWORD_MASK (PKT_DSC_LASTWORD_BITS << PKT_DSC_LASTWORD_LSB) - + /* #define PKT_DSC_CFB_MASK */ #define PKT_DSC_CFB_MASK_LSB 48 #define PKT_DSC_CFB_MASK_BITS EIGHT_BITS #define PKT_DSC_CFB_MASK_MASK (PKT_DSC_CFB_MASK_BITS << PKT_DSC_CFB_MASK_LSB) - + /* #define PKT_DSC_NONCE_HI */ #define PKT_DSC_NONCE_HI_LSB 40 #define PKT_DSC_NONCE_HI_BITS EIGHT_BITS @@ -2280,100 +2280,100 @@ ected) regular CTR * Control Error Code and Conditions * ****************************************************************** */ -#define CTL_ERR_NONE 0x0000 /* No Error */ -#define CTL_ERR_CIPHER_OP 0x0001 /* Unknown Cipher Op */ -#define CTL_ERR_MODE 0x0002 /* Unknown or Not Allowed Mode */ -#define CTL_ERR_CHKSUM_SRC 0x0004 /* Unknown CkSum Src - UNUSED */ -#define CTL_ERR_CFB_MASK 0x0008 /* Forbidden CFB Mask - UNUSED */ -#define CTL_ERR_OP 0x0010 /* Unknown Ctrl Op - UNUSED */ -#define CTL_ERR_UNDEF1 0x0020 /* UNUSED */ -#define CTL_ERR_UNDEF2 0x0040 /* UNUSED */ -#define CTL_ERR_DATA_READ 0x0080 /* Data Read Error */ -#define CTL_ERR_DESC_CTRL 0x0100 /* Descriptor Ctrl Field Error */ +#define CTL_ERR_NONE 0x0000 /* No Error */ +#define CTL_ERR_CIPHER_OP 0x0001 /* Unknown Cipher Op */ +#define CTL_ERR_MODE 0x0002 /* Unknown or Not Allowed Mode */ +#define CTL_ERR_CHKSUM_SRC 0x0004 /* Unknown CkSum Src - UNUSED */ +#define CTL_ERR_CFB_MASK 0x0008 /* Forbidden CFB Mask - UNUSED */ +#define CTL_ERR_OP 0x0010 /* Unknown Ctrl Op - UNUSED */ +#define CTL_ERR_UNDEF1 0x0020 /* UNUSED */ +#define CTL_ERR_UNDEF2 0x0040 /* UNUSED */ +#define CTL_ERR_DATA_READ 0x0080 /* Data Read Error */ +#define CTL_ERR_DESC_CTRL 0x0100 /* Descriptor Ctrl Field Error */ -#define CTL_ERR_TIMEOUT 0x1000 /* Message Response Timeout */ +#define CTL_ERR_TIMEOUT 0x1000 /* Message Response Timeout */ /* ****************************************************************** * Data Error Code and Conditions * ****************************************************************** */ -#define DATA_ERR_NONE 0x0000 /* No Error */ -#define DATA_ERR_LEN_CIPHER 0x0001 /* Not Enough Data To Cipher */ -#define DATA_ERR_IV_ADDR 0x0002 /* Illegal IV Loacation */ -#define DATA_ERR_WD_LEN_AES 0x0004 /* Illegal Nb Words To AES */ -#define DATA_ERR_BYTE_COUNT 0x0008 /* Illegal Pad And ByteCount Spec */ -#define DATA_ERR_LEN_CKSUM 0x0010 /* Not Enough Data To CkSum */ -#define DATA_ERR_OP 0x0020 /* Unknown Data Op */ -#define DATA_ERR_UNDEF1 0x0040 /* UNUSED */ -#define DATA_ERR_READ 0x0080 /* Data Read Error */ -#define DATA_ERR_WRITE 0x0100 /* Data Write Error */ +#define DATA_ERR_NONE 0x0000 /* No Error */ +#define DATA_ERR_LEN_CIPHER 0x0001 /* Not Enough Data To Cipher */ +#define DATA_ERR_IV_ADDR 0x0002 /* Illegal IV Loacation */ +#define DATA_ERR_WD_LEN_AES 0x0004 /* Illegal Nb Words To AES */ +#define DATA_ERR_BYTE_COUNT 0x0008 /* Illegal Pad And ByteCount Spec */ +#define DATA_ERR_LEN_CKSUM 0x0010 /* Not Enough Data To CkSum */ +#define DATA_ERR_OP 0x0020 /* Unknown Data Op */ +#define DATA_ERR_UNDEF1 0x0040 /* UNUSED */ +#define DATA_ERR_READ 0x0080 /* Data Read Error */ +#define DATA_ERR_WRITE 0x0100 /* Data Write Error */ /* - * Common Descriptor + * Common Descriptor * NOTE: Size of struct is size of cacheline. */ typedef struct OperationDescriptor_s { - uint64_t phys_self; - uint32_t stn_id; - uint32_t flags; - uint32_t cpu; - uint32_t seq_num; - uint64_t reserved; -} OperationDescriptor_t, *OperationDescriptor_pt; + uint64_t phys_self; + uint32_t stn_id; + uint32_t flags; + uint32_t cpu; + uint32_t seq_num; + uint64_t reserved; +} OperationDescriptor_t, *OperationDescriptor_pt; /* * This defines the security data descriptor format */ typedef struct PacketDescriptor_s { - uint64_t srcLengthIVOffUseIVNext; - uint64_t dstDataSettings; - uint64_t authDstNonceLow; - uint64_t ckSumDstNonceHiCFBMaskLLWMask; -} PacketDescriptor_t, *PacketDescriptor_pt; + uint64_t srcLengthIVOffUseIVNext; + uint64_t dstDataSettings; + uint64_t authDstNonceLow; + uint64_t ckSumDstNonceHiCFBMaskLLWMask; +} PacketDescriptor_t, *PacketDescriptor_pt; typedef struct { - uint8_t *user_auth; - uint8_t *user_src; - uint8_t *user_dest; - uint8_t *user_state; - uint8_t *kern_auth; - uint8_t *kern_src; - uint8_t *kern_dest; - uint8_t *kern_state; - uint8_t *aligned_auth; - uint8_t *aligned_src; - uint8_t *aligned_dest; - uint8_t *aligned_state; -} xlr_sec_drv_user_t, *xlr_sec_drv_user_pt; + uint8_t *user_auth; + uint8_t *user_src; + uint8_t *user_dest; + uint8_t *user_state; + uint8_t *kern_auth; + uint8_t *kern_src; + uint8_t *kern_dest; + uint8_t *kern_state; + uint8_t *aligned_auth; + uint8_t *aligned_src; + uint8_t *aligned_dest; + uint8_t *aligned_state; +} xlr_sec_drv_user_t, *xlr_sec_drv_user_pt; typedef struct symkey_desc { - OperationDescriptor_t op_ctl; /* size is cacheline */ - PacketDescriptor_t pkt_desc[2]; /* size is cacheline */ - ControlDescriptor_t ctl_desc; /* makes this aligned */ - uint64_t control; /* message word0 */ - uint64_t data; /* message word1 */ - uint64_t ctl_result; - uint64_t data_result; - struct symkey_desc *alloc; /* real allocated addr */ - xlr_sec_drv_user_t user; -// volatile atomic_t flag_complete; -// struct semaphore sem_complete; -// wait_queue_t submit_wait; - - uint8_t *next_src_buf; - uint32_t next_src_len; + OperationDescriptor_t op_ctl; /* size is cacheline */ + PacketDescriptor_t pkt_desc[2]; /* size is cacheline */ + ControlDescriptor_t ctl_desc; /* makes this aligned */ + uint64_t control; /* message word0 */ + uint64_t data; /* message word1 */ + uint64_t ctl_result; + uint64_t data_result; + struct symkey_desc *alloc; /* real allocated addr */ + xlr_sec_drv_user_t user; + //volatile atomic_t flag_complete; + //struct semaphore sem_complete; + //wait_queue_t submit_wait; - uint8_t *next_dest_buf; - uint32_t next_dest_len; - - uint8_t* next_auth_dest; - uint8_t* next_cksum_dest; + uint8_t *next_src_buf; + uint32_t next_src_len; - void* ses; -} symkey_desc_t, *symkey_desc_pt; + uint8_t *next_dest_buf; + uint32_t next_dest_len; + + uint8_t *next_auth_dest; + uint8_t *next_cksum_dest; + + void *ses; +} symkey_desc_t, *symkey_desc_pt; /* @@ -2406,7 +2406,7 @@ typedef struct symkey_desc { * Op Class = 7'h0_0 Modular exponentiation * 7'h0_1 ECC (including prime modular ops and binary GF ops) * REMAINDER UNDEF - * + * * Valid Op = 1'b1 Will cause operation to start; descriptors sent back at end of operation * 1'b0 No operation performed; descriptors sent back right away * @@ -2420,7 +2420,7 @@ typedef struct symkey_desc { * Block Width = 1'b1 1024 bit op * = 1'b0 512 bit op * Load Constant = 1'b1 Load constant from data structure - * 1'b0 Preserve old constant (this assumes + * 1'b0 Preserve old constant (this assumes * Source Addr points to RSAData_pt->Exponent * or that the length of Constant is 0) * Exponent Width = 11-bit expression of exponent width EXPRESSED IN NUMBER OF BITS @@ -2483,11 +2483,11 @@ typedef struct symkey_desc { * Software Scratch1 = Two bit field ignored by engine and returned as is in free descriptor * * Global dst data offset = Nb BYTES to left-shift (double-word boundary aligned) data by before writing it to memory - * + * * */ -/* +/* * ECC data formats */ @@ -2510,8 +2510,8 @@ typedef struct symkey_desc { * 224, 256) or 8 dwords (384, 512) * * The total lengths in dwords that are read and in - * bytes that are written, for each operation and - * length group, are specified at the bottom of each + * bytes that are written, for each operation and + * length group, are specified at the bottom of each * datastructure. * * In all that follows, m is the modulus and cst is the constant, @@ -2538,7 +2538,7 @@ typedef struct symkey_desc { * y_p 2x(3/4/6/8)= * y_p 6/8/12/16 dw * a - * k + * k * m * cst * 7x(3/4/6/8)+(4/4/8/8)= @@ -2705,7 +2705,7 @@ typedef struct symkey_desc { */ /* - * IMPORTANT NOTE: + * IMPORTANT NOTE: * * As specified in the datastructures below, * the engine assumes all data (including @@ -2847,13 +2847,13 @@ typedef struct symkey_desc { (PUBKEY_CTL_EXPWIDTH_BITS << PUBKEY_CTL_EXPWIDTH_LSB) /* #define PUBKEY_CTL_SRCADDR */ -#define PUBKEY_CTL_SRCADDR_LSB 0 +#define PUBKEY_CTL_SRCADDR_LSB 0 #define PUBKEY_CTL_SRCADDR_BITS FOURTY_BITS #define PUBKEY_CTL_SRCADDR_MASK \ (PUBKEY_CTL_SRCADDR_BITS << PUBKEY_CTL_SRCADDR_LSB) /* #define PUBKEY_CTL_SRC_OFFSET */ -#define PUBKEY_CTL_SRC_OFFSET_LSB 0 +#define PUBKEY_CTL_SRC_OFFSET_LSB 0 #define PUBKEY_CTL_SRC_OFFSET_BITS THREE_BITS #define PUBKEY_CTL_SRC_OFFSET_MASK \ (PUBKEY_CTL_SRC_OFFSET_BITS << PUBKEY_CTL_SRC_OFFSET_LSB) @@ -2865,7 +2865,7 @@ typedef struct symkey_desc { #define PUBKEY_CTL1_CTL_MASK (PUBKEY_CTL_CTL_BITS << PUBKEY_CTL_CTL_LSB) /* #define PUBKEY_CTL1_MODWIDTH */ -#define PUBKEY_CTL1_MODWIDTH_LSB 40 +#define PUBKEY_CTL1_MODWIDTH_LSB 40 #define PUBKEY_CTL1_MODWIDTH_BITS ELEVEN_BITS #define PUBKEY_CTL1_MODWIDTH_MASK \ (PUBKEY_CTL1_MODWIDTH_BITS << PUBKEY_CTL1_MODWIDTH_LSB) @@ -2953,13 +2953,13 @@ typedef struct symkey_desc { #define PUBKEY_RSLT_CTL_ERROR_BITS NINE_BITS #define PUBKEY_RSLT_CTL_ERROR_MASK \ (PUBKEY_RSLT_CTL_ERROR_BITS << PUBKEY_RSLT_CTL_ERROR_LSB) - + /* #define PUBKEY_RSLT_CTL_SRCADDR */ #define PUBKEY_RSLT_CTL_SRCADDR_LSB 0 #define PUBKEY_RSLT_CTL_SRCADDR_BITS FOURTY_BITS #define PUBKEY_RSLT_CTL_SRCADDR_MASK \ (PUBKEY_RSLT_CTL_SRCADDR_BITS << PUBKEY_RSLT_CTL_SRCADDR_LSB) - + /* #define PUBKEY_RSLT_DATA_CTL */ #define PUBKEY_RSLT_DATA_CTL_LSB 61 @@ -2984,32 +2984,33 @@ typedef struct symkey_desc { #define PUBKEY_RSLT_DATA_ERROR_BITS NINE_BITS #define PUBKEY_RSLT_DATA_ERROR_MASK \ (PUBKEY_RSLT_DATA_ERROR_BITS << PUBKEY_RSLT_DATA_ERROR_LSB) - + /* #define PUBKEY_RSLT_DATA_DSTADDR */ #define PUBKEY_RSLT_DATA_DSTADDR_LSB 40 #define PUBKEY_RSLT_DATA_DSTADDR_BITS FOURTY_BITS #define PUBKEY_RSLT_DATA_DSTADDR_MASK \ (PUBKEY_RSLT_DATA_DSTADDR_BITS << PUBKEY_RSLT_DATA_DSTADDR_LSB) -/* +/* * ****************************************************************** * RSA Block - Data Error Code and Conditions * ****************************************************************** */ -#define PK_CTL_ERR_NONE 0x0000 /* No Error */ -#define PK_CTL_ERR_OP_CLASS 0x0001 /* Undefined Op Class */ -#define PK_CTL_ERR_ECC_TYPE 0x0002 /* Undefined ECC TYPE (ECC only) */ -#define PK_CTL_ERR_ECC_FUNCT 0x0004 /* Undefined ECC FUNCTION (ECC only) */ -#define PK_CTL_ERR_ECC_TIMEOUT 0x0008 /* ECC timeout (ECC only) */ -#define PK_CTL_ERR_READ 0x0080 /* Data Read Error */ -#define PK_CTL_ERR_DESC 0x0100 /* Descriptor Ctrl Field Error (D0.Ctrl != SOP || D1.Ctrl != EOP) */ -#define PK_CTL_ERR_TIMEOUT 0x1000 /* Message Responce Timeout */ +#define PK_CTL_ERR_NONE 0x0000 /* No Error */ +#define PK_CTL_ERR_OP_CLASS 0x0001 /* Undefined Op Class */ +#define PK_CTL_ERR_ECC_TYPE 0x0002 /* Undefined ECC TYPE (ECC only) */ +#define PK_CTL_ERR_ECC_FUNCT 0x0004 /* Undefined ECC FUNCTION (ECC only) */ +#define PK_CTL_ERR_ECC_TIMEOUT 0x0008 /* ECC timeout (ECC only) */ +#define PK_CTL_ERR_READ 0x0080 /* Data Read Error */ +#define PK_CTL_ERR_DESC 0x0100 /* Descriptor Ctrl Field Error + * (D0.Ctrl != SOP || D1.Ctrl != EOP) */ +#define PK_CTL_ERR_TIMEOUT 0x1000 /* Message Responce Timeout */ -#define PK_DATA_ERR_NONE 0x0000 /* No Error */ -#define PK_DATA_ERR_EXP_WIDTH 0x0001 /* Exponent Width > Block Width */ -#define PK_DATA_ERR_MOD_WIDTH 0x0002 /* Modulus Width > Block Width */ -#define PK_DATA_ERR_READ 0x0080 /* Data Read Error */ +#define PK_DATA_ERR_NONE 0x0000 /* No Error */ +#define PK_DATA_ERR_EXP_WIDTH 0x0001 /* Exponent Width > Block Width */ +#define PK_DATA_ERR_MOD_WIDTH 0x0002 /* Modulus Width > Block Width */ +#define PK_DATA_ERR_READ 0x0080 /* Data Read Error */ /* @@ -3028,25 +3029,25 @@ typedef struct symkey_desc { */ typedef struct UserPubData_s { - uint8_t *source; - uint8_t *user_result; - uint32_t result_length; -} UserPubData_t, *UserPubData_pt; + uint8_t *source; + uint8_t *user_result; + uint32_t result_length; +} UserPubData_t, *UserPubData_pt; typedef struct pubkey_desc { - OperationDescriptor_t op_ctl; /* size is cacheline */ - uint8_t source[1024]; - uint8_t dest[256]; /* 1024 makes cacheline-aligned */ - uint64_t control0; - uint64_t control1; - uint64_t ctl_result; - uint64_t data_result; - struct pubkey_desc *alloc; - UserPubData_t kern; /* ptrs for temp buffers */ -// volatile atomic_t flag_complete; -// struct semaphore sem_complete; -// wait_queue_t submit_wait; -} pubkey_desc_t, *pubkey_desc_pt; + OperationDescriptor_t op_ctl; /* size is cacheline */ + uint8_t source[1024]; + uint8_t dest[256]; /* 1024 makes cacheline-aligned */ + uint64_t control0; + uint64_t control1; + uint64_t ctl_result; + uint64_t data_result; + struct pubkey_desc *alloc; + UserPubData_t kern; /* ptrs for temp buffers */ + //volatile atomic_t flag_complete; + //struct semaphore sem_complete; + //wait_queue_t submit_wait; +} pubkey_desc_t, *pubkey_desc_pt; /* * KASUMI F8 and F9 use the IV0/IV1 fields : @@ -3054,7 +3055,7 @@ typedef struct pubkey_desc { * 63 41 40 39 37 36 32 31 0 * ---------------------------------------------------------------------------- * | |FX/DIRECTION| | F8/BEARER | F8/COUNT | IV0 - * ---------------------------------------------------------------------------- + * ---------------------------------------------------------------------------- * 1 5 32 * * 63 32 31 0 @@ -3063,4 +3064,4 @@ typedef struct pubkey_desc { * ---------------------------------------------------------------------------- * 32 32 */ -#endif /* _XLR_SEC_DESC_H_ */ +#endif /* _XLR_SEC_DESC_H_ */ diff --git a/sys/dev/rmi/sec/rmilib.c b/sys/dev/rmi/sec/rmilib.c index a2eda2bc959..219ef6c9383 100644 --- a/sys/dev/rmi/sec/rmilib.c +++ b/sys/dev/rmi/sec/rmilib.c @@ -58,67 +58,74 @@ #include -//static int msgrng_stnid_pk0 = MSGRNG_STNID_PK0; +// static int msgrng_stnid_pk0 = MSGRNG_STNID_PK0; + /*#define RMI_SEC_DEBUG */ #define SMP_CACHE_BYTES XLR_CACHELINE_SIZE #define NUM_CHUNKS(size, bits) ( ((size)>>(bits)) + (((size)&((1<<(bits))-1))?1:0) ) static const char nib2hex[] = "0123456789ABCDEF"; -symkey_desc_pt g_desc; -struct xlr_sec_command *g_cmd; +symkey_desc_pt g_desc; +struct xlr_sec_command *g_cmd; #ifdef XLR_SEC_CMD_DEBUG static void -decode_symkey_desc (symkey_desc_pt desc, uint32_t cfg_vector); + decode_symkey_desc(symkey_desc_pt desc, uint32_t cfg_vector); + #endif -void print_buf (char *desc, void *data, int len); +void print_buf(char *desc, void *data, int len); static int -xlr_sec_cipher_hash_command(xlr_sec_io_pt op, symkey_desc_pt desc, uint8_t ); + xlr_sec_cipher_hash_command(xlr_sec_io_pt op, symkey_desc_pt desc, uint8_t); -static xlr_sec_error_t -xlr_sec_setup_descriptor (xlr_sec_io_pt op, - unsigned int flags, - symkey_desc_pt desc, - uint32_t *cfg_vector); +static xlr_sec_error_t +xlr_sec_setup_descriptor(xlr_sec_io_pt op, + unsigned int flags, + symkey_desc_pt desc, + uint32_t * cfg_vector); static -xlr_sec_error_t xlr_sec_setup_packet (xlr_sec_io_pt op, - symkey_desc_pt desc, - unsigned int flags, - uint64_t *data, - PacketDescriptor_pt pkt_desc, - ControlDescriptor_pt ctl_desc, - uint32_t vector, - PacketDescriptor_pt next_pkt_desc, - uint8_t multi_frag_flag); +xlr_sec_error_t +xlr_sec_setup_packet(xlr_sec_io_pt op, + symkey_desc_pt desc, + unsigned int flags, + uint64_t * data, + PacketDescriptor_pt pkt_desc, + ControlDescriptor_pt ctl_desc, + uint32_t vector, + PacketDescriptor_pt next_pkt_desc, + uint8_t multi_frag_flag); -static int -xlr_sec_submit_message(symkey_desc_pt desc, uint32_t cfg_vector); +static int + xlr_sec_submit_message(symkey_desc_pt desc, uint32_t cfg_vector); static -xlr_sec_error_t xlr_sec_setup_cipher(xlr_sec_io_pt op, - ControlDescriptor_pt ctl_desc, - uint32_t *vector); +xlr_sec_error_t +xlr_sec_setup_cipher(xlr_sec_io_pt op, + ControlDescriptor_pt ctl_desc, + uint32_t * vector); static -xlr_sec_error_t xlr_sec_setup_digest(xlr_sec_io_pt op, - ControlDescriptor_pt ctl_desc, - uint32_t *vector); +xlr_sec_error_t +xlr_sec_setup_digest(xlr_sec_io_pt op, + ControlDescriptor_pt ctl_desc, + uint32_t * vector); static -xlr_sec_error_t xlr_sec_setup_cksum(xlr_sec_io_pt op, - ControlDescriptor_pt ctl_desc); +xlr_sec_error_t +xlr_sec_setup_cksum(xlr_sec_io_pt op, + ControlDescriptor_pt ctl_desc); static -xlr_sec_error_t xlr_sec_control_setup (xlr_sec_io_pt op, - unsigned int flags, - uint64_t *control, - ControlDescriptor_pt ctl_desc, - xlr_sec_drv_user_t *user, - uint32_t vector); +xlr_sec_error_t +xlr_sec_control_setup(xlr_sec_io_pt op, + unsigned int flags, + uint64_t * control, + ControlDescriptor_pt ctl_desc, + xlr_sec_drv_user_t * user, + uint32_t vector); xlr_sec_error_t @@ -126,3068 +133,3040 @@ xlr_sec_submit_op(symkey_desc_pt desc); static void xlr_sec_free_desc(symkey_desc_pt desc); -void xlr_sec_msgring_handler(int bucket, int size, int code, int stid, - struct msgrng_msg *msg, void *data); +void +xlr_sec_msgring_handler(int bucket, int size, int code, int stid, + struct msgrng_msg *msg, void *data); -void xlr_sec_init( struct xlr_sec_softc *sc) +void +xlr_sec_init(struct xlr_sec_softc *sc) { - unsigned int i; - xlr_reg_t* mmio; + unsigned int i; + xlr_reg_t *mmio; - mmio = sc->mmio = xlr_io_mmio( XLR_IO_SECURITY_OFFSET ) ; + mmio = sc->mmio = xlr_io_mmio(XLR_IO_SECURITY_OFFSET); - xlr_write_reg(mmio, SEC_DMA_CREDIT, SEC_DMA_CREDIT_CONFIG); + xlr_write_reg(mmio, SEC_DMA_CREDIT, SEC_DMA_CREDIT_CONFIG); - xlr_write_reg(mmio, SEC_CONFIG2, SEC_CFG2_ROUND_ROBIN_ON); + xlr_write_reg(mmio, SEC_CONFIG2, SEC_CFG2_ROUND_ROBIN_ON); - for(i = 0; i < 8; i++) - xlr_write_reg (mmio, - SEC_MSG_BUCKET0_SIZE + i, - xlr_is_xls() ? - xls_bucket_sizes.bucket[MSGRNG_STNID_SEC + i]: - bucket_sizes.bucket[MSGRNG_STNID_SEC + i]); + for (i = 0; i < 8; i++) + xlr_write_reg(mmio, + SEC_MSG_BUCKET0_SIZE + i, + xlr_is_xls() ? + xls_bucket_sizes.bucket[MSGRNG_STNID_SEC + i] : + bucket_sizes.bucket[MSGRNG_STNID_SEC + i]); - for(i = 0; i < 128; i++) - xlr_write_reg (mmio, - SEC_CC_CPU0_0 + i, - xlr_is_xls() ? - xls_cc_table_sec.counters[i>>3][i&0x07]: - cc_table_sec.counters[i>>3][i&0x07]); + for (i = 0; i < 128; i++) + xlr_write_reg(mmio, + SEC_CC_CPU0_0 + i, + xlr_is_xls() ? + xls_cc_table_sec.counters[i >> 3][i & 0x07] : + cc_table_sec.counters[i >> 3][i & 0x07]); - /* - * Register a bucket handler with the phoenix messaging subsystem - * For now, register handler for bucket 0->5 in msg stn 0 - */ - if (register_msgring_handler(TX_STN_SAE, xlr_sec_msgring_handler,NULL)) { - panic("Couldn't register msgring handler 0\n"); - } - - return ; + /* + * Register a bucket handler with the phoenix messaging subsystem + * For now, register handler for bucket 0->5 in msg stn 0 + */ + if (register_msgring_handler(TX_STN_SAE, xlr_sec_msgring_handler, NULL)) { + panic("Couldn't register msgring handler 0\n"); + } + return; } -int xlr_sec_setup( struct xlr_sec_session* ses, - struct xlr_sec_command *cmd, - symkey_desc_pt desc - ) +int +xlr_sec_setup(struct xlr_sec_session *ses, + struct xlr_sec_command *cmd, + symkey_desc_pt desc +) { - xlr_sec_io_pt op; - int size, ret_val; - int iv_len; + xlr_sec_io_pt op; + int size, ret_val; + int iv_len; - desc->ses = ses; - op = &cmd->op ; - if(op == NULL) - return (-ENOMEM); + desc->ses = ses; + op = &cmd->op; + if (op == NULL) + return (-ENOMEM); - desc->ctl_desc.instruction = 0; - memset(&desc->ctl_desc.cipherHashInfo ,0 , sizeof(CipherHashInfo_t)); - desc->control = 0; + desc->ctl_desc.instruction = 0; + memset(&desc->ctl_desc.cipherHashInfo, 0, sizeof(CipherHashInfo_t)); + desc->control = 0; - desc->pkt_desc[0].srcLengthIVOffUseIVNext = 0; - desc->pkt_desc[0].dstDataSettings = 0; - desc->pkt_desc[0].authDstNonceLow = 0; - desc->pkt_desc[0].ckSumDstNonceHiCFBMaskLLWMask = 0; - desc->pkt_desc[1].srcLengthIVOffUseIVNext = 0; - desc->pkt_desc[1].dstDataSettings = 0; - desc->pkt_desc[1].authDstNonceLow = 0; - desc->pkt_desc[1].ckSumDstNonceHiCFBMaskLLWMask = 0; + desc->pkt_desc[0].srcLengthIVOffUseIVNext = 0; + desc->pkt_desc[0].dstDataSettings = 0; + desc->pkt_desc[0].authDstNonceLow = 0; + desc->pkt_desc[0].ckSumDstNonceHiCFBMaskLLWMask = 0; + desc->pkt_desc[1].srcLengthIVOffUseIVNext = 0; + desc->pkt_desc[1].dstDataSettings = 0; + desc->pkt_desc[1].authDstNonceLow = 0; + desc->pkt_desc[1].ckSumDstNonceHiCFBMaskLLWMask = 0; - desc->data = 0; - desc->ctl_result = 0; - desc->data_result = 0; + desc->data = 0; + desc->ctl_result = 0; + desc->data_result = 0; - if (op->flags & XLR_SEC_FLAGS_HIGH_PRIORITY) - if (!xlr_is_xls()) - desc->op_ctl.stn_id++; + if (op->flags & XLR_SEC_FLAGS_HIGH_PRIORITY) + if (!xlr_is_xls()) + desc->op_ctl.stn_id++; - desc->user.user_src = (uint8_t *)(unsigned long)op->source_buf; - desc->user.user_dest = (uint8_t *)(unsigned long)op->dest_buf; - desc->user.user_auth = (uint8_t *)(unsigned long)op->auth_dest; + desc->user.user_src = (uint8_t *) (unsigned long)op->source_buf; + desc->user.user_dest = (uint8_t *) (unsigned long)op->dest_buf; + desc->user.user_auth = (uint8_t *) (unsigned long)op->auth_dest; - if ((op->cipher_type == XLR_SEC_CIPHER_TYPE_ARC4) && - (!op->rc4_state && (op->rc4_loadstate || op->rc4_savestate))) { - printf(" ** Load/Save State and no State **"); - xlr_sec_free_desc(desc); - return (-EINVAL); - } - desc->user.user_state = (uint8_t *)(unsigned long)op->rc4_state; + if ((op->cipher_type == XLR_SEC_CIPHER_TYPE_ARC4) && + (!op->rc4_state && (op->rc4_loadstate || op->rc4_savestate))) { + printf(" ** Load/Save State and no State **"); + xlr_sec_free_desc(desc); + return (-EINVAL); + } + desc->user.user_state = (uint8_t *) (unsigned long)op->rc4_state; - switch (op->cipher_type) { - case XLR_SEC_CIPHER_TYPE_NONE: - iv_len = 0; - break; - case XLR_SEC_CIPHER_TYPE_DES: - case XLR_SEC_CIPHER_TYPE_3DES: - iv_len = XLR_SEC_DES_IV_LENGTH; - break; - case XLR_SEC_CIPHER_TYPE_AES128: - case XLR_SEC_CIPHER_TYPE_AES192: - case XLR_SEC_CIPHER_TYPE_AES256: - iv_len = XLR_SEC_AES_IV_LENGTH; - break; - case XLR_SEC_CIPHER_TYPE_ARC4: - iv_len = XLR_SEC_ARC4_IV_LENGTH; - break; - case XLR_SEC_CIPHER_TYPE_KASUMI_F8: - iv_len = XLR_SEC_KASUMI_F8_IV_LENGTH; - break; + switch (op->cipher_type) { + case XLR_SEC_CIPHER_TYPE_NONE: + iv_len = 0; + break; + case XLR_SEC_CIPHER_TYPE_DES: + case XLR_SEC_CIPHER_TYPE_3DES: + iv_len = XLR_SEC_DES_IV_LENGTH; + break; + case XLR_SEC_CIPHER_TYPE_AES128: + case XLR_SEC_CIPHER_TYPE_AES192: + case XLR_SEC_CIPHER_TYPE_AES256: + iv_len = XLR_SEC_AES_IV_LENGTH; + break; + case XLR_SEC_CIPHER_TYPE_ARC4: + iv_len = XLR_SEC_ARC4_IV_LENGTH; + break; + case XLR_SEC_CIPHER_TYPE_KASUMI_F8: + iv_len = XLR_SEC_KASUMI_F8_IV_LENGTH; + break; - default: - printf(" ** Undefined Cipher Type **"); - xlr_sec_free_desc(desc); - return (-EINVAL); - } + default: + printf(" ** Undefined Cipher Type **"); + xlr_sec_free_desc(desc); + return (-EINVAL); + } - size = op->source_buf_size + iv_len; + size = op->source_buf_size + iv_len; - /* make sure that there are enough bytes for aes based stream ciphers */ - if (op->cipher_mode == XLR_SEC_CIPHER_MODE_F8 || - op->cipher_mode == XLR_SEC_CIPHER_MODE_CTR) - size += XLR_SEC_AES_BLOCK_SIZE - 1; + /* + * make sure that there are enough bytes for aes based stream + * ciphers + */ + if (op->cipher_mode == XLR_SEC_CIPHER_MODE_F8 || + op->cipher_mode == XLR_SEC_CIPHER_MODE_CTR) + size += XLR_SEC_AES_BLOCK_SIZE - 1; - if (op->cipher_type == XLR_SEC_CIPHER_TYPE_NONE) { - if(op->source_buf_size != 0){ - memcpy(desc->user.aligned_src,(uint8_t *)(unsigned long)op->source_buf, - op->source_buf_size); - } - } - else { - if(ses->multi_frag_flag){ - /* copy IV into temporary kernel source buffer */ - memcpy (desc->user.aligned_src, &op->initial_vector[0], iv_len); + if (op->cipher_type == XLR_SEC_CIPHER_TYPE_NONE) { + if (op->source_buf_size != 0) { + memcpy(desc->user.aligned_src, (uint8_t *) (unsigned long)op->source_buf, + op->source_buf_size); + } + } else { + if (ses->multi_frag_flag) { + /* copy IV into temporary kernel source buffer */ + memcpy(desc->user.aligned_src, &op->initial_vector[0], iv_len); - /* copy input data to temporary kernel source buffer */ - memcpy((uint8_t *) (desc->user.aligned_src + iv_len), - (uint8_t *)(unsigned long)op->source_buf, SEC_MAX_FRAG_LEN); + /* copy input data to temporary kernel source buffer */ + memcpy((uint8_t *) (desc->user.aligned_src + iv_len), + (uint8_t *) (unsigned long)op->source_buf, SEC_MAX_FRAG_LEN); - desc->next_src_len = op->source_buf_size - SEC_MAX_FRAG_LEN; - memcpy((uint8_t *) (desc->next_src_buf ), - (uint8_t *)(unsigned long)(op->source_buf + SEC_MAX_FRAG_LEN), - desc->next_src_len ); + desc->next_src_len = op->source_buf_size - SEC_MAX_FRAG_LEN; + memcpy((uint8_t *) (desc->next_src_buf), + (uint8_t *) (unsigned long)(op->source_buf + SEC_MAX_FRAG_LEN), + desc->next_src_len); - op->source_buf_size = SEC_MAX_FRAG_LEN ; - op->source_buf_size += iv_len; - } - else{ - /* copy IV into temporary kernel source buffer */ - memcpy (desc->user.aligned_src, &op->initial_vector[0], iv_len); + op->source_buf_size = SEC_MAX_FRAG_LEN; + op->source_buf_size += iv_len; + } else { + /* copy IV into temporary kernel source buffer */ + memcpy(desc->user.aligned_src, &op->initial_vector[0], iv_len); - /* copy input data to temporary kernel source buffer */ - memcpy((uint8_t *) (desc->user.aligned_src + iv_len), - (uint8_t *)(unsigned long)op->source_buf,op->source_buf_size); - op->source_buf_size += iv_len; - } - } + /* copy input data to temporary kernel source buffer */ + memcpy((uint8_t *) (desc->user.aligned_src + iv_len), + (uint8_t *) (unsigned long)op->source_buf, op->source_buf_size); + op->source_buf_size += iv_len; + } + } - /* Set source to new kernel space */ - op->source_buf = (uint64_t)(unsigned long)desc->user.aligned_src; + /* Set source to new kernel space */ + op->source_buf = (uint64_t) (unsigned long)desc->user.aligned_src; - /* - * Build new dest buffer, for Cipher output only - */ - if (op->cipher_type == XLR_SEC_CIPHER_TYPE_NONE) { - /* - * Digest Engine *NEEDS* this, - * otherwise it will write at 0[x] - */ - op->dest_buf = (uint64_t)(unsigned long)desc->user.aligned_src; - } - else { - /* DEBUG -dpk */ - XLR_SEC_CMD_DIAG("dest_buf_size = %d \n", op->dest_buf_size); + /* + * Build new dest buffer, for Cipher output only + */ + if (op->cipher_type == XLR_SEC_CIPHER_TYPE_NONE) { + /* + * Digest Engine *NEEDS* this, otherwise it will write at + * 0[x] + */ + op->dest_buf = (uint64_t) (unsigned long)desc->user.aligned_src; + } else { + /* DEBUG -dpk */ + XLR_SEC_CMD_DIAG("dest_buf_size = %d \n", op->dest_buf_size); - size = op->dest_buf_size + iv_len; + size = op->dest_buf_size + iv_len; - /* make sure that there are enough bytes for aes based stream ciphers */ - if (op->cipher_mode == XLR_SEC_CIPHER_MODE_F8 || - op->cipher_mode == XLR_SEC_CIPHER_MODE_CTR) - size += XLR_SEC_AES_BLOCK_SIZE - 1; - op->dest_buf = (uint64_t)(unsigned long)desc->user.aligned_dest; + /* + * make sure that there are enough bytes for aes based + * stream ciphers + */ + if (op->cipher_mode == XLR_SEC_CIPHER_MODE_F8 || + op->cipher_mode == XLR_SEC_CIPHER_MODE_CTR) + size += XLR_SEC_AES_BLOCK_SIZE - 1; + op->dest_buf = (uint64_t) (unsigned long)desc->user.aligned_dest; - } + } - ret_val = xlr_sec_cipher_hash_command (op, desc, ses->multi_frag_flag); + ret_val = xlr_sec_cipher_hash_command(op, desc, ses->multi_frag_flag); - return (ret_val); + return (ret_val); } static int -xlr_sec_cipher_hash_command(xlr_sec_io_pt op, symkey_desc_pt desc, - uint8_t multi_frag_flag) +xlr_sec_cipher_hash_command(xlr_sec_io_pt op, symkey_desc_pt desc, + uint8_t multi_frag_flag) { - xlr_sec_error_t err; - uint32_t cfg_vector; - unsigned int setup_flags = 0; - - err = XLR_SEC_ERR_NONE; - cfg_vector = 0; + xlr_sec_error_t err; + uint32_t cfg_vector; + unsigned int setup_flags = 0; - if ((op->digest_type == XLR_SEC_DIGEST_TYPE_NONE) && - (op->cipher_type != XLR_SEC_CIPHER_TYPE_ARC4) && - (op->cipher_mode != XLR_SEC_CIPHER_MODE_F8) && - (op->cipher_type != XLR_SEC_CIPHER_TYPE_KASUMI_F8) && - (op->source_buf_size & 0x7)) { - printf("Invalid Cipher Block Size, data len=%d\n", - op->source_buf_size); - return (-EINVAL); - } + err = XLR_SEC_ERR_NONE; + cfg_vector = 0; - do { + if ((op->digest_type == XLR_SEC_DIGEST_TYPE_NONE) && + (op->cipher_type != XLR_SEC_CIPHER_TYPE_ARC4) && + (op->cipher_mode != XLR_SEC_CIPHER_MODE_F8) && + (op->cipher_type != XLR_SEC_CIPHER_TYPE_KASUMI_F8) && + (op->source_buf_size & 0x7)) { + printf("Invalid Cipher Block Size, data len=%d\n", + op->source_buf_size); + return (-EINVAL); + } + do { - if ((op->cipher_type == XLR_SEC_CIPHER_TYPE_3DES) && - (op->cipher_op == XLR_SEC_CIPHER_OP_DECRYPT)) - setup_flags = XLR_SEC_SETUP_OP_FLIP_3DES_KEY; + if ((op->cipher_type == XLR_SEC_CIPHER_TYPE_3DES) && + (op->cipher_op == XLR_SEC_CIPHER_OP_DECRYPT)) + setup_flags = XLR_SEC_SETUP_OP_FLIP_3DES_KEY; - err = xlr_sec_setup_descriptor(op, - setup_flags, - desc, &cfg_vector); - if (err != XLR_SEC_ERR_NONE) - break; + err = xlr_sec_setup_descriptor(op, + setup_flags, + desc, &cfg_vector); + if (err != XLR_SEC_ERR_NONE) + break; - err = xlr_sec_setup_packet(op, - desc, - op->digest_type != XLR_SEC_DIGEST_TYPE_NONE ? - XLR_SEC_SETUP_OP_CIPHER_HMAC : 0, - &desc->data, - &desc->pkt_desc[0], - &desc->ctl_desc, - cfg_vector, - &desc->pkt_desc[1], - multi_frag_flag); - if (err != XLR_SEC_ERR_NONE) - break; - } while(0); - if (err != XLR_SEC_ERR_NONE) { - return (EINVAL); - } - - err = xlr_sec_submit_message(desc, cfg_vector); - return err; + err = xlr_sec_setup_packet(op, + desc, + op->digest_type != XLR_SEC_DIGEST_TYPE_NONE ? + XLR_SEC_SETUP_OP_CIPHER_HMAC : 0, + &desc->data, + &desc->pkt_desc[0], + &desc->ctl_desc, + cfg_vector, + &desc->pkt_desc[1], + multi_frag_flag); + if (err != XLR_SEC_ERR_NONE) + break; + } while (0); + if (err != XLR_SEC_ERR_NONE) { + return (EINVAL); + } + err = xlr_sec_submit_message(desc, cfg_vector); + return err; } static xlr_sec_error_t -xlr_sec_setup_descriptor (xlr_sec_io_pt op, - unsigned int flags, - symkey_desc_pt desc, - uint32_t *cfg_vector) +xlr_sec_setup_descriptor(xlr_sec_io_pt op, + unsigned int flags, + symkey_desc_pt desc, + uint32_t * cfg_vector) { - xlr_sec_error_t err; + xlr_sec_error_t err; - XLR_SEC_CMD_DIAG("xlr_sec_setup_descriptor: ENTER\n"); + XLR_SEC_CMD_DIAG("xlr_sec_setup_descriptor: ENTER\n"); - if ((err=xlr_sec_setup_cipher(op,&desc->ctl_desc,cfg_vector)) != XLR_SEC_ERR_NONE) { - XLR_SEC_CMD_DIAG("xlr_sec_setup_descriptor: xlr_sec_setup_cipher done err %d\n", - (int)err); - return err; - } - - if (op->digest_type != XLR_SEC_DIGEST_TYPE_NONE) { - if ((err=xlr_sec_setup_digest(op,&desc->ctl_desc,cfg_vector)) != XLR_SEC_ERR_NONE) { - XLR_SEC_CMD_DIAG("xlr_sec_setup_descriptor: xlr_sec_setup_digest done err %d\n", - (int)err); - return err; - } - } - - if ((err = xlr_sec_setup_cksum(op, &desc->ctl_desc)) != XLR_SEC_ERR_NONE) { - XLR_SEC_CMD_DIAG("xlr_sec_setup_descriptor: xlr_sec_setup_cksum done err %d\n", - (int)err); - return err; - } - - if ((err = xlr_sec_control_setup(op, - flags, - &desc->control, - &desc->ctl_desc, - &desc->user, - *cfg_vector)) != XLR_SEC_ERR_NONE) { - XLR_SEC_CMD_DIAG("xlr_sec_setup_descriptor: xlr_sec_control_setup done err %d\n", - (int)err); - return err; - } - - XLR_SEC_CMD_DIAG("xlr_sec_setup_descriptor: DONE\n"); - return err; + if ((err = xlr_sec_setup_cipher(op, &desc->ctl_desc, cfg_vector)) != XLR_SEC_ERR_NONE) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_descriptor: xlr_sec_setup_cipher done err %d\n", + (int)err); + return err; + } + if (op->digest_type != XLR_SEC_DIGEST_TYPE_NONE) { + if ((err = xlr_sec_setup_digest(op, &desc->ctl_desc, cfg_vector)) != XLR_SEC_ERR_NONE) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_descriptor: xlr_sec_setup_digest done err %d\n", + (int)err); + return err; + } + } + if ((err = xlr_sec_setup_cksum(op, &desc->ctl_desc)) != XLR_SEC_ERR_NONE) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_descriptor: xlr_sec_setup_cksum done err %d\n", + (int)err); + return err; + } + if ((err = xlr_sec_control_setup(op, + flags, + &desc->control, + &desc->ctl_desc, + &desc->user, + *cfg_vector)) != XLR_SEC_ERR_NONE) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_descriptor: xlr_sec_control_setup done err %d\n", + (int)err); + return err; + } + XLR_SEC_CMD_DIAG("xlr_sec_setup_descriptor: DONE\n"); + return err; } static -xlr_sec_error_t xlr_sec_setup_packet (xlr_sec_io_pt op, - symkey_desc_pt desc, - unsigned int flags, - uint64_t *data, - PacketDescriptor_pt pkt_desc, - ControlDescriptor_pt ctl_desc, - uint32_t vector, - PacketDescriptor_pt next_pkt_desc, - uint8_t multi_frag_flag) +xlr_sec_error_t +xlr_sec_setup_packet(xlr_sec_io_pt op, + symkey_desc_pt desc, + unsigned int flags, + uint64_t * data, + PacketDescriptor_pt pkt_desc, + ControlDescriptor_pt ctl_desc, + uint32_t vector, + PacketDescriptor_pt next_pkt_desc, + uint8_t multi_frag_flag) { - uint32_t len, next_len = 0, len_dwords, last_u64_bytes; - uint64_t addr; - uint64_t seg_addr, next_seg_addr = 0; - uint64_t byte_offset, global_offset; - uint32_t cipher_offset_dwords; - - XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ENTER vector = %04x\n", vector); - - /* physical address of the source buffer */ - addr = (uint64_t)vtophys((void*)(unsigned long)op->source_buf); - /* cache-aligned base of the source buffer */ - seg_addr = (addr & ~(SMP_CACHE_BYTES - 1)); - /* offset in bytes to the source buffer start from the segment base */ - byte_offset = addr - seg_addr; - /* global offset: 0-7 bytes */ - global_offset = byte_offset & 0x7; - - - /* - * op->source_buf_size is expected to be the Nb double words to stream - * in (Including Segment address->CP/IV/Auth/CkSum offsets) - */ - - /* adjusted length of the whole thing, accounting for the added head, - sans global_offset (per Paul S.) - */ - - len = op->source_buf_size + byte_offset - global_offset; - if(multi_frag_flag){ - next_seg_addr = (uint64_t)vtophys((void*)(unsigned long)(desc->next_src_buf) ); - next_seg_addr = (next_seg_addr & ~(SMP_CACHE_BYTES - 1)); - next_len = desc->next_src_len; - } - - /* length of the whole thing in dwords */ - len_dwords = NUM_CHUNKS(len, 3); - /* number of bytes in the last chunk (len % 8) */ - last_u64_bytes = len & 0x07; - - if (op->cipher_offset & 0x7) { - printf("** cipher_offset(%d) fails 64-bit word alignment **", - op->cipher_offset); - - return XLR_SEC_ERR_CIPHER_MODE; /* ! fix ! */ - } - - /* global_offset is only three bits, so work the number of the whole - 8-byte words into the global offset. - both offset and cipher_offset are byte counts - */ - cipher_offset_dwords = (op->iv_offset + byte_offset) >> 3; - - - if (op->cipher_mode == XLR_SEC_CIPHER_MODE_F8 || - op->cipher_mode == XLR_SEC_CIPHER_MODE_CTR) { - if(multi_frag_flag){ - int nlhmac = ((op->source_buf_size + global_offset + 7 - op->cipher_offset) >> 3) & 1; - pkt_desc->srcLengthIVOffUseIVNext = - - FIELD_VALUE(PKT_DSC_HASHBYTES, len & 7) | - FIELD_VALUE(PKT_DSC_IVOFF, cipher_offset_dwords) | - FIELD_VALUE(PKT_DSC_PKTLEN, nlhmac + ((len + 7) >> 3)) | - FIELD_VALUE(PKT_DSC_NLHMAC, nlhmac) | - FIELD_VALUE(PKT_DSC_BREAK, 0) | - FIELD_VALUE(PKT_DSC_WAIT, 1) | - FIELD_VALUE(PKT_DSC_NEXT, 1) | - FIELD_VALUE(PKT_DSC_SEGADDR, seg_addr >> (PKT_DSC_SEGADDR_LSB)) | - FIELD_VALUE(PKT_DSC_SEGOFFSET, global_offset); - } - else{ - int nlhmac = ((op->source_buf_size + global_offset + 7 - op->cipher_offset) >> 3) & 1; - pkt_desc->srcLengthIVOffUseIVNext = - FIELD_VALUE(PKT_DSC_HASHBYTES, len & 7) | - FIELD_VALUE(PKT_DSC_IVOFF, cipher_offset_dwords) | - FIELD_VALUE(PKT_DSC_PKTLEN, nlhmac + ((len + 7) >> 3)) | - FIELD_VALUE(PKT_DSC_NLHMAC, nlhmac) | - FIELD_VALUE(PKT_DSC_BREAK, 0) | - FIELD_VALUE(PKT_DSC_WAIT, 0) | - FIELD_VALUE(PKT_DSC_SEGADDR, seg_addr >> (PKT_DSC_SEGADDR_LSB)) | - FIELD_VALUE(PKT_DSC_SEGOFFSET, global_offset); - - } - } - else{ - if(multi_frag_flag){ - pkt_desc->srcLengthIVOffUseIVNext = - - FIELD_VALUE(PKT_DSC_HASHBYTES, len & 7) | - FIELD_VALUE(PKT_DSC_IVOFF, cipher_offset_dwords) | - FIELD_VALUE(PKT_DSC_PKTLEN, (len + 7) >> 3) | - FIELD_VALUE(PKT_DSC_BREAK, 0) | - FIELD_VALUE(PKT_DSC_WAIT, 0) | - FIELD_VALUE(PKT_DSC_NEXT, 1) | - FIELD_VALUE(PKT_DSC_SEGADDR, seg_addr >> (PKT_DSC_SEGADDR_LSB)) | - FIELD_VALUE(PKT_DSC_SEGOFFSET, global_offset); - - - next_pkt_desc->srcLengthIVOffUseIVNext = - FIELD_VALUE(PKT_DSC_HASHBYTES, (next_len & 7)) | - FIELD_VALUE(PKT_DSC_IVOFF, 0) | - FIELD_VALUE(PKT_DSC_PKTLEN, (next_len + 7) >> 3) | - FIELD_VALUE(PKT_DSC_BREAK, 0) | - FIELD_VALUE(PKT_DSC_WAIT, 0) | - FIELD_VALUE(PKT_DSC_NEXT, 0) | - FIELD_VALUE(PKT_DSC_SEGADDR, next_seg_addr >> (PKT_DSC_SEGADDR_LSB)) | - FIELD_VALUE(PKT_DSC_SEGOFFSET, 0); - - - } - else{ - pkt_desc->srcLengthIVOffUseIVNext = - FIELD_VALUE(PKT_DSC_HASHBYTES, len & 7) | - FIELD_VALUE(PKT_DSC_IVOFF, cipher_offset_dwords) | - FIELD_VALUE(PKT_DSC_PKTLEN, (len + 7) >> 3) | - FIELD_VALUE(PKT_DSC_BREAK, 0) | - FIELD_VALUE(PKT_DSC_WAIT, 0) | - FIELD_VALUE(PKT_DSC_SEGADDR, seg_addr >> (PKT_DSC_SEGADDR_LSB)) | - FIELD_VALUE(PKT_DSC_SEGOFFSET, global_offset); - - - } - } - - switch (op->pkt_hmac) { - case XLR_SEC_LOADHMACKEY_MODE_OLD: - CLEAR_SET_FIELD(pkt_desc->srcLengthIVOffUseIVNext, - PKT_DSC_LOADHMACKEY, PKT_DSC_LOADHMACKEY_OLD); - if(multi_frag_flag){ - CLEAR_SET_FIELD(next_pkt_desc->srcLengthIVOffUseIVNext, - PKT_DSC_LOADHMACKEY, PKT_DSC_LOADHMACKEY_OLD); - - } - break; - case XLR_SEC_LOADHMACKEY_MODE_LOAD: - CLEAR_SET_FIELD(pkt_desc->srcLengthIVOffUseIVNext, - PKT_DSC_LOADHMACKEY, PKT_DSC_LOADHMACKEY_LOAD); - if(multi_frag_flag){ - CLEAR_SET_FIELD(next_pkt_desc->srcLengthIVOffUseIVNext, - PKT_DSC_LOADHMACKEY, PKT_DSC_LOADHMACKEY_LOAD); - - } - break; - default: - if (vector & (XLR_SEC_VECTOR_HMAC | XLR_SEC_VECTOR_HMAC2 | XLR_SEC_VECTOR_GCM | XLR_SEC_VECTOR_F9)) { - XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ERR_LOADHMACKEY_MODE EXIT\n"); - return XLR_SEC_ERR_LOADHMACKEY_MODE; - } - break; - } - - switch (op->pkt_hash) { - case XLR_SEC_PADHASH_PADDED: - CLEAR_SET_FIELD(pkt_desc->srcLengthIVOffUseIVNext, - PKT_DSC_PADHASH, PKT_DSC_PADHASH_PADDED); - if(multi_frag_flag){ - CLEAR_SET_FIELD(next_pkt_desc->srcLengthIVOffUseIVNext, - PKT_DSC_PADHASH, PKT_DSC_PADHASH_PADDED); - } - break; - case XLR_SEC_PADHASH_PAD: - CLEAR_SET_FIELD(pkt_desc->srcLengthIVOffUseIVNext, - PKT_DSC_PADHASH, PKT_DSC_PADHASH_PAD); - if(multi_frag_flag){ - CLEAR_SET_FIELD(next_pkt_desc->srcLengthIVOffUseIVNext, - PKT_DSC_PADHASH, PKT_DSC_PADHASH_PAD); - } - break; - default: - if (vector & (XLR_SEC_VECTOR_MAC | XLR_SEC_VECTOR_HMAC | XLR_SEC_VECTOR_HMAC2)) { - XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ERR_PADHASH_MODE EXIT\n"); - return XLR_SEC_ERR_PADHASH_MODE; - } - break; - } - - switch (op->pkt_iv) { - case XLR_SEC_PKT_IV_OLD: - CLEAR_SET_FIELD(pkt_desc->srcLengthIVOffUseIVNext, - PKT_DSC_IV, PKT_DSC_IV_OLD); - if(multi_frag_flag){ - CLEAR_SET_FIELD(next_pkt_desc->srcLengthIVOffUseIVNext, - PKT_DSC_IV, PKT_DSC_IV_OLD); - - } - break; - case XLR_SEC_PKT_IV_NEW: - CLEAR_SET_FIELD(pkt_desc->srcLengthIVOffUseIVNext, - PKT_DSC_IV, PKT_DSC_IV_NEW); - if(multi_frag_flag){ - CLEAR_SET_FIELD(next_pkt_desc->srcLengthIVOffUseIVNext, - PKT_DSC_IV, PKT_DSC_IV_NEW); - - } - break; - default: - if (vector & XLR_SEC_VECTOR_CIPHER) { - XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ERR_PKT_IV_MODE EXIT\n"); - return XLR_SEC_ERR_PKT_IV_MODE; - } - break; - } - - XLR_SEC_CMD_DIAG ("xlr_sec_setup_packet: src_buf=%llx phys_src_buf=%llx \n", - (unsigned long long)op->source_buf, (unsigned long long)addr); - - XLR_SEC_CMD_DIAG ("xlr_sec_setup_packet: seg_addr=%llx offset=%lld\n", - (unsigned long long)seg_addr, (unsigned long long)byte_offset); - - XLR_SEC_CMD_DIAG ("xlr_sec_setup_packet: global src offset: %d, iv_offset=%d\n", - cipher_offset_dwords, op->iv_offset); - - XLR_SEC_CMD_DIAG ("xlr_sec_setup_packet: src_buf_sz=%d PKT_LEN=%d\n", - op->source_buf_size, len_dwords); - - /* same operation with the destination. - cipher offset affects this, as well - */ - if(multi_frag_flag){ - next_seg_addr = (uint64_t)vtophys((void*)(unsigned long)(desc->next_dest_buf) ); - next_seg_addr = (next_seg_addr & ~(SMP_CACHE_BYTES - 1)); - } - - addr = (uint64_t)vtophys((void*)(unsigned long)op->dest_buf); - seg_addr = (addr & ~(SMP_CACHE_BYTES - 1)); - byte_offset = addr - seg_addr; - global_offset = byte_offset & 0x7; - - XLR_SEC_CMD_DIAG ("xlr_sec_setup_packet: dest_buf=%llx phys_dest_buf=%llx \n", - (unsigned long long)op->dest_buf, (unsigned long long)addr); - - XLR_SEC_CMD_DIAG ("xlr_sec_setup_packet: seg_addr=%llx offset=%lld\n", - (unsigned long long)seg_addr, (unsigned long long)byte_offset); - - /* - * Dest Address = - * (Cipher Dest Address) + (Cipher Offset) + (Global Dest Data Offset) - * - * Cipher Dest Address - Cache-line (0xffffffffe0) - * Cipher Offset - Which (64-bit) Word in Cacheline (0-3) - * Global Dest Data Offset - Number of Bytes in (64-bit) Word before data - * - * It must be set for Digest-only Ops, since - * the Digest engine will write data to this address. - */ - cipher_offset_dwords = (op->cipher_offset + byte_offset) >> 3; - - - pkt_desc->dstDataSettings = - /* SYM_OP, HASHSRC */ - FIELD_VALUE(PKT_DSC_CPHROFF, cipher_offset_dwords) | - FIELD_VALUE(PKT_DSC_HASHOFF, (op->digest_offset + byte_offset) >> 3) | - FIELD_VALUE(PKT_DSC_CPHR_DST_ADDR, seg_addr) | - FIELD_VALUE(PKT_DSC_CPHR_DST_DWOFFSET, 0) | - FIELD_VALUE(PKT_DSC_CPHR_DST_OFFSET, global_offset); - - if(multi_frag_flag){ - next_pkt_desc->dstDataSettings = - /* SYM_OP, HASHSRC */ - FIELD_VALUE(PKT_DSC_CPHROFF, cipher_offset_dwords) | - FIELD_VALUE(PKT_DSC_HASHOFF, (op->digest_offset + byte_offset) >> 3) | - FIELD_VALUE(PKT_DSC_CPHR_DST_ADDR, next_seg_addr) | - FIELD_VALUE(PKT_DSC_CPHR_DST_DWOFFSET, 0) | - FIELD_VALUE(PKT_DSC_CPHR_DST_OFFSET, global_offset); - - } - - if (op->cipher_type == XLR_SEC_CIPHER_TYPE_ARC4) - pkt_desc->dstDataSettings |= FIELD_VALUE(PKT_DSC_ARC4BYTECOUNT, last_u64_bytes); - - if (op->cipher_type != XLR_SEC_CIPHER_TYPE_NONE) { - switch (op->cipher_op) { - case XLR_SEC_CIPHER_OP_ENCRYPT: - CLEAR_SET_FIELD(pkt_desc->dstDataSettings, - PKT_DSC_SYM_OP, PKT_DSC_SYM_OP_ENCRYPT); - if(multi_frag_flag){ - CLEAR_SET_FIELD(next_pkt_desc->dstDataSettings, - PKT_DSC_SYM_OP, PKT_DSC_SYM_OP_ENCRYPT); - - } - break; - case XLR_SEC_CIPHER_OP_DECRYPT: - CLEAR_SET_FIELD(pkt_desc->dstDataSettings, - PKT_DSC_SYM_OP, PKT_DSC_SYM_OP_DECRYPT); - if(multi_frag_flag){ - CLEAR_SET_FIELD(next_pkt_desc->dstDataSettings, - PKT_DSC_SYM_OP, PKT_DSC_SYM_OP_DECRYPT); - - } - break; - default: - XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ERR_CIPHER_OP EXIT\n"); - return XLR_SEC_ERR_CIPHER_OP; - } - } - if (flags & XLR_SEC_SETUP_OP_HMAC) { - switch (op->digest_src) { - case XLR_SEC_DIGEST_SRC_DMA: - CLEAR_SET_FIELD(pkt_desc->dstDataSettings, - PKT_DSC_HASHSRC, PKT_DSC_HASHSRC_DMA); - if(multi_frag_flag){ - CLEAR_SET_FIELD(next_pkt_desc->dstDataSettings, - PKT_DSC_HASHSRC, PKT_DSC_HASHSRC_DMA); - - } - break; - case XLR_SEC_DIGEST_SRC_CPHR: - CLEAR_SET_FIELD(pkt_desc->dstDataSettings, - PKT_DSC_HASHSRC, PKT_DSC_HASHSRC_CIPHER); - if(multi_frag_flag){ - CLEAR_SET_FIELD(next_pkt_desc->dstDataSettings, - PKT_DSC_HASHSRC, PKT_DSC_HASHSRC_CIPHER); - } - break; - default: - XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ERR_DIGEST_SRC EXIT\n"); - return XLR_SEC_ERR_DIGEST_SRC; - } - } - if (op->cksum_type != XLR_SEC_CKSUM_TYPE_NOP) { - switch (op->cksum_src) { - case XLR_SEC_CKSUM_SRC_DMA: - CLEAR_SET_FIELD(pkt_desc->dstDataSettings, - PKT_DSC_CKSUMSRC, PKT_DSC_CKSUMSRC_DMA); - if(multi_frag_flag){ - CLEAR_SET_FIELD(next_pkt_desc->dstDataSettings, - PKT_DSC_CKSUMSRC, PKT_DSC_CKSUMSRC_DMA); - } - break; - case XLR_SEC_CKSUM_SRC_CIPHER: - CLEAR_SET_FIELD(next_pkt_desc->dstDataSettings, - PKT_DSC_CKSUMSRC, PKT_DSC_CKSUMSRC_CIPHER); - if(multi_frag_flag){ - CLEAR_SET_FIELD(next_pkt_desc->dstDataSettings, - PKT_DSC_CKSUMSRC, PKT_DSC_CKSUMSRC_CIPHER); - } - break; - default: - XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ERR_CKSUM_SRC EXIT\n"); - return XLR_SEC_ERR_CKSUM_SRC; - } - } - - pkt_desc->ckSumDstNonceHiCFBMaskLLWMask = - FIELD_VALUE(PKT_DSC_HASH_BYTE_OFF, (op->digest_offset & 0x7)) | - FIELD_VALUE(PKT_DSC_PKTLEN_BYTES, 0) | - /* NONCE_HI, PKT_DSC_LASTWORD, CFB_MASK, CKSUM_DST_ADDR */ - FIELD_VALUE(PKT_DSC_IV_OFF_HI, 0); - - if(multi_frag_flag){ - next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask = - FIELD_VALUE(PKT_DSC_HASH_BYTE_OFF, (op->digest_offset & 0x7)) | - FIELD_VALUE(PKT_DSC_PKTLEN_BYTES, 0) | - /* NONCE_HI, PKT_DSC_LASTWORD, CFB_MASK, CKSUM_DST_ADDR */ - FIELD_VALUE(PKT_DSC_IV_OFF_HI, 0); - - } - switch (op->pkt_lastword) { - case XLR_SEC_LASTWORD_128: - CLEAR_SET_FIELD(pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, - PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_128); - if(multi_frag_flag){ - CLEAR_SET_FIELD(next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, - PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_128); - - } - break; - case XLR_SEC_LASTWORD_96MASK: - CLEAR_SET_FIELD(pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, - PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_96MASK); - if(multi_frag_flag){ - CLEAR_SET_FIELD(next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, - PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_96MASK); - } - break; - case XLR_SEC_LASTWORD_64MASK: - CLEAR_SET_FIELD(pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, - PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_64MASK); - if(multi_frag_flag){ - CLEAR_SET_FIELD(next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, - PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_64MASK); - } - break; - case XLR_SEC_LASTWORD_32MASK: - CLEAR_SET_FIELD(pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, - PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_32MASK); - if(multi_frag_flag){ - CLEAR_SET_FIELD(next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, - PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_32MASK); - } - break; - default: - XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ERR_LASTWORD_MODE EXIT\n"); - return XLR_SEC_ERR_LASTWORD_MODE; - } - CLEAR_SET_FIELD(pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, - PKT_DSC_CFB_MASK, op->cfb_mask); - CLEAR_SET_FIELD(pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, - PKT_DSC_NONCE_HI, htonl(op->nonce)>>24); - CLEAR_SET_FIELD(pkt_desc->authDstNonceLow, - PKT_DSC_NONCE_LOW, htonl(op->nonce)&0xffffff); - - if(multi_frag_flag){ - CLEAR_SET_FIELD(next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, - PKT_DSC_CFB_MASK, op->cfb_mask); - CLEAR_SET_FIELD(next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, - PKT_DSC_NONCE_HI, htonl(op->nonce)>>24); - CLEAR_SET_FIELD(next_pkt_desc->authDstNonceLow, - PKT_DSC_NONCE_LOW, htonl(op->nonce)&0xffffff); - - - } - - /* Auth Dest Address must be Cacheline aligned on input */ - if (vector & (XLR_SEC_VECTOR_MAC | XLR_SEC_VECTOR_HMAC | XLR_SEC_VECTOR_HMAC2 | XLR_SEC_VECTOR_GCM | XLR_SEC_VECTOR_F9)){ - pkt_desc->authDstNonceLow |= - /* NONCE_LOW */ - FIELD_VALUE(PKT_DSC_AUTH_DST_ADDR, - (uint64_t) vtophys((void*)(unsigned long)op->auth_dest)) | - FIELD_VALUE(PKT_DSC_CIPH_OFF_HI, 0); - - - if(multi_frag_flag){ - next_pkt_desc->authDstNonceLow |= - /* NONCE_LOW */ - FIELD_VALUE(PKT_DSC_AUTH_DST_ADDR, - (uint64_t) vtophys((void*)(unsigned long)desc->next_auth_dest)) | - FIELD_VALUE(PKT_DSC_CIPH_OFF_HI, 0); - - - } - - - } - - - /* CkSum Dest Address must be Cacheline aligned on input */ - if (op->cksum_type == XLR_SEC_CKSUM_TYPE_IP){ - CLEAR_SET_FIELD(pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, - PKT_DSC_CKSUM_DST_ADDR, - (uint64_t)vtophys((void*)(unsigned long)op->cksum_dest)); - - if(multi_frag_flag){ - CLEAR_SET_FIELD(next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, - PKT_DSC_CKSUM_DST_ADDR, - (uint64_t)vtophys((void*)(unsigned long)desc->next_cksum_dest)); - - } - - } - /* - XLR_SEC_CMD_DIAG (" xlr_sec_setup_packet(): pkt_desc=%llx phys_pkt_desc=%llx \n", - (unsigned long long)pkt_desc, (unsigned long long)virt_to_phys(pkt_desc)); - (unsigned long long)pkt_desc, (unsigned long long)vtophys(pkt_desc)); - */ - XLR_SEC_CMD_DIAG (" xlr_sec_setup_packet(): pkt_desc=%p phys_pkt_desc=%llx \n", - pkt_desc, (unsigned long long)vtophys(pkt_desc)); - - - - CLEAR_SET_FIELD(*data, MSG_CMD_DATA_ADDR, ((uint64_t)vtophys(pkt_desc))); - CLEAR_SET_FIELD(*data, MSG_CMD_DATA_CTL, SEC_EOP); - CLEAR_SET_FIELD(*data, MSG_CMD_DATA_LEN, MSG_CMD_DATA_LEN_LOAD); - - - XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: DONE\n"); + uint32_t len, next_len = 0, len_dwords, last_u64_bytes; + uint64_t addr; + uint64_t seg_addr, next_seg_addr = 0; + uint64_t byte_offset, global_offset; + uint32_t cipher_offset_dwords; + + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ENTER vector = %04x\n", vector); + + /* physical address of the source buffer */ + addr = (uint64_t) vtophys((void *)(unsigned long)op->source_buf); + /* cache-aligned base of the source buffer */ + seg_addr = (addr & ~(SMP_CACHE_BYTES - 1)); + /* offset in bytes to the source buffer start from the segment base */ + byte_offset = addr - seg_addr; + /* global offset: 0-7 bytes */ + global_offset = byte_offset & 0x7; + + + /* + * op->source_buf_size is expected to be the Nb double words to + * stream in (Including Segment address->CP/IV/Auth/CkSum offsets) + */ + + /* + * adjusted length of the whole thing, accounting for the added + * head, sans global_offset (per Paul S.) + */ + + len = op->source_buf_size + byte_offset - global_offset; + if (multi_frag_flag) { + next_seg_addr = (uint64_t) vtophys((void *)(unsigned long)(desc->next_src_buf)); + next_seg_addr = (next_seg_addr & ~(SMP_CACHE_BYTES - 1)); + next_len = desc->next_src_len; + } + /* length of the whole thing in dwords */ + len_dwords = NUM_CHUNKS(len, 3); + /* number of bytes in the last chunk (len % 8) */ + last_u64_bytes = len & 0x07; + + if (op->cipher_offset & 0x7) { + printf("** cipher_offset(%d) fails 64-bit word alignment **", + op->cipher_offset); + + return XLR_SEC_ERR_CIPHER_MODE; /* ! fix ! */ + } + /* + * global_offset is only three bits, so work the number of the whole + * 8-byte words into the global offset. both offset and + * cipher_offset are byte counts + */ + cipher_offset_dwords = (op->iv_offset + byte_offset) >> 3; + + + if (op->cipher_mode == XLR_SEC_CIPHER_MODE_F8 || + op->cipher_mode == XLR_SEC_CIPHER_MODE_CTR) { + if (multi_frag_flag) { + int nlhmac = ((op->source_buf_size + global_offset + 7 - op->cipher_offset) >> 3) & 1; + + pkt_desc->srcLengthIVOffUseIVNext = + + FIELD_VALUE(PKT_DSC_HASHBYTES, len & 7) | + FIELD_VALUE(PKT_DSC_IVOFF, cipher_offset_dwords) | + FIELD_VALUE(PKT_DSC_PKTLEN, nlhmac + ((len + 7) >> 3)) | + FIELD_VALUE(PKT_DSC_NLHMAC, nlhmac) | + FIELD_VALUE(PKT_DSC_BREAK, 0) | + FIELD_VALUE(PKT_DSC_WAIT, 1) | + FIELD_VALUE(PKT_DSC_NEXT, 1) | + FIELD_VALUE(PKT_DSC_SEGADDR, seg_addr >> (PKT_DSC_SEGADDR_LSB)) | + FIELD_VALUE(PKT_DSC_SEGOFFSET, global_offset); + } else { + int nlhmac = ((op->source_buf_size + global_offset + 7 - op->cipher_offset) >> 3) & 1; + + pkt_desc->srcLengthIVOffUseIVNext = + FIELD_VALUE(PKT_DSC_HASHBYTES, len & 7) | + FIELD_VALUE(PKT_DSC_IVOFF, cipher_offset_dwords) | + FIELD_VALUE(PKT_DSC_PKTLEN, nlhmac + ((len + 7) >> 3)) | + FIELD_VALUE(PKT_DSC_NLHMAC, nlhmac) | + FIELD_VALUE(PKT_DSC_BREAK, 0) | + FIELD_VALUE(PKT_DSC_WAIT, 0) | + FIELD_VALUE(PKT_DSC_SEGADDR, seg_addr >> (PKT_DSC_SEGADDR_LSB)) | + FIELD_VALUE(PKT_DSC_SEGOFFSET, global_offset); + + } + } else { + if (multi_frag_flag) { + pkt_desc->srcLengthIVOffUseIVNext = + + FIELD_VALUE(PKT_DSC_HASHBYTES, len & 7) | + FIELD_VALUE(PKT_DSC_IVOFF, cipher_offset_dwords) | + FIELD_VALUE(PKT_DSC_PKTLEN, (len + 7) >> 3) | + FIELD_VALUE(PKT_DSC_BREAK, 0) | + FIELD_VALUE(PKT_DSC_WAIT, 0) | + FIELD_VALUE(PKT_DSC_NEXT, 1) | + FIELD_VALUE(PKT_DSC_SEGADDR, seg_addr >> (PKT_DSC_SEGADDR_LSB)) | + FIELD_VALUE(PKT_DSC_SEGOFFSET, global_offset); + + + next_pkt_desc->srcLengthIVOffUseIVNext = + FIELD_VALUE(PKT_DSC_HASHBYTES, (next_len & 7)) | + FIELD_VALUE(PKT_DSC_IVOFF, 0) | + FIELD_VALUE(PKT_DSC_PKTLEN, (next_len + 7) >> 3) | + FIELD_VALUE(PKT_DSC_BREAK, 0) | + FIELD_VALUE(PKT_DSC_WAIT, 0) | + FIELD_VALUE(PKT_DSC_NEXT, 0) | + FIELD_VALUE(PKT_DSC_SEGADDR, next_seg_addr >> (PKT_DSC_SEGADDR_LSB)) | + FIELD_VALUE(PKT_DSC_SEGOFFSET, 0); + + + } else { + pkt_desc->srcLengthIVOffUseIVNext = + FIELD_VALUE(PKT_DSC_HASHBYTES, len & 7) | + FIELD_VALUE(PKT_DSC_IVOFF, cipher_offset_dwords) | + FIELD_VALUE(PKT_DSC_PKTLEN, (len + 7) >> 3) | + FIELD_VALUE(PKT_DSC_BREAK, 0) | + FIELD_VALUE(PKT_DSC_WAIT, 0) | + FIELD_VALUE(PKT_DSC_SEGADDR, seg_addr >> (PKT_DSC_SEGADDR_LSB)) | + FIELD_VALUE(PKT_DSC_SEGOFFSET, global_offset); + + + } + } + + switch (op->pkt_hmac) { + case XLR_SEC_LOADHMACKEY_MODE_OLD: + CLEAR_SET_FIELD(pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_LOADHMACKEY, PKT_DSC_LOADHMACKEY_OLD); + if (multi_frag_flag) { + CLEAR_SET_FIELD(next_pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_LOADHMACKEY, PKT_DSC_LOADHMACKEY_OLD); + + } + break; + case XLR_SEC_LOADHMACKEY_MODE_LOAD: + CLEAR_SET_FIELD(pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_LOADHMACKEY, PKT_DSC_LOADHMACKEY_LOAD); + if (multi_frag_flag) { + CLEAR_SET_FIELD(next_pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_LOADHMACKEY, PKT_DSC_LOADHMACKEY_LOAD); + + } + break; + default: + if (vector & (XLR_SEC_VECTOR_HMAC | XLR_SEC_VECTOR_HMAC2 | XLR_SEC_VECTOR_GCM | XLR_SEC_VECTOR_F9)) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ERR_LOADHMACKEY_MODE EXIT\n"); + return XLR_SEC_ERR_LOADHMACKEY_MODE; + } + break; + } + + switch (op->pkt_hash) { + case XLR_SEC_PADHASH_PADDED: + CLEAR_SET_FIELD(pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_PADHASH, PKT_DSC_PADHASH_PADDED); + if (multi_frag_flag) { + CLEAR_SET_FIELD(next_pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_PADHASH, PKT_DSC_PADHASH_PADDED); + } + break; + case XLR_SEC_PADHASH_PAD: + CLEAR_SET_FIELD(pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_PADHASH, PKT_DSC_PADHASH_PAD); + if (multi_frag_flag) { + CLEAR_SET_FIELD(next_pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_PADHASH, PKT_DSC_PADHASH_PAD); + } + break; + default: + if (vector & (XLR_SEC_VECTOR_MAC | XLR_SEC_VECTOR_HMAC | XLR_SEC_VECTOR_HMAC2)) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ERR_PADHASH_MODE EXIT\n"); + return XLR_SEC_ERR_PADHASH_MODE; + } + break; + } + + switch (op->pkt_iv) { + case XLR_SEC_PKT_IV_OLD: + CLEAR_SET_FIELD(pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_IV, PKT_DSC_IV_OLD); + if (multi_frag_flag) { + CLEAR_SET_FIELD(next_pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_IV, PKT_DSC_IV_OLD); + + } + break; + case XLR_SEC_PKT_IV_NEW: + CLEAR_SET_FIELD(pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_IV, PKT_DSC_IV_NEW); + if (multi_frag_flag) { + CLEAR_SET_FIELD(next_pkt_desc->srcLengthIVOffUseIVNext, + PKT_DSC_IV, PKT_DSC_IV_NEW); + + } + break; + default: + if (vector & XLR_SEC_VECTOR_CIPHER) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ERR_PKT_IV_MODE EXIT\n"); + return XLR_SEC_ERR_PKT_IV_MODE; + } + break; + } + + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: src_buf=%llx phys_src_buf=%llx \n", + (unsigned long long)op->source_buf, (unsigned long long)addr); + + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: seg_addr=%llx offset=%lld\n", + (unsigned long long)seg_addr, (unsigned long long)byte_offset); + + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: global src offset: %d, iv_offset=%d\n", + cipher_offset_dwords, op->iv_offset); + + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: src_buf_sz=%d PKT_LEN=%d\n", + op->source_buf_size, len_dwords); + + /* + * same operation with the destination. cipher offset affects this, + * as well + */ + if (multi_frag_flag) { + next_seg_addr = (uint64_t) vtophys((void *)(unsigned long)(desc->next_dest_buf)); + next_seg_addr = (next_seg_addr & ~(SMP_CACHE_BYTES - 1)); + } + addr = (uint64_t) vtophys((void *)(unsigned long)op->dest_buf); + seg_addr = (addr & ~(SMP_CACHE_BYTES - 1)); + byte_offset = addr - seg_addr; + global_offset = byte_offset & 0x7; + + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: dest_buf=%llx phys_dest_buf=%llx \n", + (unsigned long long)op->dest_buf, (unsigned long long)addr); + + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: seg_addr=%llx offset=%lld\n", + (unsigned long long)seg_addr, (unsigned long long)byte_offset); + + /* + * Dest Address = (Cipher Dest Address) + (Cipher Offset) + (Global + * Dest Data Offset) + * + * Cipher Dest Address - Cache-line (0xffffffffe0) Cipher Offset - + * Which (64-bit) Word in Cacheline (0-3) Global Dest Data Offset - + * Number of Bytes in (64-bit) Word before data + * + * It must be set for Digest-only Ops, since the Digest engine will + * write data to this address. + */ + cipher_offset_dwords = (op->cipher_offset + byte_offset) >> 3; + + + pkt_desc->dstDataSettings = + /* SYM_OP, HASHSRC */ + FIELD_VALUE(PKT_DSC_CPHROFF, cipher_offset_dwords) | + FIELD_VALUE(PKT_DSC_HASHOFF, (op->digest_offset + byte_offset) >> 3) | + FIELD_VALUE(PKT_DSC_CPHR_DST_ADDR, seg_addr) | + FIELD_VALUE(PKT_DSC_CPHR_DST_DWOFFSET, 0) | + FIELD_VALUE(PKT_DSC_CPHR_DST_OFFSET, global_offset); + + if (multi_frag_flag) { + next_pkt_desc->dstDataSettings = + /* SYM_OP, HASHSRC */ + FIELD_VALUE(PKT_DSC_CPHROFF, cipher_offset_dwords) | + FIELD_VALUE(PKT_DSC_HASHOFF, (op->digest_offset + byte_offset) >> 3) | + FIELD_VALUE(PKT_DSC_CPHR_DST_ADDR, next_seg_addr) | + FIELD_VALUE(PKT_DSC_CPHR_DST_DWOFFSET, 0) | + FIELD_VALUE(PKT_DSC_CPHR_DST_OFFSET, global_offset); + + } + if (op->cipher_type == XLR_SEC_CIPHER_TYPE_ARC4) + pkt_desc->dstDataSettings |= FIELD_VALUE(PKT_DSC_ARC4BYTECOUNT, last_u64_bytes); + + if (op->cipher_type != XLR_SEC_CIPHER_TYPE_NONE) { + switch (op->cipher_op) { + case XLR_SEC_CIPHER_OP_ENCRYPT: + CLEAR_SET_FIELD(pkt_desc->dstDataSettings, + PKT_DSC_SYM_OP, PKT_DSC_SYM_OP_ENCRYPT); + if (multi_frag_flag) { + CLEAR_SET_FIELD(next_pkt_desc->dstDataSettings, + PKT_DSC_SYM_OP, PKT_DSC_SYM_OP_ENCRYPT); + + } + break; + case XLR_SEC_CIPHER_OP_DECRYPT: + CLEAR_SET_FIELD(pkt_desc->dstDataSettings, + PKT_DSC_SYM_OP, PKT_DSC_SYM_OP_DECRYPT); + if (multi_frag_flag) { + CLEAR_SET_FIELD(next_pkt_desc->dstDataSettings, + PKT_DSC_SYM_OP, PKT_DSC_SYM_OP_DECRYPT); + + } + break; + default: + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ERR_CIPHER_OP EXIT\n"); + return XLR_SEC_ERR_CIPHER_OP; + } + } + if (flags & XLR_SEC_SETUP_OP_HMAC) { + switch (op->digest_src) { + case XLR_SEC_DIGEST_SRC_DMA: + CLEAR_SET_FIELD(pkt_desc->dstDataSettings, + PKT_DSC_HASHSRC, PKT_DSC_HASHSRC_DMA); + if (multi_frag_flag) { + CLEAR_SET_FIELD(next_pkt_desc->dstDataSettings, + PKT_DSC_HASHSRC, PKT_DSC_HASHSRC_DMA); + + } + break; + case XLR_SEC_DIGEST_SRC_CPHR: + CLEAR_SET_FIELD(pkt_desc->dstDataSettings, + PKT_DSC_HASHSRC, PKT_DSC_HASHSRC_CIPHER); + if (multi_frag_flag) { + CLEAR_SET_FIELD(next_pkt_desc->dstDataSettings, + PKT_DSC_HASHSRC, PKT_DSC_HASHSRC_CIPHER); + } + break; + default: + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ERR_DIGEST_SRC EXIT\n"); + return XLR_SEC_ERR_DIGEST_SRC; + } + } + if (op->cksum_type != XLR_SEC_CKSUM_TYPE_NOP) { + switch (op->cksum_src) { + case XLR_SEC_CKSUM_SRC_DMA: + CLEAR_SET_FIELD(pkt_desc->dstDataSettings, + PKT_DSC_CKSUMSRC, PKT_DSC_CKSUMSRC_DMA); + if (multi_frag_flag) { + CLEAR_SET_FIELD(next_pkt_desc->dstDataSettings, + PKT_DSC_CKSUMSRC, PKT_DSC_CKSUMSRC_DMA); + } + break; + case XLR_SEC_CKSUM_SRC_CIPHER: + CLEAR_SET_FIELD(next_pkt_desc->dstDataSettings, + PKT_DSC_CKSUMSRC, PKT_DSC_CKSUMSRC_CIPHER); + if (multi_frag_flag) { + CLEAR_SET_FIELD(next_pkt_desc->dstDataSettings, + PKT_DSC_CKSUMSRC, PKT_DSC_CKSUMSRC_CIPHER); + } + break; + default: + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ERR_CKSUM_SRC EXIT\n"); + return XLR_SEC_ERR_CKSUM_SRC; + } + } + pkt_desc->ckSumDstNonceHiCFBMaskLLWMask = + FIELD_VALUE(PKT_DSC_HASH_BYTE_OFF, (op->digest_offset & 0x7)) | + FIELD_VALUE(PKT_DSC_PKTLEN_BYTES, 0) | + /* NONCE_HI, PKT_DSC_LASTWORD, CFB_MASK, CKSUM_DST_ADDR */ + FIELD_VALUE(PKT_DSC_IV_OFF_HI, 0); + + if (multi_frag_flag) { + next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask = + FIELD_VALUE(PKT_DSC_HASH_BYTE_OFF, (op->digest_offset & 0x7)) | + FIELD_VALUE(PKT_DSC_PKTLEN_BYTES, 0) | + /* NONCE_HI, PKT_DSC_LASTWORD, CFB_MASK, CKSUM_DST_ADDR */ + FIELD_VALUE(PKT_DSC_IV_OFF_HI, 0); + + } + switch (op->pkt_lastword) { + case XLR_SEC_LASTWORD_128: + CLEAR_SET_FIELD(pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_128); + if (multi_frag_flag) { + CLEAR_SET_FIELD(next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_128); + + } + break; + case XLR_SEC_LASTWORD_96MASK: + CLEAR_SET_FIELD(pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_96MASK); + if (multi_frag_flag) { + CLEAR_SET_FIELD(next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_96MASK); + } + break; + case XLR_SEC_LASTWORD_64MASK: + CLEAR_SET_FIELD(pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_64MASK); + if (multi_frag_flag) { + CLEAR_SET_FIELD(next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_64MASK); + } + break; + case XLR_SEC_LASTWORD_32MASK: + CLEAR_SET_FIELD(pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_32MASK); + if (multi_frag_flag) { + CLEAR_SET_FIELD(next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_LASTWORD, PKT_DSC_LASTWORD_32MASK); + } + break; + default: + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: ERR_LASTWORD_MODE EXIT\n"); + return XLR_SEC_ERR_LASTWORD_MODE; + } + CLEAR_SET_FIELD(pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_CFB_MASK, op->cfb_mask); + CLEAR_SET_FIELD(pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_NONCE_HI, htonl(op->nonce) >> 24); + CLEAR_SET_FIELD(pkt_desc->authDstNonceLow, + PKT_DSC_NONCE_LOW, htonl(op->nonce) & 0xffffff); + + if (multi_frag_flag) { + CLEAR_SET_FIELD(next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_CFB_MASK, op->cfb_mask); + CLEAR_SET_FIELD(next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_NONCE_HI, htonl(op->nonce) >> 24); + CLEAR_SET_FIELD(next_pkt_desc->authDstNonceLow, + PKT_DSC_NONCE_LOW, htonl(op->nonce) & 0xffffff); + + + } + /* Auth Dest Address must be Cacheline aligned on input */ + if (vector & (XLR_SEC_VECTOR_MAC | XLR_SEC_VECTOR_HMAC | XLR_SEC_VECTOR_HMAC2 | XLR_SEC_VECTOR_GCM | XLR_SEC_VECTOR_F9)) { + pkt_desc->authDstNonceLow |= + /* NONCE_LOW */ + FIELD_VALUE(PKT_DSC_AUTH_DST_ADDR, + (uint64_t) vtophys((void *)(unsigned long)op->auth_dest)) | + FIELD_VALUE(PKT_DSC_CIPH_OFF_HI, 0); + + + if (multi_frag_flag) { + next_pkt_desc->authDstNonceLow |= + /* NONCE_LOW */ + FIELD_VALUE(PKT_DSC_AUTH_DST_ADDR, + (uint64_t) vtophys((void *)(unsigned long)desc->next_auth_dest)) | + FIELD_VALUE(PKT_DSC_CIPH_OFF_HI, 0); + + + } + } + /* CkSum Dest Address must be Cacheline aligned on input */ + if (op->cksum_type == XLR_SEC_CKSUM_TYPE_IP) { + CLEAR_SET_FIELD(pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_CKSUM_DST_ADDR, + (uint64_t) vtophys((void *)(unsigned long)op->cksum_dest)); + + if (multi_frag_flag) { + CLEAR_SET_FIELD(next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask, + PKT_DSC_CKSUM_DST_ADDR, + (uint64_t) vtophys((void *)(unsigned long)desc->next_cksum_dest)); + + } + } + /* + * XLR_SEC_CMD_DIAG (" xlr_sec_setup_packet(): pkt_desc=%llx + * phys_pkt_desc=%llx \n", (unsigned long long)pkt_desc, (unsigned + * long long)virt_to_phys(pkt_desc)); (unsigned long long)pkt_desc, + * (unsigned long long)vtophys(pkt_desc)); + */ + XLR_SEC_CMD_DIAG(" xlr_sec_setup_packet(): pkt_desc=%p phys_pkt_desc=%llx \n", + pkt_desc, (unsigned long long)vtophys(pkt_desc)); + + + + CLEAR_SET_FIELD(*data, MSG_CMD_DATA_ADDR, ((uint64_t) vtophys(pkt_desc))); + CLEAR_SET_FIELD(*data, MSG_CMD_DATA_CTL, SEC_EOP); + CLEAR_SET_FIELD(*data, MSG_CMD_DATA_LEN, MSG_CMD_DATA_LEN_LOAD); + + + XLR_SEC_CMD_DIAG("xlr_sec_setup_packet: DONE\n"); #ifdef RMI_SEC_DEBUG - { - printf("data desc\n"); - printf("srcLengthIVOffUseIVNext = 0x%llx\n",pkt_desc->srcLengthIVOffUseIVNext ); - printf("dstDataSettings = 0x%llx\n", pkt_desc->dstDataSettings); - printf("authDstNonceLow = 0x%llx\n", pkt_desc->authDstNonceLow); - printf("ckSumDstNonceHiCFBMaskLLWMask = 0x%llx\n", pkt_desc->ckSumDstNonceHiCFBMaskLLWMask); - } + { + printf("data desc\n"); + printf("srcLengthIVOffUseIVNext = 0x%llx\n", pkt_desc->srcLengthIVOffUseIVNext); + printf("dstDataSettings = 0x%llx\n", pkt_desc->dstDataSettings); + printf("authDstNonceLow = 0x%llx\n", pkt_desc->authDstNonceLow); + printf("ckSumDstNonceHiCFBMaskLLWMask = 0x%llx\n", pkt_desc->ckSumDstNonceHiCFBMaskLLWMask); + } - if(multi_frag_flag){ - - printf("next data desc\n"); - printf("srcLengthIVOffUseIVNext = 0x%llx\n",next_pkt_desc->srcLengthIVOffUseIVNext ); - printf("dstDataSettings = 0x%llx\n", next_pkt_desc->dstDataSettings); - printf("authDstNonceLow = 0x%llx\n", next_pkt_desc->authDstNonceLow); - printf("ckSumDstNonceHiCFBMaskLLWMask = 0x%llx\n", next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask); - } + if (multi_frag_flag) { + printf("next data desc\n"); + printf("srcLengthIVOffUseIVNext = 0x%llx\n", next_pkt_desc->srcLengthIVOffUseIVNext); + printf("dstDataSettings = 0x%llx\n", next_pkt_desc->dstDataSettings); + printf("authDstNonceLow = 0x%llx\n", next_pkt_desc->authDstNonceLow); + printf("ckSumDstNonceHiCFBMaskLLWMask = 0x%llx\n", next_pkt_desc->ckSumDstNonceHiCFBMaskLLWMask); + } #endif #ifdef SYMBOL - if (op->cipher_type == XLR_SEC_CIPHER_TYPE_ARC4) { - op->source_buf -= 0; - op->source_buf_size += 0; - op->dest_buf -= 0; - } + if (op->cipher_type == XLR_SEC_CIPHER_TYPE_ARC4) { + op->source_buf -= 0; + op->source_buf_size += 0; + op->dest_buf -= 0; + } #endif - return XLR_SEC_ERR_NONE; + return XLR_SEC_ERR_NONE; } -static int identify_symkey_ctl_error(uint32_t code, xlr_sec_error_t err) +static int +identify_symkey_ctl_error(uint32_t code, xlr_sec_error_t err) { - int ret_val = EINVAL; + int ret_val = EINVAL; - switch(code) { - case CTL_ERR_NONE: - XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error: No Error\n"); - ret_val = 0; - break; - case CTL_ERR_CIPHER_OP: - XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error(CTL_ERR_CIPHER_OP) - Unknown Cipher Op \n"); - break; - case CTL_ERR_MODE: - XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error(CTL_ERR_MODE) - " - "Unknown or Not Allowed Mode \n"); - break; - case CTL_ERR_CHKSUM_SRC: - XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error(CTL_ERR_CHKSUM_SRC) - Unknown CkSum Src\n"); - break; - case CTL_ERR_CFB_MASK: - XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error(CTL_ERR_CFB_MASK) - Forbidden CFB Mask \n"); - break; - case CTL_ERR_OP: - XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error(CTL_ERR_OP) - Unknown Ctrl Op \n"); - break; - case CTL_ERR_DATA_READ: - XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error(CTL_ERR_DATA_READ) - Data Read Error\n"); - break; - case CTL_ERR_DESC_CTRL: - XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error(CTL_ERR_DESC_CTRL) - " - "Descriptor Ctrl Field Error \n"); - break; - case CTL_ERR_UNDEF1: - case CTL_ERR_UNDEF2: - default: - XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error: UNKNOWN CODE=%d \n", code); - break; - } - return ret_val; + switch (code) { + case CTL_ERR_NONE: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error: No Error\n"); + ret_val = 0; + break; + case CTL_ERR_CIPHER_OP: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error(CTL_ERR_CIPHER_OP) - Unknown Cipher Op \n"); + break; + case CTL_ERR_MODE: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error(CTL_ERR_MODE) - " + "Unknown or Not Allowed Mode \n"); + break; + case CTL_ERR_CHKSUM_SRC: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error(CTL_ERR_CHKSUM_SRC) - Unknown CkSum Src\n"); + break; + case CTL_ERR_CFB_MASK: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error(CTL_ERR_CFB_MASK) - Forbidden CFB Mask \n"); + break; + case CTL_ERR_OP: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error(CTL_ERR_OP) - Unknown Ctrl Op \n"); + break; + case CTL_ERR_DATA_READ: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error(CTL_ERR_DATA_READ) - Data Read Error\n"); + break; + case CTL_ERR_DESC_CTRL: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error(CTL_ERR_DESC_CTRL) - " + "Descriptor Ctrl Field Error \n"); + break; + case CTL_ERR_UNDEF1: + case CTL_ERR_UNDEF2: + default: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: CTL Error: UNKNOWN CODE=%d \n", code); + break; + } + return ret_val; } static -int identify_symkey_data_error(uint32_t code, xlr_sec_error_t err) +int +identify_symkey_data_error(uint32_t code, xlr_sec_error_t err) { - int ret_val = -EINVAL; + int ret_val = -EINVAL; - switch(code) { - case DATA_ERR_NONE: - XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error No Error\n"); - ret_val = 0; - break; - case DATA_ERR_LEN_CIPHER: - XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Not Enough Data To Cipher\n"); - break; - case DATA_ERR_IV_ADDR: - XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Illegal IV Loacation\n"); - break; - case DATA_ERR_WD_LEN_AES: - XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Illegal Nb Words To AES\n"); - break; - case DATA_ERR_BYTE_COUNT: - XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Illegal Pad And ByteCount Spec\n"); - break; - case DATA_ERR_LEN_CKSUM: - XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Not Enough Data To CkSum\n"); - break; - case DATA_ERR_OP: - XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Unknown Data Op \n"); - break; - case DATA_ERR_READ: - XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Data Read Error \n"); - break; - case DATA_ERR_WRITE: - XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Data Write Error \n"); - break; - case DATA_ERR_UNDEF1: - default: - XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error - UNKNOWN CODE=%d \n", code); - break; - } - return ret_val; + switch (code) { + case DATA_ERR_NONE: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error No Error\n"); + ret_val = 0; + break; + case DATA_ERR_LEN_CIPHER: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Not Enough Data To Cipher\n"); + break; + case DATA_ERR_IV_ADDR: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Illegal IV Loacation\n"); + break; + case DATA_ERR_WD_LEN_AES: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Illegal Nb Words To AES\n"); + break; + case DATA_ERR_BYTE_COUNT: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Illegal Pad And ByteCount Spec\n"); + break; + case DATA_ERR_LEN_CKSUM: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Not Enough Data To CkSum\n"); + break; + case DATA_ERR_OP: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Unknown Data Op \n"); + break; + case DATA_ERR_READ: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Data Read Error \n"); + break; + case DATA_ERR_WRITE: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error() - Data Write Error \n"); + break; + case DATA_ERR_UNDEF1: + default: + XLR_SEC_CMD_DIAG("XLR_SEC_SEC: DATA Error - UNKNOWN CODE=%d \n", code); + break; + } + return ret_val; } static int xlr_sec_submit_message(symkey_desc_pt desc, uint32_t cfg_vector) { - xlr_sec_error_t err; - uint32_t ctl_error, data_error; - int ret_val = 0; + xlr_sec_error_t err; + uint32_t ctl_error, data_error; + int ret_val = 0; - XLR_SEC_CMD_DIAG("xlr_sec_submit_message: ENTER\n"); - - err = XLR_SEC_ERR_NONE; + XLR_SEC_CMD_DIAG("xlr_sec_submit_message: ENTER\n"); - XLR_SEC_CMD_DIAG_SYM_DESC(desc, cfg_vector); + err = XLR_SEC_ERR_NONE; - do { - /* For now, send message and wait for response */ - err = xlr_sec_submit_op(desc); + XLR_SEC_CMD_DIAG_SYM_DESC(desc, cfg_vector); - XLR_SEC_CMD_DIAG("xlr_sec_submit_message: err = %d \n", (uint32_t)err); + do { + /* For now, send message and wait for response */ + err = xlr_sec_submit_op(desc); - if( err != XLR_SEC_ERR_NONE ) { - ret_val = (EINVAL); - break; - } + XLR_SEC_CMD_DIAG("xlr_sec_submit_message: err = %d \n", (uint32_t) err); - ctl_error = desc->ctl_result; - data_error = desc->data_result; - - XLR_SEC_CMD_DIAG("xlr_sec_submit_message: ctl_error = %x data_error = %x\n", - ctl_error, data_error); + if (err != XLR_SEC_ERR_NONE) { + ret_val = (EINVAL); + break; + } + ctl_error = desc->ctl_result; + data_error = desc->data_result; - if ((ret_val = identify_symkey_ctl_error(ctl_error, err)) == 0) - ret_val = identify_symkey_data_error(data_error, err); + XLR_SEC_CMD_DIAG("xlr_sec_submit_message: ctl_error = %x data_error = %x\n", + ctl_error, data_error); - XLR_SEC_CMD_DIAG("xlr_sec_submit_message: identify error = %d \n", ret_val ); + if ((ret_val = identify_symkey_ctl_error(ctl_error, err)) == 0) + ret_val = identify_symkey_data_error(data_error, err); - } while( 0 ); + XLR_SEC_CMD_DIAG("xlr_sec_submit_message: identify error = %d \n", ret_val); - XLR_SEC_CMD_DIAG("xlr_sec_submit_message: DONE\n"); - return (ret_val); + } while (0); + + XLR_SEC_CMD_DIAG("xlr_sec_submit_message: DONE\n"); + return (ret_val); } static -xlr_sec_error_t xlr_sec_setup_cipher(xlr_sec_io_pt op, - ControlDescriptor_pt ctl_desc, - uint32_t *vector) +xlr_sec_error_t +xlr_sec_setup_cipher(xlr_sec_io_pt op, + ControlDescriptor_pt ctl_desc, + uint32_t * vector) { - uint32_t aes_flag = 0; - uint32_t cipher_vector = 0; + uint32_t aes_flag = 0; + uint32_t cipher_vector = 0; - XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ENTER vector = %04x\n", *vector); + XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ENTER vector = %04x\n", *vector); - switch (op->cipher_type) { - case XLR_SEC_CIPHER_TYPE_NONE: - SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_BYPASS); - XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: CIPHER_TYPE_NONE EXIT\n"); - return XLR_SEC_ERR_NONE; - case XLR_SEC_CIPHER_TYPE_DES: - cipher_vector |= XLR_SEC_VECTOR_CIPHER_DES; - SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_DES); - break; - case XLR_SEC_CIPHER_TYPE_3DES: - cipher_vector |= XLR_SEC_VECTOR_CIPHER_3DES; - SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_3DES); - break; - case XLR_SEC_CIPHER_TYPE_AES128: - aes_flag = 1; - cipher_vector |= XLR_SEC_VECTOR_CIPHER_AES128; - SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_AES128); - break; - case XLR_SEC_CIPHER_TYPE_AES192: - aes_flag = 1; - cipher_vector |= XLR_SEC_VECTOR_CIPHER_AES192; - SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_AES192); - break; - case XLR_SEC_CIPHER_TYPE_AES256: - aes_flag = 1; - cipher_vector |= XLR_SEC_VECTOR_CIPHER_AES256; - SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_AES256); - break; - case XLR_SEC_CIPHER_TYPE_ARC4: - cipher_vector |= XLR_SEC_VECTOR_CIPHER_ARC4; - SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_ARC4); - SET_FIELD(ctl_desc->instruction, CTL_DSC_ARC4_KEYLEN, - op->rc4_key_len); - SET_FIELD(ctl_desc->instruction, CTL_DSC_ARC4_LOADSTATE, - op->rc4_loadstate); - SET_FIELD(ctl_desc->instruction, CTL_DSC_ARC4_SAVESTATE, - op->rc4_savestate); - if (op->rc4_loadstate || op->rc4_savestate) - cipher_vector |= XLR_SEC_VECTOR_STATE; - break; - case XLR_SEC_CIPHER_TYPE_KASUMI_F8: - aes_flag = 1; - cipher_vector |= XLR_SEC_VECTOR_CIPHER_KASUMI_F8; - SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_KASUMI_F8); - break; - default: - XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ERR_CIPHER_TYPE EXIT\n"); - return XLR_SEC_ERR_CIPHER_TYPE; - } - - switch (op->cipher_mode) { - case XLR_SEC_CIPHER_MODE_ECB: - if (aes_flag == 1) - cipher_vector |= XLR_SEC_VECTOR_MODE_ECB_CBC_OFB; - else - cipher_vector |= XLR_SEC_VECTOR_MODE_ECB_CBC; - SET_FIELD(ctl_desc->instruction, CTL_DSC_MODE, CTL_DSC_MODE_ECB); - break; - case XLR_SEC_CIPHER_MODE_CBC: - if (aes_flag == 1) - cipher_vector |= XLR_SEC_VECTOR_MODE_ECB_CBC_OFB; - else - cipher_vector |= XLR_SEC_VECTOR_MODE_ECB_CBC; - SET_FIELD(ctl_desc->instruction, CTL_DSC_MODE, CTL_DSC_MODE_CBC); - break; - case XLR_SEC_CIPHER_MODE_OFB: - if (aes_flag == 0) { - XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ERR_CIPHER_MODE EXIT\n"); - return XLR_SEC_ERR_CIPHER_MODE; + switch (op->cipher_type) { + case XLR_SEC_CIPHER_TYPE_NONE: + SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_BYPASS); + XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: CIPHER_TYPE_NONE EXIT\n"); + return XLR_SEC_ERR_NONE; + case XLR_SEC_CIPHER_TYPE_DES: + cipher_vector |= XLR_SEC_VECTOR_CIPHER_DES; + SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_DES); + break; + case XLR_SEC_CIPHER_TYPE_3DES: + cipher_vector |= XLR_SEC_VECTOR_CIPHER_3DES; + SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_3DES); + break; + case XLR_SEC_CIPHER_TYPE_AES128: + aes_flag = 1; + cipher_vector |= XLR_SEC_VECTOR_CIPHER_AES128; + SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_AES128); + break; + case XLR_SEC_CIPHER_TYPE_AES192: + aes_flag = 1; + cipher_vector |= XLR_SEC_VECTOR_CIPHER_AES192; + SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_AES192); + break; + case XLR_SEC_CIPHER_TYPE_AES256: + aes_flag = 1; + cipher_vector |= XLR_SEC_VECTOR_CIPHER_AES256; + SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_AES256); + break; + case XLR_SEC_CIPHER_TYPE_ARC4: + cipher_vector |= XLR_SEC_VECTOR_CIPHER_ARC4; + SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_ARC4); + SET_FIELD(ctl_desc->instruction, CTL_DSC_ARC4_KEYLEN, + op->rc4_key_len); + SET_FIELD(ctl_desc->instruction, CTL_DSC_ARC4_LOADSTATE, + op->rc4_loadstate); + SET_FIELD(ctl_desc->instruction, CTL_DSC_ARC4_SAVESTATE, + op->rc4_savestate); + if (op->rc4_loadstate || op->rc4_savestate) + cipher_vector |= XLR_SEC_VECTOR_STATE; + break; + case XLR_SEC_CIPHER_TYPE_KASUMI_F8: + aes_flag = 1; + cipher_vector |= XLR_SEC_VECTOR_CIPHER_KASUMI_F8; + SET_FIELD(ctl_desc->instruction, CTL_DSC_CPHR, CTL_DSC_CPHR_KASUMI_F8); + break; + default: + XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ERR_CIPHER_TYPE EXIT\n"); + return XLR_SEC_ERR_CIPHER_TYPE; } - cipher_vector |= XLR_SEC_VECTOR_MODE_ECB_CBC_OFB; - SET_FIELD(ctl_desc->instruction, CTL_DSC_MODE, CTL_DSC_MODE_OFB); - break; - case XLR_SEC_CIPHER_MODE_CTR: - if (aes_flag == 0) { - XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ERR_CIPHER_MODE EXIT\n"); - return XLR_SEC_ERR_CIPHER_MODE; + + switch (op->cipher_mode) { + case XLR_SEC_CIPHER_MODE_ECB: + if (aes_flag == 1) + cipher_vector |= XLR_SEC_VECTOR_MODE_ECB_CBC_OFB; + else + cipher_vector |= XLR_SEC_VECTOR_MODE_ECB_CBC; + SET_FIELD(ctl_desc->instruction, CTL_DSC_MODE, CTL_DSC_MODE_ECB); + break; + case XLR_SEC_CIPHER_MODE_CBC: + if (aes_flag == 1) + cipher_vector |= XLR_SEC_VECTOR_MODE_ECB_CBC_OFB; + else + cipher_vector |= XLR_SEC_VECTOR_MODE_ECB_CBC; + SET_FIELD(ctl_desc->instruction, CTL_DSC_MODE, CTL_DSC_MODE_CBC); + break; + case XLR_SEC_CIPHER_MODE_OFB: + if (aes_flag == 0) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ERR_CIPHER_MODE EXIT\n"); + return XLR_SEC_ERR_CIPHER_MODE; + } + cipher_vector |= XLR_SEC_VECTOR_MODE_ECB_CBC_OFB; + SET_FIELD(ctl_desc->instruction, CTL_DSC_MODE, CTL_DSC_MODE_OFB); + break; + case XLR_SEC_CIPHER_MODE_CTR: + if (aes_flag == 0) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ERR_CIPHER_MODE EXIT\n"); + return XLR_SEC_ERR_CIPHER_MODE; + } + cipher_vector |= XLR_SEC_VECTOR_MODE_CTR_CFB; + SET_FIELD(ctl_desc->instruction, CTL_DSC_MODE, CTL_DSC_MODE_CTR); + break; + case XLR_SEC_CIPHER_MODE_CFB: + if (aes_flag == 0) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ERR_CIPHER_MODE EXIT\n"); + return XLR_SEC_ERR_CIPHER_MODE; + } + cipher_vector |= XLR_SEC_VECTOR_MODE_CTR_CFB; + SET_FIELD(ctl_desc->instruction, CTL_DSC_MODE, CTL_DSC_MODE_CFB); + break; + case XLR_SEC_CIPHER_MODE_F8: + if (aes_flag == 0) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ERR_CIPHER_MODE EXIT\n"); + return XLR_SEC_ERR_CIPHER_MODE; + } + cipher_vector |= XLR_SEC_VECTOR_MODE_F8; + SET_FIELD(ctl_desc->instruction, CTL_DSC_MODE, CTL_DSC_MODE_F8); + break; + default: + if (!(cipher_vector & (XLR_SEC_VECTOR_CIPHER_ARC4 | XLR_SEC_VECTOR_CIPHER_KASUMI_F8))) { + XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ERR_CIPHER_MODE EXIT\n"); + return XLR_SEC_ERR_CIPHER_MODE; + } } - cipher_vector |= XLR_SEC_VECTOR_MODE_CTR_CFB; - SET_FIELD(ctl_desc->instruction, CTL_DSC_MODE, CTL_DSC_MODE_CTR); - break; - case XLR_SEC_CIPHER_MODE_CFB: - if (aes_flag == 0) { - XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ERR_CIPHER_MODE EXIT\n"); - return XLR_SEC_ERR_CIPHER_MODE; + + switch (op->cipher_init) { + case XLR_SEC_CIPHER_INIT_OK: + SET_FIELD(ctl_desc->instruction, + CTL_DSC_ICPHR, CTL_DSC_ICPHR_OKY); + break; + + case XLR_SEC_CIPHER_INIT_NK: + SET_FIELD(ctl_desc->instruction, + CTL_DSC_ICPHR, CTL_DSC_ICPHR_NKY); + break; + default: + XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ERR_CIPHER_INIT EXIT\n"); + return XLR_SEC_ERR_CIPHER_INIT; } - cipher_vector |= XLR_SEC_VECTOR_MODE_CTR_CFB; - SET_FIELD(ctl_desc->instruction, CTL_DSC_MODE, CTL_DSC_MODE_CFB); - break; - case XLR_SEC_CIPHER_MODE_F8: - if (aes_flag == 0) { - XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ERR_CIPHER_MODE EXIT\n"); - return XLR_SEC_ERR_CIPHER_MODE; - } - cipher_vector |= XLR_SEC_VECTOR_MODE_F8; - SET_FIELD(ctl_desc->instruction, CTL_DSC_MODE, CTL_DSC_MODE_F8); - break; - default: - if (!(cipher_vector & (XLR_SEC_VECTOR_CIPHER_ARC4 | XLR_SEC_VECTOR_CIPHER_KASUMI_F8))) { - XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ERR_CIPHER_MODE EXIT\n"); - return XLR_SEC_ERR_CIPHER_MODE; - } - } - switch (op->cipher_init) { - case XLR_SEC_CIPHER_INIT_OK: - SET_FIELD(ctl_desc->instruction, - CTL_DSC_ICPHR, CTL_DSC_ICPHR_OKY); - break; + *vector |= cipher_vector; - case XLR_SEC_CIPHER_INIT_NK: - SET_FIELD(ctl_desc->instruction, - CTL_DSC_ICPHR, CTL_DSC_ICPHR_NKY); - break; - default: - XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: ERR_CIPHER_INIT EXIT\n"); - return XLR_SEC_ERR_CIPHER_INIT; - } + XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: EXIT vector = %04x\n", *vector); - *vector |= cipher_vector; - - XLR_SEC_CMD_DIAG("xlr_sec_setup_cipher: EXIT vector = %04x\n", *vector); - - return XLR_SEC_ERR_NONE; + return XLR_SEC_ERR_NONE; } static -xlr_sec_error_t xlr_sec_setup_digest(xlr_sec_io_pt op, - ControlDescriptor_pt ctl_desc, - uint32_t *vector) +xlr_sec_error_t +xlr_sec_setup_digest(xlr_sec_io_pt op, + ControlDescriptor_pt ctl_desc, + uint32_t * vector) { - uint32_t hash_flag = 0; - uint32_t hmac_flag = 0; - uint32_t digest_vector = 0; + uint32_t hash_flag = 0; + uint32_t hmac_flag = 0; + uint32_t digest_vector = 0; - XLR_SEC_CMD_DIAG("xlr_sec_setup_digest: ENTER vector = %04x\n", *vector); - - switch (op->digest_type) { - case XLR_SEC_DIGEST_TYPE_MD5: - digest_vector |= XLR_SEC_VECTOR_MAC; - SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_MD5); - break; - case XLR_SEC_DIGEST_TYPE_SHA1: - digest_vector |= XLR_SEC_VECTOR_MAC; - SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA1); - break; - case XLR_SEC_DIGEST_TYPE_SHA256: - digest_vector |= XLR_SEC_VECTOR_MAC; - SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA256); - break; - case XLR_SEC_DIGEST_TYPE_SHA384: - digest_vector |= XLR_SEC_VECTOR_MAC; - SET_FIELD(ctl_desc->instruction, CTL_DSC_HASHHI, CTL_DSC_HASH_SHA384>>2); - SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA384); - break; - case XLR_SEC_DIGEST_TYPE_SHA512: - digest_vector |= XLR_SEC_VECTOR_MAC; - SET_FIELD(ctl_desc->instruction, CTL_DSC_HASHHI, CTL_DSC_HASH_SHA512>>2); - SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA512); - break; - case XLR_SEC_DIGEST_TYPE_GCM: - hash_flag = 1; - digest_vector |= XLR_SEC_VECTOR_GCM; - SET_FIELD(ctl_desc->instruction, CTL_DSC_HASHHI, CTL_DSC_HASH_GCM>>2); - SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_GCM); - break; - case XLR_SEC_DIGEST_TYPE_KASUMI_F9: - hash_flag = 1; - digest_vector |= XLR_SEC_VECTOR_F9; - SET_FIELD(ctl_desc->instruction, CTL_DSC_HASHHI, CTL_DSC_HASH_KASUMI_F9>>2); - SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_KASUMI_F9); - break; - case XLR_SEC_DIGEST_TYPE_HMAC_MD5: - hmac_flag = 1; - digest_vector |= XLR_SEC_VECTOR_HMAC; - SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_MD5); - break; - case XLR_SEC_DIGEST_TYPE_HMAC_SHA1: - hmac_flag = 1; - digest_vector |= XLR_SEC_VECTOR_HMAC; - SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA1); - break; - case XLR_SEC_DIGEST_TYPE_HMAC_SHA256: - hmac_flag = 1; - digest_vector |= XLR_SEC_VECTOR_HMAC; - SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA256); - break; - case XLR_SEC_DIGEST_TYPE_HMAC_SHA384: - hmac_flag = 1; - digest_vector |= XLR_SEC_VECTOR_HMAC2; - SET_FIELD(ctl_desc->instruction, CTL_DSC_HASHHI, CTL_DSC_HASH_SHA384>>2); - SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA384); - break; - case XLR_SEC_DIGEST_TYPE_HMAC_SHA512: - hmac_flag = 1; - digest_vector |= XLR_SEC_VECTOR_HMAC2; - SET_FIELD(ctl_desc->instruction, CTL_DSC_HASHHI, CTL_DSC_HASH_SHA512>>2); - SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA512); - break; - default: - return XLR_SEC_ERR_DIGEST_TYPE; - } + XLR_SEC_CMD_DIAG("xlr_sec_setup_digest: ENTER vector = %04x\n", *vector); - if (hmac_flag == 1) { - SET_FIELD(ctl_desc->instruction, CTL_DSC_HMAC, CTL_DSC_HMAC_ON); + switch (op->digest_type) { + case XLR_SEC_DIGEST_TYPE_MD5: + digest_vector |= XLR_SEC_VECTOR_MAC; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_MD5); + break; + case XLR_SEC_DIGEST_TYPE_SHA1: + digest_vector |= XLR_SEC_VECTOR_MAC; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA1); + break; + case XLR_SEC_DIGEST_TYPE_SHA256: + digest_vector |= XLR_SEC_VECTOR_MAC; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA256); + break; + case XLR_SEC_DIGEST_TYPE_SHA384: + digest_vector |= XLR_SEC_VECTOR_MAC; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASHHI, CTL_DSC_HASH_SHA384 >> 2); + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA384); + break; + case XLR_SEC_DIGEST_TYPE_SHA512: + digest_vector |= XLR_SEC_VECTOR_MAC; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASHHI, CTL_DSC_HASH_SHA512 >> 2); + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA512); + break; + case XLR_SEC_DIGEST_TYPE_GCM: + hash_flag = 1; + digest_vector |= XLR_SEC_VECTOR_GCM; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASHHI, CTL_DSC_HASH_GCM >> 2); + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_GCM); + break; + case XLR_SEC_DIGEST_TYPE_KASUMI_F9: + hash_flag = 1; + digest_vector |= XLR_SEC_VECTOR_F9; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASHHI, CTL_DSC_HASH_KASUMI_F9 >> 2); + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_KASUMI_F9); + break; + case XLR_SEC_DIGEST_TYPE_HMAC_MD5: + hmac_flag = 1; + digest_vector |= XLR_SEC_VECTOR_HMAC; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_MD5); + break; + case XLR_SEC_DIGEST_TYPE_HMAC_SHA1: + hmac_flag = 1; + digest_vector |= XLR_SEC_VECTOR_HMAC; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA1); + break; + case XLR_SEC_DIGEST_TYPE_HMAC_SHA256: + hmac_flag = 1; + digest_vector |= XLR_SEC_VECTOR_HMAC; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA256); + break; + case XLR_SEC_DIGEST_TYPE_HMAC_SHA384: + hmac_flag = 1; + digest_vector |= XLR_SEC_VECTOR_HMAC2; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASHHI, CTL_DSC_HASH_SHA384 >> 2); + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA384); + break; + case XLR_SEC_DIGEST_TYPE_HMAC_SHA512: + hmac_flag = 1; + digest_vector |= XLR_SEC_VECTOR_HMAC2; + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASHHI, CTL_DSC_HASH_SHA512 >> 2); + SET_FIELD(ctl_desc->instruction, CTL_DSC_HASH, CTL_DSC_HASH_SHA512); + break; + default: + return XLR_SEC_ERR_DIGEST_TYPE; + } - } - if (hmac_flag || hash_flag) { - switch (op->digest_init) { - case XLR_SEC_DIGEST_INIT_OLDKEY: - SET_FIELD(ctl_desc->instruction, CTL_DSC_IHASH, CTL_DSC_IHASH_OLD); - break; - case XLR_SEC_DIGEST_INIT_NEWKEY: - SET_FIELD(ctl_desc->instruction, CTL_DSC_IHASH, CTL_DSC_IHASH_NEW); - break; - default: - return XLR_SEC_ERR_DIGEST_INIT; - } - } /* hmac_flag */ + if (hmac_flag == 1) { + SET_FIELD(ctl_desc->instruction, CTL_DSC_HMAC, CTL_DSC_HMAC_ON); - *vector |= digest_vector; + } + if (hmac_flag || hash_flag) { + switch (op->digest_init) { + case XLR_SEC_DIGEST_INIT_OLDKEY: + SET_FIELD(ctl_desc->instruction, CTL_DSC_IHASH, CTL_DSC_IHASH_OLD); + break; + case XLR_SEC_DIGEST_INIT_NEWKEY: + SET_FIELD(ctl_desc->instruction, CTL_DSC_IHASH, CTL_DSC_IHASH_NEW); + break; + default: + return XLR_SEC_ERR_DIGEST_INIT; + } + } /* hmac_flag */ + *vector |= digest_vector; - XLR_SEC_CMD_DIAG("xlr_sec_setup_digest: EXIT vector = %04x\n", *vector); + XLR_SEC_CMD_DIAG("xlr_sec_setup_digest: EXIT vector = %04x\n", *vector); - return XLR_SEC_ERR_NONE; + return XLR_SEC_ERR_NONE; } static -xlr_sec_error_t xlr_sec_setup_cksum(xlr_sec_io_pt op, - ControlDescriptor_pt ctl_desc) +xlr_sec_error_t +xlr_sec_setup_cksum(xlr_sec_io_pt op, + ControlDescriptor_pt ctl_desc) { - switch (op->cksum_type) { - case XLR_SEC_CKSUM_TYPE_NOP: - SET_FIELD(ctl_desc->instruction, CTL_DSC_CKSUM, CTL_DSC_CKSUM_NOP); - return XLR_SEC_ERR_NONE; - case XLR_SEC_CKSUM_TYPE_IP: - SET_FIELD(ctl_desc->instruction, CTL_DSC_CKSUM, CTL_DSC_CKSUM_IP); - break; - default: - return XLR_SEC_ERR_CKSUM_TYPE; - } + switch (op->cksum_type) { + case XLR_SEC_CKSUM_TYPE_NOP: + SET_FIELD(ctl_desc->instruction, CTL_DSC_CKSUM, CTL_DSC_CKSUM_NOP); + return XLR_SEC_ERR_NONE; + case XLR_SEC_CKSUM_TYPE_IP: + SET_FIELD(ctl_desc->instruction, CTL_DSC_CKSUM, CTL_DSC_CKSUM_IP); + break; + default: + return XLR_SEC_ERR_CKSUM_TYPE; + } - return XLR_SEC_ERR_NONE; + return XLR_SEC_ERR_NONE; } static -xlr_sec_error_t xlr_sec_control_setup (xlr_sec_io_pt op, - unsigned int flags, - uint64_t *control, - ControlDescriptor_pt ctl_desc, - xlr_sec_drv_user_t *user, - uint32_t vector) +xlr_sec_error_t +xlr_sec_control_setup(xlr_sec_io_pt op, + unsigned int flags, + uint64_t * control, + ControlDescriptor_pt ctl_desc, + xlr_sec_drv_user_t * user, + uint32_t vector) { - uint64_t *hmac_key = NULL; - uint64_t *cipher_key = NULL; - uint64_t *cipher_state = NULL; - uint32_t ctl_size = 0; - uint64_t ctl_addr = 0; - uint32_t cipher_keylen = 0; - uint32_t hmac_keylen = 0; - uint32_t ctl_len; + uint64_t *hmac_key = NULL; + uint64_t *cipher_key = NULL; + uint64_t *cipher_state = NULL; + uint32_t ctl_size = 0; + uint64_t ctl_addr = 0; + uint32_t cipher_keylen = 0; + uint32_t hmac_keylen = 0; + uint32_t ctl_len; #ifdef SYM_DEBUG - XLR_SEC_CMD_DIAG(" ENTER vector = %04x\n", vector); + XLR_SEC_CMD_DIAG(" ENTER vector = %04x\n", vector); #endif - switch (vector) { - case XLR_SEC_VECTOR_MAC: - XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR_MAC \n"); - ctl_size = sizeof(HMAC_t); - break; - case XLR_SEC_VECTOR_HMAC: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_HMAC \n"); - hmac_key = &ctl_desc->cipherHashInfo.infoHMAC.hmacKey0; - hmac_keylen = sizeof(HMAC_t); - ctl_size = sizeof(HMAC_t); - break; - case XLR_SEC_VECTOR_CIPHER_ARC4: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4\n"); - cipher_key = &ctl_desc->cipherHashInfo.infoARC4.cipherKey0; - cipher_keylen = op->rc4_key_len; - ctl_size = sizeof(ARC4_t); - break; - case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__HMAC\n"); - cipher_key = &ctl_desc->cipherHashInfo.infoARC4HMAC.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoARC4HMAC.hmacKey0; - cipher_keylen = op->rc4_key_len; - hmac_keylen = sizeof(HMAC_t); - ctl_size = sizeof(ARC4HMAC_t); - break; - case XLR_SEC_VECTOR_CIPHER_ARC4__STATE: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__STATE\n"); - cipher_key = &ctl_desc->cipherHashInfo.infoARC4State.cipherKey0; - cipher_state = - &ctl_desc->cipherHashInfo.infoARC4State.Arc4SboxData0; - cipher_keylen = op->rc4_key_len; - ctl_size = sizeof(ARC4State_t); - break; - case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC__STATE: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__HMAC__STATE\n"); - cipher_key = &ctl_desc->cipherHashInfo.infoARC4StateHMAC.cipherKey0; - cipher_state = - &ctl_desc->cipherHashInfo.infoARC4StateHMAC.Arc4SboxData0; - hmac_key = &ctl_desc->cipherHashInfo.infoARC4StateHMAC.hmacKey0; - cipher_keylen = op->rc4_key_len; - hmac_keylen = sizeof(HMAC_t); - ctl_size = sizeof(ARC4StateHMAC_t); - break; - case XLR_SEC_VECTOR_CIPHER_KASUMI_F8: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_KASUMI_F8\n"); - cipher_key = &ctl_desc->cipherHashInfo.infoKASUMIF8.cipherKey0; - cipher_keylen = XLR_SEC_KASUMI_F8_KEY_LENGTH; - ctl_size = sizeof(KASUMIF8_t); - break; - case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC\n"); - cipher_key = &ctl_desc->cipherHashInfo.infoKASUMIF8HMAC.cipherKey0; - cipher_keylen = XLR_SEC_KASUMI_F8_KEY_LENGTH; - hmac_key = &ctl_desc->cipherHashInfo.infoKASUMIF8HMAC.hmacKey0; - hmac_keylen = sizeof(HMAC_t); - ctl_size = sizeof(KASUMIF8HMAC_t); - break; - case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC2: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC2\n"); - cipher_key = &ctl_desc->cipherHashInfo.infoKASUMIF8HMAC2.cipherKey0; - cipher_keylen = XLR_SEC_KASUMI_F8_KEY_LENGTH; - hmac_key = &ctl_desc->cipherHashInfo.infoKASUMIF8HMAC2.hmacKey0; - hmac_keylen = sizeof(HMAC2_t); - ctl_size = sizeof(KASUMIF8HMAC2_t); - break; - case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__GCM: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__GCM\n"); - cipher_key = &ctl_desc->cipherHashInfo.infoKASUMIF8GCM.cipherKey0; - cipher_keylen = XLR_SEC_KASUMI_F8_KEY_LENGTH; - hmac_key = &ctl_desc->cipherHashInfo.infoKASUMIF8GCM.GCMH0; - hmac_keylen = sizeof(GCM_t); - ctl_size = sizeof(KASUMIF8GCM_t); - break; - case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__F9: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__F9\n"); - cipher_key = &ctl_desc->cipherHashInfo.infoKASUMIF8F9.cipherKey0; - cipher_keylen = XLR_SEC_KASUMI_F8_KEY_LENGTH; - hmac_key = &ctl_desc->cipherHashInfo.infoKASUMIF8F9.authKey0; - hmac_keylen = sizeof(F9_t); - ctl_size = sizeof(KASUMIF8F9_t); - break; - case XLR_SEC_VECTOR__CIPHER_DES__HMAC__MODE_ECB_CBC: - XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_DES__HMAC__MODE_ECB_CBC \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoDESHMAC.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoDESHMAC.hmacKey0; - hmac_keylen = sizeof(HMAC_t); - cipher_keylen = XLR_SEC_DES_KEY_LENGTH; - ctl_size = sizeof(DESHMAC_t); - break; - case XLR_SEC_VECTOR__CIPHER_DES__MODE_ECB_CBC: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_DES__MODE_ECB_CBC \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoDES.cipherKey0; - cipher_keylen = XLR_SEC_DES_KEY_LENGTH; - ctl_size = sizeof(DES_t); - break; - case XLR_SEC_VECTOR__CIPHER_3DES__HMAC__MODE_ECB_CBC: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_3DES__HMAC__MODE_ECB_CBC \n"); - cipher_key = &ctl_desc->cipherHashInfo.info3DESHMAC.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.info3DESHMAC.hmacKey0; - cipher_keylen = XLR_SEC_3DES_KEY_LENGTH; - hmac_keylen = sizeof(HMAC_t); - ctl_size = sizeof(DES3HMAC_t); - break; - case XLR_SEC_VECTOR__CIPHER_3DES__MODE_ECB_CBC: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_3DES__MODE_ECB_CBC \n"); - cipher_key = &ctl_desc->cipherHashInfo.info3DES.cipherKey0; - cipher_keylen = XLR_SEC_3DES_KEY_LENGTH; - ctl_size = sizeof(DES3_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_CTR_CFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_CTR_CFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES128HMAC.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES128HMAC.hmacKey0; - cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; - hmac_keylen = sizeof(HMAC_t); - ctl_size = sizeof(AES128HMAC_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__MODE_CTR_CFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__MODE_CTR_CFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES128.cipherKey0; - cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; - ctl_size = sizeof(AES128_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_ECB_CBC_OFB: - XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_ECB_CBC_OFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES128HMAC.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES128HMAC.hmacKey0; - cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; - hmac_keylen = sizeof(HMAC_t); - ctl_size = sizeof(AES128HMAC_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__MODE_ECB_CBC_OFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__MODE_ECB_CBC_OFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES128.cipherKey0; - cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; - ctl_size = sizeof(AES128_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_F8: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_F8 \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES128F8HMAC.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES128F8HMAC.hmacKey0; - cipher_keylen = XLR_SEC_AES128F8_KEY_LENGTH; - hmac_keylen = sizeof(HMAC_t); - ctl_size = sizeof(AES128F8HMAC_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__MODE_F8: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__MODE_F8 \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES128F8.cipherKey0; - cipher_keylen = XLR_SEC_AES128F8_KEY_LENGTH; - ctl_size = sizeof(AES128F8_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_CTR_CFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_CTR_CFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES192HMAC.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES192HMAC.hmacKey0; - cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; - hmac_keylen = sizeof(HMAC_t); - ctl_size = sizeof(AES192HMAC_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__MODE_CTR_CFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__MODE_CTR_CFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES192.cipherKey0; - cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; - ctl_size = sizeof(AES192_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_ECB_CBC_OFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_ECB_CBC_OFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES192HMAC.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES192HMAC.hmacKey0; - cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; - hmac_keylen = sizeof(HMAC_t); - ctl_size = sizeof(AES192HMAC_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__MODE_ECB_CBC_OFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__MODE_ECB_CBC_OFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES192.cipherKey0; - cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; - ctl_size = sizeof(AES192_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_F8: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_F8 \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES192F8HMAC.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES192F8HMAC.hmacKey0; - cipher_keylen = XLR_SEC_AES192F8_KEY_LENGTH; - hmac_keylen = sizeof(HMAC_t); - ctl_size = sizeof(AES192F8HMAC_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__MODE_F8: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__MODE_F8 \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES192F8.cipherKey0; - cipher_keylen = XLR_SEC_AES192F8_KEY_LENGTH; - ctl_size = sizeof(AES192F8_t); - break; + switch (vector) { + case XLR_SEC_VECTOR_MAC: + XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR_MAC \n"); + ctl_size = sizeof(HMAC_t); + break; + case XLR_SEC_VECTOR_HMAC: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_HMAC \n"); + hmac_key = &ctl_desc->cipherHashInfo.infoHMAC.hmacKey0; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(HMAC_t); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoARC4.cipherKey0; + cipher_keylen = op->rc4_key_len; + ctl_size = sizeof(ARC4_t); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__HMAC\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoARC4HMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoARC4HMAC.hmacKey0; + cipher_keylen = op->rc4_key_len; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(ARC4HMAC_t); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__STATE: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__STATE\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoARC4State.cipherKey0; + cipher_state = + &ctl_desc->cipherHashInfo.infoARC4State.Arc4SboxData0; + cipher_keylen = op->rc4_key_len; + ctl_size = sizeof(ARC4State_t); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC__STATE: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__HMAC__STATE\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoARC4StateHMAC.cipherKey0; + cipher_state = + &ctl_desc->cipherHashInfo.infoARC4StateHMAC.Arc4SboxData0; + hmac_key = &ctl_desc->cipherHashInfo.infoARC4StateHMAC.hmacKey0; + cipher_keylen = op->rc4_key_len; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(ARC4StateHMAC_t); + break; + case XLR_SEC_VECTOR_CIPHER_KASUMI_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_KASUMI_F8\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoKASUMIF8.cipherKey0; + cipher_keylen = XLR_SEC_KASUMI_F8_KEY_LENGTH; + ctl_size = sizeof(KASUMIF8_t); + break; + case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoKASUMIF8HMAC.cipherKey0; + cipher_keylen = XLR_SEC_KASUMI_F8_KEY_LENGTH; + hmac_key = &ctl_desc->cipherHashInfo.infoKASUMIF8HMAC.hmacKey0; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(KASUMIF8HMAC_t); + break; + case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC2: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC2\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoKASUMIF8HMAC2.cipherKey0; + cipher_keylen = XLR_SEC_KASUMI_F8_KEY_LENGTH; + hmac_key = &ctl_desc->cipherHashInfo.infoKASUMIF8HMAC2.hmacKey0; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(KASUMIF8HMAC2_t); + break; + case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__GCM: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__GCM\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoKASUMIF8GCM.cipherKey0; + cipher_keylen = XLR_SEC_KASUMI_F8_KEY_LENGTH; + hmac_key = &ctl_desc->cipherHashInfo.infoKASUMIF8GCM.GCMH0; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(KASUMIF8GCM_t); + break; + case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__F9: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__F9\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoKASUMIF8F9.cipherKey0; + cipher_keylen = XLR_SEC_KASUMI_F8_KEY_LENGTH; + hmac_key = &ctl_desc->cipherHashInfo.infoKASUMIF8F9.authKey0; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(KASUMIF8F9_t); + break; + case XLR_SEC_VECTOR__CIPHER_DES__HMAC__MODE_ECB_CBC: + XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_DES__HMAC__MODE_ECB_CBC \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoDESHMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoDESHMAC.hmacKey0; + hmac_keylen = sizeof(HMAC_t); + cipher_keylen = XLR_SEC_DES_KEY_LENGTH; + ctl_size = sizeof(DESHMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_DES__MODE_ECB_CBC: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_DES__MODE_ECB_CBC \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoDES.cipherKey0; + cipher_keylen = XLR_SEC_DES_KEY_LENGTH; + ctl_size = sizeof(DES_t); + break; + case XLR_SEC_VECTOR__CIPHER_3DES__HMAC__MODE_ECB_CBC: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_3DES__HMAC__MODE_ECB_CBC \n"); + cipher_key = &ctl_desc->cipherHashInfo.info3DESHMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.info3DESHMAC.hmacKey0; + cipher_keylen = XLR_SEC_3DES_KEY_LENGTH; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(DES3HMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_3DES__MODE_ECB_CBC: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_3DES__MODE_ECB_CBC \n"); + cipher_key = &ctl_desc->cipherHashInfo.info3DES.cipherKey0; + cipher_keylen = XLR_SEC_3DES_KEY_LENGTH; + ctl_size = sizeof(DES3_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128HMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128HMAC.hmacKey0; + cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(AES128HMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128.cipherKey0; + cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; + ctl_size = sizeof(AES128_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128HMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128HMAC.hmacKey0; + cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(AES128HMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128.cipherKey0; + cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; + ctl_size = sizeof(AES128_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128F8HMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128F8HMAC.hmacKey0; + cipher_keylen = XLR_SEC_AES128F8_KEY_LENGTH; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(AES128F8HMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128F8.cipherKey0; + cipher_keylen = XLR_SEC_AES128F8_KEY_LENGTH; + ctl_size = sizeof(AES128F8_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192HMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192HMAC.hmacKey0; + cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(AES192HMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192.cipherKey0; + cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; + ctl_size = sizeof(AES192_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192HMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192HMAC.hmacKey0; + cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(AES192HMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192.cipherKey0; + cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; + ctl_size = sizeof(AES192_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192F8HMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192F8HMAC.hmacKey0; + cipher_keylen = XLR_SEC_AES192F8_KEY_LENGTH; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(AES192F8HMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192F8.cipherKey0; + cipher_keylen = XLR_SEC_AES192F8_KEY_LENGTH; + ctl_size = sizeof(AES192F8_t); + break; - case XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_CTR_CFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_CTR_CFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES256HMAC.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES256HMAC.hmacKey0; - cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; - hmac_keylen = sizeof(HMAC_t); - ctl_size = sizeof(AES256HMAC_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__MODE_CTR_CFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__MODE_CTR_CFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES256.cipherKey0; - cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; - ctl_size = sizeof(AES256_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_ECB_CBC_OFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_ECB_CBC_OFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES256HMAC.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES256HMAC.hmacKey0; - cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; - hmac_keylen = sizeof(HMAC_t); - ctl_size = sizeof(AES256HMAC_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__MODE_ECB_CBC_OFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__MODE_ECB_CBC_OFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES256.cipherKey0; - cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; - ctl_size = sizeof(AES256_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_F8: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_F8 \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES256F8HMAC.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES256F8HMAC.hmacKey0; - cipher_keylen = XLR_SEC_AES256F8_KEY_LENGTH; - hmac_keylen = sizeof(HMAC_t); - ctl_size = sizeof(AES256F8HMAC_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__MODE_F8: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__MODE_F8 \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES256F8.cipherKey0; - cipher_keylen = XLR_SEC_AES256F8_KEY_LENGTH; - ctl_size = sizeof(AES256F8_t); - break; - case XLR_SEC_VECTOR_HMAC2: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_HMAC2 \n"); - hmac_key = &ctl_desc->cipherHashInfo.infoHMAC2.hmacKey0; - hmac_keylen = sizeof(HMAC2_t); - ctl_size = sizeof(HMAC2_t); - break; - case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2\n"); - cipher_key = &ctl_desc->cipherHashInfo.infoARC4HMAC2.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoARC4HMAC2.hmacKey0; - cipher_keylen = op->rc4_key_len; - hmac_keylen = sizeof(HMAC2_t); - ctl_size = sizeof(ARC4HMAC2_t); - break; - case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2__STATE: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2__STATE\n"); - cipher_key = &ctl_desc->cipherHashInfo.infoARC4StateHMAC2.cipherKey0; - cipher_state = - &ctl_desc->cipherHashInfo.infoARC4StateHMAC2.Arc4SboxData0; - hmac_key = &ctl_desc->cipherHashInfo.infoARC4StateHMAC2.hmacKey0; - cipher_keylen = op->rc4_key_len; - hmac_keylen = sizeof(HMAC2_t); - ctl_size = sizeof(ARC4StateHMAC2_t); - break; - case XLR_SEC_VECTOR__CIPHER_DES__HMAC2__MODE_ECB_CBC: - XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_DES__HMAC2__MODE_ECB_CBC \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoDESHMAC2.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoDESHMAC2.hmacKey0; - hmac_keylen = sizeof(HMAC2_t); - cipher_keylen = XLR_SEC_DES_KEY_LENGTH; - ctl_size = sizeof(DESHMAC2_t); - break; - case XLR_SEC_VECTOR__CIPHER_3DES__HMAC2__MODE_ECB_CBC: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_3DES__HMAC2__MODE_ECB_CBC \n"); - cipher_key = &ctl_desc->cipherHashInfo.info3DESHMAC2.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.info3DESHMAC2.hmacKey0; - cipher_keylen = XLR_SEC_3DES_KEY_LENGTH; - hmac_keylen = sizeof(HMAC2_t); - ctl_size = sizeof(DES3HMAC2_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_CTR_CFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_CTR_CFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES128HMAC2.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES128HMAC2.hmacKey0; - cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; - hmac_keylen = sizeof(HMAC2_t); - ctl_size = sizeof(AES128HMAC2_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_ECB_CBC_OFB: - XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_ECB_CBC_OFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES128HMAC2.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES128HMAC2.hmacKey0; - cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; - hmac_keylen = sizeof(HMAC2_t); - ctl_size = sizeof(AES128HMAC2_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_F8: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_F8 \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES128F8HMAC2.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES128F8HMAC2.hmacKey0; - cipher_keylen = XLR_SEC_AES128F8_KEY_LENGTH; - hmac_keylen = sizeof(HMAC2_t); - ctl_size = sizeof(AES128F8HMAC2_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_CTR_CFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_CTR_CFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES192HMAC2.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES192HMAC2.hmacKey0; - cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; - hmac_keylen = sizeof(HMAC2_t); - ctl_size = sizeof(AES192HMAC2_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_ECB_CBC_OFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_ECB_CBC_OFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES192HMAC2.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES192HMAC2.hmacKey0; - cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; - hmac_keylen = sizeof(HMAC2_t); - ctl_size = sizeof(AES192HMAC2_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_F8: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_F8 \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES192F8HMAC2.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES192F8HMAC2.hmacKey0; - cipher_keylen = XLR_SEC_AES192F8_KEY_LENGTH; - hmac_keylen = sizeof(HMAC2_t); - ctl_size = sizeof(AES192F8HMAC2_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_CTR_CFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_CTR_CFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES256HMAC2.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES256HMAC2.hmacKey0; - cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; - hmac_keylen = sizeof(HMAC2_t); - ctl_size = sizeof(AES256HMAC2_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_ECB_CBC_OFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_ECB_CBC_OFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES256HMAC2.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES256HMAC2.hmacKey0; - cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; - hmac_keylen = sizeof(HMAC2_t); - ctl_size = sizeof(AES256HMAC2_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_F8: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_F8 \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES256F8HMAC2.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES256F8HMAC2.hmacKey0; - cipher_keylen = XLR_SEC_AES256F8_KEY_LENGTH; - hmac_keylen = sizeof(HMAC2_t); - ctl_size = sizeof(AES256F8HMAC2_t); - break; - case XLR_SEC_VECTOR_GCM: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_GCM \n"); - hmac_key = &ctl_desc->cipherHashInfo.infoGCM.GCMH0; - hmac_keylen = sizeof(GCM_t); - ctl_size = sizeof(GCM_t); - break; - case XLR_SEC_VECTOR_CIPHER_ARC4__GCM: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__GCM\n"); - cipher_key = &ctl_desc->cipherHashInfo.infoARC4GCM.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoARC4GCM.GCMH0; - cipher_keylen = op->rc4_key_len; - hmac_keylen = sizeof(GCM_t); - ctl_size = sizeof(ARC4GCM_t); - break; - case XLR_SEC_VECTOR_CIPHER_ARC4__GCM__STATE: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__GCM__STATE\n"); - cipher_key = &ctl_desc->cipherHashInfo.infoARC4StateGCM.cipherKey0; - cipher_state = - &ctl_desc->cipherHashInfo.infoARC4StateGCM.Arc4SboxData0; - hmac_key = &ctl_desc->cipherHashInfo.infoARC4StateGCM.GCMH0; - cipher_keylen = op->rc4_key_len; - hmac_keylen = sizeof(GCM_t); - ctl_size = sizeof(ARC4StateGCM_t); - break; - case XLR_SEC_VECTOR__CIPHER_DES__GCM__MODE_ECB_CBC: - XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_DES__GCM__MODE_ECB_CBC \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoDESGCM.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoDESGCM.GCMH0; - hmac_keylen = sizeof(GCM_t); - cipher_keylen = XLR_SEC_DES_KEY_LENGTH; - ctl_size = sizeof(DESGCM_t); - break; - case XLR_SEC_VECTOR__CIPHER_3DES__GCM__MODE_ECB_CBC: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_3DES__GCM__MODE_ECB_CBC \n"); - cipher_key = &ctl_desc->cipherHashInfo.info3DESGCM.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.info3DESGCM.GCMH0; - cipher_keylen = XLR_SEC_3DES_KEY_LENGTH; - hmac_keylen = sizeof(GCM_t); - ctl_size = sizeof(DES3GCM_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_CTR_CFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_CTR_CFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES128GCM.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES128GCM.GCMH0; - cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; - hmac_keylen = sizeof(GCM_t); - ctl_size = sizeof(AES128GCM_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_ECB_CBC_OFB: - XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_ECB_CBC_OFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES128GCM.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES128GCM.GCMH0; - cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; - hmac_keylen = sizeof(GCM_t); - ctl_size = sizeof(AES128GCM_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_F8: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_F8 \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES128F8GCM.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES128F8GCM.GCMH0; - cipher_keylen = XLR_SEC_AES128F8_KEY_LENGTH; - hmac_keylen = sizeof(GCM_t); - ctl_size = sizeof(AES128F8GCM_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_CTR_CFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_CTR_CFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES192GCM.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES192GCM.GCMH0; - cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; - hmac_keylen = sizeof(GCM_t); - ctl_size = sizeof(AES192GCM_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_ECB_CBC_OFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_ECB_CBC_OFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES192GCM.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES192GCM.GCMH0; - cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; - hmac_keylen = sizeof(GCM_t); - ctl_size = sizeof(AES192GCM_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_F8: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_F8 \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES192F8GCM.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES192F8GCM.GCMH0; - cipher_keylen = XLR_SEC_AES192F8_KEY_LENGTH; - hmac_keylen = sizeof(GCM_t); - ctl_size = sizeof(AES192F8GCM_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_CTR_CFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_CTR_CFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES256GCM.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES256GCM.GCMH0; - cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; - hmac_keylen = sizeof(GCM_t); - ctl_size = sizeof(AES256GCM_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_ECB_CBC_OFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_ECB_CBC_OFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES256GCM.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES256GCM.GCMH0; - cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; - hmac_keylen = sizeof(GCM_t); - ctl_size = sizeof(AES256GCM_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_F8: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_F8 \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES256F8GCM.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES256F8GCM.GCMH0; - cipher_keylen = XLR_SEC_AES256F8_KEY_LENGTH; - hmac_keylen = sizeof(GCM_t); - ctl_size = sizeof(AES256F8GCM_t); - break; - case XLR_SEC_VECTOR_F9: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_F9 \n"); - hmac_key = &ctl_desc->cipherHashInfo.infoF9.authKey0; - hmac_keylen = sizeof(F9_t); - ctl_size = sizeof(F9_t); - break; - case XLR_SEC_VECTOR_CIPHER_ARC4__F9: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__F9\n"); - cipher_key = &ctl_desc->cipherHashInfo.infoARC4F9.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoARC4F9.authKey0; - cipher_keylen = op->rc4_key_len; - hmac_keylen = sizeof(F9_t); - ctl_size = sizeof(ARC4F9_t); - break; - case XLR_SEC_VECTOR_CIPHER_ARC4__F9__STATE: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__F9__STATE\n"); - cipher_key = &ctl_desc->cipherHashInfo.infoARC4StateF9.cipherKey0; - cipher_state = - &ctl_desc->cipherHashInfo.infoARC4StateF9.Arc4SboxData0; - hmac_key = &ctl_desc->cipherHashInfo.infoARC4StateF9.authKey0; - cipher_keylen = op->rc4_key_len; - hmac_keylen = sizeof(F9_t); - ctl_size = sizeof(ARC4StateF9_t); - break; - case XLR_SEC_VECTOR__CIPHER_DES__F9__MODE_ECB_CBC: - XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_DES__F9__MODE_ECB_CBC \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoDESF9.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoDESF9.authKey0; - hmac_keylen = sizeof(F9_t); - cipher_keylen = XLR_SEC_DES_KEY_LENGTH; - ctl_size = sizeof(DESF9_t); - break; - case XLR_SEC_VECTOR__CIPHER_3DES__F9__MODE_ECB_CBC: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_3DES__F9__MODE_ECB_CBC \n"); - cipher_key = &ctl_desc->cipherHashInfo.info3DESF9.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.info3DESF9.authKey0; - cipher_keylen = XLR_SEC_3DES_KEY_LENGTH; - hmac_keylen = sizeof(F9_t); - ctl_size = sizeof(DES3F9_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_CTR_CFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_CTR_CFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES128F9.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES128F9.authKey0; - cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; - hmac_keylen = sizeof(F9_t); - ctl_size = sizeof(AES128F9_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_ECB_CBC_OFB: - XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_ECB_CBC_OFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES128F9.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES128F9.authKey0; - cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; - hmac_keylen = sizeof(F9_t); - ctl_size = sizeof(AES128F9_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_F8: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_F8 \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES128F8F9.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES128F8F9.authKey0; - cipher_keylen = XLR_SEC_AES128F8_KEY_LENGTH; - hmac_keylen = sizeof(F9_t); - ctl_size = sizeof(AES128F8F9_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_CTR_CFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_CTR_CFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES192F9.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES192F9.authKey0; - cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; - hmac_keylen = sizeof(F9_t); - ctl_size = sizeof(AES192F9_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_ECB_CBC_OFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_ECB_CBC_OFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES192F9.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES192F9.authKey0; - cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; - hmac_keylen = sizeof(F9_t); - ctl_size = sizeof(AES192F9_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_F8: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_F8 \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES192F8F9.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES192F8F9.authKey0; - cipher_keylen = XLR_SEC_AES192F8_KEY_LENGTH; - hmac_keylen = sizeof(F9_t); - ctl_size = sizeof(AES192F8F9_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_CTR_CFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_CTR_CFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES256F9.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES256F9.authKey0; - cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; - hmac_keylen = sizeof(F9_t); - ctl_size = sizeof(AES256F9_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_ECB_CBC_OFB: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_ECB_CBC_OFB \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES256F9.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES256F9.authKey0; - cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; - hmac_keylen = sizeof(F9_t); - ctl_size = sizeof(AES256F9_t); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_F8: - XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_F8 \n"); - cipher_key = &ctl_desc->cipherHashInfo.infoAES256F8F9.cipherKey0; - hmac_key = &ctl_desc->cipherHashInfo.infoAES256F8F9.authKey0; - cipher_keylen = XLR_SEC_AES256F8_KEY_LENGTH; - hmac_keylen = sizeof(F9_t); - ctl_size = sizeof(AES256F8F9_t); - break; + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256HMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256HMAC.hmacKey0; + cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(AES256HMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256.cipherKey0; + cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; + ctl_size = sizeof(AES256_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256HMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256HMAC.hmacKey0; + cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(AES256HMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256.cipherKey0; + cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; + ctl_size = sizeof(AES256_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256F8HMAC.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256F8HMAC.hmacKey0; + cipher_keylen = XLR_SEC_AES256F8_KEY_LENGTH; + hmac_keylen = sizeof(HMAC_t); + ctl_size = sizeof(AES256F8HMAC_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256F8.cipherKey0; + cipher_keylen = XLR_SEC_AES256F8_KEY_LENGTH; + ctl_size = sizeof(AES256F8_t); + break; + case XLR_SEC_VECTOR_HMAC2: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_HMAC2 \n"); + hmac_key = &ctl_desc->cipherHashInfo.infoHMAC2.hmacKey0; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(HMAC2_t); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoARC4HMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoARC4HMAC2.hmacKey0; + cipher_keylen = op->rc4_key_len; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(ARC4HMAC2_t); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2__STATE: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2__STATE\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoARC4StateHMAC2.cipherKey0; + cipher_state = + &ctl_desc->cipherHashInfo.infoARC4StateHMAC2.Arc4SboxData0; + hmac_key = &ctl_desc->cipherHashInfo.infoARC4StateHMAC2.hmacKey0; + cipher_keylen = op->rc4_key_len; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(ARC4StateHMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_DES__HMAC2__MODE_ECB_CBC: + XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_DES__HMAC2__MODE_ECB_CBC \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoDESHMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoDESHMAC2.hmacKey0; + hmac_keylen = sizeof(HMAC2_t); + cipher_keylen = XLR_SEC_DES_KEY_LENGTH; + ctl_size = sizeof(DESHMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_3DES__HMAC2__MODE_ECB_CBC: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_3DES__HMAC2__MODE_ECB_CBC \n"); + cipher_key = &ctl_desc->cipherHashInfo.info3DESHMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.info3DESHMAC2.hmacKey0; + cipher_keylen = XLR_SEC_3DES_KEY_LENGTH; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(DES3HMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128HMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128HMAC2.hmacKey0; + cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(AES128HMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128HMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128HMAC2.hmacKey0; + cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(AES128HMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128F8HMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128F8HMAC2.hmacKey0; + cipher_keylen = XLR_SEC_AES128F8_KEY_LENGTH; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(AES128F8HMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192HMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192HMAC2.hmacKey0; + cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(AES192HMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192HMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192HMAC2.hmacKey0; + cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(AES192HMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192F8HMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192F8HMAC2.hmacKey0; + cipher_keylen = XLR_SEC_AES192F8_KEY_LENGTH; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(AES192F8HMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256HMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256HMAC2.hmacKey0; + cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(AES256HMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256HMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256HMAC2.hmacKey0; + cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(AES256HMAC2_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256F8HMAC2.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256F8HMAC2.hmacKey0; + cipher_keylen = XLR_SEC_AES256F8_KEY_LENGTH; + hmac_keylen = sizeof(HMAC2_t); + ctl_size = sizeof(AES256F8HMAC2_t); + break; + case XLR_SEC_VECTOR_GCM: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_GCM \n"); + hmac_key = &ctl_desc->cipherHashInfo.infoGCM.GCMH0; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(GCM_t); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__GCM: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__GCM\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoARC4GCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoARC4GCM.GCMH0; + cipher_keylen = op->rc4_key_len; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(ARC4GCM_t); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__GCM__STATE: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__GCM__STATE\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoARC4StateGCM.cipherKey0; + cipher_state = + &ctl_desc->cipherHashInfo.infoARC4StateGCM.Arc4SboxData0; + hmac_key = &ctl_desc->cipherHashInfo.infoARC4StateGCM.GCMH0; + cipher_keylen = op->rc4_key_len; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(ARC4StateGCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_DES__GCM__MODE_ECB_CBC: + XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_DES__GCM__MODE_ECB_CBC \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoDESGCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoDESGCM.GCMH0; + hmac_keylen = sizeof(GCM_t); + cipher_keylen = XLR_SEC_DES_KEY_LENGTH; + ctl_size = sizeof(DESGCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_3DES__GCM__MODE_ECB_CBC: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_3DES__GCM__MODE_ECB_CBC \n"); + cipher_key = &ctl_desc->cipherHashInfo.info3DESGCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.info3DESGCM.GCMH0; + cipher_keylen = XLR_SEC_3DES_KEY_LENGTH; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(DES3GCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128GCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128GCM.GCMH0; + cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(AES128GCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128GCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128GCM.GCMH0; + cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(AES128GCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128F8GCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128F8GCM.GCMH0; + cipher_keylen = XLR_SEC_AES128F8_KEY_LENGTH; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(AES128F8GCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192GCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192GCM.GCMH0; + cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(AES192GCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192GCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192GCM.GCMH0; + cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(AES192GCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192F8GCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192F8GCM.GCMH0; + cipher_keylen = XLR_SEC_AES192F8_KEY_LENGTH; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(AES192F8GCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256GCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256GCM.GCMH0; + cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(AES256GCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256GCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256GCM.GCMH0; + cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(AES256GCM_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256F8GCM.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256F8GCM.GCMH0; + cipher_keylen = XLR_SEC_AES256F8_KEY_LENGTH; + hmac_keylen = sizeof(GCM_t); + ctl_size = sizeof(AES256F8GCM_t); + break; + case XLR_SEC_VECTOR_F9: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_F9 \n"); + hmac_key = &ctl_desc->cipherHashInfo.infoF9.authKey0; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(F9_t); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__F9: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__F9\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoARC4F9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoARC4F9.authKey0; + cipher_keylen = op->rc4_key_len; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(ARC4F9_t); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__F9__STATE: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR_CIPHER_ARC4__F9__STATE\n"); + cipher_key = &ctl_desc->cipherHashInfo.infoARC4StateF9.cipherKey0; + cipher_state = + &ctl_desc->cipherHashInfo.infoARC4StateF9.Arc4SboxData0; + hmac_key = &ctl_desc->cipherHashInfo.infoARC4StateF9.authKey0; + cipher_keylen = op->rc4_key_len; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(ARC4StateF9_t); + break; + case XLR_SEC_VECTOR__CIPHER_DES__F9__MODE_ECB_CBC: + XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_DES__F9__MODE_ECB_CBC \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoDESF9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoDESF9.authKey0; + hmac_keylen = sizeof(F9_t); + cipher_keylen = XLR_SEC_DES_KEY_LENGTH; + ctl_size = sizeof(DESF9_t); + break; + case XLR_SEC_VECTOR__CIPHER_3DES__F9__MODE_ECB_CBC: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_3DES__F9__MODE_ECB_CBC \n"); + cipher_key = &ctl_desc->cipherHashInfo.info3DESF9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.info3DESF9.authKey0; + cipher_keylen = XLR_SEC_3DES_KEY_LENGTH; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(DES3F9_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128F9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128F9.authKey0; + cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(AES128F9_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG(" XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128F9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128F9.authKey0; + cipher_keylen = XLR_SEC_AES128_KEY_LENGTH; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(AES128F9_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES128F8F9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES128F8F9.authKey0; + cipher_keylen = XLR_SEC_AES128F8_KEY_LENGTH; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(AES128F8F9_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192F9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192F9.authKey0; + cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(AES192F9_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192F9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192F9.authKey0; + cipher_keylen = XLR_SEC_AES192_KEY_LENGTH; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(AES192F9_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES192F8F9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES192F8F9.authKey0; + cipher_keylen = XLR_SEC_AES192F8_KEY_LENGTH; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(AES192F8F9_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_CTR_CFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_CTR_CFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256F9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256F9.authKey0; + cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(AES256F9_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_ECB_CBC_OFB: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_ECB_CBC_OFB \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256F9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256F9.authKey0; + cipher_keylen = XLR_SEC_AES256_KEY_LENGTH; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(AES256F9_t); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_F8: + XLR_SEC_CMD_DIAG("XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_F8 \n"); + cipher_key = &ctl_desc->cipherHashInfo.infoAES256F8F9.cipherKey0; + hmac_key = &ctl_desc->cipherHashInfo.infoAES256F8F9.authKey0; + cipher_keylen = XLR_SEC_AES256F8_KEY_LENGTH; + hmac_keylen = sizeof(F9_t); + ctl_size = sizeof(AES256F8F9_t); + break; - default: - XLR_SEC_CMD_DIAG("default \n"); - return XLR_SEC_ERR_CONTROL_VECTOR; - } + default: + XLR_SEC_CMD_DIAG("default \n"); + return XLR_SEC_ERR_CONTROL_VECTOR; + } - if ((cipher_key != NULL) && !(flags & XLR_SEC_SETUP_OP_PRESERVE_CIPHER_KEY)) - memcpy(cipher_key, &op->crypt_key[0], cipher_keylen); + if ((cipher_key != NULL) && !(flags & XLR_SEC_SETUP_OP_PRESERVE_CIPHER_KEY)) + memcpy(cipher_key, &op->crypt_key[0], cipher_keylen); - if ((hmac_key != NULL) && !(flags & XLR_SEC_SETUP_OP_PRESERVE_HMAC_KEY)) - memcpy(hmac_key, &op->mac_key[0], hmac_keylen); - if (cipher_state) { - if (op->rc4_loadstate) - memcpy(cipher_state, (void *)(unsigned long)op->rc4_state, + if ((hmac_key != NULL) && !(flags & XLR_SEC_SETUP_OP_PRESERVE_HMAC_KEY)) + memcpy(hmac_key, &op->mac_key[0], hmac_keylen); + if (cipher_state) { + if (op->rc4_loadstate) + memcpy(cipher_state, (void *)(unsigned long)op->rc4_state, XLR_SEC_MAX_RC4_STATE_SIZE); - if (op->rc4_savestate) - user->aligned_state = (char *)cipher_state; - } + if (op->rc4_savestate) + user->aligned_state = (char *)cipher_state; + } + if (flags & XLR_SEC_SETUP_OP_FLIP_3DES_KEY) { + uint64_t temp; - if (flags & XLR_SEC_SETUP_OP_FLIP_3DES_KEY) { - uint64_t temp; + temp = ctl_desc->cipherHashInfo.info3DES.cipherKey0; + ctl_desc->cipherHashInfo.info3DES.cipherKey0 = + ctl_desc->cipherHashInfo.info3DES.cipherKey2; + ctl_desc->cipherHashInfo.info3DES.cipherKey2 = temp; + } + /* + * Control length is the number of control cachelines to be read so + * user needs to round up the control length to closest integer + * multiple of 32 bytes. + */ + ctl_size += sizeof(ctl_desc->instruction); + ctl_len = NUM_CHUNKS(ctl_size, 5); + XLR_SEC_CMD_DIAG("ctl_size in bytes: %u, in cachelines: %u\n", ctl_size, ctl_len); + CLEAR_SET_FIELD(*control, MSG_CMD_CTL_LEN, ctl_len); - temp = ctl_desc->cipherHashInfo.info3DES.cipherKey0; - ctl_desc->cipherHashInfo.info3DES.cipherKey0 = - ctl_desc->cipherHashInfo.info3DES.cipherKey2; - ctl_desc->cipherHashInfo.info3DES.cipherKey2 = temp; - } + ctl_addr = (uint64_t) vtophys(ctl_desc); + CLEAR_SET_FIELD(*control, MSG_CMD_CTL_ADDR, ctl_addr); - /* - * Control length is the number of control cachelines to be read so - * user needs to round up the control length to closest integer - * multiple of 32 bytes. - */ - ctl_size += sizeof(ctl_desc->instruction); - ctl_len = NUM_CHUNKS(ctl_size, 5); - XLR_SEC_CMD_DIAG("ctl_size in bytes: %u, in cachelines: %u\n", ctl_size, ctl_len); - CLEAR_SET_FIELD(*control, MSG_CMD_CTL_LEN, ctl_len); + XLR_SEC_CMD_DIAG(" xlr_sec_control_setup(): ctl_desc=%p ctl_addr=%llx \n", + ctl_desc, (unsigned long long)ctl_addr); - ctl_addr = (uint64_t)vtophys(ctl_desc); - CLEAR_SET_FIELD(*control, MSG_CMD_CTL_ADDR, ctl_addr); + CLEAR_SET_FIELD(*control, MSG_CMD_CTL_CTL, SEC_SOP); - XLR_SEC_CMD_DIAG(" xlr_sec_control_setup(): ctl_desc=%p ctl_addr=%llx \n", - ctl_desc, (unsigned long long)ctl_addr); - - CLEAR_SET_FIELD(*control, MSG_CMD_CTL_CTL, SEC_SOP); - - return XLR_SEC_ERR_NONE; + return XLR_SEC_ERR_NONE; } xlr_sec_error_t xlr_sec_submit_op(symkey_desc_pt desc) { - struct msgrng_msg send_msg; + struct msgrng_msg send_msg; - int rsp_dest_id, cpu, hard_cpu, hard_thread; - int code, retries; - unsigned long msgrng_flags = 0; + int rsp_dest_id, cpu, hard_cpu, hard_thread; + int code, retries; + unsigned long msgrng_flags = 0; - /* threads (0-3) are orthogonal to buckets 0-3 */ - cpu = xlr_cpu_id(); + /* threads (0-3) are orthogonal to buckets 0-3 */ + cpu = xlr_cpu_id(); - hard_cpu = cpu >> 2; - hard_thread = cpu & 0x3; /* thread id */ - rsp_dest_id = (hard_cpu << 3) + hard_thread; + hard_cpu = cpu >> 2; + hard_thread = cpu & 0x3;/* thread id */ + rsp_dest_id = (hard_cpu << 3) + hard_thread; - desc->op_ctl.cpu = hard_cpu; - desc->op_ctl.flags = 0; /* called from kernel thread */ + desc->op_ctl.cpu = hard_cpu; + desc->op_ctl.flags = 0; /* called from kernel thread */ - XLR_SEC_CMD_DIAG("[%s]:%d: cpu=0x%x hard_cpu=0x%x hard_thrd=0x%x id=0x%x \n", - __FUNCTION__, __LINE__, cpu, hard_cpu, hard_thread, rsp_dest_id); + XLR_SEC_CMD_DIAG("[%s]:%d: cpu=0x%x hard_cpu=0x%x hard_thrd=0x%x id=0x%x \n", + __FUNCTION__, __LINE__, cpu, hard_cpu, hard_thread, rsp_dest_id); - /* - * Set DestId in Message Control Word. - * This tells the Security Engine which bucket to send the - * reply to for this CPU - */ - CLEAR_SET_FIELD(desc->control, MSG_CMD_CTL_ID, rsp_dest_id); - CLEAR_SET_FIELD(desc->data, MSG_CMD_CTL_ID, rsp_dest_id); + /* + * Set DestId in Message Control Word. This tells the Security + * Engine which bucket to send the reply to for this CPU + */ + CLEAR_SET_FIELD(desc->control, MSG_CMD_CTL_ID, rsp_dest_id); + CLEAR_SET_FIELD(desc->data, MSG_CMD_CTL_ID, rsp_dest_id); - CLEAR_SET_FIELD(desc->control, MSG_CTL_OP_TYPE, MSG0_CTL_OP_ENGINE_SYMKEY); - CLEAR_SET_FIELD(desc->data, MSG_CTL_OP_TYPE, MSG1_CTL_OP_SYMKEY_PIPE0); + CLEAR_SET_FIELD(desc->control, MSG_CTL_OP_TYPE, MSG0_CTL_OP_ENGINE_SYMKEY); + CLEAR_SET_FIELD(desc->data, MSG_CTL_OP_TYPE, MSG1_CTL_OP_SYMKEY_PIPE0); - send_msg.msg0 = desc->control | (1ULL<<53); - send_msg.msg1 = desc->data | (1ULL<<53) | (1ULL<<52); - send_msg.msg2 = send_msg.msg3 = 0; + send_msg.msg0 = desc->control | (1ULL << 53); + send_msg.msg1 = desc->data | (1ULL << 53) | (1ULL << 52); + send_msg.msg2 = send_msg.msg3 = 0; - desc->op_ctl.flags = 1; // in_interrupt(); /* ipsec softirq ? */ + desc->op_ctl.flags = 1; + //in_interrupt(); /* ipsec softirq ? */ - XLR_SEC_CMD_DIAG("[%s]: IN_IRQ=%d msg0=0x%llx msg1=0x%llx \n", - __FUNCTION__, desc->op_ctl.flags, send_msg.msg0, send_msg.msg1); + XLR_SEC_CMD_DIAG("[%s]: IN_IRQ=%d msg0=0x%llx msg1=0x%llx \n", + __FUNCTION__, desc->op_ctl.flags, send_msg.msg0, send_msg.msg1); - retries = 100; + retries = 100; - while (retries--) { - msgrng_flags_save(msgrng_flags); + while (retries--) { + msgrng_flags_save(msgrng_flags); - code = message_send_retry(SEC_MSGRING_WORDSIZE, - MSGRNG_CODE_SEC, - desc->op_ctl.stn_id, - &send_msg); + code = message_send_retry(SEC_MSGRING_WORDSIZE, + MSGRNG_CODE_SEC, + desc->op_ctl.stn_id, + &send_msg); - msgrng_flags_restore(msgrng_flags); + msgrng_flags_restore(msgrng_flags); - if (code == 0) - break; - } + if (code == 0) + break; + } - return (XLR_SEC_ERR_NONE); + return (XLR_SEC_ERR_NONE); } -symkey_desc_pt xlr_sec_allocate_desc(void* session_ptr) +symkey_desc_pt +xlr_sec_allocate_desc(void *session_ptr) { - uint64_t addr; - symkey_desc_pt aligned, new; + uint64_t addr; + symkey_desc_pt aligned, new; - new = (symkey_desc_pt) malloc(sizeof(symkey_desc_t), - M_DEVBUF, M_NOWAIT | M_ZERO); + new = (symkey_desc_pt) malloc(sizeof(symkey_desc_t), + M_DEVBUF, M_NOWAIT | M_ZERO); - if (new == NULL) - return (NULL); + if (new == NULL) + return (NULL); - new->ses = session_ptr ; + new->ses = session_ptr; - new->user.kern_src = new->user.aligned_src = - (uint8_t *) contigmalloc(256*1024+1024, - M_DEVBUF, M_NOWAIT | M_ZERO, - 0, 0xffffffff, XLR_CACHELINE_SIZE, 0); + new->user.kern_src = new->user.aligned_src = + (uint8_t *) contigmalloc(256 * 1024 + 1024, + M_DEVBUF, M_NOWAIT | M_ZERO, + 0, 0xffffffff, XLR_CACHELINE_SIZE, 0); - if(new->user.kern_src == NULL){ - printf("ERROR - malloc failed for user.kern_src\n"); - return NULL; - } + if (new->user.kern_src == NULL) { + printf("ERROR - malloc failed for user.kern_src\n"); + return NULL; + } + new->user.aligned_dest = new->user.kern_dest = + (uint8_t *) contigmalloc(257 * 1024, + M_DEVBUF, M_NOWAIT | M_ZERO, + 0, 0xffffffff, XLR_CACHELINE_SIZE, 0); + + if (new->user.aligned_dest == NULL) { + printf("ERROR - malloc failed for user.aligned_dest\n"); + return NULL; + } + new->next_src_buf = (uint8_t *) contigmalloc(256 * 1024 + 1024, + M_DEVBUF, M_NOWAIT | M_ZERO, + 0, 0xffffffff, XLR_CACHELINE_SIZE, 0); + + if (new->next_src_buf == NULL) { + printf("ERROR - malloc failed for next_src_buf\n"); + return NULL; + } + new->next_dest_buf = + (uint8_t *) contigmalloc(257 * 1024, + M_DEVBUF, M_NOWAIT | M_ZERO, + 0, 0xffffffff, XLR_CACHELINE_SIZE, 0); + + if (new->next_dest_buf == NULL) { + printf("ERROR - malloc failed for next_dest_buf\n"); + return NULL; + } + new->user.kern_auth = new->user.user_auth = NULL; + new->user.aligned_auth = new->user.user_auth = NULL; - new->user.aligned_dest = new->user.kern_dest = - (uint8_t *) contigmalloc(257*1024, - M_DEVBUF, M_NOWAIT | M_ZERO, - 0, 0xffffffff, XLR_CACHELINE_SIZE, 0); + /* find cacheline alignment */ + aligned = new; + addr = (uint64_t) vtophys(new); - if(new->user.aligned_dest == NULL){ - printf("ERROR - malloc failed for user.aligned_dest\n"); - return NULL; - } - + /* save for free */ + aligned->alloc = new; - new->next_src_buf = (uint8_t *) contigmalloc(256*1024+1024, - M_DEVBUF, M_NOWAIT | M_ZERO, - 0, 0xffffffff, XLR_CACHELINE_SIZE, 0); + /* setup common control info */ + aligned->op_ctl.phys_self = addr; + aligned->op_ctl.stn_id = MSGRNG_STNID_SEC0; - if(new->next_src_buf == NULL){ - printf("ERROR - malloc failed for next_src_buf\n"); - return NULL; - } - - - new->next_dest_buf = - (uint8_t *) contigmalloc(257*1024, - M_DEVBUF, M_NOWAIT | M_ZERO, - 0, 0xffffffff, XLR_CACHELINE_SIZE, 0); - - if(new->next_dest_buf == NULL){ - printf("ERROR - malloc failed for next_dest_buf\n"); - return NULL; - } - - new->user.kern_auth = new->user.user_auth = NULL; - new->user.aligned_auth = new->user.user_auth = NULL; - - - /* find cacheline alignment */ - aligned = new; - addr = (uint64_t)vtophys(new); - - /* save for free */ - aligned->alloc = new; - - /* setup common control info */ - aligned->op_ctl.phys_self = addr; - aligned->op_ctl.stn_id = MSGRNG_STNID_SEC0; - - return (aligned); + return (aligned); } -static void xlr_sec_free_desc(symkey_desc_pt desc) +static void +xlr_sec_free_desc(symkey_desc_pt desc) { - if ((desc == NULL) || (desc->alloc == NULL)) { - printf("%s: NULL descriptor \n", __FUNCTION__); - return; - } - - contigfree(desc,sizeof(symkey_desc_t),M_DEVBUF); + if ((desc == NULL) || (desc->alloc == NULL)) { + printf("%s: NULL descriptor \n", __FUNCTION__); + return; + } + contigfree(desc, sizeof(symkey_desc_t), M_DEVBUF); - return; + return; } -void print_buf (char *desc, void *data, int len) +void +print_buf(char *desc, void *data, int len) { - uint8_t *dp; - int i; + uint8_t *dp; + int i; - DPRINT("%s: ", desc); /* newline done in for-loop */ - dp = data; - for (i=0; i < len; i++, dp++) { - if ((i % 16) == 0) DPRINT("\n"); - DPRINT(" %c%c", - nib2hex[(((*dp)&0xf0)>>4)], - nib2hex[((*dp)&0x0f)] ); - } - DPRINT("\n"); + DPRINT("%s: ", desc); /* newline done in for-loop */ + dp = data; + for (i = 0; i < len; i++, dp++) { + if ((i % 16) == 0) + DPRINT("\n"); + DPRINT(" %c%c", + nib2hex[(((*dp) & 0xf0) >> 4)], + nib2hex[((*dp) & 0x0f)]); + } + DPRINT("\n"); } #ifdef XLR_SEC_CMD_DEBUG static void -decode_symkey_desc (symkey_desc_pt desc, uint32_t cfg_vector) +decode_symkey_desc(symkey_desc_pt desc, uint32_t cfg_vector) { - unsigned long long word; - /* uint8_t *info; */ - /* int i; */ + unsigned long long word; - DPRINT ("MSG - CTL: \n"); - DPRINT ("\t CTRL = %lld \n", - GET_FIELD(desc->control, MSG_CMD_CTL_CTL)); - DPRINT ("\t CTRL LEN = %lld \n", - GET_FIELD(desc->control, MSG_CMD_CTL_LEN)); - DPRINT ("\t CTRL ADDR = %llx \n\n", - GET_FIELD(desc->control, MSG_CMD_CTL_ADDR)); + /* uint8_t *info; */ + /* int i; */ - DPRINT ("MSG - DATA: \n"); - DPRINT ("\t CTRL = %lld \n", - GET_FIELD(desc->data, MSG_CMD_DATA_CTL)); - DPRINT ("\t DATA LEN = %lld \n", - GET_FIELD(desc->data, MSG_CMD_DATA_LEN)); - DPRINT ("\t DATA ADDR = %llx \n\n", - GET_FIELD(desc->data, MSG_CMD_DATA_ADDR)); + DPRINT("MSG - CTL: \n"); + DPRINT("\t CTRL = %lld \n", + GET_FIELD(desc->control, MSG_CMD_CTL_CTL)); + DPRINT("\t CTRL LEN = %lld \n", + GET_FIELD(desc->control, MSG_CMD_CTL_LEN)); + DPRINT("\t CTRL ADDR = %llx \n\n", + GET_FIELD(desc->control, MSG_CMD_CTL_ADDR)); - DPRINT ("CONTROL DESCRIPTOR: \n"); - word = desc->ctl_desc.instruction; - DPRINT ("\tINSTRUCTION: %llx\n", word); - DPRINT("\t\tOVERRIDE CIPH = %lld \n", GET_FIELD(word, CTL_DSC_OVERRIDECIPHER)); - DPRINT("\t\tARC4 WAIT = %lld \n", GET_FIELD(word, CTL_DSC_ARC4_WAIT4SAVE)); - DPRINT("\t\tARC4 SAVE = %lld \n", GET_FIELD(word, CTL_DSC_ARC4_SAVESTATE)); - DPRINT("\t\tARC4 LOAD = %lld \n", GET_FIELD(word, CTL_DSC_ARC4_LOADSTATE)); - DPRINT("\t\tARC4 KEYLEN = %lld \n", GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); - DPRINT("\t\tCIPHER = %lld \n", GET_FIELD(word, CTL_DSC_CPHR)); - DPRINT("\t\tCIPHER MODE = %lld \n", GET_FIELD(word, CTL_DSC_MODE)); - DPRINT("\t\tINIT CIPHER = %lld \n", GET_FIELD(word, CTL_DSC_ICPHR)); - DPRINT("\t\tHMAC = %lld \n", GET_FIELD(word, CTL_DSC_HMAC)); - DPRINT("\t\tHASH ALG = %lld \n", GET_FIELD(word, CTL_DSC_HASH) | (GET_FIELD(word, CTL_DSC_HASHHI)<<2)); - DPRINT("\t\tINIT HASH = %lld \n", GET_FIELD(word, CTL_DSC_IHASH)); - DPRINT("\t\tCHKSUM = %lld \n", GET_FIELD(word, CTL_DSC_CKSUM)); - DPRINT ("\tCIPHER HASH INFO: \n"); + DPRINT("MSG - DATA: \n"); + DPRINT("\t CTRL = %lld \n", + GET_FIELD(desc->data, MSG_CMD_DATA_CTL)); + DPRINT("\t DATA LEN = %lld \n", + GET_FIELD(desc->data, MSG_CMD_DATA_LEN)); + DPRINT("\t DATA ADDR = %llx \n\n", + GET_FIELD(desc->data, MSG_CMD_DATA_ADDR)); + + DPRINT("CONTROL DESCRIPTOR: \n"); + word = desc->ctl_desc.instruction; + DPRINT("\tINSTRUCTION: %llx\n", word); + DPRINT("\t\tOVERRIDE CIPH = %lld \n", GET_FIELD(word, CTL_DSC_OVERRIDECIPHER)); + DPRINT("\t\tARC4 WAIT = %lld \n", GET_FIELD(word, CTL_DSC_ARC4_WAIT4SAVE)); + DPRINT("\t\tARC4 SAVE = %lld \n", GET_FIELD(word, CTL_DSC_ARC4_SAVESTATE)); + DPRINT("\t\tARC4 LOAD = %lld \n", GET_FIELD(word, CTL_DSC_ARC4_LOADSTATE)); + DPRINT("\t\tARC4 KEYLEN = %lld \n", GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + DPRINT("\t\tCIPHER = %lld \n", GET_FIELD(word, CTL_DSC_CPHR)); + DPRINT("\t\tCIPHER MODE = %lld \n", GET_FIELD(word, CTL_DSC_MODE)); + DPRINT("\t\tINIT CIPHER = %lld \n", GET_FIELD(word, CTL_DSC_ICPHR)); + DPRINT("\t\tHMAC = %lld \n", GET_FIELD(word, CTL_DSC_HMAC)); + DPRINT("\t\tHASH ALG = %lld \n", GET_FIELD(word, CTL_DSC_HASH) | (GET_FIELD(word, CTL_DSC_HASHHI) << 2)); + DPRINT("\t\tINIT HASH = %lld \n", GET_FIELD(word, CTL_DSC_IHASH)); + DPRINT("\t\tCHKSUM = %lld \n", GET_FIELD(word, CTL_DSC_CKSUM)); + DPRINT("\tCIPHER HASH INFO: \n"); #if 0 - info = (uint8_t *)&desc->ctl_desc->cipherHashInfo; - for (i=0; i < sizeof(CipherHashInfo_t); i++, info++) { - DPRINT(" %02x", *info); - if (i && (i % 16) == 0) DPRINT("\n"); - } - DPRINT("\n\n"); + info = (uint8_t *) & desc->ctl_desc->cipherHashInfo; + for (i = 0; i < sizeof(CipherHashInfo_t); i++, info++) { + DPRINT(" %02x", *info); + if (i && (i % 16) == 0) + DPRINT("\n"); + } + DPRINT("\n\n"); #endif - switch (cfg_vector) { - case XLR_SEC_VECTOR_CIPHER_ARC4: - DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4 \n"); - print_buf("ARC4 Key", - &desc->ctl_desc.cipherHashInfo.infoARC4.cipherKey0, - GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); - break; - case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC: - DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__HMAC \n"); - print_buf("ARC4 Key", - &desc->ctl_desc.cipherHashInfo.infoARC4HMAC.cipherKey0, - GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); - print_buf("HMAC Key", - &desc->ctl_desc.cipherHashInfo.infoARC4HMAC.hmacKey0, - sizeof(HMAC_t)); - break; - case XLR_SEC_VECTOR_CIPHER_ARC4__STATE: - DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__STATE \n"); - print_buf("ARC4 Key", - &desc->ctl_desc.cipherHashInfo.infoARC4State.cipherKey0, - GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); - break; - case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC__STATE: - DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__HMAC__STATE \n"); - print_buf("ARC4 Key", - &desc->ctl_desc.cipherHashInfo.infoARC4StateHMAC.cipherKey0, - GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); - print_buf("HMAC Key", - &desc->ctl_desc.cipherHashInfo.infoARC4StateHMAC.hmacKey0, - sizeof(HMAC_t)); - break; - case XLR_SEC_VECTOR_CIPHER_KASUMI_F8: - DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_KASUMI_F8 \n"); - print_buf("KASUMI_F8 Key", - &desc->ctl_desc.cipherHashInfo.infoKASUMIF8.cipherKey0, - XLR_SEC_KASUMI_F8_KEY_LENGTH); - break; - case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC: - DPRINT("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC\n"); - print_buf("KASUMI_F8 Key", - &desc->ctl_desc.cipherHashInfo.infoKASUMIF8HMAC.cipherKey0, - XLR_SEC_KASUMI_F8_KEY_LENGTH); - print_buf("HMAC Key", - &desc->ctl_desc.cipherHashInfo.infoKASUMIF8HMAC.hmacKey0, - sizeof(HMAC_t)); - break; - case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC2: - DPRINT("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC2\n"); - print_buf("KASUMI_F8 Key", - &desc->ctl_desc.cipherHashInfo.infoKASUMIF8HMAC2.cipherKey0, - XLR_SEC_KASUMI_F8_KEY_LENGTH); - print_buf("HMAC2 Key", - &desc->ctl_desc.cipherHashInfo.infoKASUMIF8HMAC2.hmacKey0, - sizeof(HMAC2_t)); - break; - case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__GCM: - DPRINT("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__GCM\n"); - print_buf("KASUMI_F8 Key", - &desc->ctl_desc.cipherHashInfo.infoKASUMIF8GCM.cipherKey0, - XLR_SEC_KASUMI_F8_KEY_LENGTH); - print_buf("GCM Key", - &desc->ctl_desc.cipherHashInfo.infoKASUMIF8GCM.GCMH0, - sizeof(GCM_t)); - break; - case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__F9: - DPRINT("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__F9\n"); - print_buf("KASUMI_F8 Key", - &desc->ctl_desc.cipherHashInfo.infoKASUMIF8F9.cipherKey0, - XLR_SEC_KASUMI_F8_KEY_LENGTH); - print_buf("F9 Key", - &desc->ctl_desc.cipherHashInfo.infoKASUMIF8F9.authKey0, - sizeof(F9_t)); - break; - case XLR_SEC_VECTOR_MAC: - DPRINT("VECTOR: XLR_SEC_VECTOR_MAC \n"); - DPRINT("MAC-ONLY - No Info\n"); - break; - case XLR_SEC_VECTOR_HMAC: - DPRINT ("VECTOR: XLR_SEC_VECTOR_HMAC \n"); - print_buf("HMAC Key", - &desc->ctl_desc.cipherHashInfo.infoHMAC.hmacKey0, - sizeof(HMAC_t)); - break; - case XLR_SEC_VECTOR__CIPHER_DES__HMAC__MODE_ECB_CBC: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_DES__HMAC__MODE_ECB_CBC \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoDESHMAC.cipherKey0, - XLR_SEC_DES_KEY_LENGTH); - print_buf("HMAC Key", - &desc->ctl_desc.cipherHashInfo.infoDESHMAC.hmacKey0, - sizeof(HMAC_t)); - break; - case XLR_SEC_VECTOR__CIPHER_DES__MODE_ECB_CBC: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_DES__MODE_ECB_CBC \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoDES.cipherKey0, - XLR_SEC_DES_KEY_LENGTH); - break; - case XLR_SEC_VECTOR__CIPHER_3DES__HMAC__MODE_ECB_CBC: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_3DES__HMAC__MODE_ECB_CBC \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.info3DESHMAC.cipherKey0, - XLR_SEC_3DES_KEY_LENGTH); - print_buf("HMAC Key", - &desc->ctl_desc.cipherHashInfo.info3DESHMAC.hmacKey0, - sizeof(HMAC_t)); - break; - case XLR_SEC_VECTOR__CIPHER_3DES__MODE_ECB_CBC: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_3DES__MODE_ECB_CBC \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.info3DES.cipherKey0, - XLR_SEC_3DES_KEY_LENGTH); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_CTR_CFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_CTR_CFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES128HMAC.cipherKey0, - XLR_SEC_AES128_KEY_LENGTH); - print_buf("HMAC Key", - &desc->ctl_desc.cipherHashInfo.infoAES128HMAC.hmacKey0, - sizeof(HMAC_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__MODE_CTR_CFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__MODE_CTR_CFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES128.cipherKey0, - XLR_SEC_AES128_KEY_LENGTH); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_ECB_CBC_OFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_ECB_CBC_OFB\n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES128HMAC.cipherKey0, - XLR_SEC_AES128_KEY_LENGTH); - print_buf("HMAC Key", - &desc->ctl_desc.cipherHashInfo.infoAES128HMAC.hmacKey0, - sizeof(HMAC_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__MODE_ECB_CBC_OFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__MODE_ECB_CBC_OFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES128.cipherKey0, - XLR_SEC_AES128_KEY_LENGTH); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_CTR_CFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_CTR_CFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES192HMAC.cipherKey0, - XLR_SEC_AES192_KEY_LENGTH); - print_buf("HMAC Key", - &desc->ctl_desc.cipherHashInfo.infoAES192HMAC.hmacKey0, - sizeof(HMAC_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__MODE_CTR_CFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__MODE_CTR_CFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES192.cipherKey0, - XLR_SEC_AES192_KEY_LENGTH); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_ECB_CBC_OFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_ECB_CBC_OFB\n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES192HMAC.cipherKey0, - XLR_SEC_AES192_KEY_LENGTH); - print_buf("HMAC Key", - &desc->ctl_desc.cipherHashInfo.infoAES192HMAC.hmacKey0, - sizeof(HMAC_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__MODE_ECB_CBC_OFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__MODE_ECB_CBC_OFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES192.cipherKey0, - XLR_SEC_AES192_KEY_LENGTH); - break; + switch (cfg_vector) { + case XLR_SEC_VECTOR_CIPHER_ARC4: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4 \n"); + print_buf("ARC4 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4.cipherKey0, + GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__HMAC \n"); + print_buf("ARC4 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4HMAC.cipherKey0, + GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoARC4HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__STATE: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__STATE \n"); + print_buf("ARC4 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4State.cipherKey0, + GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC__STATE: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__HMAC__STATE \n"); + print_buf("ARC4 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4StateHMAC.cipherKey0, + GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoARC4StateHMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR_CIPHER_KASUMI_F8: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_KASUMI_F8 \n"); + print_buf("KASUMI_F8 Key", + &desc->ctl_desc.cipherHashInfo.infoKASUMIF8.cipherKey0, + XLR_SEC_KASUMI_F8_KEY_LENGTH); + break; + case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC: + DPRINT("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC\n"); + print_buf("KASUMI_F8 Key", + &desc->ctl_desc.cipherHashInfo.infoKASUMIF8HMAC.cipherKey0, + XLR_SEC_KASUMI_F8_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoKASUMIF8HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC2: + DPRINT("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__HMAC2\n"); + print_buf("KASUMI_F8 Key", + &desc->ctl_desc.cipherHashInfo.infoKASUMIF8HMAC2.cipherKey0, + XLR_SEC_KASUMI_F8_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoKASUMIF8HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__GCM: + DPRINT("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__GCM\n"); + print_buf("KASUMI_F8 Key", + &desc->ctl_desc.cipherHashInfo.infoKASUMIF8GCM.cipherKey0, + XLR_SEC_KASUMI_F8_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoKASUMIF8GCM.GCMH0, + sizeof(GCM_t)); + break; + case XLR_SEC_VECTOR_CIPHER_KASUMI_F8__F9: + DPRINT("XLR_SEC_VECTOR_CIPHER_KASUMI_F8__F9\n"); + print_buf("KASUMI_F8 Key", + &desc->ctl_desc.cipherHashInfo.infoKASUMIF8F9.cipherKey0, + XLR_SEC_KASUMI_F8_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoKASUMIF8F9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR_MAC: + DPRINT("VECTOR: XLR_SEC_VECTOR_MAC \n"); + DPRINT("MAC-ONLY - No Info\n"); + break; + case XLR_SEC_VECTOR_HMAC: + DPRINT("VECTOR: XLR_SEC_VECTOR_HMAC \n"); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoHMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_DES__HMAC__MODE_ECB_CBC: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_DES__HMAC__MODE_ECB_CBC \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoDESHMAC.cipherKey0, + XLR_SEC_DES_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoDESHMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_DES__MODE_ECB_CBC: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_DES__MODE_ECB_CBC \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoDES.cipherKey0, + XLR_SEC_DES_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_3DES__HMAC__MODE_ECB_CBC: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_3DES__HMAC__MODE_ECB_CBC \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.info3DESHMAC.cipherKey0, + XLR_SEC_3DES_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.info3DESHMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_3DES__MODE_ECB_CBC: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_3DES__MODE_ECB_CBC \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.info3DES.cipherKey0, + XLR_SEC_3DES_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_CTR_CFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128HMAC.cipherKey0, + XLR_SEC_AES128_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoAES128HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__MODE_CTR_CFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128.cipherKey0, + XLR_SEC_AES128_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_ECB_CBC_OFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_ECB_CBC_OFB\n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128HMAC.cipherKey0, + XLR_SEC_AES128_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoAES128HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__MODE_ECB_CBC_OFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__MODE_ECB_CBC_OFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128.cipherKey0, + XLR_SEC_AES128_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_CTR_CFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192HMAC.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoAES192HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__MODE_CTR_CFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_ECB_CBC_OFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_ECB_CBC_OFB\n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192HMAC.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoAES192HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__MODE_ECB_CBC_OFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__MODE_ECB_CBC_OFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + break; - case XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_CTR_CFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_CTR_CFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES256HMAC.cipherKey0, - XLR_SEC_AES256_KEY_LENGTH); - print_buf("HMAC Key", - &desc->ctl_desc.cipherHashInfo.infoAES256HMAC.hmacKey0, - sizeof(HMAC_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__MODE_CTR_CFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__MODE_CTR_CFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES256.cipherKey0, - XLR_SEC_AES256_KEY_LENGTH); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_ECB_CBC_OFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_ECB_CBC_OFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES256HMAC.cipherKey0, - XLR_SEC_AES256_KEY_LENGTH); - print_buf("HMAC Key", - &desc->ctl_desc.cipherHashInfo.infoAES256HMAC.hmacKey0, - sizeof(HMAC_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__MODE_ECB_CBC_OFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__MODE_ECB_CBC_OFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES256.cipherKey0, - XLR_SEC_AES256_KEY_LENGTH); - break; - case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2: - DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2 \n"); - print_buf("ARC4 Key", - &desc->ctl_desc.cipherHashInfo.infoARC4HMAC2.cipherKey0, - GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); - print_buf("HMAC2 Key", - &desc->ctl_desc.cipherHashInfo.infoARC4HMAC2.hmacKey0, - sizeof(HMAC2_t)); - break; - case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2__STATE: - DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2__STATE \n"); - print_buf("ARC4 Key", - &desc->ctl_desc.cipherHashInfo.infoARC4StateHMAC2.cipherKey0, - GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); - print_buf("HMAC2 Key", - &desc->ctl_desc.cipherHashInfo.infoARC4StateHMAC2.hmacKey0, - sizeof(HMAC2_t)); - break; - case XLR_SEC_VECTOR_HMAC2: - DPRINT ("VECTOR: XLR_SEC_VECTOR_HMAC2 \n"); - print_buf("HMAC2 Key", - &desc->ctl_desc.cipherHashInfo.infoHMAC2.hmacKey0, - sizeof(HMAC2_t)); - break; - case XLR_SEC_VECTOR__CIPHER_DES__HMAC2__MODE_ECB_CBC: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_DES__HMAC2__MODE_ECB_CBC \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoDESHMAC2.cipherKey0, - XLR_SEC_DES_KEY_LENGTH); - print_buf("HMAC2 Key", - &desc->ctl_desc.cipherHashInfo.infoDESHMAC2.hmacKey0, - sizeof(HMAC2_t)); - break; - case XLR_SEC_VECTOR__CIPHER_3DES__HMAC2__MODE_ECB_CBC: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_3DES__HMAC2__MODE_ECB_CBC \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.info3DESHMAC2.cipherKey0, - XLR_SEC_3DES_KEY_LENGTH); - print_buf("HMAC2 Key", - &desc->ctl_desc.cipherHashInfo.info3DESHMAC2.hmacKey0, - sizeof(HMAC2_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_CTR_CFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_CTR_CFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES128HMAC2.cipherKey0, - XLR_SEC_AES128_KEY_LENGTH); - print_buf("HMAC2 Key", - &desc->ctl_desc.cipherHashInfo.infoAES128HMAC2.hmacKey0, - sizeof(HMAC2_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_ECB_CBC_OFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_ECB_CBC_OFB\n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES128HMAC2.cipherKey0, - XLR_SEC_AES128_KEY_LENGTH); - print_buf("HMAC2 Key", - &desc->ctl_desc.cipherHashInfo.infoAES128HMAC2.hmacKey0, - sizeof(HMAC2_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_CTR_CFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_CTR_CFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES192HMAC2.cipherKey0, - XLR_SEC_AES192_KEY_LENGTH); - print_buf("HMAC2 Key", - &desc->ctl_desc.cipherHashInfo.infoAES192HMAC2.hmacKey0, - sizeof(HMAC2_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_ECB_CBC_OFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_ECB_CBC_OFB\n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES192HMAC2.cipherKey0, - XLR_SEC_AES192_KEY_LENGTH); - print_buf("HMAC2 Key", - &desc->ctl_desc.cipherHashInfo.infoAES192HMAC2.hmacKey0, - sizeof(HMAC2_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_CTR_CFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_CTR_CFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES256HMAC2.cipherKey0, - XLR_SEC_AES256_KEY_LENGTH); - print_buf("HMAC2 Key", - &desc->ctl_desc.cipherHashInfo.infoAES256HMAC2.hmacKey0, - sizeof(HMAC2_t)); - break; - - case XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_ECB_CBC_OFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_ECB_CBC_OFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES256HMAC2.cipherKey0, - XLR_SEC_AES256_KEY_LENGTH); - print_buf("HMAC2 Key", - &desc->ctl_desc.cipherHashInfo.infoAES256HMAC2.hmacKey0, - sizeof(HMAC2_t)); - break; - case XLR_SEC_VECTOR_CIPHER_ARC4__GCM: - DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__GCM \n"); - print_buf("ARC4 Key", - &desc->ctl_desc.cipherHashInfo.infoARC4GCM.cipherKey0, - GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); - print_buf("GCM Key", - &desc->ctl_desc.cipherHashInfo.infoARC4GCM.GCMH0, - sizeof(GCM_t)); - break; - case XLR_SEC_VECTOR_CIPHER_ARC4__GCM__STATE: - DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__GCM__STATE \n"); - print_buf("ARC4 Key", - &desc->ctl_desc.cipherHashInfo.infoARC4StateGCM.cipherKey0, - GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); - print_buf("GCM Key", - &desc->ctl_desc.cipherHashInfo.infoARC4StateGCM.GCMH0, - sizeof(GCM_t)); - break; - case XLR_SEC_VECTOR_GCM: - DPRINT ("VECTOR: XLR_SEC_VECTOR_GCM \n"); - print_buf("GCM Key", - &desc->ctl_desc.cipherHashInfo.infoGCM.GCMH0, - sizeof(GCM_t)); - break; - case XLR_SEC_VECTOR__CIPHER_DES__GCM__MODE_ECB_CBC: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_DES__GCM__MODE_ECB_CBC \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoDESGCM.cipherKey0, - XLR_SEC_DES_KEY_LENGTH); - print_buf("GCM Key", - &desc->ctl_desc.cipherHashInfo.infoDESGCM.GCMH0, - sizeof(GCM_t)); - break; - case XLR_SEC_VECTOR__CIPHER_3DES__GCM__MODE_ECB_CBC: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_3DES__GCM__MODE_ECB_CBC \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.info3DESGCM.cipherKey0, - XLR_SEC_3DES_KEY_LENGTH); - print_buf("GCM Key", - &desc->ctl_desc.cipherHashInfo.info3DESGCM.GCMH0, - sizeof(GCM_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_CTR_CFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_CTR_CFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES128GCM.cipherKey0, - XLR_SEC_AES128_KEY_LENGTH); - print_buf("GCM Key", - &desc->ctl_desc.cipherHashInfo.infoAES128GCM.GCMH0, - XLR_SEC_AES128_KEY_LENGTH); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_ECB_CBC_OFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_ECB_CBC_OFB\n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES128GCM.cipherKey0, - XLR_SEC_AES128_KEY_LENGTH); - print_buf("GCM Key", - &desc->ctl_desc.cipherHashInfo.infoAES128GCM.GCMH0, - XLR_SEC_AES128_KEY_LENGTH); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_CTR_CFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_CTR_CFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES192GCM.cipherKey0, - XLR_SEC_AES192_KEY_LENGTH); - print_buf("GCM Key", - &desc->ctl_desc.cipherHashInfo.infoAES192GCM.GCMH0, - XLR_SEC_AES192_KEY_LENGTH); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_ECB_CBC_OFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_ECB_CBC_OFB\n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES192GCM.cipherKey0, - XLR_SEC_AES192_KEY_LENGTH); - print_buf("GCM Key", - &desc->ctl_desc.cipherHashInfo.infoAES192GCM.GCMH0, - XLR_SEC_AES192_KEY_LENGTH); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_CTR_CFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_CTR_CFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES256GCM.cipherKey0, - XLR_SEC_AES256_KEY_LENGTH); - print_buf("GCM Key", - &desc->ctl_desc.cipherHashInfo.infoAES256GCM.GCMH0, - XLR_SEC_AES256_KEY_LENGTH); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_ECB_CBC_OFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_ECB_CBC_OFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES256GCM.cipherKey0, - XLR_SEC_AES256_KEY_LENGTH); - print_buf("GCM Key", - &desc->ctl_desc.cipherHashInfo.infoAES256GCM.GCMH0, - XLR_SEC_AES256_KEY_LENGTH); - break; - case XLR_SEC_VECTOR_CIPHER_ARC4__F9: - DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__F9 \n"); - print_buf("ARC4 Key", - &desc->ctl_desc.cipherHashInfo.infoARC4F9.cipherKey0, - GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); - print_buf("F9 Key", - &desc->ctl_desc.cipherHashInfo.infoARC4F9.authKey0, - sizeof(F9_t)); - break; - case XLR_SEC_VECTOR_CIPHER_ARC4__F9__STATE: - DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__F9__STATE \n"); - print_buf("ARC4 Key", - &desc->ctl_desc.cipherHashInfo.infoARC4StateF9.cipherKey0, - GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); - print_buf("F9 Key", - &desc->ctl_desc.cipherHashInfo.infoARC4StateF9.authKey0, - sizeof(F9_t)); - break; - case XLR_SEC_VECTOR_F9: - DPRINT ("VECTOR: XLR_SEC_VECTOR_F9 \n"); - print_buf("F9 Key", - &desc->ctl_desc.cipherHashInfo.infoF9.authKey0, - sizeof(F9_t)); - break; - case XLR_SEC_VECTOR__CIPHER_DES__F9__MODE_ECB_CBC: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_DES__F9__MODE_ECB_CBC \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoDESF9.cipherKey0, - XLR_SEC_DES_KEY_LENGTH); - print_buf("F9 Key", - &desc->ctl_desc.cipherHashInfo.infoDESF9.authKey0, - sizeof(F9_t)); - break; - case XLR_SEC_VECTOR__CIPHER_3DES__F9__MODE_ECB_CBC: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_3DES__F9__MODE_ECB_CBC \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.info3DESF9.cipherKey0, - XLR_SEC_3DES_KEY_LENGTH); - print_buf("F9 Key", - &desc->ctl_desc.cipherHashInfo.info3DESF9.authKey0, - sizeof(F9_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_CTR_CFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_CTR_CFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES128F9.cipherKey0, - XLR_SEC_AES128_KEY_LENGTH); - print_buf("F9 Key", - &desc->ctl_desc.cipherHashInfo.infoAES128F9.authKey0, - sizeof(F9_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_ECB_CBC_OFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_ECB_CBC_OFB\n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES128F9.cipherKey0, - XLR_SEC_AES128_KEY_LENGTH); - print_buf("F9 Key", - &desc->ctl_desc.cipherHashInfo.infoAES128F9.authKey0, - sizeof(F9_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_CTR_CFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_CTR_CFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES192F9.cipherKey0, - XLR_SEC_AES192_KEY_LENGTH); - print_buf("F9 Key", - &desc->ctl_desc.cipherHashInfo.infoAES192F9.authKey0, - sizeof(F9_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_ECB_CBC_OFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_ECB_CBC_OFB\n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES192F9.cipherKey0, - XLR_SEC_AES192_KEY_LENGTH); - print_buf("F9 Key", - &desc->ctl_desc.cipherHashInfo.infoAES192F9.authKey0, - sizeof(F9_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_CTR_CFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_CTR_CFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES256F9.cipherKey0, - XLR_SEC_AES256_KEY_LENGTH); - print_buf("F9 Key", - &desc->ctl_desc.cipherHashInfo.infoAES256F9.authKey0, - sizeof(F9_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_ECB_CBC_OFB: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_ECB_CBC_OFB \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES256F9.cipherKey0, - XLR_SEC_AES256_KEY_LENGTH); - print_buf("F9 Key", - &desc->ctl_desc.cipherHashInfo.infoAES256F9.authKey0, - sizeof(F9_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_F8: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_F8 \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES128F8HMAC.cipherKey0, - XLR_SEC_AES128F8_KEY_LENGTH); - print_buf("HMAC Key", - &desc->ctl_desc.cipherHashInfo.infoAES128F8HMAC.hmacKey0, - sizeof(HMAC_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__MODE_F8: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__MODE_F8 \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES128F8.cipherKey0, - XLR_SEC_AES128F8_KEY_LENGTH); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_F8: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_F8 \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES192F8HMAC.cipherKey0, - XLR_SEC_AES192F8_KEY_LENGTH); - print_buf("HMAC Key", - &desc->ctl_desc.cipherHashInfo.infoAES192F8HMAC.hmacKey0, - sizeof(HMAC_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__MODE_F8: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__MODE_F8 \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES192F8.cipherKey0, - XLR_SEC_AES192F8_KEY_LENGTH); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_F8: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_F8 \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES256F8HMAC.cipherKey0, - XLR_SEC_AES256F8_KEY_LENGTH); - print_buf("HMAC Key", - &desc->ctl_desc.cipherHashInfo.infoAES256HMAC.hmacKey0, - sizeof(HMAC_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__MODE_F8: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__MODE_F8 \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES256F8.cipherKey0, - XLR_SEC_AES256F8_KEY_LENGTH); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_F8: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_F8 \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES128F8HMAC2.cipherKey0, - XLR_SEC_AES128F8_KEY_LENGTH); - print_buf("HMAC2 Key", - &desc->ctl_desc.cipherHashInfo.infoAES128F8HMAC2.hmacKey0, - sizeof(HMAC2_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_F8: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_F8 \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES192F8HMAC2.cipherKey0, - XLR_SEC_AES192F8_KEY_LENGTH); - print_buf("HMAC2 Key", - &desc->ctl_desc.cipherHashInfo.infoAES192F8HMAC2.hmacKey0, - sizeof(HMAC2_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_F8: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_F8 \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES256F8HMAC2.cipherKey0, - XLR_SEC_AES256F8_KEY_LENGTH); - print_buf("HMAC2 Key", - &desc->ctl_desc.cipherHashInfo.infoAES256F8HMAC2.hmacKey0, - sizeof(HMAC2_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_F8: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_F8 \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES128F8GCM.cipherKey0, - XLR_SEC_AES128F8_KEY_LENGTH); - print_buf("GCM Key", - &desc->ctl_desc.cipherHashInfo.infoAES128GCM.GCMH0, - XLR_SEC_AES128_KEY_LENGTH); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_F8: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_F8 \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES192F8GCM.cipherKey0, - XLR_SEC_AES192_KEY_LENGTH); - print_buf("GCM Key", - &desc->ctl_desc.cipherHashInfo.infoAES192F8GCM.GCMH0, - XLR_SEC_AES192_KEY_LENGTH); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_F8: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_F8 \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES256F8GCM.cipherKey0, - XLR_SEC_AES256F8_KEY_LENGTH); - print_buf("GCM Key", - &desc->ctl_desc.cipherHashInfo.infoAES256F8GCM.GCMH0, - XLR_SEC_AES256_KEY_LENGTH); - break; - case XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_F8: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_F8 \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES128F8F9.cipherKey0, - XLR_SEC_AES128F8_KEY_LENGTH); - print_buf("F9 Key", - &desc->ctl_desc.cipherHashInfo.infoAES128F8F9.authKey0, - sizeof(F9_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_F8: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_F8 \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES192F8F9.cipherKey0, - XLR_SEC_AES192F8_KEY_LENGTH); - print_buf("F9 Key", - &desc->ctl_desc.cipherHashInfo.infoAES192F8F9.authKey0, - sizeof(F9_t)); - break; - case XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_F8: - DPRINT ("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_F8 \n"); - print_buf("CIPHER Key", - &desc->ctl_desc.cipherHashInfo.infoAES256F8F9.cipherKey0, - XLR_SEC_AES256F8_KEY_LENGTH); - print_buf("F9 Key", - &desc->ctl_desc.cipherHashInfo.infoAES256F8F9.authKey0, - sizeof(F9_t)); - break; + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_CTR_CFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256HMAC.cipherKey0, + XLR_SEC_AES256_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoAES256HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__MODE_CTR_CFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256.cipherKey0, + XLR_SEC_AES256_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_ECB_CBC_OFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_ECB_CBC_OFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256HMAC.cipherKey0, + XLR_SEC_AES256_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoAES256HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__MODE_ECB_CBC_OFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__MODE_ECB_CBC_OFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256.cipherKey0, + XLR_SEC_AES256_KEY_LENGTH); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2 \n"); + print_buf("ARC4 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4HMAC2.cipherKey0, + GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2__STATE: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__HMAC2__STATE \n"); + print_buf("ARC4 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4StateHMAC2.cipherKey0, + GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4StateHMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR_HMAC2: + DPRINT("VECTOR: XLR_SEC_VECTOR_HMAC2 \n"); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoHMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR__CIPHER_DES__HMAC2__MODE_ECB_CBC: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_DES__HMAC2__MODE_ECB_CBC \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoDESHMAC2.cipherKey0, + XLR_SEC_DES_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoDESHMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR__CIPHER_3DES__HMAC2__MODE_ECB_CBC: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_3DES__HMAC2__MODE_ECB_CBC \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.info3DESHMAC2.cipherKey0, + XLR_SEC_3DES_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.info3DESHMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_CTR_CFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128HMAC2.cipherKey0, + XLR_SEC_AES128_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoAES128HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_ECB_CBC_OFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_ECB_CBC_OFB\n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128HMAC2.cipherKey0, + XLR_SEC_AES128_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoAES128HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_CTR_CFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192HMAC2.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoAES192HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_ECB_CBC_OFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_ECB_CBC_OFB\n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192HMAC2.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoAES192HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_CTR_CFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256HMAC2.cipherKey0, + XLR_SEC_AES256_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoAES256HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; - default: - DPRINT ("VECTOR: ???? \n"); - DPRINT(">>> WHAT THE HECK !!! <<< \n"); - break; - } - DPRINT ("PACKET DESCRIPTOR: \n"); - word = desc->pkt_desc.srcLengthIVOffUseIVNext; - DPRINT ("\tSrcLengthIVOffsetIVNext: %llx\n", word); - DPRINT ("\t\tLoad HMAC = %lld \n", - GET_FIELD(word, PKT_DSC_LOADHMACKEY)); - DPRINT ("\t\tPad Hash = %lld \n", - GET_FIELD(word, PKT_DSC_PADHASH)); - DPRINT ("\t\tHash Byte Count = %lld \n", - GET_FIELD(word, PKT_DSC_HASHBYTES)); - DPRINT ("\t\tNext = %lld \n", - GET_FIELD(word, PKT_DSC_NEXT)); - DPRINT ("\t\tUse IV = %lld \n", - GET_FIELD(word, PKT_DSC_IV)); - DPRINT ("\t\tIV Offset = %lld \n", - GET_FIELD(word, PKT_DSC_IVOFF)); - DPRINT ("\t\tPacket Length = %lld \n", - GET_FIELD(word, PKT_DSC_PKTLEN)); - DPRINT ("\t\tNLHMAC = %lld \n", GET_FIELD(word, PKT_DSC_NLHMAC)); - DPRINT ("\t\tBreak = %lld \n", GET_FIELD(word, PKT_DSC_BREAK)); - DPRINT ("\t\tWait = %lld \n", GET_FIELD(word, PKT_DSC_WAIT)); - DPRINT ("\t\tSegment Src Addr = %llx \n", - (GET_FIELD(word, PKT_DSC_SEGADDR) << 5)& 0xffffffffffULL); - DPRINT("\t\tSRTCP = %lld \n", GET_FIELD(word, PKT_DSC_SRTCP)); - DPRINT ("\t\tGlobal Src Offset = %lld \n", - GET_FIELD(word, PKT_DSC_SEGOFFSET)); + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_ECB_CBC_OFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_ECB_CBC_OFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256HMAC2.cipherKey0, + XLR_SEC_AES256_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoAES256HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__GCM: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__GCM \n"); + print_buf("ARC4 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4GCM.cipherKey0, + GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoARC4GCM.GCMH0, + sizeof(GCM_t)); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__GCM__STATE: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__GCM__STATE \n"); + print_buf("ARC4 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4StateGCM.cipherKey0, + GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoARC4StateGCM.GCMH0, + sizeof(GCM_t)); + break; + case XLR_SEC_VECTOR_GCM: + DPRINT("VECTOR: XLR_SEC_VECTOR_GCM \n"); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoGCM.GCMH0, + sizeof(GCM_t)); + break; + case XLR_SEC_VECTOR__CIPHER_DES__GCM__MODE_ECB_CBC: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_DES__GCM__MODE_ECB_CBC \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoDESGCM.cipherKey0, + XLR_SEC_DES_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoDESGCM.GCMH0, + sizeof(GCM_t)); + break; + case XLR_SEC_VECTOR__CIPHER_3DES__GCM__MODE_ECB_CBC: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_3DES__GCM__MODE_ECB_CBC \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.info3DESGCM.cipherKey0, + XLR_SEC_3DES_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.info3DESGCM.GCMH0, + sizeof(GCM_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_CTR_CFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128GCM.cipherKey0, + XLR_SEC_AES128_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoAES128GCM.GCMH0, + XLR_SEC_AES128_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_ECB_CBC_OFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_ECB_CBC_OFB\n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128GCM.cipherKey0, + XLR_SEC_AES128_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoAES128GCM.GCMH0, + XLR_SEC_AES128_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_CTR_CFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192GCM.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoAES192GCM.GCMH0, + XLR_SEC_AES192_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_ECB_CBC_OFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_ECB_CBC_OFB\n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192GCM.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoAES192GCM.GCMH0, + XLR_SEC_AES192_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_CTR_CFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256GCM.cipherKey0, + XLR_SEC_AES256_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoAES256GCM.GCMH0, + XLR_SEC_AES256_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_ECB_CBC_OFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_ECB_CBC_OFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256GCM.cipherKey0, + XLR_SEC_AES256_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoAES256GCM.GCMH0, + XLR_SEC_AES256_KEY_LENGTH); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__F9: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__F9 \n"); + print_buf("ARC4 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4F9.cipherKey0, + GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4F9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR_CIPHER_ARC4__F9__STATE: + DPRINT("VECTOR: XLR_SEC_VECTOR_CIPHER_ARC4__F9__STATE \n"); + print_buf("ARC4 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4StateF9.cipherKey0, + GET_FIELD(word, CTL_DSC_ARC4_KEYLEN)); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoARC4StateF9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR_F9: + DPRINT("VECTOR: XLR_SEC_VECTOR_F9 \n"); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoF9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_DES__F9__MODE_ECB_CBC: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_DES__F9__MODE_ECB_CBC \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoDESF9.cipherKey0, + XLR_SEC_DES_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoDESF9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_3DES__F9__MODE_ECB_CBC: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_3DES__F9__MODE_ECB_CBC \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.info3DESF9.cipherKey0, + XLR_SEC_3DES_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.info3DESF9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_CTR_CFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F9.cipherKey0, + XLR_SEC_AES128_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_ECB_CBC_OFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_ECB_CBC_OFB\n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F9.cipherKey0, + XLR_SEC_AES128_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_CTR_CFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F9.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_ECB_CBC_OFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_ECB_CBC_OFB\n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F9.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_CTR_CFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_CTR_CFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F9.cipherKey0, + XLR_SEC_AES256_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_ECB_CBC_OFB: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_ECB_CBC_OFB \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F9.cipherKey0, + XLR_SEC_AES256_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_F8: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__HMAC__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F8HMAC.cipherKey0, + XLR_SEC_AES128F8_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F8HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__MODE_F8: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F8.cipherKey0, + XLR_SEC_AES128F8_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_F8: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__HMAC__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F8HMAC.cipherKey0, + XLR_SEC_AES192F8_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F8HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__MODE_F8: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F8.cipherKey0, + XLR_SEC_AES192F8_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_F8: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__HMAC__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F8HMAC.cipherKey0, + XLR_SEC_AES256F8_KEY_LENGTH); + print_buf("HMAC Key", + &desc->ctl_desc.cipherHashInfo.infoAES256HMAC.hmacKey0, + sizeof(HMAC_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__MODE_F8: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F8.cipherKey0, + XLR_SEC_AES256F8_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_F8: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__HMAC2__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F8HMAC2.cipherKey0, + XLR_SEC_AES128F8_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F8HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_F8: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__HMAC2__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F8HMAC2.cipherKey0, + XLR_SEC_AES192F8_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F8HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_F8: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__HMAC2__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F8HMAC2.cipherKey0, + XLR_SEC_AES256F8_KEY_LENGTH); + print_buf("HMAC2 Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F8HMAC2.hmacKey0, + sizeof(HMAC2_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_F8: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__GCM__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F8GCM.cipherKey0, + XLR_SEC_AES128F8_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoAES128GCM.GCMH0, + XLR_SEC_AES128_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_F8: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__GCM__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F8GCM.cipherKey0, + XLR_SEC_AES192_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F8GCM.GCMH0, + XLR_SEC_AES192_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_F8: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__GCM__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F8GCM.cipherKey0, + XLR_SEC_AES256F8_KEY_LENGTH); + print_buf("GCM Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F8GCM.GCMH0, + XLR_SEC_AES256_KEY_LENGTH); + break; + case XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_F8: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES128__F9__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F8F9.cipherKey0, + XLR_SEC_AES128F8_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoAES128F8F9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_F8: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES192__F9__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F8F9.cipherKey0, + XLR_SEC_AES192F8_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoAES192F8F9.authKey0, + sizeof(F9_t)); + break; + case XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_F8: + DPRINT("VECTOR: XLR_SEC_VECTOR__CIPHER_AES256__F9__MODE_F8 \n"); + print_buf("CIPHER Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F8F9.cipherKey0, + XLR_SEC_AES256F8_KEY_LENGTH); + print_buf("F9 Key", + &desc->ctl_desc.cipherHashInfo.infoAES256F8F9.authKey0, + sizeof(F9_t)); + break; - word = desc->pkt_desc.dstDataSettings; - DPRINT("\tdstDataSettings: %llx \n", word); - DPRINT("\t\tArc4 Byte Count = %lld \n", GET_FIELD(word, - PKT_DSC_ARC4BYTECOUNT)); - DPRINT("\t\tSym Operation = %lld \n", GET_FIELD(word, PKT_DSC_SYM_OP)); - DPRINT("\t\tCipher Offset = %lld \n", GET_FIELD(word, PKT_DSC_CPHROFF)); - DPRINT("\t\tHash Offset = %lld \n", GET_FIELD(word, PKT_DSC_HASHOFF)); - DPRINT("\t\tHash Source = %lld \n", GET_FIELD(word, PKT_DSC_HASHSRC)); - DPRINT("\t\tChecksum Offset = %lld \n", GET_FIELD(word, - PKT_DSC_CKSUMOFF)); - DPRINT("\t\tChecksum Source = %lld \n", GET_FIELD(word, - PKT_DSC_CKSUMSRC)); - DPRINT("\t\tCipher Dest Addr = %llx \n", GET_FIELD(word, - PKT_DSC_CPHR_DST_ADDR)); - DPRINT("\t\tCipher Dest Dword = %lld \n", GET_FIELD(word, - PKT_DSC_CPHR_DST_DWOFFSET)); - DPRINT("\t\tCipher Dest Offset= %lld \n", GET_FIELD(word, - PKT_DSC_CPHR_DST_OFFSET)); - word = desc->pkt_desc.authDstNonceLow; - DPRINT("\tauthDstNonceLow: %llx \n", word); - DPRINT("\t\tNonce Low 24 = %lld \n", GET_FIELD(word, - PKT_DSC_NONCE_LOW)); - DPRINT("\t\tauthDst = %llx \n", GET_FIELD(word, - PKT_DSC_AUTH_DST_ADDR)); - DPRINT("\t\tCipher Offset High= %lld \n", GET_FIELD(word, - PKT_DSC_CIPH_OFF_HI)); - word = desc->pkt_desc.ckSumDstNonceHiCFBMaskLLWMask; - DPRINT("\tckSumDstNonceHiCFBMaskLLWMask: %llx \n", word); - DPRINT("\t\tHash Byte off = %lld \n", GET_FIELD(word, PKT_DSC_HASH_BYTE_OFF)); - DPRINT("\t\tPacket Len bytes = %lld \n", GET_FIELD(word, PKT_DSC_PKTLEN_BYTES)); - DPRINT("\t\tLast Long Word Mask = %lld \n", GET_FIELD(word, - PKT_DSC_LASTWORD)); - DPRINT("\t\tCipher Dst Address = %llx \n", GET_FIELD(word, - PKT_DSC_CPHR_DST_ADDR)); - DPRINT("\t\tGlobal Dst Offset = %lld \n", GET_FIELD(word, - PKT_DSC_CPHR_DST_OFFSET)); + default: + DPRINT("VECTOR: ???? \n"); + DPRINT(">>> WHAT THE HECK !!! <<< \n"); + break; + } + DPRINT("PACKET DESCRIPTOR: \n"); + word = desc->pkt_desc.srcLengthIVOffUseIVNext; + DPRINT("\tSrcLengthIVOffsetIVNext: %llx\n", word); + DPRINT("\t\tLoad HMAC = %lld \n", + GET_FIELD(word, PKT_DSC_LOADHMACKEY)); + DPRINT("\t\tPad Hash = %lld \n", + GET_FIELD(word, PKT_DSC_PADHASH)); + DPRINT("\t\tHash Byte Count = %lld \n", + GET_FIELD(word, PKT_DSC_HASHBYTES)); + DPRINT("\t\tNext = %lld \n", + GET_FIELD(word, PKT_DSC_NEXT)); + DPRINT("\t\tUse IV = %lld \n", + GET_FIELD(word, PKT_DSC_IV)); + DPRINT("\t\tIV Offset = %lld \n", + GET_FIELD(word, PKT_DSC_IVOFF)); + DPRINT("\t\tPacket Length = %lld \n", + GET_FIELD(word, PKT_DSC_PKTLEN)); + DPRINT("\t\tNLHMAC = %lld \n", GET_FIELD(word, PKT_DSC_NLHMAC)); + DPRINT("\t\tBreak = %lld \n", GET_FIELD(word, PKT_DSC_BREAK)); + DPRINT("\t\tWait = %lld \n", GET_FIELD(word, PKT_DSC_WAIT)); + DPRINT("\t\tSegment Src Addr = %llx \n", + (GET_FIELD(word, PKT_DSC_SEGADDR) << 5) & 0xffffffffffULL); + DPRINT("\t\tSRTCP = %lld \n", GET_FIELD(word, PKT_DSC_SRTCP)); + DPRINT("\t\tGlobal Src Offset = %lld \n", + GET_FIELD(word, PKT_DSC_SEGOFFSET)); - DPRINT ("CFG_VECTOR = %04x\n", cfg_vector); - DPRINT ("\n\n"); + word = desc->pkt_desc.dstDataSettings; + DPRINT("\tdstDataSettings: %llx \n", word); + DPRINT("\t\tArc4 Byte Count = %lld \n", GET_FIELD(word, + PKT_DSC_ARC4BYTECOUNT)); + DPRINT("\t\tSym Operation = %lld \n", GET_FIELD(word, PKT_DSC_SYM_OP)); + DPRINT("\t\tCipher Offset = %lld \n", GET_FIELD(word, PKT_DSC_CPHROFF)); + DPRINT("\t\tHash Offset = %lld \n", GET_FIELD(word, PKT_DSC_HASHOFF)); + DPRINT("\t\tHash Source = %lld \n", GET_FIELD(word, PKT_DSC_HASHSRC)); + DPRINT("\t\tChecksum Offset = %lld \n", GET_FIELD(word, + PKT_DSC_CKSUMOFF)); + DPRINT("\t\tChecksum Source = %lld \n", GET_FIELD(word, + PKT_DSC_CKSUMSRC)); + DPRINT("\t\tCipher Dest Addr = %llx \n", GET_FIELD(word, + PKT_DSC_CPHR_DST_ADDR)); + DPRINT("\t\tCipher Dest Dword = %lld \n", GET_FIELD(word, + PKT_DSC_CPHR_DST_DWOFFSET)); + DPRINT("\t\tCipher Dest Offset= %lld \n", GET_FIELD(word, + PKT_DSC_CPHR_DST_OFFSET)); + word = desc->pkt_desc.authDstNonceLow; + DPRINT("\tauthDstNonceLow: %llx \n", word); + DPRINT("\t\tNonce Low 24 = %lld \n", GET_FIELD(word, + PKT_DSC_NONCE_LOW)); + DPRINT("\t\tauthDst = %llx \n", GET_FIELD(word, + PKT_DSC_AUTH_DST_ADDR)); + DPRINT("\t\tCipher Offset High= %lld \n", GET_FIELD(word, + PKT_DSC_CIPH_OFF_HI)); + word = desc->pkt_desc.ckSumDstNonceHiCFBMaskLLWMask; + DPRINT("\tckSumDstNonceHiCFBMaskLLWMask: %llx \n", word); + DPRINT("\t\tHash Byte off = %lld \n", GET_FIELD(word, PKT_DSC_HASH_BYTE_OFF)); + DPRINT("\t\tPacket Len bytes = %lld \n", GET_FIELD(word, PKT_DSC_PKTLEN_BYTES)); + DPRINT("\t\tLast Long Word Mask = %lld \n", GET_FIELD(word, + PKT_DSC_LASTWORD)); + DPRINT("\t\tCipher Dst Address = %llx \n", GET_FIELD(word, + PKT_DSC_CPHR_DST_ADDR)); + DPRINT("\t\tGlobal Dst Offset = %lld \n", GET_FIELD(word, + PKT_DSC_CPHR_DST_OFFSET)); + + DPRINT("CFG_VECTOR = %04x\n", cfg_vector); + DPRINT("\n\n"); } + #endif /* This function is called from an interrupt handler */ -void xlr_sec_msgring_handler(int bucket, int size, int code, int stid, - struct msgrng_msg *msg, void *data) +void +xlr_sec_msgring_handler(int bucket, int size, int code, int stid, + struct msgrng_msg *msg, void *data) { - uint64_t error; - uint64_t addr, sec_eng, sec_pipe; - xlr_sec_io_pt op = NULL; - symkey_desc_pt desc=NULL; - struct xlr_sec_session *ses =NULL; - struct xlr_sec_command* cmd=NULL; + uint64_t error; + uint64_t addr, sec_eng, sec_pipe; + xlr_sec_io_pt op = NULL; + symkey_desc_pt desc = NULL; + struct xlr_sec_session *ses = NULL; + struct xlr_sec_command *cmd = NULL; - if (code != MSGRNG_CODE_SEC) { - panic("xlr_sec_msgring_handler: bad code = %d," - " expected code = %d\n", - code, MSGRNG_CODE_SEC); - } + if (code != MSGRNG_CODE_SEC) { + panic("xlr_sec_msgring_handler: bad code = %d," + " expected code = %d\n", + code, MSGRNG_CODE_SEC); + } + if ((stid < MSGRNG_STNID_SEC0) || (stid > MSGRNG_STNID_PK0)) { + panic("xlr_sec_msgring_handler: bad stn id = %d, expect %d - %d\n", + stid, MSGRNG_STNID_SEC0, MSGRNG_STNID_PK0); + } + /* + * The Submit() operation encodes the engine and pipe in these two + * separate fields. This allows use to verify the result type with + * the submitted operation type. + */ + sec_eng = GET_FIELD(msg->msg0, MSG_CTL_OP_TYPE); + sec_pipe = GET_FIELD(msg->msg1, MSG_CTL_OP_TYPE); - if ((stid < MSGRNG_STNID_SEC0) || (stid > MSGRNG_STNID_PK0)) { - panic("xlr_sec_msgring_handler: bad stn id = %d, expect %d - %d\n", - stid, MSGRNG_STNID_SEC0, MSGRNG_STNID_PK0); - } + error = msg->msg0 >> 40 & 0x1ff; + if (error) + printf("ctrl error = 0x%llx\n", error); + error = msg->msg1 >> 40 & 0x1ff; + if (error) + printf("data error = 0x%llx\n", error); - /* - * The Submit() operation encodes the engine and pipe in these two - * separate fields. This allows use to verify the result type with - * the submitted operation type. - */ - sec_eng = GET_FIELD(msg->msg0, MSG_CTL_OP_TYPE); - sec_pipe = GET_FIELD(msg->msg1, MSG_CTL_OP_TYPE); + XLR_SEC_CMD_DIAG("[%s]: eng=%lld pipe=%lld\n", + __FUNCTION__, sec_eng, sec_pipe); + /* Symmetric Key Operation ? */ + if (sec_eng == MSG0_CTL_OP_ENGINE_SYMKEY) { - error = msg->msg0 >>40 & 0x1ff ; - if(error) printf("ctrl error = 0x%llx\n", error); - error = msg->msg1 >>40 & 0x1ff ; - if(error) printf("data error = 0x%llx\n", error); + /* + * The data descriptor address allows us to associate the + * response with the submitted operation. Address is 40-bit + * cacheline aligned address. We need to zero bit 0-4 since + * they are used for the engine and pipe Id. + */ + addr = GET_FIELD(msg->msg1, MSG_RSLT_DATA_DSC_ADDR); + addr = addr & ~((1 << 5) - 1); + if (!addr) { + panic("[%s:STNID_SEC]: NULL symkey addr!\n", __FUNCTION__); - XLR_SEC_CMD_DIAG("[%s]: eng=%lld pipe=%lld\n", - __FUNCTION__, sec_eng, sec_pipe); + } + /* + * The adddress points to the data descriptor. The operation + * descriptor is defined with the 32-byte cacheline size in + * mind. It allows the code to use this address to + * reference the symkey descriptor. (ref: xlr_sec_desc.h) + */ + addr = addr - sizeof(OperationDescriptor_t); + desc = (symkey_desc_pt) MIPS_PHYS_TO_KSEG0(addr); - /* Symmetric Key Operation ? */ - if (sec_eng == MSG0_CTL_OP_ENGINE_SYMKEY) { + if (!desc) { + printf("\nerror : not getting desc back correctly \n"); + panic("[%s:STNID_SEC]: NULL symkey data descriptor!\n", __FUNCTION__); + } + ses = (struct xlr_sec_session *)desc->ses; + if (!ses) { + printf("\n error : not getting ses back correctly \n"); + panic("[%s:STNID_SEC]: NULL symkey data descriptor!\n", __FUNCTION__); + } + cmd = &ses->cmd; + if (!cmd) { + printf("\n error : not getting cmd back correctly \n"); + panic("[%s:STNID_SEC]: NULL symkey data descriptor!\n", __FUNCTION__); + } + op = &cmd->op; + if (!op) { + printf("\n error : not getting op back correctly \n"); + panic("[%s:STNID_SEC]: NULL symkey data descriptor!\n", __FUNCTION__); + } + XLR_SEC_CMD_DIAG("[%s:STNID_SEC]: addr=0x%llx desc=%p alloc=%p \n", + __FUNCTION__, addr, desc, desc->alloc); - /* - * The data descriptor address allows us to associate the response - * with the submitted operation. - * Address is 40-bit cacheline aligned address. - * We need to zero bit 0-4 since they are used for the - * engine and pipe Id. - */ - addr = GET_FIELD(msg->msg1, MSG_RSLT_DATA_DSC_ADDR); + XLR_SEC_CMD_DIAG("[%s:STNID_SEC]: op_ctl=%p phys_self=%llx stn_id=%d \n", + __FUNCTION__, &desc->op_ctl, desc->op_ctl.phys_self, + desc->op_ctl.stn_id); - addr = addr & ~((1 << 5) - 1); - if (!addr) { - panic("[%s:STNID_SEC]: NULL symkey addr!\n", __FUNCTION__); + if (addr != desc->op_ctl.phys_self) { + XLR_SEC_CMD_DIAG("[%s:STNID_SEC]: Control Descriptor fails Self-Verify !\n", + __FUNCTION__); + printf("[%s:STNID_SEC]: Control Descriptor fails Self-Verify !\n", + __FUNCTION__); + printf("[%s:STNID_SEC]: addr=0x%llx desc=%p alloc=%p \n", + __FUNCTION__, (unsigned long long)addr, desc, desc->alloc); + printf("[%s:STNID_SEC]: op_ctl=%p phys_self=%llx stn_id=%d \n", + __FUNCTION__, &desc->op_ctl, (unsigned long long)desc->op_ctl.phys_self, + desc->op_ctl.stn_id); - } + } + if (desc->op_ctl.stn_id != MSGRNG_STNID_SEC0 && + desc->op_ctl.stn_id != MSGRNG_STNID_SEC1) { + XLR_SEC_CMD_DIAG("[%s:STNID_SEC]: Operation Type Mismatch !\n", + __FUNCTION__); + printf("[%s:STNID_SEC]: Operation Type Mismatch !\n", + __FUNCTION__); + printf("[%s:STNID_SEC]: addr=0x%llx desc=%p alloc=%p \n", + __FUNCTION__, (unsigned long long)addr, desc, desc->alloc); + printf("[%s:STNID_SEC]: op_ctl=%p phys_self=%llx stn_id=%d \n", + __FUNCTION__, &desc->op_ctl, (unsigned long long)desc->op_ctl.phys_self, + desc->op_ctl.stn_id); + } + desc->ctl_result = GET_FIELD(msg->msg0, MSG_RSLT_CTL_INST_ERR); + desc->data_result = GET_FIELD(msg->msg1, MSG_RSLT_DATA_INST_ERR); + XLR_SEC_CMD_DIAG("[%s:STNID_SEC]: cpu=%d ctl_result=0x%llx data_result=%llx\n", + __FUNCTION__, desc->op_ctl.cpu, + desc->ctl_result, desc->data_result); - /* - * The adddress points to the data descriptor. - * The operation descriptor is defined with the 32-byte cacheline - * size in mind. It allows the code to use this address to reference - * the symkey descriptor. (ref: xlr_sec_desc.h) - */ - addr = addr - sizeof(OperationDescriptor_t); - desc = (symkey_desc_pt) MIPS_PHYS_TO_KSEG0(addr); - - if (!desc) { - printf("\nerror : not getting desc back correctly \n"); - panic("[%s:STNID_SEC]: NULL symkey data descriptor!\n", __FUNCTION__); - } - - ses = (struct xlr_sec_session* ) desc->ses; - if (!ses) { - printf("\n error : not getting ses back correctly \n"); - panic("[%s:STNID_SEC]: NULL symkey data descriptor!\n", __FUNCTION__); - } - - cmd = &ses->cmd; - if (!cmd) { - printf("\n error : not getting cmd back correctly \n"); - panic("[%s:STNID_SEC]: NULL symkey data descriptor!\n", __FUNCTION__); - } - - op = &cmd->op; - if (!op) { - printf("\n error : not getting op back correctly \n"); - panic("[%s:STNID_SEC]: NULL symkey data descriptor!\n", __FUNCTION__); - } - - - - XLR_SEC_CMD_DIAG("[%s:STNID_SEC]: addr=0x%llx desc=%p alloc=%p \n", - __FUNCTION__, addr, desc, desc->alloc); - - XLR_SEC_CMD_DIAG("[%s:STNID_SEC]: op_ctl=%p phys_self=%llx stn_id=%d \n", - __FUNCTION__, &desc->op_ctl, desc->op_ctl.phys_self, - desc->op_ctl.stn_id); - - if (addr != desc->op_ctl.phys_self) { - XLR_SEC_CMD_DIAG("[%s:STNID_SEC]: Control Descriptor fails Self-Verify !\n", - __FUNCTION__); - printf("[%s:STNID_SEC]: Control Descriptor fails Self-Verify !\n", - __FUNCTION__); - printf("[%s:STNID_SEC]: addr=0x%llx desc=%p alloc=%p \n", - __FUNCTION__, (unsigned long long)addr, desc, desc->alloc); - printf("[%s:STNID_SEC]: op_ctl=%p phys_self=%llx stn_id=%d \n", - __FUNCTION__, &desc->op_ctl, (unsigned long long)desc->op_ctl.phys_self, - desc->op_ctl.stn_id); - - } - - if (desc->op_ctl.stn_id != MSGRNG_STNID_SEC0 && - desc->op_ctl.stn_id != MSGRNG_STNID_SEC1) { - XLR_SEC_CMD_DIAG("[%s:STNID_SEC]: Operation Type Mismatch !\n", - __FUNCTION__); - printf("[%s:STNID_SEC]: Operation Type Mismatch !\n", - __FUNCTION__); - printf("[%s:STNID_SEC]: addr=0x%llx desc=%p alloc=%p \n", - __FUNCTION__, (unsigned long long)addr, desc, desc->alloc); - printf("[%s:STNID_SEC]: op_ctl=%p phys_self=%llx stn_id=%d \n", - __FUNCTION__, &desc->op_ctl, (unsigned long long)desc->op_ctl.phys_self, - desc->op_ctl.stn_id); - } - - desc->ctl_result = GET_FIELD(msg->msg0, MSG_RSLT_CTL_INST_ERR); - desc->data_result = GET_FIELD(msg->msg1, MSG_RSLT_DATA_INST_ERR); - - XLR_SEC_CMD_DIAG("[%s:STNID_SEC]: cpu=%d ctl_result=0x%llx data_result=%llx\n", - __FUNCTION__, desc->op_ctl.cpu, - desc->ctl_result, desc->data_result); - - } + } #if 0 - else if (sec_eng == MSG0_CTL_OP_ENGINE_PUBKEY) { - pubkey_desc_pt desc; + else if (sec_eng == MSG0_CTL_OP_ENGINE_PUBKEY) { + pubkey_desc_pt desc; - if (sec_pipe != MSG1_CTL_OP_PUBKEY_PIPE0) { - /* response to uc load */ - /* - XLR_SEC_CMD_DIAG("[%s:STNID_SEC]: ecc cpu=%d ctl_result=0x%llx data_result=%llx\n", - __FUNCTION__, desc->op_ctl.cpu, - desc->ctl_result, desc->data_result); - */ - return; - } - /* - * The data descriptor address allows us to associate the response - * with the submitted operation. - * Address is 40-bit cacheline aligned address. - * We need to zero bit 0-4 since they are used for the - * engine and pipe Id. - */ - addr = GET_FIELD(msg->msg0, PUBKEY_RSLT_CTL_SRCADDR); - addr = addr & ~((1 << 5) - 1); - if (!addr) { - panic("[%s:STNID_SEC]: NULL pubkey ctrl desc!\n", __FUNCTION__); - } + if (sec_pipe != MSG1_CTL_OP_PUBKEY_PIPE0) { + /* response to uc load */ + /* + * XLR_SEC_CMD_DIAG("[%s:STNID_SEC]: ecc cpu=%d + * ctl_result=0x%llx data_result=%llx\n", + * __FUNCTION__, desc->op_ctl.cpu, desc->ctl_result, + * desc->data_result); + */ + return; + } + /* + * The data descriptor address allows us to associate the + * response with the submitted operation. Address is 40-bit + * cacheline aligned address. We need to zero bit 0-4 since + * they are used for the engine and pipe Id. + */ + addr = GET_FIELD(msg->msg0, PUBKEY_RSLT_CTL_SRCADDR); + addr = addr & ~((1 << 5) - 1); + if (!addr) { + panic("[%s:STNID_SEC]: NULL pubkey ctrl desc!\n", __FUNCTION__); + } + /* + * The adddress points to the data descriptor. The operation + * descriptor is defined with the 32-byte cacheline size in + * mind. It allows the code to use this address to + * reference the symkey descriptor. (ref: xlr_sec_desc.h) + */ + addr = addr - sizeof(OperationDescriptor_t); - /* - * The adddress points to the data descriptor. - * The operation descriptor is defined with the 32-byte cacheline - * size in mind. It allows the code to use this address to reference - * the symkey descriptor. (ref: xlr_sec_desc.h) - */ - addr = addr - sizeof(OperationDescriptor_t); + /* Get pointer to pubkey Descriptor */ + desc = (pubkey_desc_pt) (unsigned long)addr; + if (!desc) { + panic("[%s:STNID_SEC]: NULL pubkey data descriptor!\n", __FUNCTION__); + } + XLR_SEC_CMD_DIAG("[%s:STNID_PK0]: addr=0x%llx desc=%p alloc=%p \n", + __FUNCTION__, addr, desc, desc->alloc); - /* Get pointer to pubkey Descriptor */ - desc = (pubkey_desc_pt)(unsigned long) addr ; - if (!desc) { - panic("[%s:STNID_SEC]: NULL pubkey data descriptor!\n", __FUNCTION__); - } + XLR_SEC_CMD_DIAG("[%s:STNID_PK0]: op_ctl=%p phys_self=%llx stn_id=%d \n", + __FUNCTION__, &desc->op_ctl, desc->op_ctl.phys_self, + desc->op_ctl.stn_id); - XLR_SEC_CMD_DIAG("[%s:STNID_PK0]: addr=0x%llx desc=%p alloc=%p \n", - __FUNCTION__, addr, desc, desc->alloc); + if (addr != desc->op_ctl.phys_self) { + XLR_SEC_CMD_DIAG("[%s:STNID_PK0]: Control Descriptor fails Self-Verify !\n", + __FUNCTION__); + } + if (desc->op_ctl.stn_id != msgrng_stnid_pk0) { + XLR_SEC_CMD_DIAG("[%s:STNID_PK0]: Operation Type Mismatch ! \n", + __FUNCTION__); + } + desc->ctl_result = GET_FIELD(msg->msg0, PUBKEY_RSLT_CTL_ERROR); + desc->data_result = GET_FIELD(msg->msg1, PUBKEY_RSLT_DATA_ERROR); - XLR_SEC_CMD_DIAG("[%s:STNID_PK0]: op_ctl=%p phys_self=%llx stn_id=%d \n", - __FUNCTION__, &desc->op_ctl, desc->op_ctl.phys_self, - desc->op_ctl.stn_id); + XLR_SEC_CMD_DIAG("[%s:STNID_PK0]: ctl_result=0x%llx data_result=%llx\n", + __FUNCTION__, desc->ctl_result, desc->data_result); - if (addr != desc->op_ctl.phys_self) { - XLR_SEC_CMD_DIAG("[%s:STNID_PK0]: Control Descriptor fails Self-Verify !\n", - __FUNCTION__); - } - - - if (desc->op_ctl.stn_id != msgrng_stnid_pk0) { - XLR_SEC_CMD_DIAG("[%s:STNID_PK0]: Operation Type Mismatch ! \n", - __FUNCTION__); - } - - desc->ctl_result = GET_FIELD(msg->msg0, PUBKEY_RSLT_CTL_ERROR); - desc->data_result = GET_FIELD(msg->msg1, PUBKEY_RSLT_DATA_ERROR); - - XLR_SEC_CMD_DIAG("[%s:STNID_PK0]: ctl_result=0x%llx data_result=%llx\n", - __FUNCTION__, desc->ctl_result, desc->data_result); - - } + } #endif - else { - printf("[%s]: HANDLER bad id = %d\n", __FUNCTION__, stid); - } + else { + printf("[%s]: HANDLER bad id = %d\n", __FUNCTION__, stid); + } #ifdef RMI_SEC_DEBUG - if(ses->multi_frag_flag){ - int i; - char *ptr; - printf("\n RETURNED DATA: \n"); + if (ses->multi_frag_flag) { + int i; + char *ptr; - ptr = (char*) (unsigned long)(desc->user.aligned_dest+cmd->op.cipher_offset) ; - for(i = 0; i< SEC_MAX_FRAG_LEN ; i++){ - printf("%c ",(char) *ptr++); - if((i%10) == 0) printf("\n"); - } + printf("\n RETURNED DATA: \n"); - printf("second desc\n"); - ptr = (char*) (unsigned long)(desc->next_dest_buf) ; - for(i = 0; i< desc->next_src_len; i++){ - printf("%c ",(char) *ptr++); - if((i%10) == 0) printf("\n"); - } - } + ptr = (char *)(unsigned long)(desc->user.aligned_dest + cmd->op.cipher_offset); + for (i = 0; i < SEC_MAX_FRAG_LEN; i++) { + printf("%c ", (char)*ptr++); + if ((i % 10) == 0) + printf("\n"); + } + + printf("second desc\n"); + ptr = (char *)(unsigned long)(desc->next_dest_buf); + for (i = 0; i < desc->next_src_len; i++) { + printf("%c ", (char)*ptr++); + if ((i % 10) == 0) + printf("\n"); + } + } #endif - /* Copy cipher-data to User-space */ - if (op->cipher_type != XLR_SEC_CIPHER_TYPE_NONE) { + /* Copy cipher-data to User-space */ + if (op->cipher_type != XLR_SEC_CIPHER_TYPE_NONE) { - size = op->dest_buf_size; + size = op->dest_buf_size; - /* DEBUG -dpk */ - XLR_SEC_CMD_DIAG("cipher: to_addr=%p from_addr=%p size=%d \n", - desc->user.user_dest, desc->user.aligned_dest, size); + /* DEBUG -dpk */ + XLR_SEC_CMD_DIAG("cipher: to_addr=%p from_addr=%p size=%d \n", + desc->user.user_dest, desc->user.aligned_dest, size); - if(ses->multi_frag_flag){ - crypto_copyback(cmd->crp->crp_flags, cmd->crp->crp_buf, 0, - SEC_MAX_FRAG_LEN, (caddr_t)(long)desc->user.aligned_dest+op->cipher_offset); - crypto_copyback(cmd->crp->crp_flags, cmd->crp->crp_buf+SEC_MAX_FRAG_LEN, 0, - desc->next_src_len, (caddr_t)(long)desc->next_dest_buf); - crypto_done(cmd->crp); - } - else{ - crypto_copyback(cmd->crp->crp_flags, cmd->crp->crp_buf, 0, - cmd->op.dest_buf_size, (caddr_t)(long)desc->user.aligned_dest+op->cipher_offset); - crypto_done(cmd->crp); + if (ses->multi_frag_flag) { + crypto_copyback(cmd->crp->crp_flags, cmd->crp->crp_buf, 0, + SEC_MAX_FRAG_LEN, (caddr_t)(long)desc->user.aligned_dest + op->cipher_offset); + crypto_copyback(cmd->crp->crp_flags, cmd->crp->crp_buf + SEC_MAX_FRAG_LEN, 0, + desc->next_src_len, (caddr_t)(long)desc->next_dest_buf); + crypto_done(cmd->crp); + } else { + crypto_copyback(cmd->crp->crp_flags, cmd->crp->crp_buf, 0, + cmd->op.dest_buf_size, (caddr_t)(long)desc->user.aligned_dest + op->cipher_offset); + crypto_done(cmd->crp); - } + } - } + } + /* Copy digest to User-space */ + if (op->digest_type != XLR_SEC_DIGEST_TYPE_NONE) { + int offset = 0; - /* Copy digest to User-space */ - if (op->digest_type != XLR_SEC_DIGEST_TYPE_NONE) { + switch (op->digest_type) { + case XLR_SEC_DIGEST_TYPE_MD5: + size = XLR_SEC_MD5_LENGTH; + break; + case XLR_SEC_DIGEST_TYPE_SHA1: + size = XLR_SEC_SHA1_LENGTH; + break; + case XLR_SEC_DIGEST_TYPE_SHA256: + size = XLR_SEC_SHA256_LENGTH; + break; + case XLR_SEC_DIGEST_TYPE_SHA384: + size = XLR_SEC_SHA384_LENGTH; + break; + case XLR_SEC_DIGEST_TYPE_SHA512: + size = XLR_SEC_SHA512_LENGTH; + break; + case XLR_SEC_DIGEST_TYPE_GCM: + size = XLR_SEC_GCM_LENGTH; + break; + case XLR_SEC_DIGEST_TYPE_KASUMI_F9: + offset = 4; + size = XLR_SEC_KASUMI_F9_RESULT_LENGTH; + break; + default: + size = 0; + } - int offset = 0; - switch (op->digest_type) { - case XLR_SEC_DIGEST_TYPE_MD5: - size = XLR_SEC_MD5_LENGTH; - break; - case XLR_SEC_DIGEST_TYPE_SHA1: - size = XLR_SEC_SHA1_LENGTH; - break; - case XLR_SEC_DIGEST_TYPE_SHA256: - size = XLR_SEC_SHA256_LENGTH; - break; - case XLR_SEC_DIGEST_TYPE_SHA384: - size = XLR_SEC_SHA384_LENGTH; - break; - case XLR_SEC_DIGEST_TYPE_SHA512: - size = XLR_SEC_SHA512_LENGTH; - break; - case XLR_SEC_DIGEST_TYPE_GCM: - size = XLR_SEC_GCM_LENGTH; - break; - case XLR_SEC_DIGEST_TYPE_KASUMI_F9: - offset = 4; - size = XLR_SEC_KASUMI_F9_RESULT_LENGTH; - break; - default: - size = 0; - } + XLR_SEC_CMD_DIAG("digest: to_addr=%p from_addr=%p size=%d \n", + desc->user.user_auth, desc->user.aligned_auth, size); + memcpy(desc->user.user_auth, desc->user.aligned_auth + offset, size); + op->auth_dest = (uint64_t) (unsigned long)desc->user.user_auth; + } + if (op->cipher_type == XLR_SEC_CIPHER_TYPE_ARC4 && + op->rc4_savestate) { - XLR_SEC_CMD_DIAG("digest: to_addr=%p from_addr=%p size=%d \n", - desc->user.user_auth, desc->user.aligned_auth, size); - memcpy(desc->user.user_auth, desc->user.aligned_auth + offset,size); - op->auth_dest = (uint64_t)(unsigned long)desc->user.user_auth; - } + size = XLR_SEC_MAX_RC4_STATE_SIZE; - - if (op->cipher_type == XLR_SEC_CIPHER_TYPE_ARC4 && - op->rc4_savestate) { - - size = XLR_SEC_MAX_RC4_STATE_SIZE; - - XLR_SEC_CMD_DIAG("state: to_addr=%p from_addr=%p size=%d \n", - desc->user.user_state, desc->user.aligned_state, size); - op->rc4_state = (uint64_t)(unsigned long)desc->user.user_state; - } - - return; + XLR_SEC_CMD_DIAG("state: to_addr=%p from_addr=%p size=%d \n", + desc->user.user_state, desc->user.aligned_state, size); + op->rc4_state = (uint64_t) (unsigned long)desc->user.user_state; + } + return; } - diff --git a/sys/dev/rmi/sec/rmilib.h b/sys/dev/rmi/sec/rmilib.h index 7eb7c5d9545..060b9db1cbd 100644 --- a/sys/dev/rmi/sec/rmilib.h +++ b/sys/dev/rmi/sec/rmilib.h @@ -64,48 +64,48 @@ /* * Cryptographic parameter definitions */ -#define XLR_SEC_DES_KEY_LENGTH 8 /* Bytes */ -#define XLR_SEC_3DES_KEY_LENGTH 24 /* Bytes */ -#define XLR_SEC_AES128_KEY_LENGTH 16 /* Bytes */ -#define XLR_SEC_AES192_KEY_LENGTH 24 /* Bytes */ -#define XLR_SEC_AES256_KEY_LENGTH 32 /* Bytes */ -#define XLR_SEC_AES128F8_KEY_LENGTH 32 /* Bytes */ -#define XLR_SEC_AES192F8_KEY_LENGTH 48 /* Bytes */ -#define XLR_SEC_AES256F8_KEY_LENGTH 64 /* Bytes */ -#define XLR_SEC_KASUMI_F8_KEY_LENGTH 16 /* Bytes */ +#define XLR_SEC_DES_KEY_LENGTH 8 /* Bytes */ +#define XLR_SEC_3DES_KEY_LENGTH 24 /* Bytes */ +#define XLR_SEC_AES128_KEY_LENGTH 16 /* Bytes */ +#define XLR_SEC_AES192_KEY_LENGTH 24 /* Bytes */ +#define XLR_SEC_AES256_KEY_LENGTH 32 /* Bytes */ +#define XLR_SEC_AES128F8_KEY_LENGTH 32 /* Bytes */ +#define XLR_SEC_AES192F8_KEY_LENGTH 48 /* Bytes */ +#define XLR_SEC_AES256F8_KEY_LENGTH 64 /* Bytes */ +#define XLR_SEC_KASUMI_F8_KEY_LENGTH 16 /* Bytes */ #define XLR_SEC_MAX_CRYPT_KEY_LENGTH XLR_SEC_AES256F8_KEY_LENGTH -#define XLR_SEC_DES_IV_LENGTH 8 /* Bytes */ -#define XLR_SEC_AES_IV_LENGTH 16 /* Bytes */ -#define XLR_SEC_ARC4_IV_LENGTH 0 /* Bytes */ -#define XLR_SEC_KASUMI_F8_IV_LENGTH 16 /* Bytes */ -#define XLR_SEC_MAX_IV_LENGTH 16 /* Bytes */ -#define XLR_SEC_IV_LENGTH_BYTES 8 /* Bytes */ +#define XLR_SEC_DES_IV_LENGTH 8 /* Bytes */ +#define XLR_SEC_AES_IV_LENGTH 16 /* Bytes */ +#define XLR_SEC_ARC4_IV_LENGTH 0 /* Bytes */ +#define XLR_SEC_KASUMI_F8_IV_LENGTH 16 /* Bytes */ +#define XLR_SEC_MAX_IV_LENGTH 16 /* Bytes */ +#define XLR_SEC_IV_LENGTH_BYTES 8 /* Bytes */ -#define XLR_SEC_AES_BLOCK_SIZE 16 /* Bytes */ -#define XLR_SEC_DES_BLOCK_SIZE 8 /* Bytes */ -#define XLR_SEC_3DES_BLOCK_SIZE 8 /* Bytes */ +#define XLR_SEC_AES_BLOCK_SIZE 16 /* Bytes */ +#define XLR_SEC_DES_BLOCK_SIZE 8 /* Bytes */ +#define XLR_SEC_3DES_BLOCK_SIZE 8 /* Bytes */ -#define XLR_SEC_MD5_BLOCK_SIZE 64 /* Bytes */ -#define XLR_SEC_SHA1_BLOCK_SIZE 64 /* Bytes */ -#define XLR_SEC_SHA256_BLOCK_SIZE 64 /* Bytes */ -#define XLR_SEC_SHA384_BLOCK_SIZE 128/* Bytes */ -#define XLR_SEC_SHA512_BLOCK_SIZE 128/* Bytes */ -#define XLR_SEC_GCM_BLOCK_SIZE 16 /* XXX: Bytes */ -#define XLR_SEC_KASUMI_F9_BLOCK_SIZE 16 /* XXX: Bytes */ -#define XLR_SEC_MAX_BLOCK_SIZE 64 /* Max of MD5/SHA */ -#define XLR_SEC_MD5_LENGTH 16 /* Bytes */ -#define XLR_SEC_SHA1_LENGTH 20 /* Bytes */ -#define XLR_SEC_SHA256_LENGTH 32 /* Bytes */ -#define XLR_SEC_SHA384_LENGTH 64 /* Bytes */ -#define XLR_SEC_SHA512_LENGTH 64 /* Bytes */ -#define XLR_SEC_GCM_LENGTH 16 /* Bytes */ -#define XLR_SEC_KASUMI_F9_LENGTH 16 /* Bytes */ -#define XLR_SEC_KASUMI_F9_RESULT_LENGTH 4 /* Bytes */ -#define XLR_SEC_HMAC_LENGTH 64 /* Max of MD5/SHA/SHA256 */ +#define XLR_SEC_MD5_BLOCK_SIZE 64 /* Bytes */ +#define XLR_SEC_SHA1_BLOCK_SIZE 64 /* Bytes */ +#define XLR_SEC_SHA256_BLOCK_SIZE 64 /* Bytes */ +#define XLR_SEC_SHA384_BLOCK_SIZE 128 /* Bytes */ +#define XLR_SEC_SHA512_BLOCK_SIZE 128 /* Bytes */ +#define XLR_SEC_GCM_BLOCK_SIZE 16 /* XXX: Bytes */ +#define XLR_SEC_KASUMI_F9_BLOCK_SIZE 16 /* XXX: Bytes */ +#define XLR_SEC_MAX_BLOCK_SIZE 64 /* Max of MD5/SHA */ +#define XLR_SEC_MD5_LENGTH 16 /* Bytes */ +#define XLR_SEC_SHA1_LENGTH 20 /* Bytes */ +#define XLR_SEC_SHA256_LENGTH 32 /* Bytes */ +#define XLR_SEC_SHA384_LENGTH 64 /* Bytes */ +#define XLR_SEC_SHA512_LENGTH 64 /* Bytes */ +#define XLR_SEC_GCM_LENGTH 16 /* Bytes */ +#define XLR_SEC_KASUMI_F9_LENGTH 16 /* Bytes */ +#define XLR_SEC_KASUMI_F9_RESULT_LENGTH 4 /* Bytes */ +#define XLR_SEC_HMAC_LENGTH 64 /* Max of MD5/SHA/SHA256 */ #define XLR_SEC_MAX_AUTH_KEY_LENGTH XLR_SEC_SHA512_BLOCK_SIZE -#define XLR_SEC_MAX_RC4_STATE_SIZE 264 /* char s[256], int i, int j */ +#define XLR_SEC_MAX_RC4_STATE_SIZE 264 /* char s[256], int i, int j */ /* Status code is used by the SRL to indicate status */ typedef unsigned int xlr_sec_status_t; @@ -394,200 +394,204 @@ typedef int xlr_sec_error_t; * Cipher Modes */ typedef enum { - XLR_SEC_CIPHER_MODE_NONE = 0, - XLR_SEC_CIPHER_MODE_PASS = 1, - XLR_SEC_CIPHER_MODE_ECB, - XLR_SEC_CIPHER_MODE_CBC, - XLR_SEC_CIPHER_MODE_OFB, - XLR_SEC_CIPHER_MODE_CTR, - XLR_SEC_CIPHER_MODE_CFB, - XLR_SEC_CIPHER_MODE_F8 -} XLR_SEC_CIPHER_MODE; + XLR_SEC_CIPHER_MODE_NONE = 0, + XLR_SEC_CIPHER_MODE_PASS = 1, + XLR_SEC_CIPHER_MODE_ECB, + XLR_SEC_CIPHER_MODE_CBC, + XLR_SEC_CIPHER_MODE_OFB, + XLR_SEC_CIPHER_MODE_CTR, + XLR_SEC_CIPHER_MODE_CFB, + XLR_SEC_CIPHER_MODE_F8 +} XLR_SEC_CIPHER_MODE; typedef enum { - XLR_SEC_CIPHER_OP_NONE = 0, - XLR_SEC_CIPHER_OP_ENCRYPT = 1, - XLR_SEC_CIPHER_OP_DECRYPT -} XLR_SEC_CIPHER_OP; + XLR_SEC_CIPHER_OP_NONE = 0, + XLR_SEC_CIPHER_OP_ENCRYPT = 1, + XLR_SEC_CIPHER_OP_DECRYPT +} XLR_SEC_CIPHER_OP; typedef enum { - XLR_SEC_CIPHER_TYPE_UNSUPPORTED = -1, - XLR_SEC_CIPHER_TYPE_NONE = 0, - XLR_SEC_CIPHER_TYPE_DES, - XLR_SEC_CIPHER_TYPE_3DES, - XLR_SEC_CIPHER_TYPE_AES128, - XLR_SEC_CIPHER_TYPE_AES192, - XLR_SEC_CIPHER_TYPE_AES256, - XLR_SEC_CIPHER_TYPE_ARC4, - XLR_SEC_CIPHER_TYPE_KASUMI_F8 -} XLR_SEC_CIPHER_TYPE; + XLR_SEC_CIPHER_TYPE_UNSUPPORTED = -1, + XLR_SEC_CIPHER_TYPE_NONE = 0, + XLR_SEC_CIPHER_TYPE_DES, + XLR_SEC_CIPHER_TYPE_3DES, + XLR_SEC_CIPHER_TYPE_AES128, + XLR_SEC_CIPHER_TYPE_AES192, + XLR_SEC_CIPHER_TYPE_AES256, + XLR_SEC_CIPHER_TYPE_ARC4, + XLR_SEC_CIPHER_TYPE_KASUMI_F8 +} XLR_SEC_CIPHER_TYPE; typedef enum { - XLR_SEC_CIPHER_INIT_OK = 1, /* Preserve old Keys */ - XLR_SEC_CIPHER_INIT_NK /*Load new Keys */ -} XLR_SEC_CIPHER_INIT; + XLR_SEC_CIPHER_INIT_OK = 1, /* Preserve old Keys */ + XLR_SEC_CIPHER_INIT_NK /* Load new Keys */ +} XLR_SEC_CIPHER_INIT; /* * Hash Modes */ typedef enum { - XLR_SEC_DIGEST_TYPE_UNSUPPORTED = -1, - XLR_SEC_DIGEST_TYPE_NONE = 0, - XLR_SEC_DIGEST_TYPE_MD5, - XLR_SEC_DIGEST_TYPE_SHA1, - XLR_SEC_DIGEST_TYPE_SHA256, - XLR_SEC_DIGEST_TYPE_SHA384, - XLR_SEC_DIGEST_TYPE_SHA512, - XLR_SEC_DIGEST_TYPE_GCM, - XLR_SEC_DIGEST_TYPE_KASUMI_F9, - XLR_SEC_DIGEST_TYPE_HMAC_MD5, - XLR_SEC_DIGEST_TYPE_HMAC_SHA1, - XLR_SEC_DIGEST_TYPE_HMAC_SHA256, - XLR_SEC_DIGEST_TYPE_HMAC_SHA384, - XLR_SEC_DIGEST_TYPE_HMAC_SHA512, - XLR_SEC_DIGEST_TYPE_HMAC_AES_CBC, - XLR_SEC_DIGEST_TYPE_HMAC_AES_XCBC -} XLR_SEC_DIGEST_TYPE; + XLR_SEC_DIGEST_TYPE_UNSUPPORTED = -1, + XLR_SEC_DIGEST_TYPE_NONE = 0, + XLR_SEC_DIGEST_TYPE_MD5, + XLR_SEC_DIGEST_TYPE_SHA1, + XLR_SEC_DIGEST_TYPE_SHA256, + XLR_SEC_DIGEST_TYPE_SHA384, + XLR_SEC_DIGEST_TYPE_SHA512, + XLR_SEC_DIGEST_TYPE_GCM, + XLR_SEC_DIGEST_TYPE_KASUMI_F9, + XLR_SEC_DIGEST_TYPE_HMAC_MD5, + XLR_SEC_DIGEST_TYPE_HMAC_SHA1, + XLR_SEC_DIGEST_TYPE_HMAC_SHA256, + XLR_SEC_DIGEST_TYPE_HMAC_SHA384, + XLR_SEC_DIGEST_TYPE_HMAC_SHA512, + XLR_SEC_DIGEST_TYPE_HMAC_AES_CBC, + XLR_SEC_DIGEST_TYPE_HMAC_AES_XCBC +} XLR_SEC_DIGEST_TYPE; typedef enum { - XLR_SEC_DIGEST_INIT_OLDKEY = 1, /* Preserve old key HMAC key stored in ID registers (moot if HASH.HMAC == 0) */ - XLR_SEC_DIGEST_INIT_NEWKEY /*Load new HMAC key from memory ctrl section to ID registers */ -} XLR_SEC_DIGEST_INIT; + XLR_SEC_DIGEST_INIT_OLDKEY = 1, /* Preserve old key HMAC key stored in + * ID registers (moot if HASH.HMAC == + * 0) */ + XLR_SEC_DIGEST_INIT_NEWKEY /* Load new HMAC key from memory ctrl + * section to ID registers */ +} XLR_SEC_DIGEST_INIT; typedef enum { - XLR_SEC_DIGEST_SRC_DMA = 1, /* DMA channel */ - XLR_SEC_DIGEST_SRC_CPHR /*Cipher if word count exceeded Cipher_Offset; else DMA */ -} XLR_SEC_DIGEST_SRC; + XLR_SEC_DIGEST_SRC_DMA = 1, /* DMA channel */ + XLR_SEC_DIGEST_SRC_CPHR /* Cipher if word count exceeded + * Cipher_Offset; else DMA */ +} XLR_SEC_DIGEST_SRC; /* * Checksum Modes */ typedef enum { - XLR_SEC_CKSUM_TYPE_NOP = 1, - XLR_SEC_CKSUM_TYPE_IP -} XLR_SEC_CKSUM_TYPE; + XLR_SEC_CKSUM_TYPE_NOP = 1, + XLR_SEC_CKSUM_TYPE_IP +} XLR_SEC_CKSUM_TYPE; typedef enum { - XLR_SEC_CKSUM_SRC_DMA = 1, - XLR_SEC_CKSUM_SRC_CIPHER -} XLR_SEC_CKSUM_SRC; + XLR_SEC_CKSUM_SRC_DMA = 1, + XLR_SEC_CKSUM_SRC_CIPHER +} XLR_SEC_CKSUM_SRC; /* * Packet Modes */ typedef enum { - XLR_SEC_LOADHMACKEY_MODE_OLD = 1, - XLR_SEC_LOADHMACKEY_MODE_LOAD -} XLR_SEC_LOADHMACKEY_MODE; + XLR_SEC_LOADHMACKEY_MODE_OLD = 1, + XLR_SEC_LOADHMACKEY_MODE_LOAD +} XLR_SEC_LOADHMACKEY_MODE; typedef enum { - XLR_SEC_PADHASH_PADDED = 1, - XLR_SEC_PADHASH_PAD -} XLR_SEC_PADHASH_MODE; + XLR_SEC_PADHASH_PADDED = 1, + XLR_SEC_PADHASH_PAD +} XLR_SEC_PADHASH_MODE; typedef enum { - XLR_SEC_HASHBYTES_ALL8 = 1, - XLR_SEC_HASHBYTES_MSB, - XLR_SEC_HASHBYTES_MSW -} XLR_SEC_HASHBYTES_MODE; + XLR_SEC_HASHBYTES_ALL8 = 1, + XLR_SEC_HASHBYTES_MSB, + XLR_SEC_HASHBYTES_MSW +} XLR_SEC_HASHBYTES_MODE; typedef enum { - XLR_SEC_NEXT_FINISH = 1, - XLR_SEC_NEXT_DO -} XLR_SEC_NEXT_MODE; + XLR_SEC_NEXT_FINISH = 1, + XLR_SEC_NEXT_DO +} XLR_SEC_NEXT_MODE; typedef enum { - XLR_SEC_PKT_IV_OLD = 1, - XLR_SEC_PKT_IV_NEW -} XLR_SEC_PKT_IV_MODE; + XLR_SEC_PKT_IV_OLD = 1, + XLR_SEC_PKT_IV_NEW +} XLR_SEC_PKT_IV_MODE; typedef enum { - XLR_SEC_LASTWORD_128 = 1, - XLR_SEC_LASTWORD_96MASK, - XLR_SEC_LASTWORD_64MASK, - XLR_SEC_LASTWORD_32MASK -} XLR_SEC_LASTWORD_MODE; + XLR_SEC_LASTWORD_128 = 1, + XLR_SEC_LASTWORD_96MASK, + XLR_SEC_LASTWORD_64MASK, + XLR_SEC_LASTWORD_32MASK +} XLR_SEC_LASTWORD_MODE; typedef enum { - XLR_SEC_CFB_MASK_REGULAR_CTR = 0, - XLR_SEC_CFB_MASK_CCMP, - XLR_SEC_CFB_MASK_GCM_WITH_SCI, - XLR_SEC_CFB_MASK_GCM_WITHOUT_SCI -} XLR_SEC_CFB_MASK_MODE; + XLR_SEC_CFB_MASK_REGULAR_CTR = 0, + XLR_SEC_CFB_MASK_CCMP, + XLR_SEC_CFB_MASK_GCM_WITH_SCI, + XLR_SEC_CFB_MASK_GCM_WITHOUT_SCI +} XLR_SEC_CFB_MASK_MODE; /* * Public Key */ typedef enum { - RMIPK_BLKWIDTH_512 = 1, - RMIPK_BLKWIDTH_1024 -} RMIPK_BLKWIDTH_MODE; + RMIPK_BLKWIDTH_512 = 1, + RMIPK_BLKWIDTH_1024 +} RMIPK_BLKWIDTH_MODE; typedef enum { - RMIPK_LDCONST_OLD = 1, - RMIPK_LDCONST_NEW -} RMIPK_LDCONST_MODE; + RMIPK_LDCONST_OLD = 1, + RMIPK_LDCONST_NEW +} RMIPK_LDCONST_MODE; typedef struct xlr_sec_io_s { - unsigned int command; - unsigned int result_status; - unsigned int flags; - unsigned int session_num; - unsigned int use_callback; - unsigned int time_us; - unsigned int user_context[2];/*usable for anything by caller*/ - unsigned int command_context; /* Context (ID) of this command). */ - unsigned char initial_vector[XLR_SEC_MAX_IV_LENGTH]; - unsigned char crypt_key[XLR_SEC_MAX_CRYPT_KEY_LENGTH]; - unsigned char mac_key[XLR_SEC_MAX_AUTH_KEY_LENGTH]; + unsigned int command; + unsigned int result_status; + unsigned int flags; + unsigned int session_num; + unsigned int use_callback; + unsigned int time_us; + unsigned int user_context[2]; /* usable for anything by caller */ + unsigned int command_context; /* Context (ID) of this command). */ + unsigned char initial_vector[XLR_SEC_MAX_IV_LENGTH]; + unsigned char crypt_key[XLR_SEC_MAX_CRYPT_KEY_LENGTH]; + unsigned char mac_key[XLR_SEC_MAX_AUTH_KEY_LENGTH]; - XLR_SEC_CIPHER_OP cipher_op; - XLR_SEC_CIPHER_MODE cipher_mode; - XLR_SEC_CIPHER_TYPE cipher_type; - XLR_SEC_CIPHER_INIT cipher_init; - unsigned int cipher_offset; + XLR_SEC_CIPHER_OP cipher_op; + XLR_SEC_CIPHER_MODE cipher_mode; + XLR_SEC_CIPHER_TYPE cipher_type; + XLR_SEC_CIPHER_INIT cipher_init; + unsigned int cipher_offset; - XLR_SEC_DIGEST_TYPE digest_type; - XLR_SEC_DIGEST_INIT digest_init; - XLR_SEC_DIGEST_SRC digest_src; - unsigned int digest_offset; + XLR_SEC_DIGEST_TYPE digest_type; + XLR_SEC_DIGEST_INIT digest_init; + XLR_SEC_DIGEST_SRC digest_src; + unsigned int digest_offset; - XLR_SEC_CKSUM_TYPE cksum_type; - XLR_SEC_CKSUM_SRC cksum_src; - unsigned int cksum_offset; + XLR_SEC_CKSUM_TYPE cksum_type; + XLR_SEC_CKSUM_SRC cksum_src; + unsigned int cksum_offset; - XLR_SEC_LOADHMACKEY_MODE pkt_hmac; - XLR_SEC_PADHASH_MODE pkt_hash; - XLR_SEC_HASHBYTES_MODE pkt_hashbytes; - XLR_SEC_NEXT_MODE pkt_next; - XLR_SEC_PKT_IV_MODE pkt_iv; - XLR_SEC_LASTWORD_MODE pkt_lastword; + XLR_SEC_LOADHMACKEY_MODE pkt_hmac; + XLR_SEC_PADHASH_MODE pkt_hash; + XLR_SEC_HASHBYTES_MODE pkt_hashbytes; + XLR_SEC_NEXT_MODE pkt_next; + XLR_SEC_PKT_IV_MODE pkt_iv; + XLR_SEC_LASTWORD_MODE pkt_lastword; - unsigned int nonce; - unsigned int cfb_mask; + unsigned int nonce; + unsigned int cfb_mask; - unsigned int iv_offset; - unsigned short pad_type; - unsigned short rc4_key_len; + unsigned int iv_offset; + unsigned short pad_type; + unsigned short rc4_key_len; - unsigned int num_packets; - unsigned int num_fragments; + unsigned int num_packets; + unsigned int num_fragments; - uint64_t source_buf; - unsigned int source_buf_size; - uint64_t dest_buf; - unsigned int dest_buf_size; + uint64_t source_buf; + unsigned int source_buf_size; + uint64_t dest_buf; + unsigned int dest_buf_size; - uint64_t auth_dest; - uint64_t cksum_dest; + uint64_t auth_dest; + uint64_t cksum_dest; - unsigned short rc4_loadstate; - unsigned short rc4_savestate; - uint64_t rc4_state; + unsigned short rc4_loadstate; + unsigned short rc4_savestate; + uint64_t rc4_state; -} xlr_sec_io_t, *xlr_sec_io_pt; +} xlr_sec_io_t, *xlr_sec_io_pt; #define XLR_SEC_SESSION(sid) ((sid) & 0x000007ff) @@ -608,32 +612,32 @@ typedef struct xlr_sec_io_s { #define SEC_MAX_FRAG_LEN 16000 struct xlr_sec_command { - uint16_t session_num; - struct cryptop *crp; - struct cryptodesc *enccrd, *maccrd; + uint16_t session_num; + struct cryptop *crp; + struct cryptodesc *enccrd, *maccrd; - xlr_sec_io_t op; + xlr_sec_io_t op; }; -struct xlr_sec_session{ - uint32_t sessionid; - int hs_used; - int hs_mlen; - struct xlr_sec_command cmd; - void* desc_ptr; - uint8_t multi_frag_flag; +struct xlr_sec_session { + uint32_t sessionid; + int hs_used; + int hs_mlen; + struct xlr_sec_command cmd; + void *desc_ptr; + uint8_t multi_frag_flag; }; /* * Holds data specific to rmi security accelerators */ struct xlr_sec_softc { - device_t sc_dev; /* device backpointer */ - struct mtx sc_mtx; /* per-instance lock */ + device_t sc_dev; /* device backpointer */ + struct mtx sc_mtx; /* per-instance lock */ - int32_t sc_cid; - struct xlr_sec_session *sc_sessions; - int sc_nsessions; - xlr_reg_t* mmio; + int32_t sc_cid; + struct xlr_sec_session *sc_sessions; + int sc_nsessions; + xlr_reg_t *mmio; }; @@ -772,103 +776,103 @@ union xlr_sec_operand_t { enum sec_pipe_config { - SEC_PIPE_CIPHER_KEY0_L0 = 0x00, - SEC_PIPE_CIPHER_KEY0_HI, - SEC_PIPE_CIPHER_KEY1_LO, - SEC_PIPE_CIPHER_KEY1_HI, - SEC_PIPE_CIPHER_KEY2_LO, - SEC_PIPE_CIPHER_KEY2_HI, - SEC_PIPE_CIPHER_KEY3_LO, - SEC_PIPE_CIPHER_KEY3_HI, - SEC_PIPE_HMAC_KEY0_LO, - SEC_PIPE_HMAC_KEY0_HI, - SEC_PIPE_HMAC_KEY1_LO, - SEC_PIPE_HMAC_KEY1_HI, - SEC_PIPE_HMAC_KEY2_LO, - SEC_PIPE_HMAC_KEY2_HI, - SEC_PIPE_HMAC_KEY3_LO, - SEC_PIPE_HMAC_KEY3_HI, - SEC_PIPE_HMAC_KEY4_LO, - SEC_PIPE_HMAC_KEY4_HI, - SEC_PIPE_HMAC_KEY5_LO, - SEC_PIPE_HMAC_KEY5_HI, - SEC_PIPE_HMAC_KEY6_LO, - SEC_PIPE_HMAC_KEY6_HI, - SEC_PIPE_HMAC_KEY7_LO, - SEC_PIPE_HMAC_KEY7_HI, - SEC_PIPE_NCFBM_LO, - SEC_PIPE_NCFBM_HI, - SEC_PIPE_INSTR_LO, - SEC_PIPE_INSTR_HI, - SEC_PIPE_RSVD0, - SEC_PIPE_RSVD1, - SEC_PIPE_RSVD2, - SEC_PIPE_RSVD3, + SEC_PIPE_CIPHER_KEY0_L0 = 0x00, + SEC_PIPE_CIPHER_KEY0_HI, + SEC_PIPE_CIPHER_KEY1_LO, + SEC_PIPE_CIPHER_KEY1_HI, + SEC_PIPE_CIPHER_KEY2_LO, + SEC_PIPE_CIPHER_KEY2_HI, + SEC_PIPE_CIPHER_KEY3_LO, + SEC_PIPE_CIPHER_KEY3_HI, + SEC_PIPE_HMAC_KEY0_LO, + SEC_PIPE_HMAC_KEY0_HI, + SEC_PIPE_HMAC_KEY1_LO, + SEC_PIPE_HMAC_KEY1_HI, + SEC_PIPE_HMAC_KEY2_LO, + SEC_PIPE_HMAC_KEY2_HI, + SEC_PIPE_HMAC_KEY3_LO, + SEC_PIPE_HMAC_KEY3_HI, + SEC_PIPE_HMAC_KEY4_LO, + SEC_PIPE_HMAC_KEY4_HI, + SEC_PIPE_HMAC_KEY5_LO, + SEC_PIPE_HMAC_KEY5_HI, + SEC_PIPE_HMAC_KEY6_LO, + SEC_PIPE_HMAC_KEY6_HI, + SEC_PIPE_HMAC_KEY7_LO, + SEC_PIPE_HMAC_KEY7_HI, + SEC_PIPE_NCFBM_LO, + SEC_PIPE_NCFBM_HI, + SEC_PIPE_INSTR_LO, + SEC_PIPE_INSTR_HI, + SEC_PIPE_RSVD0, + SEC_PIPE_RSVD1, + SEC_PIPE_RSVD2, + SEC_PIPE_RSVD3, - SEC_PIPE_DF_PTRS0, - SEC_PIPE_DF_PTRS1, - SEC_PIPE_DF_PTRS2, - SEC_PIPE_DF_PTRS3, - SEC_PIPE_DF_PTRS4, - SEC_PIPE_DF_PTRS5, - SEC_PIPE_DF_PTRS6, - SEC_PIPE_DF_PTRS7, + SEC_PIPE_DF_PTRS0, + SEC_PIPE_DF_PTRS1, + SEC_PIPE_DF_PTRS2, + SEC_PIPE_DF_PTRS3, + SEC_PIPE_DF_PTRS4, + SEC_PIPE_DF_PTRS5, + SEC_PIPE_DF_PTRS6, + SEC_PIPE_DF_PTRS7, - SEC_PIPE_DU_DATA_IN_LO, - SEC_PIPE_DU_DATA_IN_HI, - SEC_PIPE_DU_DATA_IN_CTRL, - SEC_PIPE_DU_DATA_OUT_LO, - SEC_PIPE_DU_DATA_OUT_HI, - SEC_PIPE_DU_DATA_OUT_CTRL, + SEC_PIPE_DU_DATA_IN_LO, + SEC_PIPE_DU_DATA_IN_HI, + SEC_PIPE_DU_DATA_IN_CTRL, + SEC_PIPE_DU_DATA_OUT_LO, + SEC_PIPE_DU_DATA_OUT_HI, + SEC_PIPE_DU_DATA_OUT_CTRL, - SEC_PIPE_STATE0, - SEC_PIPE_STATE1, - SEC_PIPE_STATE2, - SEC_PIPE_STATE3, - SEC_PIPE_STATE4, - SEC_PIPE_INCLUDE_MASK0, - SEC_PIPE_INCLUDE_MASK1, - SEC_PIPE_INCLUDE_MASK2, - SEC_PIPE_INCLUDE_MASK3, - SEC_PIPE_INCLUDE_MASK4, - SEC_PIPE_EXCLUDE_MASK0, - SEC_PIPE_EXCLUDE_MASK1, - SEC_PIPE_EXCLUDE_MASK2, - SEC_PIPE_EXCLUDE_MASK3, - SEC_PIPE_EXCLUDE_MASK4, + SEC_PIPE_STATE0, + SEC_PIPE_STATE1, + SEC_PIPE_STATE2, + SEC_PIPE_STATE3, + SEC_PIPE_STATE4, + SEC_PIPE_INCLUDE_MASK0, + SEC_PIPE_INCLUDE_MASK1, + SEC_PIPE_INCLUDE_MASK2, + SEC_PIPE_INCLUDE_MASK3, + SEC_PIPE_INCLUDE_MASK4, + SEC_PIPE_EXCLUDE_MASK0, + SEC_PIPE_EXCLUDE_MASK1, + SEC_PIPE_EXCLUDE_MASK2, + SEC_PIPE_EXCLUDE_MASK3, + SEC_PIPE_EXCLUDE_MASK4, }; enum sec_pipe_base_config { - SEC_PIPE0_BASE = 0x00, - SEC_PIPE1_BASE = 0x40, - SEC_PIPE2_BASE = 0x80, - SEC_PIPE3_BASE = 0xc0 + SEC_PIPE0_BASE = 0x00, + SEC_PIPE1_BASE = 0x40, + SEC_PIPE2_BASE = 0x80, + SEC_PIPE3_BASE = 0xc0 }; enum sec_rsa_config { - SEC_RSA_PIPE0_DU_DATA_IN_LO = 0x100, - SEC_RSA_PIPE0_DU_DATA_IN_HI, - SEC_RSA_PIPE0_DU_DATA_IN_CTRL, - SEC_RSA_PIPE0_DU_DATA_OUT_LO, - SEC_RSA_PIPE0_DU_DATA_OUT_HI, - SEC_RSA_PIPE0_DU_DATA_OUT_CTRL, - SEC_RSA_RSVD0, - SEC_RSA_RSVD1, + SEC_RSA_PIPE0_DU_DATA_IN_LO = 0x100, + SEC_RSA_PIPE0_DU_DATA_IN_HI, + SEC_RSA_PIPE0_DU_DATA_IN_CTRL, + SEC_RSA_PIPE0_DU_DATA_OUT_LO, + SEC_RSA_PIPE0_DU_DATA_OUT_HI, + SEC_RSA_PIPE0_DU_DATA_OUT_CTRL, + SEC_RSA_RSVD0, + SEC_RSA_RSVD1, - SEC_RSA_PIPE0_STATE0, - SEC_RSA_PIPE0_STATE1, - SEC_RSA_PIPE0_STATE2, - SEC_RSA_PIPE0_INCLUDE_MASK0, - SEC_RSA_PIPE0_INCLUDE_MASK1, - SEC_RSA_PIPE0_INCLUDE_MASK2, - SEC_RSA_PIPE0_EXCLUDE_MASK0, - SEC_RSA_PIPE0_EXCLUDE_MASK1, - SEC_RSA_PIPE0_EXCLUDE_MASK2, - SEC_RSA_PIPE0_EVENT_CTR + SEC_RSA_PIPE0_STATE0, + SEC_RSA_PIPE0_STATE1, + SEC_RSA_PIPE0_STATE2, + SEC_RSA_PIPE0_INCLUDE_MASK0, + SEC_RSA_PIPE0_INCLUDE_MASK1, + SEC_RSA_PIPE0_INCLUDE_MASK2, + SEC_RSA_PIPE0_EXCLUDE_MASK0, + SEC_RSA_PIPE0_EXCLUDE_MASK1, + SEC_RSA_PIPE0_EXCLUDE_MASK2, + SEC_RSA_PIPE0_EVENT_CTR }; @@ -877,10 +881,10 @@ enum sec_rsa_config { enum sec_config { - SEC_DMA_CREDIT = 0x140, - SEC_CONFIG1, - SEC_CONFIG2, - SEC_CONFIG3, + SEC_DMA_CREDIT = 0x140, + SEC_CONFIG1, + SEC_CONFIG2, + SEC_CONFIG3, }; @@ -888,104 +892,106 @@ enum sec_config { enum sec_debug_config { - SEC_DW0_DESCRIPTOR0_LO = 0x180, - SEC_DW0_DESCRIPTOR0_HI, - SEC_DW0_DESCRIPTOR1_LO, - SEC_DW0_DESCRIPTOR1_HI, - SEC_DW1_DESCRIPTOR0_LO, - SEC_DW1_DESCRIPTOR0_HI, - SEC_DW1_DESCRIPTOR1_LO, - SEC_DW1_DESCRIPTOR1_HI, - SEC_DW2_DESCRIPTOR0_LO, - SEC_DW2_DESCRIPTOR0_HI, - SEC_DW2_DESCRIPTOR1_LO, - SEC_DW2_DESCRIPTOR1_HI, - SEC_DW3_DESCRIPTOR0_LO, - SEC_DW3_DESCRIPTOR0_HI, - SEC_DW3_DESCRIPTOR1_LO, - SEC_DW3_DESCRIPTOR1_HI, + SEC_DW0_DESCRIPTOR0_LO = 0x180, + SEC_DW0_DESCRIPTOR0_HI, + SEC_DW0_DESCRIPTOR1_LO, + SEC_DW0_DESCRIPTOR1_HI, + SEC_DW1_DESCRIPTOR0_LO, + SEC_DW1_DESCRIPTOR0_HI, + SEC_DW1_DESCRIPTOR1_LO, + SEC_DW1_DESCRIPTOR1_HI, + SEC_DW2_DESCRIPTOR0_LO, + SEC_DW2_DESCRIPTOR0_HI, + SEC_DW2_DESCRIPTOR1_LO, + SEC_DW2_DESCRIPTOR1_HI, + SEC_DW3_DESCRIPTOR0_LO, + SEC_DW3_DESCRIPTOR0_HI, + SEC_DW3_DESCRIPTOR1_LO, + SEC_DW3_DESCRIPTOR1_HI, - SEC_STATE0, - SEC_STATE1, - SEC_STATE2, - SEC_INCLUDE_MASK0, - SEC_INCLUDE_MASK1, - SEC_INCLUDE_MASK2, - SEC_EXCLUDE_MASK0, - SEC_EXCLUDE_MASK1, - SEC_EXCLUDE_MASK2, - SEC_EVENT_CTR + SEC_STATE0, + SEC_STATE1, + SEC_STATE2, + SEC_INCLUDE_MASK0, + SEC_INCLUDE_MASK1, + SEC_INCLUDE_MASK2, + SEC_EXCLUDE_MASK0, + SEC_EXCLUDE_MASK1, + SEC_EXCLUDE_MASK2, + SEC_EVENT_CTR }; enum sec_msgring_bucket_config { - SEC_BIU_CREDITS = 0x308, + SEC_BIU_CREDITS = 0x308, - SEC_MSG_BUCKET0_SIZE = 0x320, - SEC_MSG_BUCKET1_SIZE, - SEC_MSG_BUCKET2_SIZE, - SEC_MSG_BUCKET3_SIZE, - SEC_MSG_BUCKET4_SIZE, - SEC_MSG_BUCKET5_SIZE, - SEC_MSG_BUCKET6_SIZE, - SEC_MSG_BUCKET7_SIZE, + SEC_MSG_BUCKET0_SIZE = 0x320, + SEC_MSG_BUCKET1_SIZE, + SEC_MSG_BUCKET2_SIZE, + SEC_MSG_BUCKET3_SIZE, + SEC_MSG_BUCKET4_SIZE, + SEC_MSG_BUCKET5_SIZE, + SEC_MSG_BUCKET6_SIZE, + SEC_MSG_BUCKET7_SIZE, }; enum sec_msgring_credit_config { - SEC_CC_CPU0_0 = 0x380, - SEC_CC_CPU1_0 = 0x388, - SEC_CC_CPU2_0 = 0x390, - SEC_CC_CPU3_0 = 0x398, - SEC_CC_CPU4_0 = 0x3a0, - SEC_CC_CPU5_0 = 0x3a8, - SEC_CC_CPU6_0 = 0x3b0, - SEC_CC_CPU7_0 = 0x3b8 + SEC_CC_CPU0_0 = 0x380, + SEC_CC_CPU1_0 = 0x388, + SEC_CC_CPU2_0 = 0x390, + SEC_CC_CPU3_0 = 0x398, + SEC_CC_CPU4_0 = 0x3a0, + SEC_CC_CPU5_0 = 0x3a8, + SEC_CC_CPU6_0 = 0x3b0, + SEC_CC_CPU7_0 = 0x3b8 }; enum sec_engine_id { - SEC_PIPE0, - SEC_PIPE1, - SEC_PIPE2, - SEC_PIPE3, - SEC_RSA + SEC_PIPE0, + SEC_PIPE1, + SEC_PIPE2, + SEC_PIPE3, + SEC_RSA }; enum sec_cipher { - SEC_AES256_MODE_HMAC, - SEC_AES256_MODE, - SEC_AES256_HMAC, - SEC_AES256, - SEC_AES192_MODE_HMAC, - SEC_AES192_MODE, - SEC_AES192_HMAC, - SEC_AES192, - SEC_AES128_MODE_HMAC, - SEC_AES128_MODE, - SEC_AES128_HMAC, - SEC_AES128, - SEC_DES_HMAC, - SEC_DES, - SEC_3DES, - SEC_3DES_HMAC, - SEC_HMAC + SEC_AES256_MODE_HMAC, + SEC_AES256_MODE, + SEC_AES256_HMAC, + SEC_AES256, + SEC_AES192_MODE_HMAC, + SEC_AES192_MODE, + SEC_AES192_HMAC, + SEC_AES192, + SEC_AES128_MODE_HMAC, + SEC_AES128_MODE, + SEC_AES128_HMAC, + SEC_AES128, + SEC_DES_HMAC, + SEC_DES, + SEC_3DES, + SEC_3DES_HMAC, + SEC_HMAC }; enum sec_msgrng_msg_ctrl_config { - SEC_EOP=5, - SEC_SOP=6, + SEC_EOP = 5, + SEC_SOP = 6, }; -void xlr_sec_init( struct xlr_sec_softc *sc) ; +void +xlr_sec_init(struct xlr_sec_softc *sc); -int xlr_sec_setup(struct xlr_sec_session* ses, - struct xlr_sec_command *cmd, symkey_desc_pt desc); +int +xlr_sec_setup(struct xlr_sec_session *ses, + struct xlr_sec_command *cmd, symkey_desc_pt desc); -symkey_desc_pt xlr_sec_allocate_desc(void*); +symkey_desc_pt xlr_sec_allocate_desc(void *); #endif diff --git a/sys/dev/rmi/sec/rmisec.c b/sys/dev/rmi/sec/rmisec.c index 60eb8601a32..ad20e0955ef 100644 --- a/sys/dev/rmi/sec/rmisec.c +++ b/sys/dev/rmi/sec/rmisec.c @@ -59,33 +59,33 @@ void xlr_sec_print_data(struct cryptop *crp); -static int xlr_sec_newsession(void *arg, uint32_t *sidp, struct cryptoini *cri); +static int xlr_sec_newsession(void *arg, uint32_t * sidp, struct cryptoini *cri); static int xlr_sec_freesession(void *arg, uint64_t tid); static int xlr_sec_process(void *arg, struct cryptop *crp, int hint); -static int xlr_sec_probe(device_t); -static int xlr_sec_attach(device_t); -static int xlr_sec_detach(device_t); +static int xlr_sec_probe(device_t); +static int xlr_sec_attach(device_t); +static int xlr_sec_detach(device_t); static device_method_t xlr_sec_methods[] = { - /* device interface */ - DEVMETHOD(device_probe, xlr_sec_probe), - DEVMETHOD(device_attach, xlr_sec_attach), - DEVMETHOD(device_detach, xlr_sec_detach), + /* device interface */ + DEVMETHOD(device_probe, xlr_sec_probe), + DEVMETHOD(device_attach, xlr_sec_attach), + DEVMETHOD(device_detach, xlr_sec_detach), - /* bus interface */ - DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_driver_added, bus_generic_driver_added), + /* bus interface */ + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_driver_added, bus_generic_driver_added), - { 0, 0 } + {0, 0} }; static driver_t xlr_sec_driver = { - "rmisec", - xlr_sec_methods, - sizeof (struct xlr_sec_softc) + "rmisec", + xlr_sec_methods, + sizeof(struct xlr_sec_softc) }; static devclass_t xlr_sec_devclass; @@ -97,7 +97,7 @@ MODULE_DEPEND(rmisec, crypto, 1, 1, 1); static int xlr_sec_probe(device_t dev) { - return (BUS_PROBE_DEFAULT); + return (BUS_PROBE_DEFAULT); } @@ -109,62 +109,60 @@ static int xlr_sec_attach(device_t dev) { - struct xlr_sec_softc *sc = device_get_softc(dev); + struct xlr_sec_softc *sc = device_get_softc(dev); - bzero(sc, sizeof (*sc)); - sc->sc_dev = dev; + bzero(sc, sizeof(*sc)); + sc->sc_dev = dev; - mtx_init(&sc->sc_mtx, device_get_nameunit(dev), "rmi crypto driver", MTX_DEF); + mtx_init(&sc->sc_mtx, device_get_nameunit(dev), "rmi crypto driver", MTX_DEF); - sc->sc_cid = crypto_get_driverid(0); - if (sc->sc_cid < 0) { - printf("xlr_sec - error : could not get the driver id\n"); - goto error_exit; - } + sc->sc_cid = crypto_get_driverid(0); + if (sc->sc_cid < 0) { + printf("xlr_sec - error : could not get the driver id\n"); + goto error_exit; + } + if (crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0, + xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc) != 0) + printf("register failed for CRYPTO_DES_CBC\n"); + + if (crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0, + xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc) != 0) + printf("register failed for CRYPTO_3DES_CBC\n"); + + if (crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0, + xlr_sec_newsession, xlr_sec_freesession, + xlr_sec_process, sc) != 0) + printf("register failed for CRYPTO_AES_CBC\n"); + + if (crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0, + xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc) != 0) + printf("register failed for CRYPTO_ARC4\n"); - if(crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0, - xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc)!=0) - printf("register failed for CRYPTO_DES_CBC\n"); + if (crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0, + xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc) != 0) + printf("register failed for CRYPTO_MD5\n"); - if(crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0, - xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc)!=0) - printf("register failed for CRYPTO_3DES_CBC\n"); + if (crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0, + xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc) != 0) + printf("register failed for CRYPTO_SHA1\n"); - if(crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0, - xlr_sec_newsession, xlr_sec_freesession, - xlr_sec_process, sc)!=0) - printf("register failed for CRYPTO_AES_CBC\n"); + if (crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0, + xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc) != 0) + printf("register failed for CRYPTO_MD5_HMAC\n"); - if(crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0, - xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc)!=0) - printf("register failed for CRYPTO_ARC4\n"); + if (crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0, + xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc) != 0) + printf("register failed for CRYPTO_SHA1_HMAC\n"); - if(crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0, - xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc)!=0) - printf("register failed for CRYPTO_MD5\n"); - - if(crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0, - xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc)!=0) - printf("register failed for CRYPTO_SHA1\n"); - - if(crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0, - xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc)!=0) - printf("register failed for CRYPTO_MD5_HMAC\n"); - - if(crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0, - xlr_sec_newsession, xlr_sec_freesession, xlr_sec_process, sc)!=0) - printf("register failed for CRYPTO_SHA1_HMAC\n"); - - - xlr_sec_init(sc); - return (0); + xlr_sec_init(sc); + return (0); error_exit: - return (ENXIO); + return (ENXIO); } @@ -175,22 +173,22 @@ error_exit: static int xlr_sec_detach(device_t dev) { - int sesn; - struct xlr_sec_softc *sc = device_get_softc(dev); - struct xlr_sec_session *ses = NULL; - symkey_desc_pt desc ; + int sesn; + struct xlr_sec_softc *sc = device_get_softc(dev); + struct xlr_sec_session *ses = NULL; + symkey_desc_pt desc; - for (sesn = 0; sesn < sc->sc_nsessions; sesn++) { - ses = &sc->sc_sessions[sesn]; - desc = (symkey_desc_pt)ses->desc_ptr; - free(desc->user.kern_src, M_DEVBUF); - free(desc->user.kern_dest, M_DEVBUF); - free(desc->next_src_buf, M_DEVBUF); - free(desc->next_dest_buf, M_DEVBUF); - free(ses->desc_ptr, M_DEVBUF) ; - } + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) { + ses = &sc->sc_sessions[sesn]; + desc = (symkey_desc_pt) ses->desc_ptr; + free(desc->user.kern_src, M_DEVBUF); + free(desc->user.kern_dest, M_DEVBUF); + free(desc->next_src_buf, M_DEVBUF); + free(desc->next_dest_buf, M_DEVBUF); + free(ses->desc_ptr, M_DEVBUF); + } - return (0); + return (0); } @@ -202,107 +200,108 @@ xlr_sec_detach(device_t dev) * id on successful allocation. */ static int -xlr_sec_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri) +xlr_sec_newsession(void *arg, u_int32_t * sidp, struct cryptoini *cri) { - struct cryptoini *c; - struct xlr_sec_softc *sc = arg; - int mac = 0, cry = 0, sesn; - struct xlr_sec_session *ses = NULL; + struct cryptoini *c; + struct xlr_sec_softc *sc = arg; + int mac = 0, cry = 0, sesn; + struct xlr_sec_session *ses = NULL; - if (sidp == NULL || cri == NULL || sc == NULL) - return (EINVAL); + if (sidp == NULL || cri == NULL || sc == NULL) + return (EINVAL); - if (sc->sc_sessions == NULL) { - ses = sc->sc_sessions = (struct xlr_sec_session *)malloc( - sizeof(struct xlr_sec_session), M_DEVBUF, M_NOWAIT); - if (ses == NULL) - return (ENOMEM); + if (sc->sc_sessions == NULL) { + ses = sc->sc_sessions = (struct xlr_sec_session *)malloc( + sizeof(struct xlr_sec_session), M_DEVBUF, M_NOWAIT); + if (ses == NULL) + return (ENOMEM); - ses->desc_ptr = (void*) xlr_sec_allocate_desc((void*)ses); - if(ses->desc_ptr == NULL) - return (ENOMEM); + ses->desc_ptr = (void *)xlr_sec_allocate_desc((void *)ses); + if (ses->desc_ptr == NULL) + return (ENOMEM); - sesn = 0; - ses->sessionid = sesn; - sc->sc_nsessions = 1; - } else { - for (sesn = 0; sesn < sc->sc_nsessions; sesn++) { - if (!sc->sc_sessions[sesn].hs_used) { - ses = &sc->sc_sessions[sesn]; - break; - } - } + sesn = 0; + ses->sessionid = sesn; + sc->sc_nsessions = 1; + } else { + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) { + if (!sc->sc_sessions[sesn].hs_used) { + ses = &sc->sc_sessions[sesn]; + break; + } + } - if (ses == NULL) { - sesn = sc->sc_nsessions; - ses = (struct xlr_sec_session *)malloc((sesn + 1) * - sizeof(struct xlr_sec_session), M_DEVBUF, M_NOWAIT); - if (ses == NULL) - return (ENOMEM); - bcopy(sc->sc_sessions, ses, sesn * sizeof(struct xlr_sec_session)); - bzero(sc->sc_sessions, sesn * sizeof(struct xlr_sec_session)); - free(sc->sc_sessions, M_DEVBUF); - sc->sc_sessions = ses; - ses = &sc->sc_sessions[sesn]; - ses->sessionid = sesn; - ses->desc_ptr = (void*) xlr_sec_allocate_desc((void*)ses); - if(ses->desc_ptr == NULL) - return (ENOMEM); - sc->sc_nsessions++; - } - } - ses->hs_used = 1; + if (ses == NULL) { + sesn = sc->sc_nsessions; + ses = (struct xlr_sec_session *)malloc((sesn + 1) * + sizeof(struct xlr_sec_session), M_DEVBUF, M_NOWAIT); + if (ses == NULL) + return (ENOMEM); + bcopy(sc->sc_sessions, ses, sesn * sizeof(struct xlr_sec_session)); + bzero(sc->sc_sessions, sesn * sizeof(struct xlr_sec_session)); + free(sc->sc_sessions, M_DEVBUF); + sc->sc_sessions = ses; + ses = &sc->sc_sessions[sesn]; + ses->sessionid = sesn; + ses->desc_ptr = (void *)xlr_sec_allocate_desc((void *)ses); + if (ses->desc_ptr == NULL) + return (ENOMEM); + sc->sc_nsessions++; + } + } + ses->hs_used = 1; - for (c = cri; c != NULL; c = c->cri_next) { + for (c = cri; c != NULL; c = c->cri_next) { - switch (c->cri_alg) { - case CRYPTO_MD5: - case CRYPTO_SHA1: - case CRYPTO_MD5_HMAC: - case CRYPTO_SHA1_HMAC: - if (mac) - return (EINVAL); - mac = 1; - ses->hs_mlen = c->cri_mlen; - if (ses->hs_mlen == 0) { - switch (c->cri_alg) { - case CRYPTO_MD5: - case CRYPTO_MD5_HMAC: - ses->hs_mlen = 16; - break; - case CRYPTO_SHA1: - case CRYPTO_SHA1_HMAC: - ses->hs_mlen = 20; - break; - } - } - break; - case CRYPTO_DES_CBC: - case CRYPTO_3DES_CBC: - case CRYPTO_AES_CBC: - /* XXX this may read fewer, does it matter? */ - /* read_random(ses->hs_iv, - c->cri_alg == CRYPTO_AES_CBC ? -XLR_SEC_AES_IV_LENGTH : XLR_SEC_IV_LENGTH); - */ - /*FALLTHROUGH*/ - case CRYPTO_ARC4: - if (cry) - return (EINVAL); - cry = 1; - break; - default: - return (EINVAL); - } - } - if (mac == 0 && cry == 0) - return (EINVAL); + switch (c->cri_alg) { + case CRYPTO_MD5: + case CRYPTO_SHA1: + case CRYPTO_MD5_HMAC: + case CRYPTO_SHA1_HMAC: + if (mac) + return (EINVAL); + mac = 1; + ses->hs_mlen = c->cri_mlen; + if (ses->hs_mlen == 0) { + switch (c->cri_alg) { + case CRYPTO_MD5: + case CRYPTO_MD5_HMAC: + ses->hs_mlen = 16; + break; + case CRYPTO_SHA1: + case CRYPTO_SHA1_HMAC: + ses->hs_mlen = 20; + break; + } + } + break; + case CRYPTO_DES_CBC: + case CRYPTO_3DES_CBC: + case CRYPTO_AES_CBC: + /* XXX this may read fewer, does it matter? */ + /* + * read_random(ses->hs_iv, c->cri_alg == + * CRYPTO_AES_CBC ? XLR_SEC_AES_IV_LENGTH : + * XLR_SEC_IV_LENGTH); + */ + /* FALLTHROUGH */ + case CRYPTO_ARC4: + if (cry) + return (EINVAL); + cry = 1; + break; + default: + return (EINVAL); + } + } + if (mac == 0 && cry == 0) + return (EINVAL); - *sidp = XLR_SEC_SID(device_get_unit(sc->sc_dev), sesn); - return (0); + *sidp = XLR_SEC_SID(device_get_unit(sc->sc_dev), sesn); + return (0); } /* @@ -313,61 +312,62 @@ XLR_SEC_AES_IV_LENGTH : XLR_SEC_IV_LENGTH); static int xlr_sec_freesession(void *arg, u_int64_t tid) { - struct xlr_sec_softc *sc = arg; - int session; - u_int32_t sid = CRYPTO_SESID2LID(tid); + struct xlr_sec_softc *sc = arg; + int session; + u_int32_t sid = CRYPTO_SESID2LID(tid); - if (sc == NULL) - return (EINVAL); + if (sc == NULL) + return (EINVAL); - session = XLR_SEC_SESSION(sid); - if (session >= sc->sc_nsessions) - return (EINVAL); + session = XLR_SEC_SESSION(sid); + if (session >= sc->sc_nsessions) + return (EINVAL); - sc->sc_sessions[session].hs_used = 0; + sc->sc_sessions[session].hs_used = 0; - return (0); + return (0); } #ifdef RMI_SEC_DEBUG -void xlr_sec_print_data(struct cryptop *crp) +void +xlr_sec_print_data(struct cryptop *crp) { - int i, key_len; - struct cryptodesc *crp_desc; + int i, key_len; + struct cryptodesc *crp_desc; - printf("session id = 0x%llx, crp_ilen = %d, crp_olen=%d \n", - crp->crp_sid, crp->crp_ilen, crp->crp_olen); + printf("session id = 0x%llx, crp_ilen = %d, crp_olen=%d \n", + crp->crp_sid, crp->crp_ilen, crp->crp_olen); - printf("crp_flags = 0x%x\n", crp->crp_flags); + printf("crp_flags = 0x%x\n", crp->crp_flags); - printf("crp buf:\n"); - for(i=0; icrp_ilen; i++) - { - printf("%c ",crp->crp_buf[i] ); - if(i%10 == 0) printf("\n"); - } + printf("crp buf:\n"); + for (i = 0; i < crp->crp_ilen; i++) { + printf("%c ", crp->crp_buf[i]); + if (i % 10 == 0) + printf("\n"); + } - printf("\n"); - printf("****************** desc ****************\n"); - crp_desc = crp->crp_desc; - printf("crd_skip=%d, crd_len=%d, crd_flags=0x%x, crd_alg=%d\n", - crp_desc->crd_skip, crp_desc->crd_len, crp_desc->crd_flags, crp_desc->crd_alg); + printf("\n"); + printf("****************** desc ****************\n"); + crp_desc = crp->crp_desc; + printf("crd_skip=%d, crd_len=%d, crd_flags=0x%x, crd_alg=%d\n", + crp_desc->crd_skip, crp_desc->crd_len, crp_desc->crd_flags, crp_desc->crd_alg); - key_len = crp_desc->crd_klen / 8; - printf("key(%d) :\n",key_len); - for(i=0; i< key_len; i++) - printf("%d", crp_desc->crd_key[i]); - printf("\n"); + key_len = crp_desc->crd_klen / 8; + printf("key(%d) :\n", key_len); + for (i = 0; i < key_len; i++) + printf("%d", crp_desc->crd_key[i]); + printf("\n"); - printf(" IV : \n"); - for(i=0; i< EALG_MAX_BLOCK_LEN; i++) - printf("%d", crp_desc->crd_iv[i]); - printf("\n"); + printf(" IV : \n"); + for (i = 0; i < EALG_MAX_BLOCK_LEN; i++) + printf("%d", crp_desc->crd_iv[i]); + printf("\n"); - printf("crd_next=%p\n", crp_desc->crd_next); - return; + printf("crd_next=%p\n", crp_desc->crd_next); + return; } #endif @@ -376,242 +376,228 @@ void xlr_sec_print_data(struct cryptop *crp) static int xlr_sec_process(void *arg, struct cryptop *crp, int hint) { - struct xlr_sec_softc *sc = arg; - struct xlr_sec_command *cmd = NULL; - int session, err; - struct cryptodesc *crd1, *crd2, *maccrd, *enccrd; - struct xlr_sec_session* ses; + struct xlr_sec_softc *sc = arg; + struct xlr_sec_command *cmd = NULL; + int session, err; + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd; + struct xlr_sec_session *ses; - if (crp == NULL || crp->crp_callback == NULL) { - return (EINVAL); - } + if (crp == NULL || crp->crp_callback == NULL) { + return (EINVAL); + } + session = XLR_SEC_SESSION(crp->crp_sid); + if (sc == NULL || session >= sc->sc_nsessions) { + err = EINVAL; + goto errout; + } + ses = &sc->sc_sessions[session]; - session = XLR_SEC_SESSION(crp->crp_sid); - if (sc == NULL || session >= sc->sc_nsessions) { - err = EINVAL; - goto errout; - } + cmd = &ses->cmd; + if (cmd == NULL) { + err = ENOMEM; + goto errout; + } + crd1 = crp->crp_desc; + if (crd1 == NULL) { + err = EINVAL; + goto errout; + } + crd2 = crd1->crd_next; - ses = &sc->sc_sessions[session]; + if (crd2 == NULL) { + if (crd1->crd_alg == CRYPTO_MD5_HMAC || + crd1->crd_alg == CRYPTO_SHA1_HMAC || + crd1->crd_alg == CRYPTO_SHA1 || + crd1->crd_alg == CRYPTO_MD5) { + maccrd = crd1; + enccrd = NULL; + } else if (crd1->crd_alg == CRYPTO_DES_CBC || + crd1->crd_alg == CRYPTO_3DES_CBC || + crd1->crd_alg == CRYPTO_AES_CBC || + crd1->crd_alg == CRYPTO_ARC4) { + maccrd = NULL; + enccrd = crd1; + } else { + err = EINVAL; + goto errout; + } + } else { + if ((crd1->crd_alg == CRYPTO_MD5_HMAC || + crd1->crd_alg == CRYPTO_SHA1_HMAC || + crd1->crd_alg == CRYPTO_MD5 || + crd1->crd_alg == CRYPTO_SHA1) && + (crd2->crd_alg == CRYPTO_DES_CBC || + crd2->crd_alg == CRYPTO_3DES_CBC || + crd2->crd_alg == CRYPTO_AES_CBC || + crd2->crd_alg == CRYPTO_ARC4)) { + maccrd = crd1; + enccrd = crd2; + } else if ((crd1->crd_alg == CRYPTO_DES_CBC || + crd1->crd_alg == CRYPTO_ARC4 || + crd1->crd_alg == CRYPTO_3DES_CBC || + crd1->crd_alg == CRYPTO_AES_CBC) && + (crd2->crd_alg == CRYPTO_MD5_HMAC || + crd2->crd_alg == CRYPTO_SHA1_HMAC || + crd2->crd_alg == CRYPTO_MD5 || + crd2->crd_alg == CRYPTO_SHA1) && + (crd1->crd_flags & CRD_F_ENCRYPT)) { + enccrd = crd1; + maccrd = crd2; + } else { + err = EINVAL; + goto errout; + } + } - cmd = &ses->cmd ; - if (cmd == NULL) { - err = ENOMEM; - goto errout; - } + bzero(&cmd->op, sizeof(xlr_sec_io_t)); + + cmd->op.source_buf = (uint64_t) (unsigned long)crp->crp_buf; + cmd->op.source_buf_size = crp->crp_ilen; + if (crp->crp_flags & CRYPTO_F_REL) { + cmd->op.dest_buf = (uint64_t) (unsigned long)crp->crp_buf; + cmd->op.dest_buf_size = crp->crp_ilen; + } else { + cmd->op.dest_buf = (uint64_t) (unsigned long)crp->crp_buf; + cmd->op.dest_buf_size = crp->crp_ilen; + } + cmd->op.num_packets = 1; + cmd->op.num_fragments = 1; - crd1 = crp->crp_desc; - if (crd1 == NULL) { - err = EINVAL; - goto errout; - } + if (cmd->op.source_buf_size > SEC_MAX_FRAG_LEN) { + ses->multi_frag_flag = 1; + } else { + ses->multi_frag_flag = 0; + } - crd2 = crd1->crd_next; + if (maccrd) { + cmd->maccrd = maccrd; + cmd->op.cipher_op = XLR_SEC_CIPHER_MODE_PASS; + cmd->op.cipher_mode = XLR_SEC_CIPHER_MODE_NONE; + cmd->op.cipher_type = XLR_SEC_CIPHER_TYPE_NONE; + cmd->op.cipher_init = 0; + cmd->op.cipher_offset = 0; - if (crd2 == NULL) { - if (crd1->crd_alg == CRYPTO_MD5_HMAC || - crd1->crd_alg == CRYPTO_SHA1_HMAC || - crd1->crd_alg == CRYPTO_SHA1 || - crd1->crd_alg == CRYPTO_MD5) { - maccrd = crd1; - enccrd = NULL; - } else if (crd1->crd_alg == CRYPTO_DES_CBC || - crd1->crd_alg == CRYPTO_3DES_CBC || - crd1->crd_alg == CRYPTO_AES_CBC || - crd1->crd_alg == CRYPTO_ARC4) { - maccrd = NULL; - enccrd = crd1; - } else { - err = EINVAL; - goto errout; - } - } else { - if ((crd1->crd_alg == CRYPTO_MD5_HMAC || - crd1->crd_alg == CRYPTO_SHA1_HMAC || - crd1->crd_alg == CRYPTO_MD5 || - crd1->crd_alg == CRYPTO_SHA1) && - (crd2->crd_alg == CRYPTO_DES_CBC || - crd2->crd_alg == CRYPTO_3DES_CBC || - crd2->crd_alg == CRYPTO_AES_CBC || - crd2->crd_alg == CRYPTO_ARC4)){ - maccrd = crd1; - enccrd = crd2; - } else if ((crd1->crd_alg == CRYPTO_DES_CBC || - crd1->crd_alg == CRYPTO_ARC4 || - crd1->crd_alg == CRYPTO_3DES_CBC || - crd1->crd_alg == CRYPTO_AES_CBC) && - (crd2->crd_alg == CRYPTO_MD5_HMAC || - crd2->crd_alg == CRYPTO_SHA1_HMAC || - crd2->crd_alg == CRYPTO_MD5 || - crd2->crd_alg == CRYPTO_SHA1) && - (crd1->crd_flags & CRD_F_ENCRYPT)) { - enccrd = crd1; - maccrd = crd2; - } else { - err = EINVAL; - goto errout; - } - } + switch (maccrd->crd_alg) { + case CRYPTO_MD5: + cmd->op.digest_type = XLR_SEC_DIGEST_TYPE_MD5; + cmd->op.digest_init = XLR_SEC_DIGEST_INIT_NEWKEY; + cmd->op.digest_src = XLR_SEC_DIGEST_SRC_DMA; + cmd->op.digest_offset = 0; - bzero(&cmd->op, sizeof(xlr_sec_io_t)); + cmd->op.cksum_type = XLR_SEC_CKSUM_TYPE_NOP; + cmd->op.cksum_src = XLR_SEC_CKSUM_SRC_CIPHER; + cmd->op.cksum_offset = 0; - cmd->op.source_buf = (uint64_t)(unsigned long) crp->crp_buf; - cmd->op.source_buf_size = crp->crp_ilen; - if(crp->crp_flags & CRYPTO_F_REL){ - cmd->op.dest_buf = (uint64_t)(unsigned long)crp->crp_buf; - cmd->op.dest_buf_size = crp->crp_ilen ; - } - else{ - cmd->op.dest_buf = (uint64_t)(unsigned long)crp->crp_buf; - cmd->op.dest_buf_size = crp->crp_ilen ; - } - cmd->op.num_packets = 1; - cmd->op.num_fragments = 1; + cmd->op.pkt_hmac = XLR_SEC_LOADHMACKEY_MODE_OLD; + cmd->op.pkt_hash = XLR_SEC_PADHASH_PAD; + cmd->op.pkt_hashbytes = XLR_SEC_HASHBYTES_ALL8; + cmd->op.pkt_next = XLR_SEC_NEXT_FINISH; + cmd->op.pkt_iv = XLR_SEC_PKT_IV_OLD; + cmd->op.pkt_lastword = XLR_SEC_LASTWORD_128; - if(cmd->op.source_buf_size > SEC_MAX_FRAG_LEN){ - ses->multi_frag_flag = 1; - } - else{ - ses->multi_frag_flag = 0; - } - - if(maccrd){ - cmd->maccrd = maccrd; - cmd->op.cipher_op = XLR_SEC_CIPHER_MODE_PASS ; - cmd->op.cipher_mode = XLR_SEC_CIPHER_MODE_NONE ; - cmd->op.cipher_type = XLR_SEC_CIPHER_TYPE_NONE ; - cmd->op.cipher_init = 0 ; - cmd->op.cipher_offset = 0; - - switch(maccrd->crd_alg){ - case CRYPTO_MD5: - cmd->op.digest_type = XLR_SEC_DIGEST_TYPE_MD5 ; - cmd->op.digest_init = XLR_SEC_DIGEST_INIT_NEWKEY ; - cmd->op.digest_src = XLR_SEC_DIGEST_SRC_DMA ; - cmd->op.digest_offset = 0; - - cmd->op.cksum_type = XLR_SEC_CKSUM_TYPE_NOP ; - cmd->op.cksum_src = XLR_SEC_CKSUM_SRC_CIPHER ; - cmd->op.cksum_offset = 0; - - cmd->op.pkt_hmac = XLR_SEC_LOADHMACKEY_MODE_OLD ; - cmd->op.pkt_hash = XLR_SEC_PADHASH_PAD ; - cmd->op.pkt_hashbytes = XLR_SEC_HASHBYTES_ALL8 ; - cmd->op.pkt_next = XLR_SEC_NEXT_FINISH ; - cmd->op.pkt_iv = XLR_SEC_PKT_IV_OLD ; - cmd->op.pkt_lastword = XLR_SEC_LASTWORD_128; - - - default: - printf("currently not handled\n"); - } - } - - if(enccrd){ - cmd->enccrd = enccrd; + default: + printf("currently not handled\n"); + } + } + if (enccrd) { + cmd->enccrd = enccrd; #ifdef RMI_SEC_DEBUG - xlr_sec_print_data(crp); + xlr_sec_print_data(crp); #endif - if(enccrd->crd_flags & CRD_F_ENCRYPT){ - cmd->op.cipher_op = XLR_SEC_CIPHER_OP_ENCRYPT; - } - else - cmd->op.cipher_op = XLR_SEC_CIPHER_OP_DECRYPT; + if (enccrd->crd_flags & CRD_F_ENCRYPT) { + cmd->op.cipher_op = XLR_SEC_CIPHER_OP_ENCRYPT; + } else + cmd->op.cipher_op = XLR_SEC_CIPHER_OP_DECRYPT; - switch(enccrd->crd_alg){ - case CRYPTO_DES_CBC : - case CRYPTO_3DES_CBC: - if(enccrd->crd_alg == CRYPTO_DES_CBC){ - cmd->op.cipher_type = XLR_SEC_CIPHER_TYPE_DES; - memcpy(&cmd->op.crypt_key[0],enccrd->crd_key, XLR_SEC_DES_KEY_LENGTH); - } - else{ - cmd->op.cipher_type = XLR_SEC_CIPHER_TYPE_3DES; -// if(enccrd->crd_flags & CRD_F_KEY_EXPLICIT) - { - memcpy(&cmd->op.crypt_key[0],enccrd->crd_key, XLR_SEC_3DES_KEY_LENGTH); - } - } + switch (enccrd->crd_alg) { + case CRYPTO_DES_CBC: + case CRYPTO_3DES_CBC: + if (enccrd->crd_alg == CRYPTO_DES_CBC) { + cmd->op.cipher_type = XLR_SEC_CIPHER_TYPE_DES; + memcpy(&cmd->op.crypt_key[0], enccrd->crd_key, XLR_SEC_DES_KEY_LENGTH); + } else { + cmd->op.cipher_type = XLR_SEC_CIPHER_TYPE_3DES; + //if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) { + memcpy(&cmd->op.crypt_key[0], enccrd->crd_key, XLR_SEC_3DES_KEY_LENGTH); + } + } - cmd->op.cipher_mode = XLR_SEC_CIPHER_MODE_CBC; - cmd->op.cipher_init = XLR_SEC_CIPHER_INIT_NK; - cmd->op.cipher_offset = XLR_SEC_DES_IV_LENGTH; - - cmd->op.digest_type = XLR_SEC_DIGEST_TYPE_NONE; - cmd->op.digest_init = XLR_SEC_DIGEST_INIT_OLDKEY; - cmd->op.digest_src = XLR_SEC_DIGEST_SRC_DMA; - cmd->op.digest_offset = 0; + cmd->op.cipher_mode = XLR_SEC_CIPHER_MODE_CBC; + cmd->op.cipher_init = XLR_SEC_CIPHER_INIT_NK; + cmd->op.cipher_offset = XLR_SEC_DES_IV_LENGTH; - cmd->op.cksum_type = XLR_SEC_CKSUM_TYPE_NOP; - cmd->op.cksum_src = XLR_SEC_CKSUM_SRC_CIPHER; - cmd->op.cksum_offset = 0; + cmd->op.digest_type = XLR_SEC_DIGEST_TYPE_NONE; + cmd->op.digest_init = XLR_SEC_DIGEST_INIT_OLDKEY; + cmd->op.digest_src = XLR_SEC_DIGEST_SRC_DMA; + cmd->op.digest_offset = 0; - cmd->op.pkt_hmac = XLR_SEC_LOADHMACKEY_MODE_OLD; - cmd->op.pkt_hash = XLR_SEC_PADHASH_PAD; - cmd->op.pkt_hashbytes = XLR_SEC_HASHBYTES_ALL8; - cmd->op.pkt_next = XLR_SEC_NEXT_FINISH; - cmd->op.pkt_iv = XLR_SEC_PKT_IV_NEW; - cmd->op.pkt_lastword = XLR_SEC_LASTWORD_128; + cmd->op.cksum_type = XLR_SEC_CKSUM_TYPE_NOP; + cmd->op.cksum_src = XLR_SEC_CKSUM_SRC_CIPHER; + cmd->op.cksum_offset = 0; -// if((!(enccrd->crd_flags & CRD_F_IV_PRESENT)) && - if( (enccrd->crd_flags & CRD_F_IV_EXPLICIT)){ - memcpy(&cmd->op.initial_vector[0],enccrd->crd_iv, XLR_SEC_DES_IV_LENGTH); - } - break; + cmd->op.pkt_hmac = XLR_SEC_LOADHMACKEY_MODE_OLD; + cmd->op.pkt_hash = XLR_SEC_PADHASH_PAD; + cmd->op.pkt_hashbytes = XLR_SEC_HASHBYTES_ALL8; + cmd->op.pkt_next = XLR_SEC_NEXT_FINISH; + cmd->op.pkt_iv = XLR_SEC_PKT_IV_NEW; + cmd->op.pkt_lastword = XLR_SEC_LASTWORD_128; - case CRYPTO_AES_CBC: - if(enccrd->crd_alg == CRYPTO_AES_CBC){ - cmd->op.cipher_type = XLR_SEC_CIPHER_TYPE_AES128; -// if(enccrd->crd_flags & CRD_F_KEY_EXPLICIT) - { - memcpy(&cmd->op.crypt_key[0],enccrd->crd_key, XLR_SEC_AES128_KEY_LENGTH); - } - } + //if ((!(enccrd->crd_flags & CRD_F_IV_PRESENT)) && + if ((enccrd->crd_flags & CRD_F_IV_EXPLICIT)) { + memcpy(&cmd->op.initial_vector[0], enccrd->crd_iv, XLR_SEC_DES_IV_LENGTH); + } + break; - cmd->op.cipher_mode = XLR_SEC_CIPHER_MODE_CBC; - cmd->op.cipher_init = XLR_SEC_CIPHER_INIT_NK; - cmd->op.cipher_offset = XLR_SEC_AES_BLOCK_SIZE; + case CRYPTO_AES_CBC: + if (enccrd->crd_alg == CRYPTO_AES_CBC) { + cmd->op.cipher_type = XLR_SEC_CIPHER_TYPE_AES128; + //if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) { + memcpy(&cmd->op.crypt_key[0], enccrd->crd_key, XLR_SEC_AES128_KEY_LENGTH); + } + } + cmd->op.cipher_mode = XLR_SEC_CIPHER_MODE_CBC; + cmd->op.cipher_init = XLR_SEC_CIPHER_INIT_NK; + cmd->op.cipher_offset = XLR_SEC_AES_BLOCK_SIZE; - cmd->op.digest_type = XLR_SEC_DIGEST_TYPE_NONE; - cmd->op.digest_init = XLR_SEC_DIGEST_INIT_OLDKEY; - cmd->op.digest_src = XLR_SEC_DIGEST_SRC_DMA; - cmd->op.digest_offset = 0; + cmd->op.digest_type = XLR_SEC_DIGEST_TYPE_NONE; + cmd->op.digest_init = XLR_SEC_DIGEST_INIT_OLDKEY; + cmd->op.digest_src = XLR_SEC_DIGEST_SRC_DMA; + cmd->op.digest_offset = 0; - cmd->op.cksum_type = XLR_SEC_CKSUM_TYPE_NOP; - cmd->op.cksum_src = XLR_SEC_CKSUM_SRC_CIPHER; - cmd->op.cksum_offset = 0; + cmd->op.cksum_type = XLR_SEC_CKSUM_TYPE_NOP; + cmd->op.cksum_src = XLR_SEC_CKSUM_SRC_CIPHER; + cmd->op.cksum_offset = 0; - cmd->op.pkt_hmac = XLR_SEC_LOADHMACKEY_MODE_OLD; - cmd->op.pkt_hash = XLR_SEC_PADHASH_PAD; - cmd->op.pkt_hashbytes = XLR_SEC_HASHBYTES_ALL8; - cmd->op.pkt_next = XLR_SEC_NEXT_FINISH; - cmd->op.pkt_iv = XLR_SEC_PKT_IV_NEW; - cmd->op.pkt_lastword = XLR_SEC_LASTWORD_128; + cmd->op.pkt_hmac = XLR_SEC_LOADHMACKEY_MODE_OLD; + cmd->op.pkt_hash = XLR_SEC_PADHASH_PAD; + cmd->op.pkt_hashbytes = XLR_SEC_HASHBYTES_ALL8; + cmd->op.pkt_next = XLR_SEC_NEXT_FINISH; + cmd->op.pkt_iv = XLR_SEC_PKT_IV_NEW; + cmd->op.pkt_lastword = XLR_SEC_LASTWORD_128; -// if(!(enccrd->crd_flags & CRD_F_IV_PRESENT)){ - if( (enccrd->crd_flags & CRD_F_IV_EXPLICIT)){ - memcpy(&cmd->op.initial_vector[0],enccrd->crd_iv, XLR_SEC_AES_BLOCK_SIZE); - } -// } - break; - } - } + //if (!(enccrd->crd_flags & CRD_F_IV_PRESENT)) { + if ((enccrd->crd_flags & CRD_F_IV_EXPLICIT)) { + memcpy(&cmd->op.initial_vector[0], enccrd->crd_iv, XLR_SEC_AES_BLOCK_SIZE); + } + // + } + break; + } + } + cmd->crp = crp; + cmd->session_num = session; + xlr_sec_setup(ses, cmd, (symkey_desc_pt) ses->desc_ptr); - - cmd->crp = crp; - cmd->session_num = session; - xlr_sec_setup(ses, cmd, (symkey_desc_pt)ses->desc_ptr); - - return(0); + return (0); errout: - if (cmd != NULL) - free(cmd, M_DEVBUF); - crp->crp_etype = err; - crypto_done(crp); - return (err); + if (cmd != NULL) + free(cmd, M_DEVBUF); + crp->crp_etype = err; + crypto_done(crp); + return (err); } From 748ad3c4eecfc18979322b6e9a3ba2690e01a793 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Thu, 29 Oct 2009 21:30:21 +0000 Subject: [PATCH 295/380] adds rmi specific mips extensions file and makes sure the includes point to the new place. --- sys/mips/rmi/rmi_mips_exts.h | 144 +++++++++++++++++++++++++++++++++++ sys/mips/rmi/xlr_machdep.c | 2 +- sys/mips/rmi/xlr_pci.c | 2 +- 3 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 sys/mips/rmi/rmi_mips_exts.h diff --git a/sys/mips/rmi/rmi_mips_exts.h b/sys/mips/rmi/rmi_mips_exts.h new file mode 100644 index 00000000000..824381ac906 --- /dev/null +++ b/sys/mips/rmi/rmi_mips_exts.h @@ -0,0 +1,144 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ +#ifndef __MIPS_EXTS_H__ +#define __MIPS_EXTS_H__ + +#define enable_KX(flags) __asm__ __volatile__ ( \ + ".set push\n" \ + ".set noat\n" \ + ".set noreorder\n" \ + "mfc0 %0, $12\n\t" \ + "ori $1, %0, 0x81\n\t" \ + "xori $1, 1\n\t" \ + "mtc0 $1, $12\n" \ + ".set pop\n" \ + : "=r"(flags) ) + +#define disable_KX(flags) __asm__ __volatile__ ( \ + ".set push\n" \ + "mtc0 %0, $12\n" \ + ".set pop\n" \ + : : "r"(flags) ) + +#define CPU_BLOCKID_IFU 0 +#define CPU_BLOCKID_ICU 1 +#define CPU_BLOCKID_IEU 2 +#define CPU_BLOCKID_LSU 3 +#define CPU_BLOCKID_MMU 4 +#define CPU_BLOCKID_PRF 5 + +#define LSU_CERRLOG_REGID 9 + +static __inline__ unsigned int read_32bit_phnx_ctrl_reg(int block, int reg) +{ + unsigned int __res; + + __asm__ __volatile__( + ".set\tpush\n\t" + ".set\tnoreorder\n\t" + "move $9, %1\n" + /* "mfcr\t$8, $9\n\t" */ + ".word 0x71280018\n" + "move %0, $8\n" + ".set\tpop" + : "=r" (__res) : "r"((block<<8)|reg) + : "$8", "$9" + ); + return __res; +} + +static __inline__ void write_32bit_phnx_ctrl_reg(int block, int reg, unsigned int value) +{ + __asm__ __volatile__( + ".set\tpush\n\t" + ".set\tnoreorder\n\t" + "move $8, %0\n" + "move $9, %1\n" + /* "mtcr\t$8, $9\n\t" */ + ".word 0x71280019\n" + ".set\tpop" + : + : "r" (value), "r"((block<<8)|reg) + : "$8", "$9" + ); +} + +static __inline__ unsigned long long read_64bit_phnx_ctrl_reg(int block, int reg) +{ + unsigned int high, low; + + __asm__ __volatile__( + ".set\tmips64\n\t" + "move $9, %2\n" + /* "mfcr $8, $9\n" */ + ".word 0x71280018\n" + "dsrl32 %0, $8, 0\n\t" + "dsll32 $8, $8, 0\n\t" + "dsrl32 %1, $8, 0\n\t" + ".set mips0" + : "=r" (high), "=r"(low) + : "r"((block<<8)|reg) + : "$8", "$9" + ); + + return ( (((unsigned long long)high)<<32) | low); +} + +static __inline__ void write_64bit_phnx_ctrl_reg(int block, int reg,unsigned long long value) +{ + __uint32_t low, high; + high = value >> 32; + low = value & 0xffffffff; + + __asm__ __volatile__( + ".set push\n" + ".set noreorder\n" + ".set mips4\n\t" + /* Set up "rs" */ + "move $9, %0\n" + + /* Store 64 bit value in "rt" */ + "dsll32 $10, %1, 0 \n\t" + "dsll32 $8, %2, 0 \n\t" + "dsrl32 $8, $8, 0 \n\t" + "or $10, $8, $8 \n\t" + + ".word 0x71280019\n" /* mtcr $8, $9 */ + + ".set pop\n" + + : /* No outputs */ + : "r"((block<<8)|reg), "r" (high), "r" (low) + : "$8", "$9", "$10" + ); +} + + +#endif diff --git a/sys/mips/rmi/xlr_machdep.c b/sys/mips/rmi/xlr_machdep.c index 5839b437cac..c4dd4c891e5 100644 --- a/sys/mips/rmi/xlr_machdep.c +++ b/sys/mips/rmi/xlr_machdep.c @@ -69,7 +69,7 @@ #include #include #include -#include +#include #include #include diff --git a/sys/mips/rmi/xlr_pci.c b/sys/mips/rmi/xlr_pci.c index a3cfa5220f7..1ed6a7c9f37 100644 --- a/sys/mips/rmi/xlr_pci.c +++ b/sys/mips/rmi/xlr_pci.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include #include From 485619feeda13319a7a0ee4013dd5016b5c2bbc6 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 30 Oct 2009 00:37:04 +0000 Subject: [PATCH 296/380] db_expr_t is really closer to a register_t. Submitted by: bde@ --- sys/mips/include/db_machdep.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/include/db_machdep.h b/sys/mips/include/db_machdep.h index 26dafe4501e..ea9712005f9 100644 --- a/sys/mips/include/db_machdep.h +++ b/sys/mips/include/db_machdep.h @@ -46,7 +46,7 @@ typedef struct trapframe db_regs_t; extern db_regs_t ddb_regs; /* register state */ typedef vm_offset_t db_addr_t; /* address - unsigned */ -typedef intptr_t db_expr_t; /* expression - signed */ +typedef register_t db_expr_t; /* expression - signed */ #if BYTE_ORDER == _BIG_ENDIAN #define BYTE_MSF (1) From 87d11f28e22615df5fa83bbf6dfbc4b54180c8cf Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 30 Oct 2009 00:37:50 +0000 Subject: [PATCH 297/380] Add some newer MIPS CO cores. --- sys/mips/include/cpuregs.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/mips/include/cpuregs.h b/sys/mips/include/cpuregs.h index 036ee896ac9..e3070bab3b2 100644 --- a/sys/mips/include/cpuregs.h +++ b/sys/mips/include/cpuregs.h @@ -850,6 +850,10 @@ #define MIPS_4KEc_R2 0x90 /* MIPS 4KEc_R2 ISA 32 Rel 2 */ #define MIPS_4KEmp_R2 0x91 /* MIPS 4KEm/4KEp_R2 ISA 32 Rel 2 */ #define MIPS_4KSd 0x92 /* MIPS 4KSd ISA 32 Rel 2 */ +#define MIPS_24K 0x93 /* MIPS 24Kc/24Kf ISA 32 Rel 2 */ +#define MIPS_34K 0x95 /* MIPS 34K ISA 32 R2 MT */ +#define MIPS_24KE 0x96 /* MIPS 24KEc ISA 32 Rel 2 */ +#define MIPS_74K 0x97 /* MIPS 74Kc/74Kf ISA 32 Rel 2 */ /* * AMD (company ID 3) use the processor ID field to donote the CPU core From 12dfccb876c63c48ad28af4d8135f331c8a4204b Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 30 Oct 2009 01:40:32 +0000 Subject: [PATCH 298/380] - Fix build with DEVICE_POLLING enabled --- sys/mips/atheros/if_arge.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index c0c4c1a1008..223b5ae10f4 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -104,7 +104,7 @@ static int arge_resume(device_t); static int arge_rx_ring_init(struct arge_softc *); static int arge_tx_ring_init(struct arge_softc *); #ifdef DEVICE_POLLING -static void arge_poll(struct ifnet *, enum poll_cmd, int); +static int arge_poll(struct ifnet *, enum poll_cmd, int); #endif static int arge_shutdown(device_t); static void arge_start(struct ifnet *); @@ -112,7 +112,7 @@ static void arge_start_locked(struct ifnet *); static void arge_stop(struct arge_softc *); static int arge_suspend(device_t); -static void arge_rx_locked(struct arge_softc *); +static int arge_rx_locked(struct arge_softc *); static void arge_tx_locked(struct arge_softc *); static void arge_intr(void *); static int arge_intr_filter(void *); @@ -1394,17 +1394,20 @@ arge_fixup_rx(struct mbuf *m) } #ifdef DEVICE_POLLING -static void +static int arge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct arge_softc *sc = ifp->if_softc; + int rx_npkts = 0; if (ifp->if_drv_flags & IFF_DRV_RUNNING) { ARGE_LOCK(sc); arge_tx_locked(sc); - arge_rx_locked(sc); + rx_npkts = arge_rx_locked(sc); ARGE_UNLOCK(sc); } + + return (rx_npkts); } #endif /* DEVICE_POLLING */ @@ -1470,7 +1473,7 @@ arge_tx_locked(struct arge_softc *sc) } -static void +static int arge_rx_locked(struct arge_softc *sc) { struct arge_rxdesc *rxd; @@ -1478,6 +1481,7 @@ arge_rx_locked(struct arge_softc *sc) int cons, prog, packet_len, i; struct arge_desc *cur_rx; struct mbuf *m; + int rx_npkts = 0; ARGE_LOCK_ASSERT(sc); @@ -1510,6 +1514,7 @@ arge_rx_locked(struct arge_softc *sc) /* Skip 4 bytes of CRC */ m->m_pkthdr.len = m->m_len = packet_len - ETHER_CRC_LEN; ifp->if_ipackets++; + rx_npkts++; ARGE_UNLOCK(sc); (*ifp->if_input)(ifp, m); @@ -1535,6 +1540,8 @@ arge_rx_locked(struct arge_softc *sc) sc->arge_cdata.arge_rx_cons = cons; } + + return (rx_npkts); } static int From aa40b001c3f447de71daf9c908342f99dfb3e8b9 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Fri, 30 Oct 2009 08:51:37 +0000 Subject: [PATCH 299/380] This is a temporary hack so we can get RMI to re-use the ns8250 code. We will need to think of a better way for code reuse for this (see sys/mips/rmi/uart_cpu_mips_xlr.c for where it is used) --- sys/dev/uart/uart_dev_ns8250.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c index c01fd615009..4b9ec6a9b32 100644 --- a/sys/dev/uart/uart_dev_ns8250.c +++ b/sys/dev/uart/uart_dev_ns8250.c @@ -224,7 +224,7 @@ static void ns8250_putc(struct uart_bas *bas, int); static int ns8250_rxready(struct uart_bas *bas); static int ns8250_getc(struct uart_bas *bas, struct mtx *); -static struct uart_ops uart_ns8250_ops = { +struct uart_ops uart_ns8250_ops = { .probe = ns8250_probe, .init = ns8250_init, .term = ns8250_term, From 8fae280afb4f83cf13f8d678d03b3b2282ce0f90 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Fri, 30 Oct 2009 08:53:11 +0000 Subject: [PATCH 300/380] With this commit our friend RMI will now compile. I have not tested it and the chances of it running yet are about ZERO.. but it will now compile. The hard part now begins, making it run ;-) --- sys/conf/files.mips | 1 - sys/conf/options.mips | 4 ++- sys/mips/adm5120/adm5120_machdep.c | 6 ++++ sys/mips/adm5120/files.adm5120 | 1 + sys/mips/alchemy/alchemy_machdep.c | 6 ++++ sys/mips/alchemy/files.alchemy | 1 + sys/mips/atheros/ar71xx_machdep.c | 6 ++++ sys/mips/atheros/files.ar71xx | 1 + sys/mips/idt/files.idt | 1 + sys/mips/idt/idt_machdep.c | 6 ++++ sys/mips/include/fls64.h | 47 ++++++++++++++++++++++++++++++ sys/mips/include/hwfunc.h | 10 ++++++- sys/mips/include/intr_machdep.h | 4 +-- sys/mips/include/kdb.h | 4 +++ sys/mips/malta/files.malta | 1 + sys/mips/malta/malta_machdep.c | 6 ++++ sys/mips/mips/cpu.c | 2 ++ sys/mips/mips/machdep.c | 10 +++++-- sys/mips/mips/tick.c | 5 ++-- sys/mips/octeon1/files.octeon1 | 1 + sys/mips/octeon1/octeon_machdep.c | 5 ++++ sys/mips/sentry5/files.sentry5 | 1 + sys/mips/sentry5/s5_machdep.c | 6 ++++ sys/mips/sibyte/files.sibyte | 1 + sys/mips/sibyte/sb_machdep.c | 6 ++++ 25 files changed, 133 insertions(+), 9 deletions(-) create mode 100644 sys/mips/include/fls64.h diff --git a/sys/conf/files.mips b/sys/conf/files.mips index 025556b4de6..ded5db8fdf6 100644 --- a/sys/conf/files.mips +++ b/sys/conf/files.mips @@ -45,7 +45,6 @@ mips/mips/vm_machdep.c standard # ---------------------------------------------------------------------- # Phase 4 # ---------------------------------------------------------------------- -mips/mips/tick.c standard # ---------------------------------------------------------------------- # Phase 5 # ---------------------------------------------------------------------- diff --git a/sys/conf/options.mips b/sys/conf/options.mips index d533bfffd02..40917598312 100644 --- a/sys/conf/options.mips +++ b/sys/conf/options.mips @@ -51,9 +51,11 @@ CFE_ENV_SIZE opt_global.h KERNPHYSADDR opt_global.h KERNVIRTADDR opt_global.h PHYSADDR opt_global.h - +PHYS_ADDR_64BIT opt_global.h +NOFPU opt_global.h TARGET_OCTEON opt_global.h TARGET_EMULATOR opt_ddb.h +TARGET_XLR_XLS opt_global.h TICK_USE_YAMON_FREQ opt_global.h TICK_USE_MALTA_RTC opt_global.h diff --git a/sys/mips/adm5120/adm5120_machdep.c b/sys/mips/adm5120/adm5120_machdep.c index ef188d301d6..c30be2fc6ec 100644 --- a/sys/mips/adm5120/adm5120_machdep.c +++ b/sys/mips/adm5120/adm5120_machdep.c @@ -73,6 +73,12 @@ __FBSDID("$FreeBSD$"); extern int *edata; extern int *end; +void +platform_cpu_init() +{ + /* Nothing special */ +} + static void mips_init(void) { diff --git a/sys/mips/adm5120/files.adm5120 b/sys/mips/adm5120/files.adm5120 index 0645f406a25..c8b60ce88b5 100644 --- a/sys/mips/adm5120/files.adm5120 +++ b/sys/mips/adm5120/files.adm5120 @@ -10,3 +10,4 @@ mips/adm5120/uart_bus_adm5120.c optional uart mips/adm5120/uart_cpu_adm5120.c optional uart mips/adm5120/uart_dev_adm5120.c optional uart mips/mips/intr_machdep.c standard +mips/mips/tick.c standard diff --git a/sys/mips/alchemy/alchemy_machdep.c b/sys/mips/alchemy/alchemy_machdep.c index eca9b18ae0d..2f4f1f6ca3d 100644 --- a/sys/mips/alchemy/alchemy_machdep.c +++ b/sys/mips/alchemy/alchemy_machdep.c @@ -73,6 +73,12 @@ __FBSDID("$FreeBSD$"); extern int *edata; extern int *end; +void +platform_cpu_init() +{ + /* Nothing special */ +} + static void mips_init(void) { diff --git a/sys/mips/alchemy/files.alchemy b/sys/mips/alchemy/files.alchemy index 2e0f0e74853..240869cdcbb 100644 --- a/sys/mips/alchemy/files.alchemy +++ b/sys/mips/alchemy/files.alchemy @@ -6,3 +6,4 @@ mips/alchemy/obio.c standard mips/alchemy/uart_bus_alchemy.c optional uart mips/alchemy/uart_cpu_alchemy.c optional uart mips/mips/intr_machdep.c standard +mips/mips/tick.c standard diff --git a/sys/mips/atheros/ar71xx_machdep.c b/sys/mips/atheros/ar71xx_machdep.c index a4139c30af1..0791e687bbe 100644 --- a/sys/mips/atheros/ar71xx_machdep.c +++ b/sys/mips/atheros/ar71xx_machdep.c @@ -97,6 +97,12 @@ parse_argv(char *str) } } +void +platform_cpu_init() +{ + /* Nothing special */ +} + void platform_halt(void) { diff --git a/sys/mips/atheros/files.ar71xx b/sys/mips/atheros/files.ar71xx index ccad05751ea..29add2e06f0 100644 --- a/sys/mips/atheros/files.ar71xx +++ b/sys/mips/atheros/files.ar71xx @@ -13,3 +13,4 @@ mips/atheros/uart_bus_ar71xx.c optional uart mips/atheros/uart_cpu_ar71xx.c optional uart mips/atheros/ar71xx_bus_space_reversed.c standard mips/mips/intr_machdep.c standard +mips/mips/tick.c standard diff --git a/sys/mips/idt/files.idt b/sys/mips/idt/files.idt index b8920a7d30c..09b9959c122 100644 --- a/sys/mips/idt/files.idt +++ b/sys/mips/idt/files.idt @@ -7,3 +7,4 @@ mips/idt/obio.c standard mips/idt/uart_cpu_rc32434.c optional uart mips/idt/uart_bus_rc32434.c optional uart mips/mips/intr_machdep.c standard +mips/mips/tick.c standard diff --git a/sys/mips/idt/idt_machdep.c b/sys/mips/idt/idt_machdep.c index 040c3f90a04..776bc502d42 100644 --- a/sys/mips/idt/idt_machdep.c +++ b/sys/mips/idt/idt_machdep.c @@ -75,6 +75,12 @@ __FBSDID("$FreeBSD$"); extern int *edata; extern int *end; +void +platform_cpu_init() +{ + /* Nothing special */ +} + void platform_halt(void) { diff --git a/sys/mips/include/fls64.h b/sys/mips/include/fls64.h new file mode 100644 index 00000000000..e49c087c995 --- /dev/null +++ b/sys/mips/include/fls64.h @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * RMI_BSD */ +#ifndef _MIPS_FLS64_H_ +#define _MIPS_FLS64_H_ + +/* + * Find Last Set bit (64 bit) + */ +static inline int +fls64(__uint64_t mask) +{ + int bit; + + if (mask == 0) + return (0); + for (bit = 1; ((mask & 0x1ULL) == 0); bit++) + mask = mask >> 1; + return (bit); +} +#endif diff --git a/sys/mips/include/hwfunc.h b/sys/mips/include/hwfunc.h index ef5088cb8d8..16b1439a81d 100644 --- a/sys/mips/include/hwfunc.h +++ b/sys/mips/include/hwfunc.h @@ -29,7 +29,7 @@ #define _MACHINE_HWFUNC_H_ struct trapframe; - +struct timecounter; /* * Hooks downward into hardware functionality. */ @@ -39,4 +39,12 @@ void platform_intr(struct trapframe *); void platform_reset(void); void platform_start(__register_t, __register_t, __register_t, __register_t); +/* For clocks and ticks and such */ +void platform_initclocks(void); +uint64_t platform_get_frequency(void); +unsigned platform_get_timecount(struct timecounter *); + +/* For hardware specific CPU initialization */ +void platform_cpu_init(void); +void platform_secondary_init(void); #endif /* !_MACHINE_HWFUNC_H_ */ diff --git a/sys/mips/include/intr_machdep.h b/sys/mips/include/intr_machdep.h index 1e3e075b189..79cdf9e041c 100644 --- a/sys/mips/include/intr_machdep.h +++ b/sys/mips/include/intr_machdep.h @@ -52,9 +52,9 @@ extern struct mips_intrhand mips_intr_handlers[]; struct trapframe; -void cpu_establish_hardintr(const char *, int (*)(void*), void (*)(void*), +void cpu_establish_hardintr(const char *, driver_filter_t *, driver_intr_t *, void *, int, int, void **); -void cpu_establish_softintr(const char *, int (*)(void*), void (*)(void*), +void cpu_establish_softintr(const char *, driver_filter_t *, void (*)(void*), void *, int, int, void **); void cpu_intr(struct trapframe *); diff --git a/sys/mips/include/kdb.h b/sys/mips/include/kdb.h index 7be4ecb5ef3..cd8c6185855 100644 --- a/sys/mips/include/kdb.h +++ b/sys/mips/include/kdb.h @@ -47,4 +47,8 @@ kdb_cpu_trap(int vector, int _) { } +static __inline void +kdb_cpu_sync_icache(unsigned char *addr, size_t size) +{ +} #endif /* _MACHINE_KDB_H_ */ diff --git a/sys/mips/malta/files.malta b/sys/mips/malta/files.malta index fe805461cdd..82d9ca49b98 100644 --- a/sys/mips/malta/files.malta +++ b/sys/mips/malta/files.malta @@ -8,3 +8,4 @@ dev/uart/uart_dev_ns8250.c optional uart mips/malta/malta_machdep.c standard mips/malta/yamon.c standard mips/mips/intr_machdep.c standard +mips/mips/tick.c standard diff --git a/sys/mips/malta/malta_machdep.c b/sys/mips/malta/malta_machdep.c index 0f53f13fb47..d67f2492fb7 100644 --- a/sys/mips/malta/malta_machdep.c +++ b/sys/mips/malta/malta_machdep.c @@ -97,6 +97,12 @@ static int malta_lcd_offs[] = { MALTA_ASCIIPOS7 }; +void +platform_cpu_init() +{ + /* Nothing special */ +} + /* * Put character to Malta LCD at given position. */ diff --git a/sys/mips/mips/cpu.c b/sys/mips/mips/cpu.c index 177ec4854ba..0f3d8ad43f4 100644 --- a/sys/mips/mips/cpu.c +++ b/sys/mips/mips/cpu.c @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include static struct mips_cpuinfo cpuinfo; @@ -129,6 +130,7 @@ mips_get_identity(struct mips_cpuinfo *cpuinfo) void mips_cpu_init(void) { + platform_cpu_init(); mips_get_identity(&cpuinfo); num_tlbentries = cpuinfo.tlb_nentries; Mips_SetWIRED(0); diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c index a746b24c812..b06898dbbcd 100644 --- a/sys/mips/mips/machdep.c +++ b/sys/mips/mips/machdep.c @@ -112,8 +112,8 @@ int clocks_running = 0; vm_offset_t kstack0; #ifdef SMP -struct pcpu __pcpu[32]; -char pcpu_boot_stack[KSTACK_PAGES * PAGE_SIZE * (MAXCPU-1)]; +struct pcpu __pcpu[MAXCPU]; +char pcpu_boot_stack[KSTACK_PAGES * PAGE_SIZE * MAXCPU]; #else struct pcpu pcpu; struct pcpu *pcpup = &pcpu; @@ -288,6 +288,12 @@ mips_proc0_init(void) PCPU_SET(curpcb, thread0.td_pcb); } +void +cpu_initclocks(void) +{ + platform_initclocks(); +} + struct msgbuf *msgbufp=0; /* diff --git a/sys/mips/mips/tick.c b/sys/mips/mips/tick.c index 42f34a7e9ba..c91b1abf68d 100644 --- a/sys/mips/mips/tick.c +++ b/sys/mips/mips/tick.c @@ -59,6 +59,8 @@ u_int32_t counter_upper = 0; u_int32_t counter_lower_last = 0; int tick_started = 0; +void platform_initclocks(void); + struct clk_ticks { u_long hard_ticks; @@ -97,9 +99,8 @@ mips_timer_early_init(uint64_t clock_hz) } void -cpu_initclocks(void) +platform_initclocks(void) { - if (!tick_started) { tc_init(&counter_timecounter); tick_started++; diff --git a/sys/mips/octeon1/files.octeon1 b/sys/mips/octeon1/files.octeon1 index 8415a47563c..190d3b8c209 100644 --- a/sys/mips/octeon1/files.octeon1 +++ b/sys/mips/octeon1/files.octeon1 @@ -14,3 +14,4 @@ mips/octeon1/uart_bus_octeonusart.c optional uart mips/octeon1/uart_cpu_octeonusart.c optional uart mips/octeon1/uart_dev_oct16550.c optional uart mips/mips/intr_machdep.c standard +mips/mips/tick.c standard diff --git a/sys/mips/octeon1/octeon_machdep.c b/sys/mips/octeon1/octeon_machdep.c index e3e9e838463..140187407a9 100644 --- a/sys/mips/octeon1/octeon_machdep.c +++ b/sys/mips/octeon1/octeon_machdep.c @@ -80,6 +80,11 @@ __FBSDID("$FreeBSD$"); extern int *edata; extern int *end; +void +platform_cpu_init() +{ + /* Nothing special yet */ +} /* * Perform a board-level soft-reset. diff --git a/sys/mips/sentry5/files.sentry5 b/sys/mips/sentry5/files.sentry5 index 07043d557fd..73907f4219d 100644 --- a/sys/mips/sentry5/files.sentry5 +++ b/sys/mips/sentry5/files.sentry5 @@ -6,3 +6,4 @@ # which just need to be tweaked for attachment to an SSB system bus. mips/sentry5/s5_machdep.c standard mips/mips/intr_machdep.c standard +mips/mips/tick.c standard diff --git a/sys/mips/sentry5/s5_machdep.c b/sys/mips/sentry5/s5_machdep.c index 0923402d679..d326f73ee3e 100644 --- a/sys/mips/sentry5/s5_machdep.c +++ b/sys/mips/sentry5/s5_machdep.c @@ -87,6 +87,12 @@ extern uint32_t cfe_vector; extern int *edata; extern int *end; +void +platform_cpu_init() +{ + /* Nothing special */ +} + static void mips_init(void) { diff --git a/sys/mips/sibyte/files.sibyte b/sys/mips/sibyte/files.sibyte index 677796c1c78..4c5c9c03083 100644 --- a/sys/mips/sibyte/files.sibyte +++ b/sys/mips/sibyte/files.sibyte @@ -7,3 +7,4 @@ mips/sibyte/sb_scd.c standard mips/sibyte/ata_zbbus.c standard mips/mips/intr_machdep.c standard mips/sibyte/sb_asm.S standard +mips/mips/tick.c standard diff --git a/sys/mips/sibyte/sb_machdep.c b/sys/mips/sibyte/sb_machdep.c index 79a1b8975cc..d6bee7692a8 100644 --- a/sys/mips/sibyte/sb_machdep.c +++ b/sys/mips/sibyte/sb_machdep.c @@ -98,6 +98,12 @@ extern void cfe_env_init(void); extern int *edata; extern int *end; +void +platform_cpu_init() +{ + /* Nothing special */ +} + static void mips_init(void) { From 83b16fcf66b389a3db89be8cdd073cc49092524e Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Mon, 2 Nov 2009 15:08:33 +0000 Subject: [PATCH 301/380] Fix header file location --- sys/dev/rmi/xlr/rge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/rmi/xlr/rge.c b/sys/dev/rmi/xlr/rge.c index ef2288e852c..38f5fdde681 100644 --- a/sys/dev/rmi/xlr/rge.c +++ b/sys/dev/rmi/xlr/rge.c @@ -73,7 +73,7 @@ #include #include #include -#include +#include #include #include From 037a5859a02ce1e0e71a3ca4db24f5253aa38d72 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Mon, 2 Nov 2009 15:08:59 +0000 Subject: [PATCH 302/380] Fix spacing --- sys/mips/rmi/board.c | 60 ++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/sys/mips/rmi/board.c b/sys/mips/rmi/board.c index cf90f6cccc1..932fee2ef22 100644 --- a/sys/mips/rmi/board.c +++ b/sys/mips/rmi/board.c @@ -41,39 +41,39 @@ #include static int xlr_rxstn_to_txstn_map[128] = { - [0...7] = TX_STN_CPU_0, - [8...15] = TX_STN_CPU_1, - [16...23] = TX_STN_CPU_2, - [24...31] = TX_STN_CPU_3, - [32...39] = TX_STN_CPU_4, - [40...47] = TX_STN_CPU_5, - [48...55] = TX_STN_CPU_6, - [56...63] = TX_STN_CPU_7, - [64...95] = TX_STN_INVALID, - [96...103] = TX_STN_GMAC, - [104...107] = TX_STN_DMA, - [108...111] = TX_STN_INVALID, - [112...113] = TX_STN_XGS_0, - [114...115] = TX_STN_XGS_1, - [116...119] = TX_STN_INVALID, - [120...127] = TX_STN_SAE + [0 ... 7] = TX_STN_CPU_0, + [8 ... 15] = TX_STN_CPU_1, + [16 ... 23] = TX_STN_CPU_2, + [24 ... 31] = TX_STN_CPU_3, + [32 ... 39] = TX_STN_CPU_4, + [40 ... 47] = TX_STN_CPU_5, + [48 ... 55] = TX_STN_CPU_6, + [56 ... 63] = TX_STN_CPU_7, + [64 ... 95] = TX_STN_INVALID, + [96 ... 103] = TX_STN_GMAC, + [104 ... 107] = TX_STN_DMA, + [108 ... 111] = TX_STN_INVALID, + [112 ... 113] = TX_STN_XGS_0, + [114 ... 115] = TX_STN_XGS_1, + [116 ... 119] = TX_STN_INVALID, + [120 ... 127] = TX_STN_SAE }; static int xls_rxstn_to_txstn_map[128] = { - [0...7] = TX_STN_CPU_0, - [8...15] = TX_STN_CPU_1, - [16...23] = TX_STN_CPU_2, - [24...31] = TX_STN_CPU_3, - [32...63] = TX_STN_INVALID, - [64...71] = TX_STN_PCIE, - [72...79] = TX_STN_INVALID, - [80...87] = TX_STN_GMAC1, - [88...95] = TX_STN_INVALID, - [96...103] = TX_STN_GMAC0, - [104...107] = TX_STN_DMA, - [108...111] = TX_STN_CDE, - [112...119] = TX_STN_INVALID, - [120...127] = TX_STN_SAE + [0 ... 7] = TX_STN_CPU_0, + [8 ... 15] = TX_STN_CPU_1, + [16 ... 23] = TX_STN_CPU_2, + [24 ... 31] = TX_STN_CPU_3, + [32 ... 63] = TX_STN_INVALID, + [64 ... 71] = TX_STN_PCIE, + [72 ... 79] = TX_STN_INVALID, + [80 ... 87] = TX_STN_GMAC1, + [88 ... 95] = TX_STN_INVALID, + [96 ... 103] = TX_STN_GMAC0, + [104 ... 107] = TX_STN_DMA, + [108 ... 111] = TX_STN_CDE, + [112 ... 119] = TX_STN_INVALID, + [120 ... 127] = TX_STN_SAE }; struct stn_cc *xlr_core_cc_configs[] = {&cc_table_cpu_0, &cc_table_cpu_1, From 45ab86915b567734956dd6d5c8e32db7fff33ac4 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Mon, 2 Nov 2009 15:43:54 +0000 Subject: [PATCH 303/380] adds XLR config --- sys/mips/conf/XLR | 149 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 sys/mips/conf/XLR diff --git a/sys/mips/conf/XLR b/sys/mips/conf/XLR new file mode 100644 index 00000000000..ba37d7cb4e4 --- /dev/null +++ b/sys/mips/conf/XLR @@ -0,0 +1,149 @@ +#################################RMI_BSD##################################### +# Copyright (c) 2003-2009 RMI Corporation +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of RMI Corporation, nor the names of its contributors, +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +#################################RMI_BSD##################################### +# XLR -- Generic kernel configuration file for FreeBSD/mips +# +# For more information on this file, please read the handbook section on +# Kernel Configuration Files: +# +# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# +# The handbook is also available locally in /usr/share/doc/handbook +# if you've installed the doc distribution, otherwise always see the +# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# latest information. +# +# An exhaustive list of options and more detailed explanations of the +# device lines is also present in the ../../conf/NOTES and NOTES files. +# If you are in doubt as to the purpose or necessity of a line, check first +# in NOTES. +# +# $FreeBSD$ + +machine mips +cpu CPU_MIPS4KC +ident XLR + +makeoptions MODULES_OVERRIDE="" +makeoptions TARGET_BIG_ENDIAN +# + +options KERNVIRTADDR=0x80100000 +include "../rmi/std.xlr" + + +makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols +#profile 2 + +#options SCHED_ULE # ULE scheduler +options SCHED_4BSD # 4BSD scheduler +#options PREEMPTION # Enable kernel thread preemption +#options FULL_PREEMPTION # Enable kernel thread preemption +options INET # InterNETworking +options INET6 # IPv6 communications protocols +options FFS # Berkeley Fast Filesystem +#options SOFTUPDATES # Enable FFS soft updates support +options UFS_ACL # Support for access control lists +options UFS_DIRHASH # Improve performance on big directories +options MD_ROOT # MD is a potential root device +options MD_ROOT_SIZE=14288 +#options MD_ROOT_SIZE=5120 +options ROOTDEVNAME=\"ufs:md0\" +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions +options HZ=1000 +options PHYS_ADDR_64BIT +options NO_SWAPPING + +#Debugging options +options KTRACE # ktrace(1) support +options DDB +options KDB +options GDB +options ALT_BREAK_TO_DEBUGGER +#options INVARIANTS #Enable calls of extra sanity checking +#options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS +#options WITNESS #Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed +#options KTR # ktr(4) and ktrdump(8) support +#options KTR_COMPILE=(KTR_LOCK|KTR_PROC|KTR_INTR|KTR_CALLOUT|KTR_UMA|KTR_SYSC|KTR_CRITICAL) +#options KTR_ENTRIES=131072 +#options MUTEX_DEBUG +#options MUTEX_PROFILING + +device pci +#device ata +#device atadisk +#options XLR_PERFMON # Enable XLR processor activity monitoring + +#device genclock +device uart + +# Pseudo +device loop +device random +device md +device mem +device pty +device bpf + +# Network +device miibus +device rge +device ether +device re +device msk + +device da +device scbus +#device ohci # OHCI PCI->USB interface +device ehci # EHCI PCI->USB interface (USB 2.0) +device usb # USB Bus (required) +#device udbp # USB Double Bulk Pipe devices +#device ugen # Generic +#device uhid # "Human Interface Devices" +device umass # Disks/Mass storage - Requires scbus and da + +#device cfi + +#i2c +# Not yet +#device ic +#device iic +#device iicbb +#device iicbus +#device xlr_rtc +#device xlr_temperature +#device xlr_eeprom + +#crypto +# Not yet +#device cryptodev +#device crypto +#device rmisec +options ISA_MIPS32 +makeoptions KERNLOADADDR=0x80100000 From 3682174ee507beacef5ab58c25bfb12c5eae2afb Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Tue, 3 Nov 2009 06:42:55 +0000 Subject: [PATCH 304/380] - Handle errors when adding children to nexus. This sittuation might occure when there is dublicate of child's entry in hints --- sys/mips/mips/nexus.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sys/mips/mips/nexus.c b/sys/mips/mips/nexus.c index b939bc6b7c1..0e6f3954f64 100644 --- a/sys/mips/mips/nexus.c +++ b/sys/mips/mips/nexus.c @@ -257,6 +257,8 @@ nexus_hinted_child(device_t bus, const char *dname, int dunit) int mem_hints_count; child = BUS_ADD_CHILD(bus, 0, dname, dunit); + if (child == NULL) + return; /* * Set hard-wired resources for hinted child using @@ -306,6 +308,10 @@ nexus_add_child(device_t bus, int order, const char *name, int unit) resource_list_init(&ndev->nx_resources); child = device_add_child_ordered(bus, order, name, unit); + if (child == NULL) { + device_printf(bus, "failed to add child: %s%d\n", name, unit); + return (0); + } /* should we free this in nexus_child_detached? */ device_set_ivars(child, ndev); From a0d684a5832048f630cbb611e3ee18174d8c71e6 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 4 Nov 2009 23:33:36 +0000 Subject: [PATCH 305/380] - Remove noisy "Implement me" stubs - Handle SIOCSIFFLAGS ioctl --- sys/mips/atheros/if_arge.c | 25 ++++++++++++++++++++----- sys/mips/atheros/if_argevar.h | 1 + 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index 223b5ae10f4..e55232078d3 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -272,6 +272,7 @@ arge_attach(device_t dev) ifp->if_ioctl = arge_ioctl; ifp->if_start = arge_start; ifp->if_init = arge_init; + sc->arge_if_flags = ifp->if_flags; /* XXX: add real size */ IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); @@ -900,25 +901,38 @@ arge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) switch (command) { case SIOCSIFFLAGS: - printf("Implement me: SIOCSIFFLAGS\n"); + ARGE_LOCK(sc); + if ((ifp->if_flags & IFF_UP) != 0) { + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { + if (((ifp->if_flags ^ sc->arge_if_flags) + & (IFF_PROMISC | IFF_ALLMULTI)) != 0) + arge_rx_locked(sc); + } else { + if (!sc->arge_detach) + arge_init_locked(sc); + } + } else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + arge_stop(sc); + } + sc->arge_if_flags = ifp->if_flags; + ARGE_UNLOCK(sc); error = 0; break; case SIOCADDMULTI: case SIOCDELMULTI: - printf("Implement me: SIOCDELMULTI\n"); + /* XXX: implement SIOCDELMULTI */ error = 0; break; case SIOCGIFMEDIA: case SIOCSIFMEDIA: - printf("Implement me: SIOCSIFMEDIA\n"); mii = device_get_softc(sc->arge_miibus); error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); break; case SIOCSIFCAP: - printf("Implement me: SIOCSIFCAP\n"); + /* XXX: Check other capabilities */ #ifdef DEVICE_POLLING mask = ifp->if_capenable ^ ifr->ifr_reqcap; - error = 0; if (mask & IFCAP_POLLING) { if (ifr->ifr_reqcap & IFCAP_POLLING) { ARGE_WRITE(sc, AR71XX_DMA_INTR, 0); @@ -936,6 +950,7 @@ arge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) ARGE_UNLOCK(sc); } } + error = 0; break; #endif default: diff --git a/sys/mips/atheros/if_argevar.h b/sys/mips/atheros/if_argevar.h index 1966e61aeec..4e7e40dd87a 100644 --- a/sys/mips/atheros/if_argevar.h +++ b/sys/mips/atheros/if_argevar.h @@ -133,6 +133,7 @@ struct arge_softc { int arge_phy_num; uint32_t arge_ddr_flush_reg; uint32_t arge_pll_reg; + int arge_if_flags; }; #endif /* __IF_ARGEVAR_H__ */ From 896ef84ff0d877fb04b3c7def7308d449c5cc82b Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 4 Nov 2009 23:34:58 +0000 Subject: [PATCH 306/380] - style(9): replace whitespaces with tabs --- sys/mips/atheros/if_arge.c | 46 +++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index e55232078d3..e00b7688220 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -295,7 +295,7 @@ arge_attach(device_t dev) /* * No MAC address configured. Generate the random one. */ - if (bootverbose) + if (bootverbose) device_printf(dev, "Generating random ethernet address.\n"); @@ -929,29 +929,29 @@ arge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) mii = device_get_softc(sc->arge_miibus); error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); break; - case SIOCSIFCAP: + case SIOCSIFCAP: /* XXX: Check other capabilities */ #ifdef DEVICE_POLLING - mask = ifp->if_capenable ^ ifr->ifr_reqcap; - if (mask & IFCAP_POLLING) { - if (ifr->ifr_reqcap & IFCAP_POLLING) { + mask = ifp->if_capenable ^ ifr->ifr_reqcap; + if (mask & IFCAP_POLLING) { + if (ifr->ifr_reqcap & IFCAP_POLLING) { ARGE_WRITE(sc, AR71XX_DMA_INTR, 0); - error = ether_poll_register(arge_poll, ifp); - if (error) - return error; - ARGE_LOCK(sc); - ifp->if_capenable |= IFCAP_POLLING; - ARGE_UNLOCK(sc); - } else { + error = ether_poll_register(arge_poll, ifp); + if (error) + return error; + ARGE_LOCK(sc); + ifp->if_capenable |= IFCAP_POLLING; + ARGE_UNLOCK(sc); + } else { ARGE_WRITE(sc, AR71XX_DMA_INTR, DMA_INTR_ALL); - error = ether_poll_deregister(ifp); - ARGE_LOCK(sc); - ifp->if_capenable &= ~IFCAP_POLLING; - ARGE_UNLOCK(sc); - } - } + error = ether_poll_deregister(ifp); + ARGE_LOCK(sc); + ifp->if_capenable &= ~IFCAP_POLLING; + ARGE_UNLOCK(sc); + } + } error = 0; - break; + break; #endif default: error = ether_ioctl(ifp, command, data); @@ -1392,8 +1392,8 @@ arge_newbuf(struct arge_softc *sc, int idx) static __inline void arge_fixup_rx(struct mbuf *m) { - int i; - uint16_t *src, *dst; + int i; + uint16_t *src, *dst; src = mtod(m, uint16_t *); dst = src - 1; @@ -1415,12 +1415,12 @@ arge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) struct arge_softc *sc = ifp->if_softc; int rx_npkts = 0; - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { ARGE_LOCK(sc); arge_tx_locked(sc); rx_npkts = arge_rx_locked(sc); ARGE_UNLOCK(sc); - } + } return (rx_npkts); } From d6994d3b0e89f0b30742b8cefa9fcfc7b907ec35 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 5 Nov 2009 03:54:03 +0000 Subject: [PATCH 307/380] - Replace dumb cut'n'paste call with not to self (XXX) --- sys/mips/atheros/if_arge.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index e00b7688220..b16a088c32c 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -905,8 +905,10 @@ arge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) if ((ifp->if_flags & IFF_UP) != 0) { if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { if (((ifp->if_flags ^ sc->arge_if_flags) - & (IFF_PROMISC | IFF_ALLMULTI)) != 0) - arge_rx_locked(sc); + & (IFF_PROMISC | IFF_ALLMULTI)) != 0) { + /* XXX: handle promisc & multi flags */ + } + } else { if (!sc->arge_detach) arge_init_locked(sc); From 7a7f91f61b9665fdb49a4566baf4b7c3b1582225 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Thu, 5 Nov 2009 18:14:25 +0000 Subject: [PATCH 308/380] ok we now get so that the uart init's and we can print. We cannot set baud rate as they did in 6.4, this hoses things and we loose our 38400 default term. We now lock somewhere in tcinit. --- sys/mips/rmi/bus_space_rmi.c | 795 +++++++++++++++++++++++++++++++ sys/mips/rmi/clock.c | 24 +- sys/mips/rmi/clock.h | 2 +- sys/mips/rmi/files.xlr | 1 + sys/mips/rmi/iodi.c | 15 +- sys/mips/rmi/iomap.h | 5 +- sys/mips/rmi/msgring.h | 5 +- sys/mips/rmi/on_chip.c | 7 +- sys/mips/rmi/pcibus.c | 10 +- sys/mips/rmi/pic.h | 29 +- sys/mips/rmi/uart_bus_xlr_iodi.c | 13 +- sys/mips/rmi/uart_cpu_mips_xlr.c | 116 +---- sys/mips/rmi/xlr_machdep.c | 62 ++- 13 files changed, 941 insertions(+), 143 deletions(-) create mode 100644 sys/mips/rmi/bus_space_rmi.c diff --git a/sys/mips/rmi/bus_space_rmi.c b/sys/mips/rmi/bus_space_rmi.c new file mode 100644 index 00000000000..83146d80c7c --- /dev/null +++ b/sys/mips/rmi/bus_space_rmi.c @@ -0,0 +1,795 @@ +/*- + * Copyright (c) 2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +void xlr_putc(char); +void xlr_print_int(uint32_t); + +static int rmi_bus_space_map(void *t, bus_addr_t addr, + bus_size_t size, int flags, + bus_space_handle_t *bshp); + + +static void rmi_bus_space_unmap(void *t, bus_space_handle_t bsh, + bus_size_t size); + +static int rmi_bus_space_subregion(void *t, + bus_space_handle_t bsh, + bus_size_t offset, bus_size_t size, + bus_space_handle_t *nbshp); + +static u_int8_t rmi_bus_space_read_1(void *t, + bus_space_handle_t handle, + bus_size_t offset); + +static u_int16_t rmi_bus_space_read_2(void *t, + bus_space_handle_t handle, + bus_size_t offset); + +static u_int32_t rmi_bus_space_read_4(void *t, + bus_space_handle_t handle, + bus_size_t offset); + +static void rmi_bus_space_read_multi_1(void *t, + bus_space_handle_t handle, + bus_size_t offset, u_int8_t *addr, + size_t count); + +static void rmi_bus_space_read_multi_2(void *t, + bus_space_handle_t handle, + bus_size_t offset, u_int16_t *addr, + size_t count); + +static void rmi_bus_space_read_multi_4(void *t, + bus_space_handle_t handle, + bus_size_t offset, u_int32_t *addr, + size_t count); + +static void rmi_bus_space_read_region_1(void *t, + bus_space_handle_t bsh, + bus_size_t offset, u_int8_t *addr, + size_t count); + +static void rmi_bus_space_read_region_2(void *t, + bus_space_handle_t bsh, + bus_size_t offset, u_int16_t *addr, + size_t count); + +static void rmi_bus_space_read_region_4(void *t, + bus_space_handle_t bsh, + bus_size_t offset, u_int32_t *addr, + size_t count); + +static void rmi_bus_space_write_1(void *t, + bus_space_handle_t handle, + bus_size_t offset, u_int8_t value); + +static void rmi_bus_space_write_2(void *t, + bus_space_handle_t handle, + bus_size_t offset, u_int16_t value); + +static void rmi_bus_space_write_4(void *t, + bus_space_handle_t handle, + bus_size_t offset, u_int32_t value); + +static void rmi_bus_space_write_multi_1(void *t, + bus_space_handle_t handle, + bus_size_t offset, + const u_int8_t *addr, + size_t count); +static void rmi_bus_space_write_multi_2(void *t, + bus_space_handle_t handle, + bus_size_t offset, + const u_int16_t *addr, + size_t count); + +static void rmi_bus_space_write_multi_4(void *t, + bus_space_handle_t handle, + bus_size_t offset, + const u_int32_t *addr, + size_t count); + +static void rmi_bus_space_write_region_2(void *t, + bus_space_handle_t bsh, + bus_size_t offset, + const u_int16_t *addr, + size_t count); + +static void rmi_bus_space_write_region_4(void *t, + bus_space_handle_t bsh, + bus_size_t offset, + const u_int32_t *addr, + size_t count); + + +static void rmi_bus_space_set_region_2(void *t, + bus_space_handle_t bsh, + bus_size_t offset, u_int16_t value, + size_t count); +static void rmi_bus_space_set_region_4(void *t, + bus_space_handle_t bsh, + bus_size_t offset, u_int32_t value, + size_t count); + +static void rmi_bus_space_barrier(void *tag __unused, bus_space_handle_t bsh __unused, + bus_size_t offset __unused, bus_size_t len __unused, int flags); + + +static void rmi_bus_space_copy_region_2(void *t, + bus_space_handle_t bsh1, + bus_size_t off1, + bus_space_handle_t bsh2, + bus_size_t off2, size_t count); + +u_int8_t rmi_bus_space_read_stream_1(void *t, bus_space_handle_t handle, + bus_size_t offset); + +static u_int16_t rmi_bus_space_read_stream_2(void *t, bus_space_handle_t handle, + bus_size_t offset); + +static u_int32_t rmi_bus_space_read_stream_4(void *t, bus_space_handle_t handle, + bus_size_t offset); +static void rmi_bus_space_read_multi_stream_1(void *t, + bus_space_handle_t handle, + bus_size_t offset, u_int8_t *addr, + size_t count); + +static void rmi_bus_space_read_multi_stream_2(void *t, + bus_space_handle_t handle, + bus_size_t offset, u_int16_t *addr, + size_t count); + +static void rmi_bus_space_read_multi_stream_4(void *t, + bus_space_handle_t handle, + bus_size_t offset, u_int32_t *addr, + size_t count); + +void rmi_bus_space_write_stream_1(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int8_t value); +static void rmi_bus_space_write_stream_2(void *t, bus_space_handle_t handle, + bus_size_t offset, u_int16_t value); + +static void rmi_bus_space_write_stream_4(void *t, bus_space_handle_t handle, + bus_size_t offset, u_int32_t value); + +static void rmi_bus_space_write_multi_stream_1(void *t, + bus_space_handle_t handle, + bus_size_t offset, + const u_int8_t *addr, + size_t count); +static void rmi_bus_space_write_multi_stream_2(void *t, + bus_space_handle_t handle, + bus_size_t offset, + const u_int16_t *addr, + size_t count); + +static void rmi_bus_space_write_multi_stream_4(void *t, + bus_space_handle_t handle, + bus_size_t offset, + const u_int32_t *addr, + size_t count); + + +static struct bus_space local_rmi_bus_space = { + /* cookie */ + (void *) 0, + + /* mapping/unmapping */ + rmi_bus_space_map, + rmi_bus_space_unmap, + rmi_bus_space_subregion, + + /* allocation/deallocation */ + NULL, + NULL, + + /* barrier */ + rmi_bus_space_barrier, + + /* read (single) */ + rmi_bus_space_read_1, + rmi_bus_space_read_2, + rmi_bus_space_read_4, + NULL, + + /* read multiple */ + rmi_bus_space_read_multi_1, + rmi_bus_space_read_multi_2, + rmi_bus_space_read_multi_4, + NULL, + + /* read region */ + rmi_bus_space_read_region_1, + rmi_bus_space_read_region_2, + rmi_bus_space_read_region_4, + NULL, + + /* write (single) */ + rmi_bus_space_write_1, + rmi_bus_space_write_2, + rmi_bus_space_write_4, + NULL, + + /* write multiple */ + rmi_bus_space_write_multi_1, + rmi_bus_space_write_multi_2, + rmi_bus_space_write_multi_4, + NULL, + + /* write region */ + NULL, + rmi_bus_space_write_region_2, + rmi_bus_space_write_region_4, + NULL, + + /* set multiple */ + NULL, + NULL, + NULL, + NULL, + + /* set region */ + NULL, + rmi_bus_space_set_region_2, + rmi_bus_space_set_region_4, + NULL, + + /* copy */ + NULL, + rmi_bus_space_copy_region_2, + NULL, + NULL, + + /* read (single) stream */ + rmi_bus_space_read_stream_1, + rmi_bus_space_read_stream_2, + rmi_bus_space_read_stream_4, + NULL, + + /* read multiple stream */ + rmi_bus_space_read_multi_stream_1, + rmi_bus_space_read_multi_stream_2, + rmi_bus_space_read_multi_stream_4, + NULL, + + /* read region stream */ + rmi_bus_space_read_region_1, + rmi_bus_space_read_region_2, + rmi_bus_space_read_region_4, + NULL, + + /* write (single) stream */ + rmi_bus_space_write_stream_1, + rmi_bus_space_write_stream_2, + rmi_bus_space_write_stream_4, + NULL, + + /* write multiple stream */ + rmi_bus_space_write_multi_stream_1, + rmi_bus_space_write_multi_stream_2, + rmi_bus_space_write_multi_stream_4, + NULL, + + /* write region stream */ + NULL, + rmi_bus_space_write_region_2, + rmi_bus_space_write_region_4, + NULL, +}; + +/* generic bus_space tag */ +bus_space_tag_t rmi_bus_space = &local_rmi_bus_space; + +#define MIPS_BUS_SPACE_IO 0 /* space is i/o space */ +#define MIPS_BUS_SPACE_MEM 1 /* space is mem space */ +#define MIPS_BUS_SPACE_PCI 10 /* avoid conflict with other spaces */ + +#define BUS_SPACE_UNRESTRICTED (~0) + +#define SWAP32(x)\ + (((x) & 0xff000000) >> 24) | \ + (((x) & 0x000000ff) << 24) | \ + (((x) & 0x0000ff00) << 8) | \ + (((x) & 0x00ff0000) >> 8) + +#define SWAP16(x)\ + (((x) & 0xff00) >> 8) | \ + (((x) & 0x00ff) << 8) + +/* + * Map a region of device bus space into CPU virtual address space. + */ + + +static int +rmi_bus_space_map(void *t __unused, bus_addr_t addr, + bus_size_t size __unused, int flags __unused, + bus_space_handle_t *bshp) +{ + + *bshp = addr; + return (0); +} + +/* + * Unmap a region of device bus space. + */ +static void +rmi_bus_space_unmap(void *t __unused, bus_space_handle_t bsh __unused, + bus_size_t size __unused) +{ +} + +/* + * Get a new handle for a subregion of an already-mapped area of bus space. + */ + +static int +rmi_bus_space_subregion(void *t __unused, bus_space_handle_t bsh, + bus_size_t offset, bus_size_t size __unused, + bus_space_handle_t *nbshp) +{ + *nbshp = bsh + offset; + return (0); +} + +/* + * Read a 1, 2, 4, or 8 byte quantity from bus space + * described by tag/handle/offset. + */ + +static u_int8_t +rmi_bus_space_read_1(void *tag, bus_space_handle_t handle, + bus_size_t offset) +{ + if ((int)tag == MIPS_BUS_SPACE_PCI) + return (u_int8_t)(*(volatile u_int8_t *)(handle + offset)); + else + return (u_int8_t)(*(volatile u_int32_t *)(handle + offset)); +} + +static u_int16_t +rmi_bus_space_read_2(void *tag, bus_space_handle_t handle, + bus_size_t offset) +{ + if ((int)tag == MIPS_BUS_SPACE_PCI) + return SWAP16((u_int16_t)(*(volatile u_int16_t *)(handle + offset))); + else + return *(volatile u_int16_t *)(handle + offset); +} + +static u_int32_t +rmi_bus_space_read_4(void *tag, bus_space_handle_t handle, + bus_size_t offset) +{ + if ((int)tag == MIPS_BUS_SPACE_PCI) + return SWAP32((*(volatile u_int32_t *)(handle + offset))); + else + return (*(volatile u_int32_t *)(handle + offset)); +} + + + +/* + * Read `count' 1, 2, 4, or 8 byte quantities from bus space + * described by tag/handle/offset and copy into buffer provided. + */ +static void +rmi_bus_space_read_multi_1(void *tag, bus_space_handle_t handle, + bus_size_t offset, u_int8_t *addr, size_t count) +{ + + if ((int)tag != MIPS_BUS_SPACE_PCI) + return; + while (count--) { + *addr = (*(volatile u_int8_t *)(handle + offset)); + addr++; + } +} + +static void +rmi_bus_space_read_multi_2(void *tag, bus_space_handle_t handle, + bus_size_t offset, u_int16_t *addr, size_t count) +{ + + if ((int)tag != MIPS_BUS_SPACE_PCI) + return; + while (count--) { + *addr = *(volatile u_int16_t *)(handle + offset); + *addr = SWAP16(*addr); + addr++; + } +} + +static void +rmi_bus_space_read_multi_4(void *tag, bus_space_handle_t handle, + bus_size_t offset, u_int32_t *addr, size_t count) +{ + + if ((int)tag != MIPS_BUS_SPACE_PCI) + return; + while (count--) { + *addr = *(volatile u_int32_t *)(handle + offset); + *addr = SWAP32(*addr); + addr++; + } +} + +/* + * Write the 1, 2, 4, or 8 byte value `value' to bus space + * described by tag/handle/offset. + */ + + +static void +rmi_bus_space_write_1(void *tag, bus_space_handle_t handle, + bus_size_t offset, u_int8_t value) +{ + mips_sync(); + if ((int)tag == MIPS_BUS_SPACE_PCI) + *(volatile u_int8_t *)(handle + offset) = value; + else + *(volatile u_int32_t *)(handle + offset) = (u_int32_t)value; +} + +static void +rmi_bus_space_write_2(void *tag, bus_space_handle_t handle, + bus_size_t offset, u_int16_t value) +{ + mips_sync(); + if ((int)tag == MIPS_BUS_SPACE_PCI) { + *(volatile u_int16_t *)(handle + offset) = SWAP16(value); + } else + *(volatile u_int16_t *)(handle + offset) = value; +} + + +static void +rmi_bus_space_write_4(void *tag, bus_space_handle_t handle, + bus_size_t offset, u_int32_t value) +{ + mips_sync(); + if ((int)tag == MIPS_BUS_SPACE_PCI) { + *(volatile u_int32_t *)(handle + offset) = SWAP32(value); + } else + *(volatile u_int32_t *)(handle + offset) = value; +} + + + +/* + * Write `count' 1, 2, 4, or 8 byte quantities from the buffer + * provided to bus space described by tag/handle/offset. + */ + + +static void +rmi_bus_space_write_multi_1(void *tag, bus_space_handle_t handle, + bus_size_t offset, const u_int8_t *addr, size_t count) +{ + mips_sync(); + if ((int)tag != MIPS_BUS_SPACE_PCI) + return; + while (count--) { + (*(volatile u_int8_t *)(handle + offset)) = *addr; + addr++; + } +} + +static void +rmi_bus_space_write_multi_2(void *tag, bus_space_handle_t handle, + bus_size_t offset, const u_int16_t *addr, size_t count) +{ + mips_sync(); + if ((int)tag != MIPS_BUS_SPACE_PCI) + return; + while (count--) { + (*(volatile u_int16_t *)(handle + offset)) = SWAP16(*addr); + addr++; + } +} + +static void +rmi_bus_space_write_multi_4(void *tag, bus_space_handle_t handle, + bus_size_t offset, const u_int32_t *addr, size_t count) +{ + mips_sync(); + if ((int)tag != MIPS_BUS_SPACE_PCI) + return; + while (count--) { + (*(volatile u_int32_t *)(handle + offset)) = SWAP32(*addr); + addr++; + } +} + +/* + * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described + * by tag/handle starting at `offset'. + */ + +static void +rmi_bus_space_set_region_2(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int16_t value, size_t count) +{ + bus_addr_t addr = bsh + offset; + + for (; count != 0; count--, addr += 2) + (*(volatile u_int16_t *)(addr)) = value; +} + +static void +rmi_bus_space_set_region_4(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int32_t value, size_t count) +{ + bus_addr_t addr = bsh + offset; + + for (; count != 0; count--, addr += 4) + (*(volatile u_int32_t *)(addr)) = value; +} + + +/* + * Copy `count' 1, 2, 4, or 8 byte values from bus space starting + * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. + */ +static void +rmi_bus_space_copy_region_2(void *t, bus_space_handle_t bsh1, + bus_size_t off1, bus_space_handle_t bsh2, + bus_size_t off2, size_t count) +{ + printf("bus_space_copy_region_2 - unimplemented\n"); +} + +/* + * Read `count' 1, 2, 4, or 8 byte quantities from bus space + * described by tag/handle/offset and copy into buffer provided. + */ + +u_int8_t +rmi_bus_space_read_stream_1(void *t, bus_space_handle_t handle, + bus_size_t offset) +{ + + return *((volatile u_int8_t *)(handle + offset)); +} + + +static u_int16_t +rmi_bus_space_read_stream_2(void *t, bus_space_handle_t handle, + bus_size_t offset) +{ + return *(volatile u_int16_t *)(handle + offset); +} + + +static u_int32_t +rmi_bus_space_read_stream_4(void *t, bus_space_handle_t handle, + bus_size_t offset) +{ + return (*(volatile u_int32_t *)(handle + offset)); +} + + +static void +rmi_bus_space_read_multi_stream_1(void *tag, bus_space_handle_t handle, + bus_size_t offset, u_int8_t *addr, size_t count) +{ + + if ((int)tag != MIPS_BUS_SPACE_PCI) + return; + while (count--) { + *addr = (*(volatile u_int8_t *)(handle + offset)); + addr++; + } +} + +static void +rmi_bus_space_read_multi_stream_2(void *tag, bus_space_handle_t handle, + bus_size_t offset, u_int16_t *addr, size_t count) +{ + + if ((int)tag != MIPS_BUS_SPACE_PCI) + return; + while (count--) { + *addr = (*(volatile u_int16_t *)(handle + offset)); + addr++; + } +} + +static void +rmi_bus_space_read_multi_stream_4(void *tag, bus_space_handle_t handle, + bus_size_t offset, u_int32_t *addr, size_t count) +{ + + if ((int)tag != MIPS_BUS_SPACE_PCI) + return; + while (count--) { + *addr = (*(volatile u_int32_t *)(handle + offset)); + addr++; + } +} + + + +/* + * Read `count' 1, 2, 4, or 8 byte quantities from bus space + * described by tag/handle and starting at `offset' and copy into + * buffer provided. + */ +void +rmi_bus_space_read_region_1(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int8_t *addr, size_t count) +{ + bus_addr_t baddr = bsh + offset; + + while (count--) { + *addr++ = (*(volatile u_int8_t *)(baddr)); + baddr += 1; + } +} + +void +rmi_bus_space_read_region_2(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int16_t *addr, size_t count) +{ + bus_addr_t baddr = bsh + offset; + + while (count--) { + *addr++ = (*(volatile u_int16_t *)(baddr)); + baddr += 2; + } +} + +void +rmi_bus_space_read_region_4(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int32_t *addr, size_t count) +{ + bus_addr_t baddr = bsh + offset; + + while (count--) { + *addr++ = (*(volatile u_int32_t *)(baddr)); + baddr += 4; + } +} + + +void +rmi_bus_space_write_stream_1(void *t, bus_space_handle_t handle, + bus_size_t offset, u_int8_t value) +{ + mips_sync(); + *(volatile u_int8_t *)(handle + offset) = value; +} + + +static void +rmi_bus_space_write_stream_2(void *t, bus_space_handle_t handle, + bus_size_t offset, u_int16_t value) +{ + mips_sync(); + *(volatile u_int16_t *)(handle + offset) = value; +} + + +static void +rmi_bus_space_write_stream_4(void *t, bus_space_handle_t handle, + bus_size_t offset, u_int32_t value) +{ + mips_sync(); + *(volatile u_int32_t *)(handle + offset) = value; +} + + +static void +rmi_bus_space_write_multi_stream_1(void *tag, bus_space_handle_t handle, + bus_size_t offset, const u_int8_t *addr, size_t count) +{ + mips_sync(); + if ((int)tag != MIPS_BUS_SPACE_PCI) + return; + while (count--) { + (*(volatile u_int8_t *)(handle + offset)) = *addr; + addr++; + } +} + +static void +rmi_bus_space_write_multi_stream_2(void *tag, bus_space_handle_t handle, + bus_size_t offset, const u_int16_t *addr, size_t count) +{ + mips_sync(); + if ((int)tag != MIPS_BUS_SPACE_PCI) + return; + while (count--) { + (*(volatile u_int16_t *)(handle + offset)) = *addr; + addr++; + } +} + +static void +rmi_bus_space_write_multi_stream_4(void *tag, bus_space_handle_t handle, + bus_size_t offset, const u_int32_t *addr, size_t count) +{ + mips_sync(); + if ((int)tag != MIPS_BUS_SPACE_PCI) + return; + while (count--) { + (*(volatile u_int32_t *)(handle + offset)) = *addr; + addr++; + } +} + +void +rmi_bus_space_write_region_2(void *t, + bus_space_handle_t bsh, + bus_size_t offset, + const u_int16_t *addr, + size_t count) +{ + bus_addr_t baddr = (bus_addr_t)bsh + offset; + while (count--) { + (*(volatile u_int16_t *)(baddr)) = *addr; + addr++; + baddr += 2; + } +} + +void +rmi_bus_space_write_region_4(void *t, bus_space_handle_t bsh, + bus_size_t offset, const u_int32_t *addr, size_t count) +{ + bus_addr_t baddr = bsh + offset; + + while (count--) { + (*(volatile u_int32_t *)(baddr)) = *addr; + addr++; + baddr += 4; + } +} + +static void +rmi_bus_space_barrier(void *tag __unused, bus_space_handle_t bsh __unused, + bus_size_t offset __unused, bus_size_t len __unused, int flags) +{ + +} diff --git a/sys/mips/rmi/clock.c b/sys/mips/rmi/clock.c index 93c2fa1cae0..095eb644566 100644 --- a/sys/mips/rmi/clock.c +++ b/sys/mips/rmi/clock.c @@ -162,6 +162,24 @@ pic_timecounthandler(struct trapframe *tf) return (FILTER_HANDLED); } +void +rmi_early_counter_init() +{ + int cpu = PCPU_GET(cpuid); + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + + /* We do this to get the PIC time counter running right + * after system start. Otherwise the DELAY() function will + * not be able to work since it won't have a TC to read. + */ + xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_0, (0xffffffff & 0xffffffff)); + xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_1, (0xffffffff & 0xffffffff)); + xlr_write_reg(mmio, PIC_IRT_0_TIMER_6, (1 << cpu)); + xlr_write_reg(mmio, PIC_IRT_1_TIMER_6, (1 << 31) | (0 << 30) | (1 << 6) | (PIC_TIMER_6_IRQ)); + pic_update_control(1 << (8 + 6)); +} + + void platform_initclocks(void) { @@ -204,7 +222,8 @@ platform_initclocks(void) /* Setup PIC Interrupt */ - mtx_lock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) + mtx_lock_spin(&xlr_pic_lock); xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_0, (maxval & 0xffffffff)); /* 0x100 + 7 */ xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_1, (maxval >> 32) & 0xffffffff); /* 0x110 + 7 */ /* 0x40 + 8 */ @@ -221,7 +240,8 @@ platform_initclocks(void) xlr_write_reg(mmio, PIC_IRT_0_TIMER_6, (1 << cpu)); xlr_write_reg(mmio, PIC_IRT_1_TIMER_6, (1 << 31) | (0 << 30) | (1 << 6) | (PIC_TIMER_6_IRQ)); pic_update_control(1 << (8 + 6)); - mtx_unlock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) + mtx_unlock_spin(&xlr_pic_lock); } else { /* Setup count-compare interrupt for vcpu[1-31] */ mips_wr_compare((xlr_boot1_info.cpu_frequency) / hz); diff --git a/sys/mips/rmi/clock.h b/sys/mips/rmi/clock.h index a5d67a6011d..0d3bc5d457c 100644 --- a/sys/mips/rmi/clock.h +++ b/sys/mips/rmi/clock.h @@ -36,5 +36,5 @@ void count_compare_clockhandler(struct trapframe *); void pic_hardclockhandler(struct trapframe *); int pic_timecounthandler(struct trapframe *); - +void rmi_early_counter_init(void); #endif /* _RMI_CLOCK_H_ */ diff --git a/sys/mips/rmi/files.xlr b/sys/mips/rmi/files.xlr index 4cdd361c87f..5814409d3d6 100644 --- a/sys/mips/rmi/files.xlr +++ b/sys/mips/rmi/files.xlr @@ -18,6 +18,7 @@ mips/rmi/pcibus.c optional pci mips/rmi/xlr_pci.c optional pci #mips/rmi/xls_ehci.c optional usb ehci dev/rmi/xlr/rge.c optional rge +mips/rmi/bus_space_rmi.c standard dev/iicbus/xlr_rtc.c optional xlr_rtc dev/iicbus/xlr_temperature.c optional xlr_temperature dev/iicbus/xlr_eeprom.c optional xlr_eeprom diff --git a/sys/mips/rmi/iodi.c b/sys/mips/rmi/iodi.c index 2dc2b2b6773..c00ce9bf962 100644 --- a/sys/mips/rmi/iodi.c +++ b/sys/mips/rmi/iodi.c @@ -99,6 +99,7 @@ static void pic_usb_ack(void *arg) } */ + static int iodi_setup_intr(device_t dev, device_t child, struct resource *ires, int flags, driver_filter_t * filt, driver_intr_t * intr, void *arg, @@ -111,11 +112,13 @@ iodi_setup_intr(device_t dev, device_t child, /* FIXME is this the right place to fiddle with PIC? */ if (strcmp(device_get_name(child), "uart") == 0) { /* FIXME uart 1? */ - mtx_lock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) + mtx_lock_spin(&xlr_pic_lock); level = PIC_IRQ_IS_EDGE_TRIGGERED(PIC_IRT_UART_0_INDEX); xlr_write_reg(mmio, PIC_IRT_0_UART_0, 0x01); xlr_write_reg(mmio, PIC_IRT_1_UART_0, ((1 << 31) | (level << 30) | (1 << 6) | (PIC_UART_0_IRQ))); - mtx_unlock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) + mtx_unlock_spin(&xlr_pic_lock); cpu_establish_hardintr("uart", NULL, (driver_intr_t *) intr, (void *)arg, PIC_UART_0_IRQ, flags, cookiep); @@ -123,16 +126,20 @@ iodi_setup_intr(device_t dev, device_t child, int irq; irq = rman_get_rid(ires); - mtx_lock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) + mtx_lock_spin(&xlr_pic_lock); reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE); xlr_write_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE, reg | (1 << 6) | (1 << 30) | (1 << 31)); - mtx_unlock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) + mtx_unlock_spin(&xlr_pic_lock); cpu_establish_hardintr("rge", NULL, (driver_intr_t *) intr, (void *)arg, irq, flags, cookiep); } else if (strcmp(device_get_name(child), "ehci") == 0) { + if (rmi_spin_mutex_safe) mtx_lock_spin(&xlr_pic_lock); reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + PIC_USB_IRQ - PIC_IRQ_BASE); xlr_write_reg(mmio, PIC_IRT_1_BASE + PIC_USB_IRQ - PIC_IRQ_BASE, reg | (1 << 6) | (1 << 30) | (1 << 31)); + if (rmi_spin_mutex_safe) mtx_unlock_spin(&xlr_pic_lock); cpu_establish_hardintr("ehci", NULL, (driver_intr_t *) intr, (void *)arg, PIC_USB_IRQ, flags, cookiep); } diff --git a/sys/mips/rmi/iomap.h b/sys/mips/rmi/iomap.h index 1d1e8ee814e..afc52bf712f 100644 --- a/sys/mips/rmi/iomap.h +++ b/sys/mips/rmi/iomap.h @@ -31,7 +31,7 @@ #define _RMI_IOMAP_H_ #include - +#define XLR_DEVICE_REGISTER_BASE 0x1EF00000 #define DEFAULT_XLR_IO_BASE 0xffffffffbef00000ULL #define XLR_IO_SIZE 0x1000 @@ -65,6 +65,9 @@ #define XLR_IO_UART_0_OFFSET 0x14000 #define XLR_IO_UART_1_OFFSET 0x15000 +#define XLR_UART0ADDR (XLR_IO_UART_0_OFFSET+XLR_DEVICE_REGISTER_BASE) + + #define XLR_IO_I2C_0_OFFSET 0x16000 #define XLR_IO_I2C_1_OFFSET 0x17000 diff --git a/sys/mips/rmi/msgring.h b/sys/mips/rmi/msgring.h index c841413a87d..43be63899f8 100755 --- a/sys/mips/rmi/msgring.h +++ b/sys/mips/rmi/msgring.h @@ -469,14 +469,15 @@ extern struct stn_cc xls_cc_table_pcie; extern struct stn_cc xls_cc_table_dma; extern struct stn_cc xls_cc_table_sec; + #define msgrng_access_save(lock, mflags) do { \ - mtx_lock_spin(lock); \ + if (rmi_spin_mutex_safe) mtx_lock_spin(lock); \ msgrng_flags_save(mflags); \ }while(0) #define msgrng_access_restore(lock, mflags) do { \ msgrng_flags_restore(mflags); \ - mtx_unlock_spin(lock); \ + if (rmi_spin_mutex_safe) mtx_unlock_spin(lock); \ }while(0) #define msgrng_access_enable(mflags) do { \ diff --git a/sys/mips/rmi/on_chip.c b/sys/mips/rmi/on_chip.c index 79f30fb9fff..c0c73c4de43 100644 --- a/sys/mips/rmi/on_chip.c +++ b/sys/mips/rmi/on_chip.c @@ -262,10 +262,12 @@ register_msgring_handler(int major, //dbg_msg("major=%d, action=%p, dev_id=%p\n", major, action, dev_id); - mtx_lock_spin(&msgrng_lock); + if (rmi_spin_mutex_safe) + mtx_lock_spin(&msgrng_lock); tx_stn_handlers[major].action = action; tx_stn_handlers[major].dev_id = dev_id; - mtx_unlock_spin(&msgrng_lock); + if (rmi_spin_mutex_safe) + mtx_unlock_spin(&msgrng_lock); if (xlr_test_and_set(&msgring_int_enabled)) { platform_prep_smp_launch(); @@ -301,6 +303,7 @@ pic_init(void) */ xlr_write_reg(mmio, PIC_IRT_1_BASE + i, (level << 30) | (1 << 6) | (PIC_IRQ_BASE + i)); } + dbg_msg("PIC init now done\n"); } void diff --git a/sys/mips/rmi/pcibus.c b/sys/mips/rmi/pcibus.c index 8a22c07b405..ac664d3b407 100644 --- a/sys/mips/rmi/pcibus.c +++ b/sys/mips/rmi/pcibus.c @@ -148,7 +148,6 @@ static void pic_pcie_ack(void *arg) */ - int mips_platform_pci_setup_intr(device_t dev, device_t child, struct resource *irq, int flags, @@ -174,21 +173,22 @@ mips_platform_pci_setup_intr(device_t dev, device_t child, return 0; if (xlr_board_info.is_xls == 0) { - mtx_lock_spin(&xlr_pic_lock); + + if (rmi_spin_mutex_safe) mtx_lock_spin(&xlr_pic_lock); level = PIC_IRQ_IS_EDGE_TRIGGERED(PIC_IRT_PCIX_INDEX); xlr_write_reg(mmio, PIC_IRT_0_PCIX, 0x01); xlr_write_reg(mmio, PIC_IRT_1_PCIX, ((1 << 31) | (level << 30) | (1 << 6) | (PIC_PCIX_IRQ))); - mtx_unlock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) mtx_unlock_spin(&xlr_pic_lock); cpu_establish_hardintr(device_get_name(child), filt, (driver_intr_t *) intr, (void *)arg, PIC_PCIX_IRQ, flags, cookiep); } else { - mtx_lock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) mtx_lock_spin(&xlr_pic_lock); xlr_write_reg(mmio, PIC_IRT_0_BASE + xlrirq - PIC_IRQ_BASE, 0x01); xlr_write_reg(mmio, PIC_IRT_1_BASE + xlrirq - PIC_IRQ_BASE, ((1 << 31) | (1 << 30) | (1 << 6) | xlrirq)); - mtx_unlock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) mtx_unlock_spin(&xlr_pic_lock); if (flags & INTR_FAST) cpu_establish_hardintr(device_get_name(child), filt, diff --git a/sys/mips/rmi/pic.h b/sys/mips/rmi/pic.h index 7cdf9052f7a..1a177246ab6 100644 --- a/sys/mips/rmi/pic.h +++ b/sys/mips/rmi/pic.h @@ -30,6 +30,7 @@ #ifndef _RMI_PIC_H_ #define _RMI_PIC_H_ +extern int rmi_spin_mutex_safe; #include #include @@ -206,9 +207,11 @@ pic_read_control(void) xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); __uint32_t reg; - mtx_lock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) + mtx_lock_spin(&xlr_pic_lock); xlr_read_reg(mmio, PIC_CTRL); - mtx_unlock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) + mtx_unlock_spin(&xlr_pic_lock); return reg; } @@ -217,18 +220,22 @@ pic_write_control(__uint32_t control) { xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); - mtx_lock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) + mtx_lock_spin(&xlr_pic_lock); xlr_write_reg(mmio, PIC_CTRL, control); - mtx_unlock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) + mtx_unlock_spin(&xlr_pic_lock); } static __inline__ void pic_update_control(__uint32_t control) { xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); - mtx_lock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) + mtx_lock_spin(&xlr_pic_lock); xlr_write_reg(mmio, PIC_CTRL, (control | xlr_read_reg(mmio, PIC_CTRL))); - mtx_unlock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) + mtx_unlock_spin(&xlr_pic_lock); } static __inline__ void @@ -241,8 +248,10 @@ pic_ack(int irq) return; if (PIC_IRQ_IS_EDGE_TRIGGERED(irq)) { + if (rmi_spin_mutex_safe) mtx_lock_spin(&xlr_pic_lock); - xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE))); + xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE))); + if (rmi_spin_mutex_safe) mtx_unlock_spin(&xlr_pic_lock); return; } @@ -258,9 +267,11 @@ pic_delayed_ack(int irq) return; if (!PIC_IRQ_IS_EDGE_TRIGGERED(irq)) { - mtx_lock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) + mtx_lock_spin(&xlr_pic_lock); xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE))); - mtx_unlock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) + mtx_unlock_spin(&xlr_pic_lock); return; } } diff --git a/sys/mips/rmi/uart_bus_xlr_iodi.c b/sys/mips/rmi/uart_bus_xlr_iodi.c index 110029835ff..33f918a3e7a 100644 --- a/sys/mips/rmi/uart_bus_xlr_iodi.c +++ b/sys/mips/rmi/uart_bus_xlr_iodi.c @@ -38,9 +38,10 @@ __FBSDID("$FreeBSD: src/sys/dev/uart/uart_bus_iodi.c,v 1.6.2.5 2006/02/15 09:16: #include #include #include - +#include #include #include +#include static int uart_iodi_probe(device_t dev); @@ -58,14 +59,20 @@ static driver_t uart_iodi_driver = { sizeof(struct uart_softc), }; + +extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; static int uart_iodi_probe(device_t dev) { struct uart_softc *sc; - sc = device_get_softc(dev); + sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); sc->sc_class = &uart_ns8250_class; - + bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); + sc->sc_sysdev->bas.bst = rmi_bus_space; + sc->sc_sysdev->bas.bsh = MIPS_PHYS_TO_KSEG1(XLR_UART0ADDR); + sc->sc_bas.bst = rmi_bus_space; + sc->sc_bas.bsh = MIPS_PHYS_TO_KSEG1(XLR_UART0ADDR); /* regshft = 2, rclk = 66000000, rid = 0, chan = 0 */ return (uart_bus_probe(dev, 2, 66000000, 0, 0)); } diff --git a/sys/mips/rmi/uart_cpu_mips_xlr.c b/sys/mips/rmi/uart_cpu_mips_xlr.c index 221f4115390..816dec2a260 100644 --- a/sys/mips/rmi/uart_cpu_mips_xlr.c +++ b/sys/mips/rmi/uart_cpu_mips_xlr.c @@ -50,102 +50,11 @@ __FBSDID("$FreeBSD$"); #include #include #include - -static int xlr_uart_probe(struct uart_bas *bas); -static void xlr_uart_init(struct uart_bas *bas, int, int, int, int); -static void xlr_uart_term(struct uart_bas *bas); -static void xlr_uart_putc(struct uart_bas *bas, int); - -/*static int xlr_uart_poll(struct uart_bas *bas);*/ -static int xlr_uart_getc(struct uart_bas *bas, struct mtx *hwmtx); -struct mtx xlr_uart_mtx; /* UartLock */ - -extern struct uart_ops uart_ns8250_ops; - -struct uart_ops xlr_uart_ns8250_ops = { - .probe = xlr_uart_probe, - .init = xlr_uart_init, - .term = xlr_uart_term, - .putc = xlr_uart_putc, - /* .poll = xlr_uart_poll, ?? */ - .getc = xlr_uart_getc, -}; +#include bus_space_tag_t uart_bus_space_io; bus_space_tag_t uart_bus_space_mem; -static __inline void -xlr_uart_lock(struct mtx *hwmtx) -{ - if (!mtx_initialized(hwmtx)) - return; - if (!kdb_active && hwmtx != NULL) - mtx_lock_spin(hwmtx); -} - -static __inline void -xlr_uart_unlock(struct mtx *hwmtx) -{ - if (!mtx_initialized(hwmtx)) - return; - if (!kdb_active && hwmtx != NULL) - mtx_unlock_spin(hwmtx); -} - - -static int -xlr_uart_probe(struct uart_bas *bas) -{ - int res; - - xlr_uart_lock(&xlr_uart_mtx); - res = uart_ns8250_ops.probe(bas); - xlr_uart_unlock(&xlr_uart_mtx); - return res; -} - -static void -xlr_uart_init(struct uart_bas *bas, int baudrate, int databits, - int stopbits, int parity) -{ - xlr_uart_lock(&xlr_uart_mtx); - uart_ns8250_ops.init(bas, baudrate, databits, stopbits, parity); - xlr_uart_unlock(&xlr_uart_mtx); -} - -static void -xlr_uart_term(struct uart_bas *bas) -{ - xlr_uart_lock(&xlr_uart_mtx); - uart_ns8250_ops.term(bas); - xlr_uart_unlock(&xlr_uart_mtx); -} - -static void -xlr_uart_putc(struct uart_bas *bas, int c) -{ - xlr_uart_lock(&xlr_uart_mtx); - uart_ns8250_ops.putc(bas, c); - xlr_uart_unlock(&xlr_uart_mtx); -} - -/* -static int xlr_uart_poll(struct uart_bas *bas) -{ - int res; - xlr_uart_lock(&xlr_uart_mtx); - res = uart_ns8250_ops.poll(bas); - xlr_uart_unlock(&xlr_uart_mtx); - return res; -} -*/ - -static int -xlr_uart_getc(struct uart_bas *bas, struct mtx *hwmtx) -{ - return uart_ns8250_ops.getc(bas, hwmtx); -} - int uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) { @@ -156,29 +65,20 @@ uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) int uart_cpu_getdev(int devtype, struct uart_devinfo *di) { - di->ops = &xlr_uart_ns8250_ops; + di->ops = uart_getops(&uart_ns8250_class); di->bas.chan = 0; - di->bas.bst = uart_bus_space_mem; - /* TODO Need to call bus_space_map() here */ - di->bas.bsh = 0xbef14000; /* Try with UART0 */ + di->bas.bst = rmi_bus_space; + di->bas.bsh = MIPS_PHYS_TO_KSEG1(XLR_UART0ADDR); + di->bas.regshft = 2; /* divisor = rclk / (baudrate * 16); */ di->bas.rclk = 66000000; - - di->baudrate = 38400; + di->baudrate = 0; di->databits = 8; di->stopbits = 1; di->parity = UART_PARITY_NONE; - /* TODO: Read env variables for all console parameters */ - + uart_bus_space_io = NULL; + uart_bus_space_mem = rmi_bus_space; return (0); } - -static void -xlr_uart_mtx_init(void *dummy __unused) -{ - mtx_init(&xlr_uart_mtx, "uart lock", NULL, MTX_SPIN); -} - -SYSINIT(xlr_init_uart_mtx, SI_SUB_LOCK, SI_ORDER_ANY, xlr_uart_mtx_init, NULL); diff --git a/sys/mips/rmi/xlr_machdep.c b/sys/mips/rmi/xlr_machdep.c index c4dd4c891e5..5db3b6a1e2f 100644 --- a/sys/mips/rmi/xlr_machdep.c +++ b/sys/mips/rmi/xlr_machdep.c @@ -24,8 +24,10 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD$ */ +#include +__FBSDID("$FreeBSD$"); + #include #include #include @@ -92,7 +94,7 @@ unsigned long xlr_io_base = (unsigned long)(DEFAULT_XLR_IO_BASE); the dynamic kenv is setup */ char boot1_env[4096]; extern unsigned long _gp; - +int rmi_spin_mutex_safe=0; /* * Parameters from boot loader */ @@ -366,8 +368,48 @@ mips_init(void) #endif } -void tick_init(void); +void (*xlr_putchar)(char)=NULL; +static void +xlr_putc_init(void) +{ + uint32_t addr; + addr = (uint32_t)(xlr_boot1_info.uart_putchar & 0x00000000ffffffff); + xlr_putchar = (void (*)(char))(addr); +} + +void xlr_putc(char); +void xlr_print_int(uint32_t val); + +void +xlr_putc(char c) +{ + (*xlr_putchar)(c); + DELAY(1000); +} + +void +xlr_print_int(uint32_t val) +{ + int i; + int idx; + char ary[16] = { + '0', '1', '2', '3', + '4', '5', '6', '7', + '8', '9', 'a', 'b', + 'c', 'd', 'e', 'f' + }; + xlr_putc('0'); + xlr_putc('x'); + for(i=7;i>=0;i--) { + idx = (val >> (i*4)) & 0x0000000f; + xlr_putc(ary[idx]); + } + xlr_putc(' '); + xlr_putc(015); + xlr_putc(012); +} +void tick_init(void); void platform_start(__register_t a0 __unused, __register_t a1 __unused, @@ -377,7 +419,6 @@ platform_start(__register_t a0 __unused, vm_size_t physsz = 0; int i, j; struct xlr_boot1_mem_map *boot_map; - #ifdef SMP uint32_t tmp; void (*wakeup) (void *, void *, unsigned int); @@ -411,10 +452,14 @@ platform_start(__register_t a0 __unused, * xlr_boot1_info.cpu_frequency here. */ mips_timer_early_init(platform_get_frequency()); - mips_timer_init_params(platform_get_frequency(), 0); + + /* Init the time counter in the PIC and local putc routine*/ + xlr_putc_init(); + rmi_early_counter_init(); + + /* Init console please */ cninit(); init_static_kenv(boot1_env, sizeof(boot1_env)); - printf("Environment (from %d args):\n", xlr_argc - 1); if (xlr_argc == 1) printf("\tNone\n"); @@ -538,7 +583,12 @@ platform_start(__register_t a0 __unused, * mips_init() XXX NOTE: We may need to move this to SMP based init * code for each CPU, later. */ + printf("Here\n"); + rmi_spin_mutex_safe = 1; on_chip_init(); + printf("there\n"); + mips_timer_init_params(platform_get_frequency(), 0); + printf("ok\n"); tick_init(); } From a856badbb29b642e104dc0b7d52813b8abc8bef9 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Thu, 5 Nov 2009 18:15:16 +0000 Subject: [PATCH 309/380] white space changes --- sys/mips/rmi/bus_space_rmi.c | 403 +++++++++++++++++++---------------- 1 file changed, 220 insertions(+), 183 deletions(-) diff --git a/sys/mips/rmi/bus_space_rmi.c b/sys/mips/rmi/bus_space_rmi.c index 83146d80c7c..b0438a86505 100644 --- a/sys/mips/rmi/bus_space_rmi.c +++ b/sys/mips/rmi/bus_space_rmi.c @@ -45,174 +45,210 @@ __FBSDID("$FreeBSD$"); void xlr_putc(char); void xlr_print_int(uint32_t); -static int rmi_bus_space_map(void *t, bus_addr_t addr, - bus_size_t size, int flags, - bus_space_handle_t *bshp); +static int +rmi_bus_space_map(void *t, bus_addr_t addr, + bus_size_t size, int flags, + bus_space_handle_t * bshp); -static void rmi_bus_space_unmap(void *t, bus_space_handle_t bsh, - bus_size_t size); +static void +rmi_bus_space_unmap(void *t, bus_space_handle_t bsh, + bus_size_t size); -static int rmi_bus_space_subregion(void *t, - bus_space_handle_t bsh, - bus_size_t offset, bus_size_t size, - bus_space_handle_t *nbshp); +static int +rmi_bus_space_subregion(void *t, + bus_space_handle_t bsh, + bus_size_t offset, bus_size_t size, + bus_space_handle_t * nbshp); -static u_int8_t rmi_bus_space_read_1(void *t, - bus_space_handle_t handle, - bus_size_t offset); +static u_int8_t +rmi_bus_space_read_1(void *t, + bus_space_handle_t handle, + bus_size_t offset); -static u_int16_t rmi_bus_space_read_2(void *t, - bus_space_handle_t handle, - bus_size_t offset); +static u_int16_t +rmi_bus_space_read_2(void *t, + bus_space_handle_t handle, + bus_size_t offset); -static u_int32_t rmi_bus_space_read_4(void *t, - bus_space_handle_t handle, - bus_size_t offset); +static u_int32_t +rmi_bus_space_read_4(void *t, + bus_space_handle_t handle, + bus_size_t offset); -static void rmi_bus_space_read_multi_1(void *t, - bus_space_handle_t handle, - bus_size_t offset, u_int8_t *addr, - size_t count); +static void +rmi_bus_space_read_multi_1(void *t, + bus_space_handle_t handle, + bus_size_t offset, u_int8_t * addr, + size_t count); -static void rmi_bus_space_read_multi_2(void *t, - bus_space_handle_t handle, - bus_size_t offset, u_int16_t *addr, - size_t count); +static void +rmi_bus_space_read_multi_2(void *t, + bus_space_handle_t handle, + bus_size_t offset, u_int16_t * addr, + size_t count); -static void rmi_bus_space_read_multi_4(void *t, - bus_space_handle_t handle, - bus_size_t offset, u_int32_t *addr, - size_t count); +static void +rmi_bus_space_read_multi_4(void *t, + bus_space_handle_t handle, + bus_size_t offset, u_int32_t * addr, + size_t count); -static void rmi_bus_space_read_region_1(void *t, - bus_space_handle_t bsh, - bus_size_t offset, u_int8_t *addr, - size_t count); +static void +rmi_bus_space_read_region_1(void *t, + bus_space_handle_t bsh, + bus_size_t offset, u_int8_t * addr, + size_t count); -static void rmi_bus_space_read_region_2(void *t, - bus_space_handle_t bsh, - bus_size_t offset, u_int16_t *addr, - size_t count); +static void +rmi_bus_space_read_region_2(void *t, + bus_space_handle_t bsh, + bus_size_t offset, u_int16_t * addr, + size_t count); -static void rmi_bus_space_read_region_4(void *t, - bus_space_handle_t bsh, - bus_size_t offset, u_int32_t *addr, - size_t count); +static void +rmi_bus_space_read_region_4(void *t, + bus_space_handle_t bsh, + bus_size_t offset, u_int32_t * addr, + size_t count); -static void rmi_bus_space_write_1(void *t, - bus_space_handle_t handle, - bus_size_t offset, u_int8_t value); +static void +rmi_bus_space_write_1(void *t, + bus_space_handle_t handle, + bus_size_t offset, u_int8_t value); -static void rmi_bus_space_write_2(void *t, - bus_space_handle_t handle, - bus_size_t offset, u_int16_t value); +static void +rmi_bus_space_write_2(void *t, + bus_space_handle_t handle, + bus_size_t offset, u_int16_t value); -static void rmi_bus_space_write_4(void *t, - bus_space_handle_t handle, - bus_size_t offset, u_int32_t value); +static void +rmi_bus_space_write_4(void *t, + bus_space_handle_t handle, + bus_size_t offset, u_int32_t value); -static void rmi_bus_space_write_multi_1(void *t, - bus_space_handle_t handle, - bus_size_t offset, - const u_int8_t *addr, - size_t count); -static void rmi_bus_space_write_multi_2(void *t, - bus_space_handle_t handle, - bus_size_t offset, - const u_int16_t *addr, - size_t count); +static void +rmi_bus_space_write_multi_1(void *t, + bus_space_handle_t handle, + bus_size_t offset, + const u_int8_t * addr, + size_t count); +static void +rmi_bus_space_write_multi_2(void *t, + bus_space_handle_t handle, + bus_size_t offset, + const u_int16_t * addr, + size_t count); -static void rmi_bus_space_write_multi_4(void *t, - bus_space_handle_t handle, - bus_size_t offset, - const u_int32_t *addr, - size_t count); +static void +rmi_bus_space_write_multi_4(void *t, + bus_space_handle_t handle, + bus_size_t offset, + const u_int32_t * addr, + size_t count); -static void rmi_bus_space_write_region_2(void *t, - bus_space_handle_t bsh, - bus_size_t offset, - const u_int16_t *addr, - size_t count); +static void +rmi_bus_space_write_region_2(void *t, + bus_space_handle_t bsh, + bus_size_t offset, + const u_int16_t * addr, + size_t count); -static void rmi_bus_space_write_region_4(void *t, - bus_space_handle_t bsh, - bus_size_t offset, - const u_int32_t *addr, - size_t count); +static void +rmi_bus_space_write_region_4(void *t, + bus_space_handle_t bsh, + bus_size_t offset, + const u_int32_t * addr, + size_t count); -static void rmi_bus_space_set_region_2(void *t, - bus_space_handle_t bsh, - bus_size_t offset, u_int16_t value, - size_t count); -static void rmi_bus_space_set_region_4(void *t, - bus_space_handle_t bsh, - bus_size_t offset, u_int32_t value, - size_t count); +static void +rmi_bus_space_set_region_2(void *t, + bus_space_handle_t bsh, + bus_size_t offset, u_int16_t value, + size_t count); +static void +rmi_bus_space_set_region_4(void *t, + bus_space_handle_t bsh, + bus_size_t offset, u_int32_t value, + size_t count); -static void rmi_bus_space_barrier(void *tag __unused, bus_space_handle_t bsh __unused, - bus_size_t offset __unused, bus_size_t len __unused, int flags); +static void +rmi_bus_space_barrier(void *tag __unused, bus_space_handle_t bsh __unused, + bus_size_t offset __unused, bus_size_t len __unused, int flags); -static void rmi_bus_space_copy_region_2(void *t, - bus_space_handle_t bsh1, - bus_size_t off1, - bus_space_handle_t bsh2, - bus_size_t off2, size_t count); +static void +rmi_bus_space_copy_region_2(void *t, + bus_space_handle_t bsh1, + bus_size_t off1, + bus_space_handle_t bsh2, + bus_size_t off2, size_t count); -u_int8_t rmi_bus_space_read_stream_1(void *t, bus_space_handle_t handle, - bus_size_t offset); +u_int8_t +rmi_bus_space_read_stream_1(void *t, bus_space_handle_t handle, + bus_size_t offset); -static u_int16_t rmi_bus_space_read_stream_2(void *t, bus_space_handle_t handle, - bus_size_t offset); +static u_int16_t +rmi_bus_space_read_stream_2(void *t, bus_space_handle_t handle, + bus_size_t offset); -static u_int32_t rmi_bus_space_read_stream_4(void *t, bus_space_handle_t handle, - bus_size_t offset); -static void rmi_bus_space_read_multi_stream_1(void *t, - bus_space_handle_t handle, - bus_size_t offset, u_int8_t *addr, - size_t count); +static u_int32_t +rmi_bus_space_read_stream_4(void *t, bus_space_handle_t handle, + bus_size_t offset); +static void +rmi_bus_space_read_multi_stream_1(void *t, + bus_space_handle_t handle, + bus_size_t offset, u_int8_t * addr, + size_t count); -static void rmi_bus_space_read_multi_stream_2(void *t, - bus_space_handle_t handle, - bus_size_t offset, u_int16_t *addr, - size_t count); +static void +rmi_bus_space_read_multi_stream_2(void *t, + bus_space_handle_t handle, + bus_size_t offset, u_int16_t * addr, + size_t count); -static void rmi_bus_space_read_multi_stream_4(void *t, - bus_space_handle_t handle, - bus_size_t offset, u_int32_t *addr, - size_t count); +static void +rmi_bus_space_read_multi_stream_4(void *t, + bus_space_handle_t handle, + bus_size_t offset, u_int32_t * addr, + size_t count); -void rmi_bus_space_write_stream_1(void *t, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t value); -static void rmi_bus_space_write_stream_2(void *t, bus_space_handle_t handle, - bus_size_t offset, u_int16_t value); +void +rmi_bus_space_write_stream_1(void *t, bus_space_handle_t bsh, + bus_size_t offset, u_int8_t value); +static void +rmi_bus_space_write_stream_2(void *t, bus_space_handle_t handle, + bus_size_t offset, u_int16_t value); -static void rmi_bus_space_write_stream_4(void *t, bus_space_handle_t handle, - bus_size_t offset, u_int32_t value); +static void +rmi_bus_space_write_stream_4(void *t, bus_space_handle_t handle, + bus_size_t offset, u_int32_t value); -static void rmi_bus_space_write_multi_stream_1(void *t, - bus_space_handle_t handle, - bus_size_t offset, - const u_int8_t *addr, - size_t count); -static void rmi_bus_space_write_multi_stream_2(void *t, - bus_space_handle_t handle, - bus_size_t offset, - const u_int16_t *addr, - size_t count); - -static void rmi_bus_space_write_multi_stream_4(void *t, - bus_space_handle_t handle, - bus_size_t offset, - const u_int32_t *addr, - size_t count); +static void +rmi_bus_space_write_multi_stream_1(void *t, + bus_space_handle_t handle, + bus_size_t offset, + const u_int8_t * addr, + size_t count); +static void +rmi_bus_space_write_multi_stream_2(void *t, + bus_space_handle_t handle, + bus_size_t offset, + const u_int16_t * addr, + size_t count); + +static void +rmi_bus_space_write_multi_stream_4(void *t, + bus_space_handle_t handle, + bus_size_t offset, + const u_int32_t * addr, + size_t count); static struct bus_space local_rmi_bus_space = { /* cookie */ - (void *) 0, + (void *)0, /* mapping/unmapping */ rmi_bus_space_map, @@ -224,7 +260,7 @@ static struct bus_space local_rmi_bus_space = { NULL, /* barrier */ - rmi_bus_space_barrier, + rmi_bus_space_barrier, /* read (single) */ rmi_bus_space_read_1, @@ -322,7 +358,7 @@ bus_space_tag_t rmi_bus_space = &local_rmi_bus_space; #define MIPS_BUS_SPACE_IO 0 /* space is i/o space */ #define MIPS_BUS_SPACE_MEM 1 /* space is mem space */ -#define MIPS_BUS_SPACE_PCI 10 /* avoid conflict with other spaces */ +#define MIPS_BUS_SPACE_PCI 10 /* avoid conflict with other spaces */ #define BUS_SPACE_UNRESTRICTED (~0) @@ -334,7 +370,7 @@ bus_space_tag_t rmi_bus_space = &local_rmi_bus_space; #define SWAP16(x)\ (((x) & 0xff00) >> 8) | \ - (((x) & 0x00ff) << 8) + (((x) & 0x00ff) << 8) /* * Map a region of device bus space into CPU virtual address space. @@ -343,8 +379,8 @@ bus_space_tag_t rmi_bus_space = &local_rmi_bus_space; static int rmi_bus_space_map(void *t __unused, bus_addr_t addr, - bus_size_t size __unused, int flags __unused, - bus_space_handle_t *bshp) + bus_size_t size __unused, int flags __unused, + bus_space_handle_t * bshp) { *bshp = addr; @@ -356,7 +392,7 @@ rmi_bus_space_map(void *t __unused, bus_addr_t addr, */ static void rmi_bus_space_unmap(void *t __unused, bus_space_handle_t bsh __unused, - bus_size_t size __unused) + bus_size_t size __unused) { } @@ -366,8 +402,8 @@ rmi_bus_space_unmap(void *t __unused, bus_space_handle_t bsh __unused, static int rmi_bus_space_subregion(void *t __unused, bus_space_handle_t bsh, - bus_size_t offset, bus_size_t size __unused, - bus_space_handle_t *nbshp) + bus_size_t offset, bus_size_t size __unused, + bus_space_handle_t * nbshp) { *nbshp = bsh + offset; return (0); @@ -380,31 +416,31 @@ rmi_bus_space_subregion(void *t __unused, bus_space_handle_t bsh, static u_int8_t rmi_bus_space_read_1(void *tag, bus_space_handle_t handle, - bus_size_t offset) + bus_size_t offset) { if ((int)tag == MIPS_BUS_SPACE_PCI) - return (u_int8_t)(*(volatile u_int8_t *)(handle + offset)); + return (u_int8_t) (*(volatile u_int8_t *)(handle + offset)); else - return (u_int8_t)(*(volatile u_int32_t *)(handle + offset)); + return (u_int8_t) (*(volatile u_int32_t *)(handle + offset)); } static u_int16_t rmi_bus_space_read_2(void *tag, bus_space_handle_t handle, - bus_size_t offset) + bus_size_t offset) { if ((int)tag == MIPS_BUS_SPACE_PCI) - return SWAP16((u_int16_t)(*(volatile u_int16_t *)(handle + offset))); + return SWAP16((u_int16_t) (*(volatile u_int16_t *)(handle + offset))); else return *(volatile u_int16_t *)(handle + offset); } static u_int32_t rmi_bus_space_read_4(void *tag, bus_space_handle_t handle, - bus_size_t offset) + bus_size_t offset) { if ((int)tag == MIPS_BUS_SPACE_PCI) return SWAP32((*(volatile u_int32_t *)(handle + offset))); - else + else return (*(volatile u_int32_t *)(handle + offset)); } @@ -416,7 +452,7 @@ rmi_bus_space_read_4(void *tag, bus_space_handle_t handle, */ static void rmi_bus_space_read_multi_1(void *tag, bus_space_handle_t handle, - bus_size_t offset, u_int8_t *addr, size_t count) + bus_size_t offset, u_int8_t * addr, size_t count) { if ((int)tag != MIPS_BUS_SPACE_PCI) @@ -429,7 +465,7 @@ rmi_bus_space_read_multi_1(void *tag, bus_space_handle_t handle, static void rmi_bus_space_read_multi_2(void *tag, bus_space_handle_t handle, - bus_size_t offset, u_int16_t *addr, size_t count) + bus_size_t offset, u_int16_t * addr, size_t count) { if ((int)tag != MIPS_BUS_SPACE_PCI) @@ -443,7 +479,7 @@ rmi_bus_space_read_multi_2(void *tag, bus_space_handle_t handle, static void rmi_bus_space_read_multi_4(void *tag, bus_space_handle_t handle, - bus_size_t offset, u_int32_t *addr, size_t count) + bus_size_t offset, u_int32_t * addr, size_t count) { if ((int)tag != MIPS_BUS_SPACE_PCI) @@ -463,18 +499,18 @@ rmi_bus_space_read_multi_4(void *tag, bus_space_handle_t handle, static void rmi_bus_space_write_1(void *tag, bus_space_handle_t handle, - bus_size_t offset, u_int8_t value) + bus_size_t offset, u_int8_t value) { mips_sync(); if ((int)tag == MIPS_BUS_SPACE_PCI) *(volatile u_int8_t *)(handle + offset) = value; else - *(volatile u_int32_t *)(handle + offset) = (u_int32_t)value; + *(volatile u_int32_t *)(handle + offset) = (u_int32_t) value; } static void rmi_bus_space_write_2(void *tag, bus_space_handle_t handle, - bus_size_t offset, u_int16_t value) + bus_size_t offset, u_int16_t value) { mips_sync(); if ((int)tag == MIPS_BUS_SPACE_PCI) { @@ -486,7 +522,7 @@ rmi_bus_space_write_2(void *tag, bus_space_handle_t handle, static void rmi_bus_space_write_4(void *tag, bus_space_handle_t handle, - bus_size_t offset, u_int32_t value) + bus_size_t offset, u_int32_t value) { mips_sync(); if ((int)tag == MIPS_BUS_SPACE_PCI) { @@ -505,7 +541,7 @@ rmi_bus_space_write_4(void *tag, bus_space_handle_t handle, static void rmi_bus_space_write_multi_1(void *tag, bus_space_handle_t handle, - bus_size_t offset, const u_int8_t *addr, size_t count) + bus_size_t offset, const u_int8_t * addr, size_t count) { mips_sync(); if ((int)tag != MIPS_BUS_SPACE_PCI) @@ -518,7 +554,7 @@ rmi_bus_space_write_multi_1(void *tag, bus_space_handle_t handle, static void rmi_bus_space_write_multi_2(void *tag, bus_space_handle_t handle, - bus_size_t offset, const u_int16_t *addr, size_t count) + bus_size_t offset, const u_int16_t * addr, size_t count) { mips_sync(); if ((int)tag != MIPS_BUS_SPACE_PCI) @@ -531,7 +567,7 @@ rmi_bus_space_write_multi_2(void *tag, bus_space_handle_t handle, static void rmi_bus_space_write_multi_4(void *tag, bus_space_handle_t handle, - bus_size_t offset, const u_int32_t *addr, size_t count) + bus_size_t offset, const u_int32_t * addr, size_t count) { mips_sync(); if ((int)tag != MIPS_BUS_SPACE_PCI) @@ -549,7 +585,7 @@ rmi_bus_space_write_multi_4(void *tag, bus_space_handle_t handle, static void rmi_bus_space_set_region_2(void *t, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t value, size_t count) + bus_size_t offset, u_int16_t value, size_t count) { bus_addr_t addr = bsh + offset; @@ -559,7 +595,7 @@ rmi_bus_space_set_region_2(void *t, bus_space_handle_t bsh, static void rmi_bus_space_set_region_4(void *t, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t value, size_t count) + bus_size_t offset, u_int32_t value, size_t count) { bus_addr_t addr = bsh + offset; @@ -574,8 +610,8 @@ rmi_bus_space_set_region_4(void *t, bus_space_handle_t bsh, */ static void rmi_bus_space_copy_region_2(void *t, bus_space_handle_t bsh1, - bus_size_t off1, bus_space_handle_t bsh2, - bus_size_t off2, size_t count) + bus_size_t off1, bus_space_handle_t bsh2, + bus_size_t off2, size_t count) { printf("bus_space_copy_region_2 - unimplemented\n"); } @@ -596,23 +632,23 @@ rmi_bus_space_read_stream_1(void *t, bus_space_handle_t handle, static u_int16_t rmi_bus_space_read_stream_2(void *t, bus_space_handle_t handle, - bus_size_t offset) + bus_size_t offset) { - return *(volatile u_int16_t *)(handle + offset); + return *(volatile u_int16_t *)(handle + offset); } static u_int32_t rmi_bus_space_read_stream_4(void *t, bus_space_handle_t handle, - bus_size_t offset) + bus_size_t offset) { - return (*(volatile u_int32_t *)(handle + offset)); + return (*(volatile u_int32_t *)(handle + offset)); } static void rmi_bus_space_read_multi_stream_1(void *tag, bus_space_handle_t handle, - bus_size_t offset, u_int8_t *addr, size_t count) + bus_size_t offset, u_int8_t * addr, size_t count) { if ((int)tag != MIPS_BUS_SPACE_PCI) @@ -625,7 +661,7 @@ rmi_bus_space_read_multi_stream_1(void *tag, bus_space_handle_t handle, static void rmi_bus_space_read_multi_stream_2(void *tag, bus_space_handle_t handle, - bus_size_t offset, u_int16_t *addr, size_t count) + bus_size_t offset, u_int16_t * addr, size_t count) { if ((int)tag != MIPS_BUS_SPACE_PCI) @@ -638,7 +674,7 @@ rmi_bus_space_read_multi_stream_2(void *tag, bus_space_handle_t handle, static void rmi_bus_space_read_multi_stream_4(void *tag, bus_space_handle_t handle, - bus_size_t offset, u_int32_t *addr, size_t count) + bus_size_t offset, u_int32_t * addr, size_t count) { if ((int)tag != MIPS_BUS_SPACE_PCI) @@ -658,7 +694,7 @@ rmi_bus_space_read_multi_stream_4(void *tag, bus_space_handle_t handle, */ void rmi_bus_space_read_region_1(void *t, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t *addr, size_t count) + bus_size_t offset, u_int8_t * addr, size_t count) { bus_addr_t baddr = bsh + offset; @@ -670,7 +706,7 @@ rmi_bus_space_read_region_1(void *t, bus_space_handle_t bsh, void rmi_bus_space_read_region_2(void *t, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t *addr, size_t count) + bus_size_t offset, u_int16_t * addr, size_t count) { bus_addr_t baddr = bsh + offset; @@ -682,7 +718,7 @@ rmi_bus_space_read_region_2(void *t, bus_space_handle_t bsh, void rmi_bus_space_read_region_4(void *t, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t *addr, size_t count) + bus_size_t offset, u_int32_t * addr, size_t count) { bus_addr_t baddr = bsh + offset; @@ -704,7 +740,7 @@ rmi_bus_space_write_stream_1(void *t, bus_space_handle_t handle, static void rmi_bus_space_write_stream_2(void *t, bus_space_handle_t handle, - bus_size_t offset, u_int16_t value) + bus_size_t offset, u_int16_t value) { mips_sync(); *(volatile u_int16_t *)(handle + offset) = value; @@ -713,7 +749,7 @@ rmi_bus_space_write_stream_2(void *t, bus_space_handle_t handle, static void rmi_bus_space_write_stream_4(void *t, bus_space_handle_t handle, - bus_size_t offset, u_int32_t value) + bus_size_t offset, u_int32_t value) { mips_sync(); *(volatile u_int32_t *)(handle + offset) = value; @@ -722,7 +758,7 @@ rmi_bus_space_write_stream_4(void *t, bus_space_handle_t handle, static void rmi_bus_space_write_multi_stream_1(void *tag, bus_space_handle_t handle, - bus_size_t offset, const u_int8_t *addr, size_t count) + bus_size_t offset, const u_int8_t * addr, size_t count) { mips_sync(); if ((int)tag != MIPS_BUS_SPACE_PCI) @@ -735,7 +771,7 @@ rmi_bus_space_write_multi_stream_1(void *tag, bus_space_handle_t handle, static void rmi_bus_space_write_multi_stream_2(void *tag, bus_space_handle_t handle, - bus_size_t offset, const u_int16_t *addr, size_t count) + bus_size_t offset, const u_int16_t * addr, size_t count) { mips_sync(); if ((int)tag != MIPS_BUS_SPACE_PCI) @@ -748,7 +784,7 @@ rmi_bus_space_write_multi_stream_2(void *tag, bus_space_handle_t handle, static void rmi_bus_space_write_multi_stream_4(void *tag, bus_space_handle_t handle, - bus_size_t offset, const u_int32_t *addr, size_t count) + bus_size_t offset, const u_int32_t * addr, size_t count) { mips_sync(); if ((int)tag != MIPS_BUS_SPACE_PCI) @@ -761,12 +797,13 @@ rmi_bus_space_write_multi_stream_4(void *tag, bus_space_handle_t handle, void rmi_bus_space_write_region_2(void *t, - bus_space_handle_t bsh, - bus_size_t offset, - const u_int16_t *addr, - size_t count) + bus_space_handle_t bsh, + bus_size_t offset, + const u_int16_t * addr, + size_t count) { - bus_addr_t baddr = (bus_addr_t)bsh + offset; + bus_addr_t baddr = (bus_addr_t) bsh + offset; + while (count--) { (*(volatile u_int16_t *)(baddr)) = *addr; addr++; @@ -776,7 +813,7 @@ rmi_bus_space_write_region_2(void *t, void rmi_bus_space_write_region_4(void *t, bus_space_handle_t bsh, - bus_size_t offset, const u_int32_t *addr, size_t count) + bus_size_t offset, const u_int32_t * addr, size_t count) { bus_addr_t baddr = bsh + offset; @@ -789,7 +826,7 @@ rmi_bus_space_write_region_4(void *t, bus_space_handle_t bsh, static void rmi_bus_space_barrier(void *tag __unused, bus_space_handle_t bsh __unused, - bus_size_t offset __unused, bus_size_t len __unused, int flags) + bus_size_t offset __unused, bus_size_t len __unused, int flags) { } From 798abe2fe19c187605f7a95986044d0182150346 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Thu, 5 Nov 2009 18:15:47 +0000 Subject: [PATCH 310/380] For XLR adds extern for its bus space routines --- sys/mips/include/bus.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sys/mips/include/bus.h b/sys/mips/include/bus.h index ecb50e5f6df..94f876e01fc 100644 --- a/sys/mips/include/bus.h +++ b/sys/mips/include/bus.h @@ -718,6 +718,11 @@ void __bs_c(f,_bs_c_8) (void *t, bus_space_handle_t bsh1, \ */ DECLARE_BUS_SPACE_PROTOTYPES(generic); extern bus_space_tag_t mips_bus_space_generic; +/* Special bus space for RMI processors */ +#ifdef TARGET_XLR_XLS +extern bus_space_tag_t rmi_bus_space; +#endif + #include #endif /* _MACHINE_BUS_H_ */ From 6450bdc708a152b50a988db2f96d6ff1deb484f4 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 6 Nov 2009 06:50:45 +0000 Subject: [PATCH 311/380] - Fix initialization of PLL registers (different shifts for arge0/arge1) - Use base MAC address to generate MACs for arge1 and above --- sys/mips/atheros/if_arge.c | 20 ++++++++++++-------- sys/mips/atheros/if_argevar.h | 1 + 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index b16a088c32c..95e0c12429d 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -205,9 +205,11 @@ arge_attach(device_t dev) if (sc->arge_mac_unit == 0) { sc->arge_ddr_flush_reg = AR71XX_WB_FLUSH_GE0; sc->arge_pll_reg = AR71XX_PLL_ETH_INT0_CLK; + sc->arge_pll_reg_shift = 17; } else { sc->arge_ddr_flush_reg = AR71XX_WB_FLUSH_GE1; sc->arge_pll_reg = AR71XX_PLL_ETH_INT1_CLK; + sc->arge_pll_reg_shift = 19; } /* @@ -229,7 +231,6 @@ arge_attach(device_t dev) sc->arge_phy_num = phynum; - mtx_init(&sc->arge_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF); callout_init_mtx(&sc->arge_stat_callout, &sc->arge_mtx, 0); @@ -308,6 +309,9 @@ arge_attach(device_t dev) eaddr[5] = (rnd >> 8) & 0xff; } + if (sc->arge_mac_unit != 0) + eaddr[5] += sc->arge_mac_unit; + if (arge_dma_alloc(sc) != 0) { error = ENXIO; goto fail; @@ -617,20 +621,20 @@ arge_link_task(void *arg, int pending) /* set PLL registers */ sec_cfg = ATH_READ_REG(AR71XX_PLL_CPU_CONFIG); - sec_cfg &= ~(3 << 17); - sec_cfg |= (2 << 17); + sec_cfg &= ~(3 << sc->arge_pll_reg_shift); + sec_cfg |= (2 << sc->arge_pll_reg_shift); - ATH_WRITE_REG(AR71XX_PLL_CPU_CONFIG, sec_cfg); + ATH_WRITE_REG(AR71XX_PLL_SEC_CONFIG, sec_cfg); DELAY(100); ATH_WRITE_REG(sc->arge_pll_reg, pll); - sec_cfg |= (3 << 17); - ATH_WRITE_REG(AR71XX_PLL_CPU_CONFIG, sec_cfg); + sec_cfg |= (3 << sc->arge_pll_reg_shift); + ATH_WRITE_REG(AR71XX_PLL_SEC_CONFIG, sec_cfg); DELAY(100); - sec_cfg &= ~(3 << 17); - ATH_WRITE_REG(AR71XX_PLL_CPU_CONFIG, sec_cfg); + sec_cfg &= ~(3 << sc->arge_pll_reg_shift); + ATH_WRITE_REG(AR71XX_PLL_SEC_CONFIG, sec_cfg); DELAY(100); } } else diff --git a/sys/mips/atheros/if_argevar.h b/sys/mips/atheros/if_argevar.h index 4e7e40dd87a..aec2cf46af3 100644 --- a/sys/mips/atheros/if_argevar.h +++ b/sys/mips/atheros/if_argevar.h @@ -133,6 +133,7 @@ struct arge_softc { int arge_phy_num; uint32_t arge_ddr_flush_reg; uint32_t arge_pll_reg; + uint32_t arge_pll_reg_shift; int arge_if_flags; }; From eac3c4cd278bccbbe1ba1fcca53c0fe49e28a57e Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Fri, 6 Nov 2009 12:52:51 +0000 Subject: [PATCH 312/380] Ok With this commit we actually get through the mi_startup (or to the last of it).. and hit a panic after : uart0: <16550 or compatible> on iodi0 Trap cause = 2 (TLB miss....) I did have to take the pci bus OUT of the build to get this far, hit a cache error with the PCI code in. Interesting thing is the machine reboots too ;-) --- sys/mips/conf/XLR | 1 + sys/mips/rmi/bus_space_rmi.c | 1 - sys/mips/rmi/clock.c | 2 ++ sys/mips/rmi/files.xlr | 4 +-- sys/mips/rmi/xlr_machdep.c | 49 +----------------------------------- 5 files changed, 6 insertions(+), 51 deletions(-) diff --git a/sys/mips/conf/XLR b/sys/mips/conf/XLR index ba37d7cb4e4..b88a6af03da 100644 --- a/sys/mips/conf/XLR +++ b/sys/mips/conf/XLR @@ -61,6 +61,7 @@ makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols #profile 2 #options SCHED_ULE # ULE scheduler +options VERBOSE_SYSINIT options SCHED_4BSD # 4BSD scheduler #options PREEMPTION # Enable kernel thread preemption #options FULL_PREEMPTION # Enable kernel thread preemption diff --git a/sys/mips/rmi/bus_space_rmi.c b/sys/mips/rmi/bus_space_rmi.c index b0438a86505..568eaca4ea3 100644 --- a/sys/mips/rmi/bus_space_rmi.c +++ b/sys/mips/rmi/bus_space_rmi.c @@ -42,7 +42,6 @@ __FBSDID("$FreeBSD$"); #include #include -void xlr_putc(char); void xlr_print_int(uint32_t); static int diff --git a/sys/mips/rmi/clock.c b/sys/mips/rmi/clock.c index 095eb644566..d32197318ad 100644 --- a/sys/mips/rmi/clock.c +++ b/sys/mips/rmi/clock.c @@ -179,6 +179,7 @@ rmi_early_counter_init() pic_update_control(1 << (8 + 6)); } +void tick_init(void); void platform_initclocks(void) @@ -246,6 +247,7 @@ platform_initclocks(void) /* Setup count-compare interrupt for vcpu[1-31] */ mips_wr_compare((xlr_boot1_info.cpu_frequency) / hz); } + tick_init(); } unsigned diff --git a/sys/mips/rmi/files.xlr b/sys/mips/rmi/files.xlr index 5814409d3d6..e2ed518b040 100644 --- a/sys/mips/rmi/files.xlr +++ b/sys/mips/rmi/files.xlr @@ -14,8 +14,8 @@ mips/rmi/uart_bus_xlr_iodi.c optional uart mips/rmi/uart_cpu_mips_xlr.c optional uart mips/rmi/perfmon_kern.c optional xlr_perfmon mips/rmi/perfmon_percpu.c optional xlr_perfmon -mips/rmi/pcibus.c optional pci -mips/rmi/xlr_pci.c optional pci +#mips/rmi/pcibus.c optional pci +#mips/rmi/xlr_pci.c optional pci #mips/rmi/xls_ehci.c optional usb ehci dev/rmi/xlr/rge.c optional rge mips/rmi/bus_space_rmi.c standard diff --git a/sys/mips/rmi/xlr_machdep.c b/sys/mips/rmi/xlr_machdep.c index 5db3b6a1e2f..0882f9f208a 100644 --- a/sys/mips/rmi/xlr_machdep.c +++ b/sys/mips/rmi/xlr_machdep.c @@ -368,48 +368,6 @@ mips_init(void) #endif } -void (*xlr_putchar)(char)=NULL; - -static void -xlr_putc_init(void) -{ - uint32_t addr; - addr = (uint32_t)(xlr_boot1_info.uart_putchar & 0x00000000ffffffff); - xlr_putchar = (void (*)(char))(addr); -} - -void xlr_putc(char); -void xlr_print_int(uint32_t val); - -void -xlr_putc(char c) -{ - (*xlr_putchar)(c); - DELAY(1000); -} - -void -xlr_print_int(uint32_t val) -{ - int i; - int idx; - char ary[16] = { - '0', '1', '2', '3', - '4', '5', '6', '7', - '8', '9', 'a', 'b', - 'c', 'd', 'e', 'f' - }; - xlr_putc('0'); - xlr_putc('x'); - for(i=7;i>=0;i--) { - idx = (val >> (i*4)) & 0x0000000f; - xlr_putc(ary[idx]); - } - xlr_putc(' '); - xlr_putc(015); - xlr_putc(012); -} -void tick_init(void); void platform_start(__register_t a0 __unused, __register_t a1 __unused, @@ -454,7 +412,6 @@ platform_start(__register_t a0 __unused, mips_timer_early_init(platform_get_frequency()); /* Init the time counter in the PIC and local putc routine*/ - xlr_putc_init(); rmi_early_counter_init(); /* Init console please */ @@ -526,7 +483,6 @@ platform_start(__register_t a0 __unused, /* Set up hz, among others. */ mips_init(); - pcpup = (struct pcpu *)NULL; /* TODO To be removed */ #ifdef SMP /* @@ -583,13 +539,10 @@ platform_start(__register_t a0 __unused, * mips_init() XXX NOTE: We may need to move this to SMP based init * code for each CPU, later. */ - printf("Here\n"); rmi_spin_mutex_safe = 1; on_chip_init(); - printf("there\n"); mips_timer_init_params(platform_get_frequency(), 0); - printf("ok\n"); - tick_init(); + printf("Platform specific startup now completes\n"); } void From 40a554d7ace0b8aecfda5af7de4bba3570c3655f Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 6 Nov 2009 21:53:38 +0000 Subject: [PATCH 313/380] - Fix: Wrong register is used for initial value reading --- sys/mips/atheros/if_arge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index 95e0c12429d..6263ef1601f 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -620,7 +620,7 @@ arge_link_task(void *arg, int pending) rx_filtmask); /* set PLL registers */ - sec_cfg = ATH_READ_REG(AR71XX_PLL_CPU_CONFIG); + sec_cfg = ATH_READ_REG(AR71XX_PLL_SEC_CONFIG); sec_cfg &= ~(3 << sc->arge_pll_reg_shift); sec_cfg |= (2 << sc->arge_pll_reg_shift); From bec244c7502a5a5ce79eb297847079ea2a52140b Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sun, 8 Nov 2009 07:26:02 +0000 Subject: [PATCH 314/380] - Access to all 5 PHYs goes through registers in MAC0 memory space, rewrite miibus accessors respectively --- sys/mips/atheros/ar71xxreg.h | 4 ++++ sys/mips/atheros/if_arge.c | 34 +++++++++++++++++++++++++--------- sys/mips/atheros/if_argevar.h | 10 ++++++++++ 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/sys/mips/atheros/ar71xxreg.h b/sys/mips/atheros/ar71xxreg.h index 3f6b50a97fb..5677a4eff59 100644 --- a/sys/mips/atheros/ar71xxreg.h +++ b/sys/mips/atheros/ar71xxreg.h @@ -214,6 +214,10 @@ */ #define AR71XX_MAC0_BASE 0x19000000 #define AR71XX_MAC1_BASE 0x1A000000 +/* + * All 5 PHYs accessible only through MAC0 register space + */ +#define AR71XX_MII_BASE 0x19000000 #define AR71XX_MAC_CFG1 0x00 #define MAC_CFG1_SOFT_RESET (1 << 31) diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index 6263ef1601f..6d77edca1a6 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -162,6 +162,11 @@ DRIVER_MODULE(miibus, arge, miibus_driver, miibus_devclass, 0, 0); */ extern uint32_t ar711_base_mac[ETHER_ADDR_LEN]; +static struct mtx miibus_mtx; + +MTX_SYSINIT(miibus_mtx, &miibus_mtx, "arge mii lock", MTX_SPIN); + + /* * Flushes all */ @@ -488,23 +493,27 @@ arge_miibus_readreg(device_t dev, int phy, int reg) if (phy != sc->arge_phy_num) return (0); - ARGE_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); - ARGE_WRITE(sc, AR71XX_MAC_MII_ADDR, addr); - ARGE_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_READ); + mtx_lock(&miibus_mtx); + ARGE_MII_WRITE(AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); + ARGE_MII_WRITE(AR71XX_MAC_MII_ADDR, addr); + ARGE_MII_WRITE(AR71XX_MAC_MII_CMD, MAC_MII_CMD_READ); i = ARGE_MII_TIMEOUT; - while ((ARGE_READ(sc, AR71XX_MAC_MII_INDICATOR) & + while ((ARGE_MII_READ(AR71XX_MAC_MII_INDICATOR) & MAC_MII_INDICATOR_BUSY) && (i--)) DELAY(5); if (i < 0) { + mtx_unlock(&miibus_mtx); dprintf("%s timedout\n", __func__); /* XXX: return ERRNO istead? */ return (-1); } - result = ARGE_READ(sc, AR71XX_MAC_MII_STATUS) & MAC_MII_STATUS_MASK; - ARGE_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); + result = ARGE_MII_READ(AR71XX_MAC_MII_STATUS) & MAC_MII_STATUS_MASK; + ARGE_MII_WRITE(AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE); + mtx_unlock(&miibus_mtx); + dprintf("%s: phy=%d, reg=%02x, value[%08x]=%04x\n", __func__, phy, reg, addr, result); @@ -519,17 +528,24 @@ arge_miibus_writereg(device_t dev, int phy, int reg, int data) uint32_t addr = (phy << MAC_MII_PHY_ADDR_SHIFT) | (reg & MAC_MII_REG_MASK); + + if (phy != sc->arge_phy_num) + return (-1); + dprintf("%s: phy=%d, reg=%02x, value=%04x\n", __func__, phy, reg, data); - ARGE_WRITE(sc, AR71XX_MAC_MII_ADDR, addr); - ARGE_WRITE(sc, AR71XX_MAC_MII_CONTROL, data); + mtx_lock(&miibus_mtx); + ARGE_MII_WRITE(AR71XX_MAC_MII_ADDR, addr); + ARGE_MII_WRITE(AR71XX_MAC_MII_CONTROL, data); i = ARGE_MII_TIMEOUT; - while ((ARGE_READ(sc, AR71XX_MAC_MII_INDICATOR) & + while ((ARGE_MII_READ(AR71XX_MAC_MII_INDICATOR) & MAC_MII_INDICATOR_BUSY) && (i--)) DELAY(5); + mtx_unlock(&miibus_mtx); + if (i < 0) { dprintf("%s timedout\n", __func__); /* XXX: return ERRNO istead? */ diff --git a/sys/mips/atheros/if_argevar.h b/sys/mips/atheros/if_argevar.h index aec2cf46af3..40962ce58f1 100644 --- a/sys/mips/atheros/if_argevar.h +++ b/sys/mips/atheros/if_argevar.h @@ -64,6 +64,16 @@ #define ARGE_CLEAR_BITS(sc, reg, bits) \ ARGE_WRITE(sc, reg, ARGE_READ(sc, (reg)) & ~(bits)) +/* + * MII registers access macros + */ +#define ARGE_MII_READ(reg) \ + *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((AR71XX_MII_BASE + reg))) + +#define ARGE_MII_WRITE(reg, val) \ + *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((AR71XX_MII_BASE + reg))) = (val) + + #define ARGE_DESC_EMPTY (1 << 31) #define ARGE_DESC_MORE (1 << 24) #define ARGE_DESC_SIZE_MASK ((1 << 12) - 1) From 619ddb52b563a62d3332d343491e2e6f79c503b4 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sun, 8 Nov 2009 07:31:42 +0000 Subject: [PATCH 315/380] - Add arge1 to hints files, only one port is supported so far --- sys/mips/conf/AR71XX.hints | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/sys/mips/conf/AR71XX.hints b/sys/mips/conf/AR71XX.hints index c44d6958a00..0593dc0d2cc 100644 --- a/sys/mips/conf/AR71XX.hints +++ b/sys/mips/conf/AR71XX.hints @@ -32,10 +32,13 @@ hint.arge.0.irq=2 # Uncomment this hint for RS (not PRO) # hint.arge.0.phy=20 -# hint.arge.1.at="nexus0" -# hint.arge.1.maddr=0x1A000000 -# hint.arge.1.msize=0x1000 -# hint.arge.1.irq=3 +hint.arge.1.at="nexus0" +hint.arge.1.maddr=0x1a000000 +hint.arge.1.msize=0x1000 +hint.arge.1.irq=3 +hint.arge.1.phy=3 +# Uncomment this hint for RS (not PRO) +# hint.arge.1.phy=19 # SPI flash hint.spi.0.at="nexus0" From e20f0d885e5f0673f0f8bd2be22af90001324037 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Mon, 9 Nov 2009 16:42:08 +0000 Subject: [PATCH 316/380] - Comment out recrusive call to setup interrupt. - Change the way we pass the irq. --- sys/mips/rmi/iodi.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sys/mips/rmi/iodi.c b/sys/mips/rmi/iodi.c index c00ce9bf962..4491afc33b9 100644 --- a/sys/mips/rmi/iodi.c +++ b/sys/mips/rmi/iodi.c @@ -124,9 +124,9 @@ iodi_setup_intr(device_t dev, device_t child, } else if (strcmp(device_get_name(child), "rge") == 0) { int irq; - - irq = rman_get_rid(ires); - if (rmi_spin_mutex_safe) + /* This is a hack to pass in the irq */ + irq = (int)ires->__r_i; + if (rmi_spin_mutex_safe) mtx_lock_spin(&xlr_pic_lock); reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE); xlr_write_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE, reg | (1 << 6) | (1 << 30) | (1 << 31)); @@ -143,9 +143,10 @@ iodi_setup_intr(device_t dev, device_t child, mtx_unlock_spin(&xlr_pic_lock); cpu_establish_hardintr("ehci", NULL, (driver_intr_t *) intr, (void *)arg, PIC_USB_IRQ, flags, cookiep); } + /* This causes a panic and looks recursive to me (RRS). BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, filt, intr, arg, cookiep); - + */ return (0); } From 4c01ca5a19b8cf9d799d4c421c35e3b01fc1da16 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Mon, 9 Nov 2009 16:43:02 +0000 Subject: [PATCH 317/380] White space changes. --- sys/mips/rmi/iodi.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/sys/mips/rmi/iodi.c b/sys/mips/rmi/iodi.c index 4491afc33b9..65045c071f6 100644 --- a/sys/mips/rmi/iodi.c +++ b/sys/mips/rmi/iodi.c @@ -78,10 +78,10 @@ static struct resource * iodi_alloc_resource(device_t, device_t, int, int *, u_long, u_long, u_long, u_int); -static int +static int iodi_activate_resource(device_t, device_t, int, int, struct resource *); -static int +static int iodi_setup_intr(device_t, device_t, struct resource *, int, driver_filter_t *, driver_intr_t *, void *, void **); @@ -112,41 +112,43 @@ iodi_setup_intr(device_t dev, device_t child, /* FIXME is this the right place to fiddle with PIC? */ if (strcmp(device_get_name(child), "uart") == 0) { /* FIXME uart 1? */ - if (rmi_spin_mutex_safe) - mtx_lock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) + mtx_lock_spin(&xlr_pic_lock); level = PIC_IRQ_IS_EDGE_TRIGGERED(PIC_IRT_UART_0_INDEX); xlr_write_reg(mmio, PIC_IRT_0_UART_0, 0x01); xlr_write_reg(mmio, PIC_IRT_1_UART_0, ((1 << 31) | (level << 30) | (1 << 6) | (PIC_UART_0_IRQ))); - if (rmi_spin_mutex_safe) - mtx_unlock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) + mtx_unlock_spin(&xlr_pic_lock); cpu_establish_hardintr("uart", NULL, (driver_intr_t *) intr, (void *)arg, PIC_UART_0_IRQ, flags, cookiep); } else if (strcmp(device_get_name(child), "rge") == 0) { int irq; + /* This is a hack to pass in the irq */ irq = (int)ires->__r_i; if (rmi_spin_mutex_safe) - mtx_lock_spin(&xlr_pic_lock); + mtx_lock_spin(&xlr_pic_lock); reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE); xlr_write_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE, reg | (1 << 6) | (1 << 30) | (1 << 31)); - if (rmi_spin_mutex_safe) - mtx_unlock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) + mtx_unlock_spin(&xlr_pic_lock); cpu_establish_hardintr("rge", NULL, (driver_intr_t *) intr, (void *)arg, irq, flags, cookiep); } else if (strcmp(device_get_name(child), "ehci") == 0) { - if (rmi_spin_mutex_safe) - mtx_lock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) + mtx_lock_spin(&xlr_pic_lock); reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + PIC_USB_IRQ - PIC_IRQ_BASE); xlr_write_reg(mmio, PIC_IRT_1_BASE + PIC_USB_IRQ - PIC_IRQ_BASE, reg | (1 << 6) | (1 << 30) | (1 << 31)); - if (rmi_spin_mutex_safe) - mtx_unlock_spin(&xlr_pic_lock); + if (rmi_spin_mutex_safe) + mtx_unlock_spin(&xlr_pic_lock); cpu_establish_hardintr("ehci", NULL, (driver_intr_t *) intr, (void *)arg, PIC_USB_IRQ, flags, cookiep); } - /* This causes a panic and looks recursive to me (RRS). - BUS_SETUP_INTR(device_get_parent(dev), - child, ires, flags, filt, intr, arg, cookiep); - */ + /* + * This causes a panic and looks recursive to me (RRS). + * BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, filt, + * intr, arg, cookiep); + */ return (0); } From 49cd7d2cf3c0e9ce48f23c84f422c5f4de78ccdc Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Mon, 9 Nov 2009 16:43:50 +0000 Subject: [PATCH 318/380] Cooresponding hack to pass in the irq --- sys/dev/rmi/xlr/rge.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/dev/rmi/xlr/rge.c b/sys/dev/rmi/xlr/rge.c index 38f5fdde681..0e7757f0502 100644 --- a/sys/dev/rmi/xlr/rge.c +++ b/sys/dev/rmi/xlr/rge.c @@ -1925,7 +1925,8 @@ rge_attach(device_t dev) sc->irq = gmac_conf->baseirq + priv->instance % 4; /* Set the IRQ into the rid field */ - rman_set_rid(&sc->rge_irq, sc->irq); + /* note this is a hack to pass the irq to the iodi interrupt setup routines */ + sc->rge_irq.__r_i = (struct resource_i *)sc->irq; ret = bus_setup_intr(dev, &sc->rge_irq, INTR_FAST | INTR_TYPE_NET | INTR_MPSAFE, NULL, rge_intr, sc, &sc->rge_intrhand); From 01f43c2740288fa975f7f002019e75ecff0a246b Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Mon, 9 Nov 2009 19:22:57 +0000 Subject: [PATCH 319/380] a little more paran's --- sys/mips/rmi/intr_machdep.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/mips/rmi/intr_machdep.c b/sys/mips/rmi/intr_machdep.c index 9c1b8f818b3..d4d9dba1765 100644 --- a/sys/mips/rmi/intr_machdep.c +++ b/sys/mips/rmi/intr_machdep.c @@ -137,9 +137,10 @@ cpu_intr(struct trapframe *tf) critical_exit(); return; } + /* FIXME sched pin >? LOCK>? */ for (i = sizeof(eirr) * 8 - 1; i >= 0; i--) { - if ((eirr & 1ULL << i) == 0) + if ((eirr & (1ULL << i)) == 0) continue; #ifdef SMP /* These are reserved interrupts */ From 399804b73bc8bad335fb7242ce8b7d6f2ffd6bba Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Mon, 9 Nov 2009 19:25:30 +0000 Subject: [PATCH 320/380] Ok we need to have the clock handlers has filters. This gets us up to a mount request :-) --- sys/mips/rmi/clock.c | 27 +++++++++++++++------------ sys/mips/rmi/clock.h | 5 +++-- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/sys/mips/rmi/clock.c b/sys/mips/rmi/clock.c index d32197318ad..67bac800376 100644 --- a/sys/mips/rmi/clock.c +++ b/sys/mips/rmi/clock.c @@ -77,7 +77,7 @@ u_int32_t counter_lower_last = 0; static int scale_factor; static int count_scale_factor[32]; -uint64_t +uint64_t platform_get_frequency() { return XLR_PIC_HZ; @@ -98,7 +98,7 @@ mips_timer_early_init(uint64_t clock_hz) * Handle the clock interrupt when count becomes equal to * compare. */ -void +int count_compare_clockhandler(struct trapframe *tf) { int cpu = PCPU_GET(cpuid); @@ -126,9 +126,10 @@ count_compare_clockhandler(struct trapframe *tf) } critical_exit(); + return (FILTER_HANDLED); } -void +int pic_hardclockhandler(struct trapframe *tf) { int cpu = PCPU_GET(cpuid); @@ -154,6 +155,7 @@ pic_hardclockhandler(struct trapframe *tf) /* If needed , handle count compare tick skew here */ } critical_exit(); + return (FILTER_HANDLED); } int @@ -168,9 +170,10 @@ rmi_early_counter_init() int cpu = PCPU_GET(cpuid); xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); - /* We do this to get the PIC time counter running right - * after system start. Otherwise the DELAY() function will - * not be able to work since it won't have a TC to read. + /* + * We do this to get the PIC time counter running right after system + * start. Otherwise the DELAY() function will not be able to work + * since it won't have a TC to read. */ xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_0, (0xffffffff & 0xffffffff)); xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_1, (0xffffffff & 0xffffffff)); @@ -193,16 +196,16 @@ platform_initclocks(void) */ /* profiling/process accounting timer interrupt for non-zero cpus */ cpu_establish_hardintr("compare", + (driver_filter_t *) count_compare_clockhandler, NULL, - (driver_intr_t *) count_compare_clockhandler, NULL, IRQ_TIMER, INTR_TYPE_CLK | INTR_FAST, &cookie); /* timekeeping timer interrupt for cpu 0 */ cpu_establish_hardintr("hardclk", + (driver_filter_t *) pic_hardclockhandler, NULL, - (driver_intr_t *) pic_hardclockhandler, NULL, PIC_TIMER_7_IRQ, INTR_TYPE_CLK | INTR_FAST, @@ -224,7 +227,7 @@ platform_initclocks(void) /* Setup PIC Interrupt */ if (rmi_spin_mutex_safe) - mtx_lock_spin(&xlr_pic_lock); + mtx_lock_spin(&xlr_pic_lock); xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_0, (maxval & 0xffffffff)); /* 0x100 + 7 */ xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_1, (maxval >> 32) & 0xffffffff); /* 0x110 + 7 */ /* 0x40 + 8 */ @@ -242,7 +245,7 @@ platform_initclocks(void) xlr_write_reg(mmio, PIC_IRT_1_TIMER_6, (1 << 31) | (0 << 30) | (1 << 6) | (PIC_TIMER_6_IRQ)); pic_update_control(1 << (8 + 6)); if (rmi_spin_mutex_safe) - mtx_unlock_spin(&xlr_pic_lock); + mtx_unlock_spin(&xlr_pic_lock); } else { /* Setup count-compare interrupt for vcpu[1-31] */ mips_wr_compare((xlr_boot1_info.cpu_frequency) / hz); @@ -250,7 +253,7 @@ platform_initclocks(void) tick_init(); } -unsigned +unsigned __attribute__((no_instrument_function)) platform_get_timecount(struct timecounter *tc __unused) { @@ -290,7 +293,7 @@ DELAY(int n) } static -uint64_t +uint64_t read_pic_counter(void) { xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); diff --git a/sys/mips/rmi/clock.h b/sys/mips/rmi/clock.h index 0d3bc5d457c..c0675810fc8 100644 --- a/sys/mips/rmi/clock.h +++ b/sys/mips/rmi/clock.h @@ -33,8 +33,9 @@ #define XLR_PIC_HZ 66000000U #define XLR_CPU_HZ (xlr_boot1_info.cpu_frequency) -void count_compare_clockhandler(struct trapframe *); -void pic_hardclockhandler(struct trapframe *); +int count_compare_clockhandler(struct trapframe *); +int pic_hardclockhandler(struct trapframe *); int pic_timecounthandler(struct trapframe *); void rmi_early_counter_init(void); + #endif /* _RMI_CLOCK_H_ */ From 638c9101a05ddeb5ad6e225cd80c81a23ed62065 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Mon, 9 Nov 2009 19:26:28 +0000 Subject: [PATCH 321/380] Try moving to NFS mount of entire root --- sys/mips/conf/XLR | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sys/mips/conf/XLR b/sys/mips/conf/XLR index b88a6af03da..ec4603d6cfd 100644 --- a/sys/mips/conf/XLR +++ b/sys/mips/conf/XLR @@ -61,7 +61,7 @@ makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols #profile 2 #options SCHED_ULE # ULE scheduler -options VERBOSE_SYSINIT +#options VERBOSE_SYSINIT options SCHED_4BSD # 4BSD scheduler #options PREEMPTION # Enable kernel thread preemption #options FULL_PREEMPTION # Enable kernel thread preemption @@ -71,8 +71,11 @@ options FFS # Berkeley Fast Filesystem #options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories -options MD_ROOT # MD is a potential root device -options MD_ROOT_SIZE=14288 +options NFSCLIENT +options NFS_ROOT +options ROOTDEVNAME=\"nfs:10.1.1.15:/extra/nfsroot\" +#options MD_ROOT # MD is a potential root device +#options MD_ROOT_SIZE=21264 #options MD_ROOT_SIZE=5120 options ROOTDEVNAME=\"ufs:md0\" options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions From 4e07ba90454302b67cb9cba8793b4a617d90cce0 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Mon, 9 Nov 2009 19:56:53 +0000 Subject: [PATCH 322/380] Ok it helps if you add the bootp options too so that you can get an address ;-) --- sys/mips/conf/XLR | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sys/mips/conf/XLR b/sys/mips/conf/XLR index ec4603d6cfd..765bd07146e 100644 --- a/sys/mips/conf/XLR +++ b/sys/mips/conf/XLR @@ -74,10 +74,16 @@ options UFS_DIRHASH # Improve performance on big directories options NFSCLIENT options NFS_ROOT options ROOTDEVNAME=\"nfs:10.1.1.15:/extra/nfsroot\" +options BOOTP +options BOOTP_NFSROOT +options BOOTP_NFSV3 +options BOOTP_WIRED_TO=rge0 +options BOOTP_COMPAT +# #options MD_ROOT # MD is a potential root device #options MD_ROOT_SIZE=21264 #options MD_ROOT_SIZE=5120 -options ROOTDEVNAME=\"ufs:md0\" +#options ROOTDEVNAME=\"ufs:md0\" options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions options HZ=1000 options PHYS_ADDR_64BIT From e0c4754e8727821c268c6bae232c8fbd87b1ddfb Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Tue, 10 Nov 2009 13:41:00 +0000 Subject: [PATCH 323/380] Ok, the 40bit reads were causing crashes when they did their thing i.e. enabling SX mode and then trying to load in. Since we are o32 this is all un-needed. So I have re-structured the code to work without doing this special set of code. Packets now flow in and out.. however for some reason dhcp/bootp response comes in and the kernel does not proceed. Not sure if we have a UDP checksum error or ?? The packets look all there by comparing wireshark and the first 64 bytes of the TX and RX packets. --- sys/dev/rmi/xlr/rge.c | 100 +++++++++++++++++++++++++++--------------- 1 file changed, 64 insertions(+), 36 deletions(-) diff --git a/sys/dev/rmi/xlr/rge.c b/sys/dev/rmi/xlr/rge.c index 0e7757f0502..e0fa8c15851 100644 --- a/sys/dev/rmi/xlr/rge.c +++ b/sys/dev/rmi/xlr/rge.c @@ -332,7 +332,7 @@ DRIVER_MODULE(miibus, rge, miibus_driver, miibus_devclass, 0, 0); #endif #define XKPHYS 0x8000000000000000 - +/* -- No longer needed RRS static __inline__ uint32_t lw_40bit_phys(uint64_t phys, int cca) { @@ -355,8 +355,8 @@ lw_40bit_phys(uint64_t phys, int cca) disable_KX(flags); return value; } - - +*/ +/* -- No longer used RRS static __inline__ uint64_t ld_40bit_phys(uint64_t phys, int cca) { @@ -379,7 +379,7 @@ ld_40bit_phys(uint64_t phys, int cca) disable_KX(flags); return value; } - +*/ void *xlr_tx_ring_mem; @@ -411,7 +411,7 @@ TAILQ_HEAD(, tx_desc_node) tx_frag_desc[XLR_MAX_CORE] = }; /* This contains a list of free tx frag node descriptors */ -static +static TAILQ_HEAD(, tx_desc_node) free_tx_frag_desc[XLR_MAX_CORE] = { TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[0]), @@ -617,23 +617,33 @@ build_frag_list(struct mbuf *m_head, struct msgrng_msg *p2p_msg, struct p2d_tx_d static void release_tx_desc(struct msgrng_msg *msg, int rel_buf) { - vm_paddr_t paddr = msg->msg0 & 0xffffffffffULL; - uint64_t temp; - struct p2d_tx_desc *tx_desc; + /* + * OLD code: vm_paddr_t paddr = msg->msg0 & 0xffffffffffULL; + * uint64_t temp; struct p2d_tx_desc *tx_desc; struct mbuf *m; + * + * paddr += (XLR_MAX_TX_FRAGS * sizeof(uint64_t)); *** In o32 we will + * crash here ****** temp = ld_40bit_phys(paddr, 3); tx_desc = + * (struct p2d_tx_desc *)((vm_offset_t)temp); + * + * if (rel_buf) { paddr += sizeof(uint64_t); + * + * temp = ld_40bit_phys(paddr, 3); + * + * m = (struct mbuf *)((vm_offset_t)temp); m_freem(m); } printf("Call + * fre_p2d_desc\n"); free_p2d_desc(tx_desc); + */ + struct p2d_tx_desc *tx_desc, *chk_addr; struct mbuf *m; - paddr += (XLR_MAX_TX_FRAGS * sizeof(uint64_t)); - - temp = ld_40bit_phys(paddr, 3); - - tx_desc = (struct p2d_tx_desc *)((vm_offset_t)temp); - + tx_desc = (struct p2d_tx_desc *)MIPS_PHYS_TO_KSEG0(msg->msg0); + chk_addr = (struct p2d_tx_desc *)(uint32_t) (tx_desc->frag[XLR_MAX_TX_FRAGS] & 0x00000000ffffffff); + if (tx_desc != chk_addr) { + printf("Address %p does not match with stored addr %p - we leaked a descriptor\n", + tx_desc, chk_addr); + return; + } if (rel_buf) { - paddr += sizeof(uint64_t); - - temp = ld_40bit_phys(paddr, 3); - - m = (struct mbuf *)((vm_offset_t)temp); + m = (struct mbuf *)(uint32_t) (tx_desc->frag[XLR_MAX_TX_FRAGS + 1] & 0x00000000ffffffff); m_freem(m); } free_p2d_desc(tx_desc); @@ -703,10 +713,26 @@ static void free_buf(vm_paddr_t paddr) { struct mbuf *m; - vm_offset_t temp; + uint32_t *temp; + uint32_t mag, um; - temp = lw_40bit_phys((paddr - XLR_CACHELINE_SIZE), 3); - m = (struct mbuf *)temp; + /* + * This will crash I think. RRS temp = lw_40bit_phys((paddr - + * XLR_CACHELINE_SIZE), 3); m = (struct mbuf *)temp; + */ + /* + * This gets us a kseg0 address for the mbuf/magic on the ring but + * we need to get the va to free the mbuf. This is stored at *temp; + */ + temp = (uint32_t *) MIPS_PHYS_TO_KSEG0(paddr - XLR_CACHELINE_SIZE); + um = temp[0]; + mag = temp[1]; + if (mag != 0xf00bad) { + printf("Something is wrong kseg:%p found mag:%x not 0xf00bad\n", + temp, mag); + return; + } + m = (struct mbuf *)um; if (m != NULL) m_freem(m); } @@ -1015,7 +1041,7 @@ serdes_regs_init(struct driver_data *priv) return; } -static void +static void serdes_autoconfig(struct driver_data *priv) { int delay = 100000; @@ -1742,7 +1768,6 @@ rmi_xlr_mac_msgring_handler(int bucket, int size, int code, /* int logical_cpu = 0; */ dbg_msg("Received packet, port = %d\n", port); - /* * if num frins to be sent exceeds threshold, wake up the * helper thread @@ -1753,7 +1778,6 @@ rmi_xlr_mac_msgring_handler(int bucket, int size, int code, } dbg_msg("gmac_%d: rx packet: phys_addr = %llx, length = %x\n", priv->instance, phys_addr, length); - mac_stats_add(priv->stats.rx_packets, 1); mac_stats_add(priv->stats.rx_bytes, length); xlr_inc_counter(NETIF_RX); @@ -1779,7 +1803,7 @@ rge_probe(dev) volatile unsigned long xlr_debug_enabled; struct callout rge_dbg_count; -static void +static void xlr_debug_count(void *addr) { struct driver_data *priv = &dev_mac[0]->priv; @@ -1792,7 +1816,7 @@ xlr_debug_count(void *addr) } -static void +static void xlr_tx_q_wakeup(void *addr) { int i = 0; @@ -1925,7 +1949,10 @@ rge_attach(device_t dev) sc->irq = gmac_conf->baseirq + priv->instance % 4; /* Set the IRQ into the rid field */ - /* note this is a hack to pass the irq to the iodi interrupt setup routines */ + /* + * note this is a hack to pass the irq to the iodi interrupt setup + * routines + */ sc->rge_irq.__r_i = (struct resource_i *)sc->irq; ret = bus_setup_intr(dev, &sc->rge_irq, INTR_FAST | INTR_TYPE_NET | INTR_MPSAFE, @@ -2077,13 +2104,14 @@ rge_rx(struct rge_softc *sc, vm_paddr_t paddr, int len) */ struct mbuf *m; void *ptr; - vm_offset_t temp; + uint32_t *temp; struct ifnet *ifp = sc->rge_ifp; unsigned long msgrng_flags; int cpu = PCPU_GET(cpuid); - temp = lw_40bit_phys((paddr - XLR_CACHELINE_SIZE), 3); + temp = (uint32_t *) MIPS_PHYS_TO_KSEG0(paddr - XLR_CACHELINE_SIZE); + ptr = (void *)(temp + XLR_CACHELINE_SIZE); m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); if (m != NULL) { @@ -2132,15 +2160,15 @@ rge_rx(struct rge_softc *sc, vm_paddr_t paddr, int len) * XLR_CACHELINE_SIZE); */ struct mbuf *m; - vm_offset_t temp; - unsigned int mag; + uint32_t *temp, tm, mag; + struct ifnet *ifp = sc->rge_ifp; - temp = lw_40bit_phys((paddr - XLR_CACHELINE_SIZE), 3); - mag = lw_40bit_phys((paddr - XLR_CACHELINE_SIZE + 4), 3); - - m = (struct mbuf *)temp; + temp = (uint32_t *) MIPS_PHYS_TO_KSEG0(paddr - XLR_CACHELINE_SIZE); + tm = temp[0]; + mag = temp[1]; + m = (struct mbuf *)tm; if (mag != 0xf00bad) { /* somebody else packet Error - FIXME in intialization */ printf("cpu %d: *ERROR* Not my packet paddr %p\n", xlr_cpu_id(), (void *)paddr); From 4ba9b90b06ffbbe1722ced7402a168775e027e14 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Wed, 11 Nov 2009 22:36:19 +0000 Subject: [PATCH 324/380] Ok set in the values in clock 7 as in the original codes (I had changed one by accident) Also do the pic_ack/pic_delayed_ack after the interrupt so we clear it. The clock with these changes starts working. Its off doing a short/long short/long warning but it now runs. My NFS mount now works but has the same problem with sbin/init (errno 8 ENOEXEC) so it panics with no init. Either this is a problem with my buildworld.. OR its a yet undiscovered RMI issue. --- sys/mips/rmi/clock.c | 2 +- sys/mips/rmi/intr_machdep.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/mips/rmi/clock.c b/sys/mips/rmi/clock.c index 67bac800376..d97629750f1 100644 --- a/sys/mips/rmi/clock.c +++ b/sys/mips/rmi/clock.c @@ -240,7 +240,7 @@ platform_initclocks(void) pic_update_control(1 << (8 + 7)); xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_0, (0xffffffff & 0xffffffff)); - xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_1, (0xffffffff & 0xffffffff)); + xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_1, (0x0 & 0xffffffff)); xlr_write_reg(mmio, PIC_IRT_0_TIMER_6, (1 << cpu)); xlr_write_reg(mmio, PIC_IRT_1_TIMER_6, (1 << 31) | (0 << 30) | (1 << 6) | (PIC_TIMER_6_IRQ)); pic_update_control(1 << (8 + 6)); diff --git a/sys/mips/rmi/intr_machdep.c b/sys/mips/rmi/intr_machdep.c index d4d9dba1765..07a9dab76f9 100644 --- a/sys/mips/rmi/intr_machdep.c +++ b/sys/mips/rmi/intr_machdep.c @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include /*#include */ @@ -167,6 +168,7 @@ cpu_intr(struct trapframe *tf) ie = mih->mih_event; write_c0_eirr64(1ULL << i); + pic_ack(i); if (!ie || TAILQ_EMPTY(&ie->ie_handlers)) { printf("stray interrupt %d\n", i); continue; @@ -174,6 +176,7 @@ cpu_intr(struct trapframe *tf) if (intr_event_handle(ie, tf) != 0) { printf("stray interrupt %d\n", i); } + pic_delayed_ack(i); } critical_exit(); } From e7e9513453f1390b50fde8547587efbf1c5fcb41 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Wed, 11 Nov 2009 22:37:17 +0000 Subject: [PATCH 325/380] My NFS configured version. --- sys/mips/conf/XLR | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/mips/conf/XLR b/sys/mips/conf/XLR index 765bd07146e..eacebbb8061 100644 --- a/sys/mips/conf/XLR +++ b/sys/mips/conf/XLR @@ -73,12 +73,13 @@ options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories options NFSCLIENT options NFS_ROOT -options ROOTDEVNAME=\"nfs:10.1.1.15:/extra/nfsroot\" +# options BOOTP options BOOTP_NFSROOT options BOOTP_NFSV3 options BOOTP_WIRED_TO=rge0 options BOOTP_COMPAT +options ROOTDEVNAME=\"nfs:10.1.1.15:/extra/nfsroot\" # #options MD_ROOT # MD is a potential root device #options MD_ROOT_SIZE=21264 From 445ee40baa6befe5cb23655c97bd54c12285017b Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 12 Nov 2009 20:48:04 +0000 Subject: [PATCH 326/380] - include register definitions for respective controllers --- sys/mips/atheros/ar71xx_ehci.c | 1 + sys/mips/atheros/ar71xx_ohci.c | 1 + 2 files changed, 2 insertions(+) diff --git a/sys/mips/atheros/ar71xx_ehci.c b/sys/mips/atheros/ar71xx_ehci.c index cf89cc513e7..936fd355a00 100644 --- a/sys/mips/atheros/ar71xx_ehci.c +++ b/sys/mips/atheros/ar71xx_ehci.c @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include diff --git a/sys/mips/atheros/ar71xx_ohci.c b/sys/mips/atheros/ar71xx_ohci.c index c996b4252ab..acccd850a1c 100644 --- a/sys/mips/atheros/ar71xx_ohci.c +++ b/sys/mips/atheros/ar71xx_ohci.c @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include From 2b8344b8fa0b012e297434ba198074c0b521643e Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 12 Nov 2009 21:27:58 +0000 Subject: [PATCH 327/380] - Handle multiphy MAC case: create interface with fixed-state media with parameters set via hints and configure MAC accordingly to these parameters. All the underlying PHY magic is done by boot manager on startup. At the moment there is no proper way to make active and control all PHYs simultaneously from one MII bus and there is no way to associate incoming/outgoing packet with specific PHY. --- sys/mips/atheros/if_arge.c | 293 +++++++++++++++++++++++----------- sys/mips/atheros/if_argevar.h | 9 +- 2 files changed, 212 insertions(+), 90 deletions(-) diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index 6d77edca1a6..da8d181de08 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -95,6 +95,7 @@ static int arge_ioctl(struct ifnet *, u_long, caddr_t); static void arge_init(void *); static void arge_init_locked(struct arge_softc *); static void arge_link_task(void *, int); +static void arge_set_pll(struct arge_softc *, int, int); static int arge_miibus_readreg(device_t, int, int); static void arge_miibus_statchg(device_t); static int arge_miibus_writereg(device_t, int, int, int); @@ -118,6 +119,12 @@ static void arge_intr(void *); static int arge_intr_filter(void *); static void arge_tick(void *); +/* + * ifmedia callbacks for multiPHY MAC + */ +void arge_multiphy_mediastatus(struct ifnet *, struct ifmediareq *); +int arge_multiphy_mediachange(struct ifnet *); + static void arge_dmamap_cb(void *, bus_dma_segment_t *, int, int); static int arge_dma_alloc(struct arge_softc *); static void arge_dma_free(struct arge_softc *); @@ -197,9 +204,10 @@ arge_attach(device_t dev) uint8_t eaddr[ETHER_ADDR_LEN]; struct ifnet *ifp; struct arge_softc *sc; - int error = 0, rid, phynum; + int error = 0, rid, phymask; uint32_t reg, rnd; - int is_base_mac_empty, i; + int is_base_mac_empty, i, phys_total; + uint32_t hint; sc = device_get_softc(dev); sc->arge_dev = dev; @@ -221,20 +229,43 @@ arge_attach(device_t dev) * Get which PHY of 5 available we should use for this unit */ if (resource_int_value(device_get_name(dev), device_get_unit(dev), - "phy", &phynum) != 0) { + "phymask", &phymask) != 0) { /* * Use port 4 (WAN) for GE0. For any other port use * its PHY the same as its unit number */ if (sc->arge_mac_unit == 0) - phynum = 4; + phymask = (1 << 4); else - phynum = sc->arge_mac_unit; + /* Use all phys up to 4 */ + phymask = (1 << 4) - 1; - device_printf(dev, "No PHY specified, using %d\n", phynum); + device_printf(dev, "No PHY specified, using mask %d\n", phymask); } - sc->arge_phy_num = phynum; + /* + * Get default media & duplex mode, by default its Base100T + * and full duplex + */ + if (resource_int_value(device_get_name(dev), device_get_unit(dev), + "media", &hint) != 0) + hint = 0; + + if (hint == 1000) + sc->arge_media_type = IFM_1000_T; + else + sc->arge_media_type = IFM_100_TX; + + if (resource_int_value(device_get_name(dev), device_get_unit(dev), + "fduplex", &hint) != 0) + hint = 1; + + if (hint) + sc->arge_duplex_mode = IFM_FDX; + else + sc->arge_duplex_mode = 0; + + sc->arge_phymask = phymask; mtx_init(&sc->arge_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF); @@ -379,14 +410,40 @@ arge_attach(device_t dev) ARGE_WRITE(sc, AR71XX_MAC_FIFO_RX_FILTMASK, FIFO_RX_FILTMASK_DEFAULT); - /* Do MII setup. */ - if (mii_phy_probe(dev, &sc->arge_miibus, - arge_ifmedia_upd, arge_ifmedia_sts)) { - device_printf(dev, "MII without any phy!\n"); - error = ENXIO; + /* + * Check if we have single-PHY MAC or multi-PHY + */ + phys_total = 0; + for (i = 0; i < ARGE_NPHY; i++) + if (phymask & (1 << i)) + phys_total ++; + + if (phys_total == 0) { + error = EINVAL; goto fail; } + if (phys_total == 1) { + /* Do MII setup. */ + if (mii_phy_probe(dev, &sc->arge_miibus, + arge_ifmedia_upd, arge_ifmedia_sts)) { + device_printf(dev, "MII without any phy!\n"); + error = ENXIO; + goto fail; + } + } + else { + ifmedia_init(&sc->arge_ifmedia, 0, + arge_multiphy_mediachange, + arge_multiphy_mediastatus); + ifmedia_add(&sc->arge_ifmedia, + IFM_ETHER | sc->arge_media_type | sc->arge_duplex_mode, + 0, NULL); + ifmedia_set(&sc->arge_ifmedia, + IFM_ETHER | sc->arge_media_type | sc->arge_duplex_mode); + arge_set_pll(sc, sc->arge_media_type, sc->arge_duplex_mode); + } + /* Call MI attach routine. */ ether_ifattach(ifp, eaddr); @@ -432,6 +489,7 @@ arge_detach(device_t dev) if (sc->arge_miibus) device_delete_child(dev, sc->arge_miibus); + bus_generic_detach(dev); if (sc->arge_intrhand) @@ -490,7 +548,7 @@ arge_miibus_readreg(device_t dev, int phy, int reg) uint32_t addr = (phy << MAC_MII_PHY_ADDR_SHIFT) | (reg & MAC_MII_REG_MASK); - if (phy != sc->arge_phy_num) + if ((sc->arge_phymask & (1 << phy)) == 0) return (0); mtx_lock(&miibus_mtx); @@ -529,7 +587,7 @@ arge_miibus_writereg(device_t dev, int phy, int reg, int data) (phy << MAC_MII_PHY_ADDR_SHIFT) | (reg & MAC_MII_REG_MASK); - if (phy != sc->arge_phy_num) + if ((sc->arge_phymask & (1 << phy)) == 0) return (-1); dprintf("%s: phy=%d, reg=%02x, value=%04x\n", __func__, @@ -570,8 +628,7 @@ arge_link_task(void *arg, int pending) struct arge_softc *sc; struct mii_data *mii; struct ifnet *ifp; - uint32_t media; - uint32_t cfg, ifcontrol, rx_filtmask, pll, sec_cfg; + uint32_t media, duplex; sc = (struct arge_softc *)arg; @@ -590,68 +647,8 @@ arge_link_task(void *arg, int pending) if (media != IFM_NONE) { sc->arge_link_status = 1; - - cfg = ARGE_READ(sc, AR71XX_MAC_CFG2); - cfg &= ~(MAC_CFG2_IFACE_MODE_1000 - | MAC_CFG2_IFACE_MODE_10_100 - | MAC_CFG2_FULL_DUPLEX); - - if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) - cfg |= MAC_CFG2_FULL_DUPLEX; - - ifcontrol = ARGE_READ(sc, AR71XX_MAC_IFCONTROL); - ifcontrol &= ~MAC_IFCONTROL_SPEED; - rx_filtmask = - ARGE_READ(sc, AR71XX_MAC_FIFO_RX_FILTMASK); - rx_filtmask &= ~FIFO_RX_MASK_BYTE_MODE; - - switch(media) { - case IFM_10_T: - cfg |= MAC_CFG2_IFACE_MODE_10_100; - pll = PLL_ETH_INT_CLK_10; - break; - case IFM_100_TX: - cfg |= MAC_CFG2_IFACE_MODE_10_100; - ifcontrol |= MAC_IFCONTROL_SPEED; - pll = PLL_ETH_INT_CLK_100; - break; - case IFM_1000_T: - case IFM_1000_SX: - cfg |= MAC_CFG2_IFACE_MODE_1000; - rx_filtmask |= FIFO_RX_MASK_BYTE_MODE; - pll = PLL_ETH_INT_CLK_1000; - break; - default: - pll = PLL_ETH_INT_CLK_100; - device_printf(sc->arge_dev, - "Unknown media %d\n", media); - } - - ARGE_WRITE(sc, AR71XX_MAC_FIFO_TX_THRESHOLD, - 0x008001ff); - - ARGE_WRITE(sc, AR71XX_MAC_CFG2, cfg); - ARGE_WRITE(sc, AR71XX_MAC_IFCONTROL, ifcontrol); - ARGE_WRITE(sc, AR71XX_MAC_FIFO_RX_FILTMASK, - rx_filtmask); - - /* set PLL registers */ - sec_cfg = ATH_READ_REG(AR71XX_PLL_SEC_CONFIG); - sec_cfg &= ~(3 << sc->arge_pll_reg_shift); - sec_cfg |= (2 << sc->arge_pll_reg_shift); - - ATH_WRITE_REG(AR71XX_PLL_SEC_CONFIG, sec_cfg); - DELAY(100); - - ATH_WRITE_REG(sc->arge_pll_reg, pll); - - sec_cfg |= (3 << sc->arge_pll_reg_shift); - ATH_WRITE_REG(AR71XX_PLL_SEC_CONFIG, sec_cfg); - DELAY(100); - - sec_cfg &= ~(3 << sc->arge_pll_reg_shift); - ATH_WRITE_REG(AR71XX_PLL_SEC_CONFIG, sec_cfg); - DELAY(100); + duplex = mii->mii_media_active & IFM_GMASK; + arge_set_pll(sc, media, duplex); } } else sc->arge_link_status = 0; @@ -659,6 +656,75 @@ arge_link_task(void *arg, int pending) ARGE_UNLOCK(sc); } +static void +arge_set_pll(struct arge_softc *sc, int media, int duplex) +{ + uint32_t cfg, ifcontrol, rx_filtmask, pll, sec_cfg; + + cfg = ARGE_READ(sc, AR71XX_MAC_CFG2); + cfg &= ~(MAC_CFG2_IFACE_MODE_1000 + | MAC_CFG2_IFACE_MODE_10_100 + | MAC_CFG2_FULL_DUPLEX); + + if (duplex == IFM_FDX) + cfg |= MAC_CFG2_FULL_DUPLEX; + + ifcontrol = ARGE_READ(sc, AR71XX_MAC_IFCONTROL); + ifcontrol &= ~MAC_IFCONTROL_SPEED; + rx_filtmask = + ARGE_READ(sc, AR71XX_MAC_FIFO_RX_FILTMASK); + rx_filtmask &= ~FIFO_RX_MASK_BYTE_MODE; + + switch(media) { + case IFM_10_T: + cfg |= MAC_CFG2_IFACE_MODE_10_100; + pll = PLL_ETH_INT_CLK_10; + break; + case IFM_100_TX: + cfg |= MAC_CFG2_IFACE_MODE_10_100; + ifcontrol |= MAC_IFCONTROL_SPEED; + pll = PLL_ETH_INT_CLK_100; + break; + case IFM_1000_T: + case IFM_1000_SX: + cfg |= MAC_CFG2_IFACE_MODE_1000; + rx_filtmask |= FIFO_RX_MASK_BYTE_MODE; + pll = PLL_ETH_INT_CLK_1000; + break; + default: + pll = PLL_ETH_INT_CLK_100; + device_printf(sc->arge_dev, + "Unknown media %d\n", media); + } + + ARGE_WRITE(sc, AR71XX_MAC_FIFO_TX_THRESHOLD, + 0x008001ff); + + ARGE_WRITE(sc, AR71XX_MAC_CFG2, cfg); + ARGE_WRITE(sc, AR71XX_MAC_IFCONTROL, ifcontrol); + ARGE_WRITE(sc, AR71XX_MAC_FIFO_RX_FILTMASK, + rx_filtmask); + + /* set PLL registers */ + sec_cfg = ATH_READ_REG(AR71XX_PLL_SEC_CONFIG); + sec_cfg &= ~(3 << sc->arge_pll_reg_shift); + sec_cfg |= (2 << sc->arge_pll_reg_shift); + + ATH_WRITE_REG(AR71XX_PLL_SEC_CONFIG, sec_cfg); + DELAY(100); + + ATH_WRITE_REG(sc->arge_pll_reg, pll); + + sec_cfg |= (3 << sc->arge_pll_reg_shift); + ATH_WRITE_REG(AR71XX_PLL_SEC_CONFIG, sec_cfg); + DELAY(100); + + sec_cfg &= ~(3 << sc->arge_pll_reg_shift); + ATH_WRITE_REG(AR71XX_PLL_SEC_CONFIG, sec_cfg); + DELAY(100); +} + + static void arge_reset_dma(struct arge_softc *sc) { @@ -707,8 +773,6 @@ arge_init_locked(struct arge_softc *sc) ARGE_LOCK_ASSERT(sc); - mii = device_get_softc(sc->arge_miibus); - arge_stop(sc); /* Init circular RX list. */ @@ -724,13 +788,24 @@ arge_init_locked(struct arge_softc *sc) arge_reset_dma(sc); - sc->arge_link_status = 0; - mii_mediachg(mii); + + if (sc->arge_miibus) { + sc->arge_link_status = 0; + mii = device_get_softc(sc->arge_miibus); + mii_mediachg(mii); + } + else { + /* + * Sun always shines over multiPHY interface + */ + sc->arge_link_status = 1; + } ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - callout_reset(&sc->arge_stat_callout, hz, arge_tick, sc); + if (sc->arge_miibus) + callout_reset(&sc->arge_stat_callout, hz, arge_tick, sc); ARGE_WRITE(sc, AR71XX_DMA_TX_DESC, ARGE_TX_RING_ADDR(sc, 0)); ARGE_WRITE(sc, AR71XX_DMA_RX_DESC, ARGE_RX_RING_ADDR(sc, 0)); @@ -899,7 +974,8 @@ arge_stop(struct arge_softc *sc) ifp = sc->arge_ifp; ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - callout_stop(&sc->arge_stat_callout); + if (sc->arge_miibus) + callout_stop(&sc->arge_stat_callout); /* mask out interrupts */ ARGE_WRITE(sc, AR71XX_DMA_INTR, 0); @@ -948,8 +1024,12 @@ arge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) break; case SIOCGIFMEDIA: case SIOCSIFMEDIA: - mii = device_get_softc(sc->arge_miibus); - error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); + if (sc->arge_miibus) { + mii = device_get_softc(sc->arge_miibus); + error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); + } + else + error = ifmedia_ioctl(ifp, ifr, &sc->arge_ifmedia, command); break; case SIOCSIFCAP: /* XXX: Check other capabilities */ @@ -1690,7 +1770,42 @@ arge_tick(void *xsc) ARGE_LOCK_ASSERT(sc); - mii = device_get_softc(sc->arge_miibus); - mii_tick(mii); - callout_reset(&sc->arge_stat_callout, hz, arge_tick, sc); + if (sc->arge_miibus) { + mii = device_get_softc(sc->arge_miibus); + mii_tick(mii); + callout_reset(&sc->arge_stat_callout, hz, arge_tick, sc); + } } + +int +arge_multiphy_mediachange(struct ifnet *ifp) +{ + struct arge_softc *sc = ifp->if_softc; + struct ifmedia *ifm = &sc->arge_ifmedia; + struct ifmedia_entry *ife = ifm->ifm_cur; + + if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) + return (EINVAL); + + if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) { + device_printf(sc->arge_dev, + "AUTO is not supported for multiphy MAC"); + return (EINVAL); + } + + /* + * Ignore everything + */ + return (0); +} + +void +arge_multiphy_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) +{ + struct arge_softc *sc = ifp->if_softc; + + ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE; + ifmr->ifm_active = IFM_ETHER | sc->arge_media_type | + sc->arge_duplex_mode; +} + diff --git a/sys/mips/atheros/if_argevar.h b/sys/mips/atheros/if_argevar.h index 40962ce58f1..bfa45099cc9 100644 --- a/sys/mips/atheros/if_argevar.h +++ b/sys/mips/atheros/if_argevar.h @@ -28,6 +28,7 @@ #ifndef __IF_ARGEVAR_H__ #define __IF_ARGEVAR_H__ +#define ARGE_NPHY 32 #define ARGE_TX_RING_COUNT 128 #define ARGE_RX_RING_COUNT 128 #define ARGE_RX_DMA_SIZE ARGE_RX_RING_COUNT * sizeof(struct arge_desc) @@ -124,6 +125,12 @@ struct arge_ring_data { struct arge_softc { struct ifnet *arge_ifp; /* interface info */ device_t arge_dev; + struct ifmedia arge_ifmedia; + /* + * Media & duples settings for multiPHY MAC + */ + uint32_t arge_media_type; + uint32_t arge_duplex_mode; struct resource *arge_res; int arge_rid; struct resource *arge_irq; @@ -140,7 +147,7 @@ struct arge_softc { int arge_detach; uint32_t arge_intr_status; int arge_mac_unit; - int arge_phy_num; + int arge_phymask; uint32_t arge_ddr_flush_reg; uint32_t arge_pll_reg; uint32_t arge_pll_reg_shift; From 04709b7c07ee4e5391fd3a338a4d79de5c97a948 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 12 Nov 2009 21:33:36 +0000 Subject: [PATCH 328/380] - Reorganize hints according to if_arge changes: set media for multiPHY MAC and use mask to specify PHYs. --- sys/mips/conf/AR71XX.hints | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/sys/mips/conf/AR71XX.hints b/sys/mips/conf/AR71XX.hints index 0593dc0d2cc..e3966ba8d64 100644 --- a/sys/mips/conf/AR71XX.hints +++ b/sys/mips/conf/AR71XX.hints @@ -29,16 +29,23 @@ hint.arge.0.at="nexus0" hint.arge.0.maddr=0x19000000 hint.arge.0.msize=0x1000 hint.arge.0.irq=2 +# PHY4 = 1 << 4 +hint.arge.0.phymask=0x10 # Uncomment this hint for RS (not PRO) -# hint.arge.0.phy=20 +# PHY20 = 1 << 20 +# hint.arge.0.phymask=0x100000 hint.arge.1.at="nexus0" hint.arge.1.maddr=0x1a000000 hint.arge.1.msize=0x1000 hint.arge.1.irq=3 -hint.arge.1.phy=3 +# PHY1, PHY2, PHY3 +hint.arge.1.phymask=0x0e +# should be 100 for RS +hint.arge.1.media=1000 +hint.arge.1.fduplex=1 # Uncomment this hint for RS (not PRO) -# hint.arge.1.phy=19 +# hint.arge.0.phymask=70000 # SPI flash hint.spi.0.at="nexus0" From b3d4d25037c2bb730141b6d1f9185a66a9671a5b Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Fri, 13 Nov 2009 09:24:09 +0000 Subject: [PATCH 329/380] Make pmap_copy_page() L2-cache friendly by doing the copy through the cacheable window on physical memory (KSEG0). On the Sibyte processor going through the uncacheable window (KSEG1) bypasses both L1 and L2 caches so we may end up with stale contents in the L2 cache. This also makes it consistent with the rest of the function that uses cacheable mappings to copy pages. Approved by: imp (mentor) --- sys/mips/mips/pmap.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index ed14869178b..137f5fce2fa 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -2415,7 +2415,7 @@ pmap_copy_page(vm_page_t src, vm_page_t dst) #endif { if ((phy_src < MIPS_KSEG0_LARGEST_PHYS) && (phy_dst < MIPS_KSEG0_LARGEST_PHYS)) { - /* easy case, all can be accessed via KSEG1 */ + /* easy case, all can be accessed via KSEG0 */ /* * Flush all caches for VA that are mapped to this page * to make sure that data in SDRAM is up to date @@ -2423,9 +2423,10 @@ pmap_copy_page(vm_page_t src, vm_page_t dst) pmap_flush_pvcache(src); mips_dcache_wbinv_range_index( MIPS_PHYS_TO_CACHED(phy_dst), NBPG); - va_src = MIPS_PHYS_TO_UNCACHED(phy_src); - va_dst = MIPS_PHYS_TO_UNCACHED(phy_dst); + va_src = MIPS_PHYS_TO_CACHED(phy_src); + va_dst = MIPS_PHYS_TO_CACHED(phy_dst); bcopy((caddr_t)va_src, (caddr_t)va_dst, PAGE_SIZE); + mips_dcache_wbinv_range(va_dst, PAGE_SIZE); } else { int cpu; struct local_sysmaps *sysm; From b39188331e57a74c417cfcbfe908422450544a53 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 18 Nov 2009 22:14:36 +0000 Subject: [PATCH 330/380] - Code reorg: extract mx25l_read and mx25l_write methods - Add entry for Spansion flash controller Submitted by: Eric L. Chen --- sys/dev/flash/mx25l.c | 227 +++++++++++++++++++++++++++--------------- 1 file changed, 146 insertions(+), 81 deletions(-) diff --git a/sys/dev/flash/mx25l.c b/sys/dev/flash/mx25l.c index ff51fd7c550..41e4e134570 100644 --- a/sys/dev/flash/mx25l.c +++ b/sys/dev/flash/mx25l.c @@ -59,6 +59,7 @@ struct mx25l_softc device_t sc_dev; uint8_t sc_manufacturer_id; uint16_t sc_device_id; + unsigned int sc_sectorsize; struct mtx sc_mtx; struct disk *sc_disk; struct proc *sc_p; @@ -85,6 +86,7 @@ struct mx25l_flash_ident flash_devices[] = { { "mx25ll32", 0xc2, 0x2016, 64 * 1024, 64 }, { "mx25ll64", 0xc2, 0x2017, 64 * 1024, 128 }, { "mx25ll128", 0xc2, 0x2018, 64 * 1024, 256 }, + { "s25fl128", 0x01, 0x2018, 64 * 1024, 256 }, }; static uint8_t @@ -200,6 +202,136 @@ mx25l_erase_sector(device_t dev, off_t sector) err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd); } +static int +mx25l_write(device_t dev, off_t offset, caddr_t data, off_t count) +{ + struct mx25l_softc *sc; + uint8_t txBuf[8], rxBuf[8]; + struct spi_command cmd; + off_t write_offset; + long bytes_to_write, bytes_writen; + device_t pdev; + int err = 0; + + pdev = device_get_parent(dev); + sc = device_get_softc(dev); + + cmd.tx_cmd_sz = 4; + cmd.rx_cmd_sz = 4; + + bytes_writen = 0; + write_offset = offset; + + /* + * Sanity checks + */ + KASSERT(count % sc->sc_sectorsize == 0, + ("count for BIO_WRITE is not sector size (%d bytes) aligned", + sc->sc_sectorsize)); + + KASSERT(offset % sc->sc_sectorsize == 0, + ("offset for BIO_WRITE is not sector size (%d bytes) aligned", + sc->sc_sectorsize)); + + /* + * Assume here that we write per-sector only + * and sector size should be 256 bytes aligned + */ + KASSERT(write_offset % FLASH_PAGE_SIZE == 0, + ("offset for BIO_WRITE is not page size (%d bytes) aligned", + FLASH_PAGE_SIZE)); + + /* + * Maximum write size for CMD_PAGE_PROGRAM is + * FLASH_PAGE_SIZE, so split data to chunks + * FLASH_PAGE_SIZE bytes eash and write them + * one by one + */ + while (bytes_writen < count) { + /* + * If we crossed sector boundary - erase next sector + */ + if (((offset + bytes_writen) % sc->sc_sectorsize) == 0) + mx25l_erase_sector(dev, offset + bytes_writen); + + txBuf[0] = CMD_PAGE_PROGRAM; + txBuf[1] = ((write_offset >> 16) & 0xff); + txBuf[2] = ((write_offset >> 8) & 0xff); + txBuf[3] = (write_offset & 0xff); + + bytes_to_write = MIN(FLASH_PAGE_SIZE, + count - bytes_writen); + cmd.tx_cmd = txBuf; + cmd.rx_cmd = rxBuf; + cmd.tx_data = data + bytes_writen; + cmd.tx_data_sz = bytes_to_write; + cmd.rx_data = data + bytes_writen; + cmd.rx_data_sz = bytes_to_write; + + /* + * Eash completed write operation resets WEL + * (write enable latch) to disabled state, + * so we re-enable it here + */ + mx25l_wait_for_device_ready(dev); + mx25l_set_writable(dev, 1); + + err = SPIBUS_TRANSFER(pdev, dev, &cmd); + if (err) + break; + + bytes_writen += bytes_to_write; + write_offset += bytes_to_write; + } + + return (err); +} + +static int +mx25l_read(device_t dev, off_t offset, caddr_t data, off_t count) +{ + struct mx25l_softc *sc; + uint8_t txBuf[8], rxBuf[8]; + struct spi_command cmd; + device_t pdev; + int err = 0; + + pdev = device_get_parent(dev); + sc = device_get_softc(dev); + + /* + * Sanity checks + */ + KASSERT(count % sc->sc_sectorsize == 0, + ("count for BIO_WRITE is not sector size (%d bytes) aligned", + sc->sc_sectorsize)); + + KASSERT(offset % sc->sc_sectorsize == 0, + ("offset for BIO_WRITE is not sector size (%d bytes) aligned", + sc->sc_sectorsize)); + + txBuf[0] = CMD_FAST_READ; + cmd.tx_cmd_sz = 5; + cmd.rx_cmd_sz = 5; + + txBuf[1] = ((offset >> 16) & 0xff); + txBuf[2] = ((offset >> 8) & 0xff); + txBuf[3] = (offset & 0xff); + /* Dummy byte */ + txBuf[4] = 0; + + cmd.tx_cmd = txBuf; + cmd.rx_cmd = rxBuf; + cmd.tx_data = data; + cmd.tx_data_sz = count; + cmd.rx_data = data; + cmd.rx_data_sz = count; + + err = SPIBUS_TRANSFER(pdev, dev, &cmd); + + return (err); +} + static int mx25l_probe(device_t dev) { @@ -235,6 +367,8 @@ mx25l_attach(device_t dev) sc->sc_disk->d_mediasize = ident->sectorsize * ident->sectorcount; sc->sc_disk->d_unit = device_get_unit(sc->sc_dev); sc->sc_disk->d_dump = NULL; /* NB: no dumps */ + /* Sectorsize for erase operations */ + sc->sc_sectorsize = ident->sectorsize; /* NB: use stripesize to hold the erase/region size for RedBoot */ sc->sc_disk->d_stripesize = ident->sectorsize; @@ -294,15 +428,10 @@ mx25l_task(void *arg) { struct mx25l_softc *sc = (struct mx25l_softc*)arg; struct bio *bp; - uint8_t txBuf[8], rxBuf[8]; - struct spi_command cmd; - device_t dev, pdev; - off_t write_offset; - long bytes_to_write, bytes_writen; + device_t dev; for (;;) { dev = sc->sc_dev; - pdev = device_get_parent(dev); M25PXX_LOCK(sc); do { bp = bioq_first(&sc->sc_bio_queue); @@ -312,82 +441,18 @@ mx25l_task(void *arg) bioq_remove(&sc->sc_bio_queue, bp); M25PXX_UNLOCK(sc); - if (bp->bio_cmd == BIO_READ) { - txBuf[0] = CMD_FAST_READ; - cmd.tx_cmd_sz = 5; - cmd.rx_cmd_sz = 5; - - txBuf[1] = (((bp->bio_offset) >> 16) & 0xff); - txBuf[2] = (((bp->bio_offset) >> 8) & 0xff); - txBuf[3] = ((bp->bio_offset) & 0xff); - /* Dummy byte */ - txBuf[4] = 0; - - cmd.tx_cmd = txBuf; - cmd.rx_cmd = rxBuf; - cmd.tx_data = bp->bio_data; - cmd.tx_data_sz = bp->bio_bcount; - cmd.rx_data = bp->bio_data; - cmd.rx_data_sz = bp->bio_bcount; - - bp->bio_error = SPIBUS_TRANSFER(pdev, dev, &cmd); - } - else if (bp->bio_cmd == BIO_WRITE) { - mx25l_erase_sector(dev, bp->bio_offset); - - cmd.tx_cmd_sz = 4; - cmd.rx_cmd_sz = 4; - - bytes_writen = 0; - write_offset = bp->bio_offset; - - /* - * I assume here that we write per-sector only - * and sector size should be 256 bytes aligned - */ - KASSERT(write_offset % FLASH_PAGE_SIZE == 0, - ("offset for BIO_WRITE is not %d bytes aliIgned", - FLASH_PAGE_SIZE)); - - /* - * Maximum write size for CMD_PAGE_PROGRAM is - * FLASH_PAGE_SIZE, so split data to chunks - * FLASH_PAGE_SIZE bytes eash and write them - * one by one - */ - while (bytes_writen < bp->bio_bcount) { - txBuf[0] = CMD_PAGE_PROGRAM; - txBuf[1] = ((write_offset >> 16) & 0xff); - txBuf[2] = ((write_offset >> 8) & 0xff); - txBuf[3] = (write_offset & 0xff); - - bytes_to_write = MIN(FLASH_PAGE_SIZE, - bp->bio_bcount - bytes_writen); - cmd.tx_cmd = txBuf; - cmd.rx_cmd = rxBuf; - cmd.tx_data = bp->bio_data + bytes_writen; - cmd.tx_data_sz = bytes_to_write; - cmd.rx_data = bp->bio_data + bytes_writen; - cmd.rx_data_sz = bytes_to_write; - - /* - * Eash completed write operation resets WEL - * (write enable latch) to disabled state, - * so we re-enable it here - */ - mx25l_wait_for_device_ready(dev); - mx25l_set_writable(dev, 1); - - bp->bio_error = SPIBUS_TRANSFER(pdev, dev, &cmd); - if (bp->bio_error) - break; - - bytes_writen += bytes_to_write; - write_offset += bytes_to_write; - } - } - else + switch (bp->bio_cmd) { + case BIO_READ: + bp->bio_error = mx25l_read(dev, bp->bio_offset, + bp->bio_data, bp->bio_bcount); + break; + case BIO_WRITE: + bp->bio_error = mx25l_write(dev, bp->bio_offset, + bp->bio_data, bp->bio_bcount); + break; + default: bp->bio_error = EINVAL; + } biodone(bp); From 51d85c463d924f41adfc26ee8c4bfcec4c1fe280 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 18 Nov 2009 22:52:05 +0000 Subject: [PATCH 331/380] - Add cpu_init_interrupts function that is supposed to prepeare stuff required for spinning out interrupts later - Add API for managing intrcnt/intrnames arrays - Some minor style(9) fixes --- sys/mips/include/intr_machdep.h | 14 +++++++ sys/mips/mips/exception.S | 15 +++---- sys/mips/mips/genassym.c | 1 + sys/mips/mips/intr_machdep.c | 69 ++++++++++++++++++++++++++------- sys/mips/mips/machdep.c | 12 +++--- 5 files changed, 84 insertions(+), 27 deletions(-) diff --git a/sys/mips/include/intr_machdep.h b/sys/mips/include/intr_machdep.h index 79cdf9e041c..d72828eead2 100644 --- a/sys/mips/include/intr_machdep.h +++ b/sys/mips/include/intr_machdep.h @@ -52,11 +52,25 @@ extern struct mips_intrhand mips_intr_handlers[]; struct trapframe; +void cpu_init_interrupts(void); void cpu_establish_hardintr(const char *, driver_filter_t *, driver_intr_t *, void *, int, int, void **); void cpu_establish_softintr(const char *, driver_filter_t *, void (*)(void*), void *, int, int, void **); void cpu_intr(struct trapframe *); +/* + * Opaque datatype that represents intr counter + */ +typedef unsigned long* mips_intrcnt_t; +mips_intrcnt_t mips_intrcnt_create(const char *); +void mips_intrcnt_setname(mips_intrcnt_t, const char *); + +static __inline void +mips_intrcnt_inc(mips_intrcnt_t counter) +{ + if (counter) + atomic_add_long(counter, 1); +} #endif /* !_MACHINE_INTR_MACHDEP_H_ */ diff --git a/sys/mips/mips/exception.S b/sys/mips/mips/exception.S index 2fc1bb83839..8ea732b0023 100644 --- a/sys/mips/mips/exception.S +++ b/sys/mips/mips/exception.S @@ -96,6 +96,11 @@ .set mips3 #endif +/* + * Reasonable limit + */ +#define INTRCNT_COUNT 128 + /* * Assume that w alaways need nops to escape CP0 hazard * TODO: Make hazard delays configurable. Stuck with 5 cycles on the moment @@ -1273,15 +1278,11 @@ END(MipsFPTrap) .globl intrnames .globl eintrnames intrnames: - .asciiz "clock" - .asciiz "rtc" - .asciiz "sio" - .asciiz "pe" - .asciiz "pic-nic" + .space INTRCNT_COUNT * (MAXCOMLEN + 1) * 2 eintrnames: - .align 2 + .align 4 intrcnt: - .word 0,0,0,0,0 + .space INTRCNT_COUNT * 4 * 2 eintrcnt: diff --git a/sys/mips/mips/genassym.c b/sys/mips/mips/genassym.c index ce95cc6b60e..81ed9df4e4a 100644 --- a/sys/mips/mips/genassym.c +++ b/sys/mips/mips/genassym.c @@ -99,3 +99,4 @@ ASSYM(NPTEPG, NPTEPG); ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED); ASSYM(TDF_ASTPENDING, TDF_ASTPENDING); ASSYM(PCPU_SIZE, sizeof(struct pcpu)); +ASSYM(MAXCOMLEN, MAXCOMLEN); diff --git a/sys/mips/mips/intr_machdep.c b/sys/mips/mips/intr_machdep.c index c42b5fb729d..530cc08c247 100644 --- a/sys/mips/mips/intr_machdep.c +++ b/sys/mips/mips/intr_machdep.c @@ -46,12 +46,29 @@ __FBSDID("$FreeBSD$"); static struct intr_event *hardintr_events[NHARD_IRQS]; static struct intr_event *softintr_events[NSOFT_IRQS]; +static mips_intrcnt_t mips_intr_counters[NSOFT_IRQS + NHARD_IRQS]; -#ifdef notyet -static int intrcnt_tab[NHARD_IRQS + NSOFT_IRQS]; -static int intrcnt_index = 0; -static int last_printed = 0; -#endif +static int intrcnt_index; + +mips_intrcnt_t +mips_intrcnt_create(const char* name) +{ + mips_intrcnt_t counter = &intrcnt[intrcnt_index++]; + + mips_intrcnt_setname(counter, name); + return counter; +} + +void +mips_intrcnt_setname(mips_intrcnt_t counter, const char *name) +{ + int idx = counter - intrcnt; + + KASSERT(counter != NULL, ("mips_intrcnt_setname: NULL counter")); + + snprintf(intrnames + (MAXCOMLEN + 1) * idx, + MAXCOMLEN + 1, "%-*s", MAXCOMLEN, name); +} static void mips_mask_hard_irq(void *source) @@ -85,6 +102,30 @@ mips_unmask_soft_irq(void *source) mips_wr_status(mips_rd_status() | ((1 << irq) << 8)); } +/* + * Perform initialization of interrupts prior to setting + * handlings + */ +void +cpu_init_interrupts() +{ + int i; + char name[MAXCOMLEN + 1]; + + /* + * Initialize all available vectors so spare IRQ + * would show up in systat output + */ + for (i = 0; i < NSOFT_IRQS; i++) { + snprintf(name, MAXCOMLEN + 1, "sint%d:", i); + mips_intr_counters[i] = mips_intrcnt_create(name); + } + + for (i = 0; i < NHARD_IRQS; i++) { + snprintf(name, MAXCOMLEN + 1, "int%d:", i); + mips_intr_counters[NSOFT_IRQS + i] = mips_intrcnt_create(name); + } +} void cpu_establish_hardintr(const char *name, driver_filter_t *filt, @@ -107,23 +148,17 @@ cpu_establish_hardintr(const char *name, driver_filter_t *filt, if (event == NULL) { error = intr_event_create(&event, (void *)(uintptr_t)irq, 0, irq, mips_mask_hard_irq, mips_unmask_hard_irq, - NULL, NULL, "hard intr%d:", irq); + NULL, NULL, "int%d", irq); if (error) return; hardintr_events[irq] = event; -#ifdef notyet - last_printed += snprintf(intrnames + last_printed, - MAXCOMLEN + 1, "hard irq%d: %s", irq, name); - last_printed++; - intrcnt_tab[irq] = intrcnt_index; - intrcnt_index++; -#endif - } intr_event_add_handler(event, name, filt, handler, arg, intr_priority(flags), flags, cookiep); + mips_intrcnt_setname(mips_intr_counters[NSOFT_IRQS + irq], event->ie_fullname); + mips_unmask_hard_irq((void*)(uintptr_t)irq); } @@ -146,7 +181,7 @@ cpu_establish_softintr(const char *name, driver_filter_t *filt, if (event == NULL) { error = intr_event_create(&event, (void *)(uintptr_t)irq, 0, irq, mips_mask_soft_irq, mips_unmask_soft_irq, - NULL, NULL, "intr%d:", irq); + NULL, NULL, "sint%d:", irq); if (error) return; softintr_events[irq] = event; @@ -155,6 +190,8 @@ cpu_establish_softintr(const char *name, driver_filter_t *filt, intr_event_add_handler(event, name, filt, handler, arg, intr_priority(flags), flags, cookiep); + mips_intrcnt_setname(mips_intr_counters[irq], event->ie_fullname); + mips_unmask_soft_irq((void*)(uintptr_t)irq); } @@ -184,6 +221,7 @@ cpu_intr(struct trapframe *tf) i--; /* Get a 0-offset interrupt. */ hard = 0; event = softintr_events[i]; + mips_intrcnt_inc(mips_intr_counters[i]); break; default: /* Hardware interrupt. */ @@ -191,6 +229,7 @@ cpu_intr(struct trapframe *tf) i--; /* Get a 0-offset interrupt. */ hard = 1; event = hardintr_events[i]; + mips_intrcnt_inc(mips_intr_counters[NSOFT_IRQS + i]); break; } diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c index b06898dbbcd..61e0da544e1 100644 --- a/sys/mips/mips/machdep.c +++ b/sys/mips/mips/machdep.c @@ -75,16 +75,17 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include -#include -#include -#include -#include -#include #include #include +#include +#include +#include #include +#include +#include #ifdef DDB #include #include @@ -186,6 +187,7 @@ cpu_startup(void *dummy) printf("avail memory = %lu (%luMB)\n", ptoa(cnt.v_free_count), ptoa(cnt.v_free_count) / 1048576); + cpu_init_interrupts(); /* * Set up buffers, so they can be used to read disk labels. From 2839b59a94177bb9115437264e9209c4b1c967e0 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 18 Nov 2009 22:53:05 +0000 Subject: [PATCH 332/380] - Add intr counters for APB interrupts --- sys/mips/atheros/apb.c | 13 +++++++++++-- sys/mips/atheros/apbvar.h | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/sys/mips/atheros/apb.c b/sys/mips/atheros/apb.c index ee8a167c76c..d71b24210e0 100644 --- a/sys/mips/atheros/apb.c +++ b/sys/mips/atheros/apb.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -285,11 +286,18 @@ apb_setup_intr(device_t bus, device_t child, struct resource *ires, NULL, NULL, "apb intr%d:", irq); - sc->sc_eventstab[irq] = event; + if (error == 0) { + sc->sc_eventstab[irq] = event; + sc->sc_intr_counter[irq] = + mips_intrcnt_create(event->ie_name); + } + else + return (error); } intr_event_add_handler(event, device_get_nameunit(child), filt, handler, arg, intr_priority(flags), flags, cookiep); + mips_intrcnt_setname(sc->sc_intr_counter[irq], event->ie_fullname); apb_unmask_irq((void*)irq); @@ -333,12 +341,13 @@ apb_intr(void *arg) if (!event || TAILQ_EMPTY(&event->ie_handlers)) { /* Ignore timer interrupts */ if (irq != 0) - printf("Stray IRQ %d\n", irq); + printf("Stray APB IRQ %d\n", irq); continue; } /* TODO: frame instead of NULL? */ intr_event_handle(event, NULL); + mips_intrcnt_inc(sc->sc_intr_counter[irq]); } } diff --git a/sys/mips/atheros/apbvar.h b/sys/mips/atheros/apbvar.h index 9afd690d2a8..2706034d254 100644 --- a/sys/mips/atheros/apbvar.h +++ b/sys/mips/atheros/apbvar.h @@ -37,6 +37,7 @@ struct apb_softc { struct rman apb_mem_rman; /* IRQ events structs for child devices */ struct intr_event *sc_eventstab[APB_NIRQS]; + mips_intrcnt_t sc_intr_counter[APB_NIRQS]; /* Resources and cookies for MIPS CPU INTs */ struct resource *sc_misc_irq; void *sc_misc_ih; From 21ed765c7f53b2bb7acd7483a00ccdafdf6c2b7a Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 20 Nov 2009 15:56:51 +0000 Subject: [PATCH 333/380] Formatting nit. --- sys/mips/octeon1/uart_bus_octeonusart.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/mips/octeon1/uart_bus_octeonusart.c b/sys/mips/octeon1/uart_bus_octeonusart.c index 63b5e9b5e29..2916aa0a24e 100644 --- a/sys/mips/octeon1/uart_bus_octeonusart.c +++ b/sys/mips/octeon1/uart_bus_octeonusart.c @@ -85,8 +85,9 @@ static driver_t uart_octeon_driver = { extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; - static int - uart_octeon_probe(device_t dev) + +static int +uart_octeon_probe(device_t dev) { struct uart_softc *sc; int unit; From 6ecc37e7947094626955ae65ad7a73a7fc5d7d17 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 20 Nov 2009 15:57:45 +0000 Subject: [PATCH 334/380] Don't assume register addresses can fit into void *. Minor formatting simplification while I'm here. --- sys/mips/octeon1/octeon_machdep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/mips/octeon1/octeon_machdep.c b/sys/mips/octeon1/octeon_machdep.c index 140187407a9..c1f90a1393f 100644 --- a/sys/mips/octeon1/octeon_machdep.c +++ b/sys/mips/octeon1/octeon_machdep.c @@ -605,8 +605,8 @@ void ciu_dump_interrutps_enabled (int core_num, int intx, int enx, int ciu_ip) } ciu_intr_bits = oct_read64(ciu_intr_reg_addr); - printf(" CIU core %d int: %d en: %d ip: %d Add: %p enabled: 0x%llX SR: %x\n", - core_num, intx, enx, ciu_ip, (void *)ciu_intr_reg_addr, + printf(" CIU core %d int: %d en: %d ip: %d Add: %#llx enabled: %#llx SR: %x\n", + core_num, intx, enx, ciu_ip, (unsigned long long)ciu_intr_reg_addr, (unsigned long long)ciu_intr_bits, mips_rd_status()); } From 6962307a9a971f4c57df0280fc78027d67c40101 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 20 Nov 2009 15:59:41 +0000 Subject: [PATCH 335/380] If we're ompiling ISA_MIPS32, then use the 32-bit address-size definitions. --- sys/mips/octeon1/octeon_pcmap_regs.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/mips/octeon1/octeon_pcmap_regs.h b/sys/mips/octeon1/octeon_pcmap_regs.h index 8834a9b55e3..1655566e568 100644 --- a/sys/mips/octeon1/octeon_pcmap_regs.h +++ b/sys/mips/octeon1/octeon_pcmap_regs.h @@ -6,6 +6,7 @@ #ifndef __OCTEON_PCMAP_REGS_H__ #define __OCTEON_PCMAP_REGS_H__ +#include "opt_cputype.h" #define OCTEON_CACHE_LINE_SIZE 0x80 /* 128 bytes cache line size */ #define IS_OCTEON_ALIGNED(p) (!((u_long)(p) & 0x7f)) @@ -549,7 +550,7 @@ typedef enum { /* PTR_SIZE == sizeof(uint32_t) */ -#if 0 +#ifdef ISA_MIPS32 #define mipsx_addr_size uint32_t // u_int64 #define MIPSX_ADDR_SIZE_KSEGX_BIT_SHIFT 30 // 62 #define MIPSX_ADDR_SIZE_KSEGX_MASK_REMOVED 0x1fffffff // 0x1fffffff From e7a9535945aec26bc21ffdfb91ab4d916556c077 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 20 Nov 2009 16:23:04 +0000 Subject: [PATCH 336/380] 32-bit mixed-mode OCTEON kernel config file. --- sys/mips/conf/OCTEON1-32 | 90 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 sys/mips/conf/OCTEON1-32 diff --git a/sys/mips/conf/OCTEON1-32 b/sys/mips/conf/OCTEON1-32 new file mode 100644 index 00000000000..c3c0d176ae9 --- /dev/null +++ b/sys/mips/conf/OCTEON1-32 @@ -0,0 +1,90 @@ +# OCTEON1 -- Configuration kernel for all Octeon1 SoCs from Cavium Networks +# +# For more information on this file, please read the handbook section on +# Kernel Configuration Files: +# +# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# +# The handbook is also available locally in /usr/share/doc/handbook +# if you've installed the doc distribution, otherwise always see the +# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# latest information. +# +# An exhaustive list of options and more detailed explanations of the +# device lines is also present in the ../../conf/NOTES and NOTES files. +# If you are in doubt as to the purpose or necessity of a line, check first +# in NOTES. +# +# $FreeBSD$ + +machine mips +cpu CPU_MIPS4KC +ident OCTEON1 + +#makeoptions ARCH_FLAGS="-march=mips64 -mabi=64" +#makeoptions LDSCRIPT_NAME= ldscript.mips.mips64 + +# Don't build any modules yet. +makeoptions MODULES_OVERRIDE="" +makeoptions TARGET_BIG_ENDIAN=defined +#makeoptions TARGET_64BIT=defined + +options KERNVIRTADDR=0x80100000 +include "../octeon1/std.octeon1" + +hints "OCTEON1.hints" #Default places to look for devices. + +makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols + +#XXXimp: Need to make work with 64-bit too +#options ISA_MIPS64 +options ISA_MIPS32 + +options DDB +options KDB + +options SCHED_4BSD #4BSD scheduler +options INET #InterNETworking +options NFSCLIENT #Network Filesystem Client +#options NFS_ROOT #NFS usable as /, requires NFSCLIENT +options PSEUDOFS #Pseudo-filesystem framework +options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions +#options ROOTDEVNAME=\"ufs:ad0s1a\" # Original +options NO_SWAPPING + + +options FFS #Berkeley Fast Filesystem +options SOFTUPDATES #Enable FFS soft updates support +options UFS_ACL #Support for access control lists +options UFS_DIRHASH #Improve performance on big directories + + +# Debugging for use in -current +options INVARIANTS #Enable calls of extra sanity checking +options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS +#options WITNESS #Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed + +#XXXimp device genclock +device loop +device ether +device md +device uart +nodevice uart_ns8250 +device rgmii +#options VERBOSE_SYSINIT + + +# +# Use the following for Compact Flash file-system +device cf +options ROOTDEVNAME = \"ufs:cf0s2\" # Unmask if compact flash is needed as RFS + +# +# Use the following for RFS in mem-device +#options MD_ROOT +#options ROOTDEVNAME = \"ufs:md0\" + +#options MD_ROOT_SIZE = 21264 +#XXX: Bring up UP first, then generalize. +#options SMP From 1e80c0e4aaa81a1e15a583118c1eb849845c6b30 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 20 Nov 2009 16:27:50 +0000 Subject: [PATCH 337/380] cast vaddr to uintptr_t before casting it to a bus_space_handle_t. # I'm sure this indicates a problem, but I'm not sure what... --- sys/mips/mips/nexus.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/mips/mips/nexus.c b/sys/mips/mips/nexus.c index 0e6f3954f64..a325f3ebb9f 100644 --- a/sys/mips/mips/nexus.c +++ b/sys/mips/mips/nexus.c @@ -404,6 +404,7 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid, * If this is a memory resource, track the direct mapping * in the uncached MIPS KSEG1 segment. */ + /* XXX we shouldn't be supporting sys_res_ioport here */ if ((type == SYS_RES_MEMORY) || (type == SYS_RES_IOPORT)) { caddr_t vaddr = 0; u_int32_t paddr; @@ -417,7 +418,7 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid, rman_set_virtual(r, vaddr); rman_set_bustag(r, mips_bus_space_generic); - rman_set_bushandle(r, (bus_space_handle_t)vaddr); + rman_set_bushandle(r, (bus_space_handle_t)(uintptr_t)vaddr); } return (rman_activate_resource(r)); From 10153d080c87e1779f519e69b557a440b74aefcb Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 20 Nov 2009 16:30:35 +0000 Subject: [PATCH 338/380] Horrible kludge to make octeon32 work. I think a better way is to move the generic code into the config files.... --- sys/mips/mips/bus_space_generic.c | 79 +++++++++++++++++++------------ 1 file changed, 49 insertions(+), 30 deletions(-) diff --git a/sys/mips/mips/bus_space_generic.c b/sys/mips/mips/bus_space_generic.c index 8f8ec6283e2..84ca7765ace 100644 --- a/sys/mips/mips/bus_space_generic.c +++ b/sys/mips/mips/bus_space_generic.c @@ -196,6 +196,25 @@ static struct bus_space generic_space = { NULL, }; +/* Ultra-gross kludge */ +#include "opt_cputype.h" +#if defined(TARGET_OCTEON) && defined(ISA_MIPS32) +#include +#define rd8(a) oct_read8(a) +#define rd16(a) oct_read16(a) +#define rd32(a) oct_read32(a) +#define wr8(a, v) oct_write8(a, v) +#define wr16(a, v) oct_write16(a, v) +#define wr32(a, v) oct_write32(a, v) +#else +#define rd8(a) readb(a) +#define rd16(a) readw(a) +#define rd32(a) readl(a) +#define wr8(a, v) writeb(a, v) +#define wr16(a, v) writew(a, v) +#define wr32(a, v) writel(a, v) +#endif + /* generic bus_space tag */ bus_space_tag_t mips_bus_space_generic = &generic_space; @@ -233,7 +252,7 @@ generic_bs_r_1(void *t, bus_space_handle_t handle, bus_size_t offset) { - return (readb(handle + offset)); + return (rd8(handle + offset)); } u_int16_t @@ -241,7 +260,7 @@ generic_bs_r_2(void *t, bus_space_handle_t handle, bus_size_t offset) { - return (readw(handle + offset)); + return (rd16(handle + offset)); } u_int32_t @@ -249,7 +268,7 @@ generic_bs_r_4(void *t, bus_space_handle_t handle, bus_size_t offset) { - return (readl(handle + offset)); + return (rd32(handle + offset)); } @@ -259,7 +278,7 @@ generic_bs_rm_1(void *t, bus_space_handle_t bsh, { while (count--) - *addr++ = readb(bsh + offset); + *addr++ = rd8(bsh + offset); } void @@ -269,7 +288,7 @@ generic_bs_rm_2(void *t, bus_space_handle_t bsh, bus_addr_t baddr = bsh + offset; while (count--) - *addr++ = readw(baddr); + *addr++ = rd16(baddr); } void @@ -279,7 +298,7 @@ generic_bs_rm_4(void *t, bus_space_handle_t bsh, bus_addr_t baddr = bsh + offset; while (count--) - *addr++ = readl(baddr); + *addr++ = rd32(baddr); } @@ -295,7 +314,7 @@ generic_bs_rr_1(void *t, bus_space_handle_t bsh, bus_addr_t baddr = bsh + offset; while (count--) { - *addr++ = readb(baddr); + *addr++ = rd8(baddr); baddr += 1; } } @@ -307,7 +326,7 @@ generic_bs_rr_2(void *t, bus_space_handle_t bsh, bus_addr_t baddr = bsh + offset; while (count--) { - *addr++ = readw(baddr); + *addr++ = rd16(baddr); baddr += 2; } } @@ -319,7 +338,7 @@ generic_bs_rr_4(void *t, bus_space_handle_t bsh, bus_addr_t baddr = bsh + offset; while (count--) { - *addr++ = readl(baddr); + *addr++ = rd32(baddr); baddr += 4; } } @@ -333,7 +352,7 @@ generic_bs_w_1(void *t, bus_space_handle_t bsh, bus_size_t offset, u_int8_t value) { - writeb(bsh + offset, value); + wr8(bsh + offset, value); } void @@ -341,7 +360,7 @@ generic_bs_w_2(void *t, bus_space_handle_t bsh, bus_size_t offset, u_int16_t value) { - writew(bsh + offset, value); + wr16(bsh + offset, value); } void @@ -349,7 +368,7 @@ generic_bs_w_4(void *t, bus_space_handle_t bsh, bus_size_t offset, u_int32_t value) { - writel(bsh + offset, value); + wr32(bsh + offset, value); } /* @@ -363,7 +382,7 @@ generic_bs_wm_1(void *t, bus_space_handle_t bsh, bus_addr_t baddr = bsh + offset; while (count--) - writeb(baddr, *addr++); + wr8(baddr, *addr++); } void @@ -373,7 +392,7 @@ generic_bs_wm_2(void *t, bus_space_handle_t bsh, bus_addr_t baddr = bsh + offset; while (count--) - writew(baddr, *addr++); + wr16(baddr, *addr++); } void @@ -383,7 +402,7 @@ generic_bs_wm_4(void *t, bus_space_handle_t bsh, bus_addr_t baddr = bsh + offset; while (count--) - writel(baddr, *addr++); + wr32(baddr, *addr++); } /* @@ -397,7 +416,7 @@ generic_bs_wr_1(void *t, bus_space_handle_t bsh, bus_addr_t baddr = bsh + offset; while (count--) { - writeb(baddr, *addr++); + wr8(baddr, *addr++); baddr += 1; } } @@ -409,7 +428,7 @@ generic_bs_wr_2(void *t, bus_space_handle_t bsh, bus_addr_t baddr = bsh + offset; while (count--) { - writew(baddr, *addr++); + wr16(baddr, *addr++); baddr += 2; } } @@ -421,7 +440,7 @@ generic_bs_wr_4(void *t, bus_space_handle_t bsh, bus_addr_t baddr = bsh + offset; while (count--) { - writel(baddr, *addr++); + wr32(baddr, *addr++); baddr += 4; } } @@ -437,7 +456,7 @@ generic_bs_sm_1(void *t, bus_space_handle_t bsh, bus_addr_t addr = bsh + offset; while (count--) - writeb(addr, value); + wr8(addr, value); } void @@ -447,7 +466,7 @@ generic_bs_sm_2(void *t, bus_space_handle_t bsh, bus_addr_t addr = bsh + offset; while (count--) - writew(addr, value); + wr16(addr, value); } void @@ -457,7 +476,7 @@ generic_bs_sm_4(void *t, bus_space_handle_t bsh, bus_addr_t addr = bsh + offset; while (count--) - writel(addr, value); + wr32(addr, value); } /* @@ -471,7 +490,7 @@ generic_bs_sr_1(void *t, bus_space_handle_t bsh, bus_addr_t addr = bsh + offset; for (; count != 0; count--, addr++) - writeb(addr, value); + wr8(addr, value); } void @@ -481,7 +500,7 @@ generic_bs_sr_2(void *t, bus_space_handle_t bsh, bus_addr_t addr = bsh + offset; for (; count != 0; count--, addr += 2) - writew(addr, value); + wr16(addr, value); } void @@ -491,7 +510,7 @@ generic_bs_sr_4(void *t, bus_space_handle_t bsh, bus_addr_t addr = bsh + offset; for (; count != 0; count--, addr += 4) - writel(addr, value); + wr32(addr, value); } /* @@ -509,12 +528,12 @@ generic_bs_c_1(void *t, bus_space_handle_t bsh1, if (addr1 >= addr2) { /* src after dest: copy forward */ for (; count != 0; count--, addr1++, addr2++) - writeb(addr2, readb(addr1)); + wr8(addr2, rd8(addr1)); } else { /* dest after src: copy backwards */ for (addr1 += (count - 1), addr2 += (count - 1); count != 0; count--, addr1--, addr2--) - writeb(addr2, readb(addr1)); + wr8(addr2, rd8(addr1)); } } @@ -529,12 +548,12 @@ generic_bs_c_2(void *t, bus_space_handle_t bsh1, if (addr1 >= addr2) { /* src after dest: copy forward */ for (; count != 0; count--, addr1 += 2, addr2 += 2) - writew(addr2, readw(addr1)); + wr16(addr2, rd16(addr1)); } else { /* dest after src: copy backwards */ for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1); count != 0; count--, addr1 -= 2, addr2 -= 2) - writew(addr2, readw(addr1)); + wr16(addr2, rd16(addr1)); } } @@ -549,12 +568,12 @@ generic_bs_c_4(void *t, bus_space_handle_t bsh1, if (addr1 >= addr2) { /* src after dest: copy forward */ for (; count != 0; count--, addr1 += 4, addr2 += 4) - writel(addr2, readl(addr1)); + wr32(addr2, rd32(addr1)); } else { /* dest after src: copy backwards */ for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1); count != 0; count--, addr1 -= 4, addr2 -= 4) - writel(addr2, readl(addr1)); + wr32(addr2, rd32(addr1)); } } From 714697cd3d3220c0be6bfc2d37cd88d668c45eb4 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 20 Nov 2009 16:32:26 +0000 Subject: [PATCH 339/380] Another kludge for 64-bit bus_addr_t with 32-bit pointers... --- sys/mips/include/_bus.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sys/mips/include/_bus.h b/sys/mips/include/_bus.h index df6169a2f4e..3ba6e2cc1ee 100644 --- a/sys/mips/include/_bus.h +++ b/sys/mips/include/_bus.h @@ -34,12 +34,17 @@ /* * Bus address and size types */ +#include "opt_cputype.h" +#if !(defined(TARGET_OCTEON) || defined(ISA_MIPS32)) typedef uintptr_t bus_addr_t; +#else +typedef uint64_t bus_addr_t; +#endif typedef uintptr_t bus_size_t; /* * Access methods for bus resources and address space. */ typedef struct bus_space *bus_space_tag_t; -typedef u_long bus_space_handle_t; +typedef bus_addr_t bus_space_handle_t; #endif /* MIPS_INCLUDE__BUS_H */ From cefc105a5436b36cd39ab6ef9886fbedba54246c Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 23 Nov 2009 07:11:10 +0000 Subject: [PATCH 340/380] Linker scripts for octeon1 kernels of various flavors. --- sys/conf/ldscript.mips.octeon1.kernel.32 | 60 ++++++++++++++++++++++ sys/conf/ldscript.mips.octeon1.kernel.64 | 61 +++++++++++++++++++++++ sys/conf/ldscript.mips.octeon1.kernel.n32 | 57 +++++++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 sys/conf/ldscript.mips.octeon1.kernel.32 create mode 100644 sys/conf/ldscript.mips.octeon1.kernel.64 create mode 100644 sys/conf/ldscript.mips.octeon1.kernel.n32 diff --git a/sys/conf/ldscript.mips.octeon1.kernel.32 b/sys/conf/ldscript.mips.octeon1.kernel.32 new file mode 100644 index 00000000000..cac9db29a53 --- /dev/null +++ b/sys/conf/ldscript.mips.octeon1.kernel.32 @@ -0,0 +1,60 @@ +/* + * This product includes software developed by the University of + * California, Berkeley and its contributors." +*/ +OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips") +OUTPUT_ARCH(mips) +ENTRY(_start) + __DYNAMIC = 0; +PROVIDE (_DYNAMIC = 0); + +SECTIONS { + + .text . : { + *(.text) + *(.dynamic) + etext = .; + _etext = .; + . = ALIGN(0x2000); + } + + .rodata ALIGN(0x2000) : { + _fdata = .; + *(.rodata) + . = ALIGN(32); + } + + .data . : { + _rwdata = .; + *(.data) + . = ALIGN(32); + CONSTRUCTORS; + } + + _gp = (. + 0x8000); + + .sdata . : { + _small_start = .; + *(.sdata) + . = ALIGN(32); + edata = .; + _edata = .; + } + + .sbss . : { + __bss_start = .; + _fbss = .; + *(.sbss) *(.scommon) + _small_end = .; + . = ALIGN(32); + } + + .bss . : { + *(.bss) + *(COMMON) + . = ALIGN(32); + _end = .; + end = .; + } + +} diff --git a/sys/conf/ldscript.mips.octeon1.kernel.64 b/sys/conf/ldscript.mips.octeon1.kernel.64 new file mode 100644 index 00000000000..b476abf0cbd --- /dev/null +++ b/sys/conf/ldscript.mips.octeon1.kernel.64 @@ -0,0 +1,61 @@ +TARGET(elf64-tradbigmips) +OUTPUT_FORMAT("elf64-tradbigmips", "elf64-tradbigmips", "elf64-tradlittlemips") +OUTPUT_ARCH(mips) +ENTRY(_start) +/* __DYNAMIC = 0; +PROVIDE (_DYNAMIC = 0); +*/ +PHDRS { + text PT_LOAD FLAGS ( 5 ) ; +} + +SECTIONS { + + .text _start : { + *(.text) + /*(.dynamic)*/ + etext = .; + _etext = .; + . = ALIGN(0x2000); + } : text + + .rodata ALIGN(0x2000) : { + _fdata = .; + *(.rodata) + . = ALIGN(32); + } + + .data . : { + _rwdata = .; + *(.data) + . = ALIGN(32); + CONSTRUCTORS; + } + + _gp = (. + 0x8000); + + .sdata . : { + _small_start = .; + *(.sdata) + . = ALIGN(32); + edata = .; + _edata = .; + } + + .sbss . : { + __bss_start = .; + _fbss = .; + *(.sbss) *(.scommon) + _small_end = .; + . = ALIGN(32); + } + + .bss . : { + *(.bss) + *(COMMON) + . = ALIGN(32); + _end = .; + end = .; + } + +} diff --git a/sys/conf/ldscript.mips.octeon1.kernel.n32 b/sys/conf/ldscript.mips.octeon1.kernel.n32 new file mode 100644 index 00000000000..4eb322483dc --- /dev/null +++ b/sys/conf/ldscript.mips.octeon1.kernel.n32 @@ -0,0 +1,57 @@ +TARGET(elf32-ntradbigmips) +OUTPUT_FORMAT("elf32-ntradbigmips", "elf32-ntradbigmips", "elf32-ntradlittlemips") +OUTPUT_ARCH(mips) +ENTRY(_start) + __DYNAMIC = 0; +PROVIDE (_DYNAMIC = 0); + +SECTIONS { + + .text . : { + *(.text) + *(.dynamic) + etext = .; + _etext = .; + . = ALIGN(0x2000); + } + + .rodata ALIGN(0x2000) : { + _fdata = .; + *(.rodata) + . = ALIGN(32); + } + + .data . : { + _rwdata = .; + *(.data) + . = ALIGN(32); + CONSTRUCTORS; + } + + _gp = (. + 0x8000); + + .sdata . : { + _small_start = .; + *(.sdata) + . = ALIGN(32); + edata = .; + _edata = .; + } + + .sbss . : { + __bss_start = .; + _fbss = .; + *(.sbss) *(.scommon) + _small_end = .; + . = ALIGN(32); + } + + .bss . : { + *(.bss) + *(COMMON) + . = ALIGN(32); + _end = .; + end = .; + } + +} From e04942b0d74fedbcffbac0d2c4258ab0d6ea4117 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 23 Nov 2009 07:49:22 +0000 Subject: [PATCH 341/380] Start linking at the kernel link address.... # this gets me a loading, but not working, kernel on octeon's simulator. --- sys/conf/ldscript.mips.octeon1.kernel.32 | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sys/conf/ldscript.mips.octeon1.kernel.32 b/sys/conf/ldscript.mips.octeon1.kernel.32 index cac9db29a53..d3b3c410456 100644 --- a/sys/conf/ldscript.mips.octeon1.kernel.32 +++ b/sys/conf/ldscript.mips.octeon1.kernel.32 @@ -5,11 +5,9 @@ OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips") OUTPUT_ARCH(mips) ENTRY(_start) - __DYNAMIC = 0; -PROVIDE (_DYNAMIC = 0); SECTIONS { - + . = KERNLOADADDR + SIZEOF_HEADERS; .text . : { *(.text) *(.dynamic) From bdc7523ccf5a1262c4c10865fdd071625f0fc3e3 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 23 Nov 2009 07:49:50 +0000 Subject: [PATCH 342/380] Specify loader script and load address --- sys/mips/conf/OCTEON1-32 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/mips/conf/OCTEON1-32 b/sys/mips/conf/OCTEON1-32 index c3c0d176ae9..a75015e2ee1 100644 --- a/sys/mips/conf/OCTEON1-32 +++ b/sys/mips/conf/OCTEON1-32 @@ -27,9 +27,11 @@ ident OCTEON1 # Don't build any modules yet. makeoptions MODULES_OVERRIDE="" makeoptions TARGET_BIG_ENDIAN=defined +makeoptions LDSCRIPT_NAME=ldscript.mips.octeon1.kernel.32 #makeoptions TARGET_64BIT=defined options KERNVIRTADDR=0x80100000 +makeoptions KERNLOADADDR=0x80100000 include "../octeon1/std.octeon1" hints "OCTEON1.hints" #Default places to look for devices. From c37c85b0e4249c9a80284095b9ee8154054943dd Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 24 Nov 2009 07:40:38 +0000 Subject: [PATCH 343/380] Prefer ANSI spellings of uintXX_t, etc. --- sys/mips/mips/bus_space_generic.c | 48 +++++++++++++++---------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/sys/mips/mips/bus_space_generic.c b/sys/mips/mips/bus_space_generic.c index 84ca7765ace..931201c89c0 100644 --- a/sys/mips/mips/bus_space_generic.c +++ b/sys/mips/mips/bus_space_generic.c @@ -247,7 +247,7 @@ generic_bs_subregion(void *t __unused, bus_space_handle_t handle __unused, return (0); } -u_int8_t +uint8_t generic_bs_r_1(void *t, bus_space_handle_t handle, bus_size_t offset) { @@ -255,7 +255,7 @@ generic_bs_r_1(void *t, bus_space_handle_t handle, return (rd8(handle + offset)); } -u_int16_t +uint16_t generic_bs_r_2(void *t, bus_space_handle_t handle, bus_size_t offset) { @@ -263,7 +263,7 @@ generic_bs_r_2(void *t, bus_space_handle_t handle, return (rd16(handle + offset)); } -u_int32_t +uint32_t generic_bs_r_4(void *t, bus_space_handle_t handle, bus_size_t offset) { @@ -274,7 +274,7 @@ generic_bs_r_4(void *t, bus_space_handle_t handle, void generic_bs_rm_1(void *t, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t *addr, size_t count) + bus_size_t offset, uint8_t *addr, size_t count) { while (count--) @@ -283,7 +283,7 @@ generic_bs_rm_1(void *t, bus_space_handle_t bsh, void generic_bs_rm_2(void *t, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t *addr, size_t count) + bus_size_t offset, uint16_t *addr, size_t count) { bus_addr_t baddr = bsh + offset; @@ -293,7 +293,7 @@ generic_bs_rm_2(void *t, bus_space_handle_t bsh, void generic_bs_rm_4(void *t, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t *addr, size_t count) + bus_size_t offset, uint32_t *addr, size_t count) { bus_addr_t baddr = bsh + offset; @@ -309,7 +309,7 @@ generic_bs_rm_4(void *t, bus_space_handle_t bsh, */ void generic_bs_rr_1(void *t, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t *addr, size_t count) + bus_size_t offset, uint8_t *addr, size_t count) { bus_addr_t baddr = bsh + offset; @@ -321,7 +321,7 @@ generic_bs_rr_1(void *t, bus_space_handle_t bsh, void generic_bs_rr_2(void *t, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t *addr, size_t count) + bus_size_t offset, uint16_t *addr, size_t count) { bus_addr_t baddr = bsh + offset; @@ -333,7 +333,7 @@ generic_bs_rr_2(void *t, bus_space_handle_t bsh, void generic_bs_rr_4(void *t, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t *addr, size_t count) + bus_size_t offset, uint32_t *addr, size_t count) { bus_addr_t baddr = bsh + offset; @@ -349,7 +349,7 @@ generic_bs_rr_4(void *t, bus_space_handle_t bsh, */ void generic_bs_w_1(void *t, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t value) + bus_size_t offset, uint8_t value) { wr8(bsh + offset, value); @@ -357,7 +357,7 @@ generic_bs_w_1(void *t, bus_space_handle_t bsh, void generic_bs_w_2(void *t, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t value) + bus_size_t offset, uint16_t value) { wr16(bsh + offset, value); @@ -365,7 +365,7 @@ generic_bs_w_2(void *t, bus_space_handle_t bsh, void generic_bs_w_4(void *t, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t value) + bus_size_t offset, uint32_t value) { wr32(bsh + offset, value); @@ -377,7 +377,7 @@ generic_bs_w_4(void *t, bus_space_handle_t bsh, */ void generic_bs_wm_1(void *t, bus_space_handle_t bsh, - bus_size_t offset, const u_int8_t *addr, size_t count) + bus_size_t offset, const uint8_t *addr, size_t count) { bus_addr_t baddr = bsh + offset; @@ -387,7 +387,7 @@ generic_bs_wm_1(void *t, bus_space_handle_t bsh, void generic_bs_wm_2(void *t, bus_space_handle_t bsh, - bus_size_t offset, const u_int16_t *addr, size_t count) + bus_size_t offset, const uint16_t *addr, size_t count) { bus_addr_t baddr = bsh + offset; @@ -397,7 +397,7 @@ generic_bs_wm_2(void *t, bus_space_handle_t bsh, void generic_bs_wm_4(void *t, bus_space_handle_t bsh, - bus_size_t offset, const u_int32_t *addr, size_t count) + bus_size_t offset, const uint32_t *addr, size_t count) { bus_addr_t baddr = bsh + offset; @@ -411,7 +411,7 @@ generic_bs_wm_4(void *t, bus_space_handle_t bsh, */ void generic_bs_wr_1(void *t, bus_space_handle_t bsh, - bus_size_t offset, const u_int8_t *addr, size_t count) + bus_size_t offset, const uint8_t *addr, size_t count) { bus_addr_t baddr = bsh + offset; @@ -423,7 +423,7 @@ generic_bs_wr_1(void *t, bus_space_handle_t bsh, void generic_bs_wr_2(void *t, bus_space_handle_t bsh, - bus_size_t offset, const u_int16_t *addr, size_t count) + bus_size_t offset, const uint16_t *addr, size_t count) { bus_addr_t baddr = bsh + offset; @@ -435,7 +435,7 @@ generic_bs_wr_2(void *t, bus_space_handle_t bsh, void generic_bs_wr_4(void *t, bus_space_handle_t bsh, - bus_size_t offset, const u_int32_t *addr, size_t count) + bus_size_t offset, const uint32_t *addr, size_t count) { bus_addr_t baddr = bsh + offset; @@ -451,7 +451,7 @@ generic_bs_wr_4(void *t, bus_space_handle_t bsh, */ void generic_bs_sm_1(void *t, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t value, size_t count) + bus_size_t offset, uint8_t value, size_t count) { bus_addr_t addr = bsh + offset; @@ -461,7 +461,7 @@ generic_bs_sm_1(void *t, bus_space_handle_t bsh, void generic_bs_sm_2(void *t, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t value, size_t count) + bus_size_t offset, uint16_t value, size_t count) { bus_addr_t addr = bsh + offset; @@ -471,7 +471,7 @@ generic_bs_sm_2(void *t, bus_space_handle_t bsh, void generic_bs_sm_4(void *t, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t value, size_t count) + bus_size_t offset, uint32_t value, size_t count) { bus_addr_t addr = bsh + offset; @@ -485,7 +485,7 @@ generic_bs_sm_4(void *t, bus_space_handle_t bsh, */ void generic_bs_sr_1(void *t, bus_space_handle_t bsh, - bus_size_t offset, u_int8_t value, size_t count) + bus_size_t offset, uint8_t value, size_t count) { bus_addr_t addr = bsh + offset; @@ -495,7 +495,7 @@ generic_bs_sr_1(void *t, bus_space_handle_t bsh, void generic_bs_sr_2(void *t, bus_space_handle_t bsh, - bus_size_t offset, u_int16_t value, size_t count) + bus_size_t offset, uint16_t value, size_t count) { bus_addr_t addr = bsh + offset; @@ -505,7 +505,7 @@ generic_bs_sr_2(void *t, bus_space_handle_t bsh, void generic_bs_sr_4(void *t, bus_space_handle_t bsh, - bus_size_t offset, u_int32_t value, size_t count) + bus_size_t offset, uint32_t value, size_t count) { bus_addr_t addr = bsh + offset; From dda960c86285f2a688a71260527e48a91b7408d1 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 24 Nov 2009 07:41:15 +0000 Subject: [PATCH 344/380] Add size of octeon uart registers to map. --- sys/mips/octeon1/octeonreg.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/mips/octeon1/octeonreg.h b/sys/mips/octeon1/octeonreg.h index 9373eb7a64b..44e927db36b 100644 --- a/sys/mips/octeon1/octeonreg.h +++ b/sys/mips/octeon1/octeonreg.h @@ -197,6 +197,7 @@ #define OCTEON_UART0ADR 0x8001180000000800ull #define OCTEON_UART1ADR 0x8001180000000C00ull +#define OCTEON_UART_SIZE 0x400 #define OCTEON_MIO_BOOT_BIST_STAT 0x80011800000000F8ull From d2aaaeac198e9364e50b5b650b4415b6e05b63bd Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 24 Nov 2009 07:50:19 +0000 Subject: [PATCH 345/380] Rewrite to try to be more sane: o Introduce a uart bus space so that we don't have to hack dev/uart to do 8 byte reads. This also handles the shift properly, so reset the shift we want dev/uart doing to 0. In effect, this bus space makes the octeon registers have an interface to dev/uart that looks just like the old ISA bus, but does the necessary 64-bit read/write to the bus. We only support read/write operations. We do all the widths, but likely could get away with only 64-bit and 8-bit given the restricted nature of use of this bus. o use bus_space_map to set the .bsh rather than a direct assignment. o Minor cleanup of uart_cpu_getdev to make it conform more to the other implementations. o Add some coments for future work. # with these changes, we now make it through cninit, but there's still some # problem that's preventing output, as well as another problem that causes # us to call panic just after we return from cninit() in platform_start. --- sys/mips/octeon1/uart_bus_octeonusart.c | 28 +++-- sys/mips/octeon1/uart_cpu_octeonusart.c | 143 ++++++++++++++++++++---- 2 files changed, 135 insertions(+), 36 deletions(-) diff --git a/sys/mips/octeon1/uart_bus_octeonusart.c b/sys/mips/octeon1/uart_bus_octeonusart.c index 2916aa0a24e..2f43c779b56 100644 --- a/sys/mips/octeon1/uart_bus_octeonusart.c +++ b/sys/mips/octeon1/uart_bus_octeonusart.c @@ -92,23 +92,23 @@ uart_octeon_probe(device_t dev) struct uart_softc *sc; int unit; -/* - * Note that both tty0 & tty1 are viable consoles. We add child devices - * such that ttyu0 ends up front of queue. - */ unit = device_get_unit(dev); sc = device_get_softc(dev); - sc->sc_sysdev = NULL; + sc->sc_class = &uart_oct16550_class; + +#if 1 + /* + * We inherit the settings from the systme console. Note, the bst + * bad bus_space_map are bogus here, but obio doesn't yet support + * them, it seems. + */ sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); - if (!unit) { - sc->sc_sysdev->bas.bst = 0; - sc->sc_sysdev->bas.bsh = OCTEON_UART0ADR; - } - sc->sc_class = &uart_oct16550_class; - sc->sc_bas.bst = 0; - sc->sc_bas.bsh = unit ? OCTEON_UART1ADR : OCTEON_UART0ADR; - sc->sc_bas.regshft = 0x3; + sc->sc_bas.bst = uart_bus_space_mem; + if (bus_space_map(sc->sc_bas.bst, OCTEON_UART0ADR, OCTEON_UART_SIZE, + 0, &sc->sc_bas.bsh) != 0) + return (ENXIO); +#endif return (uart_bus_probe(dev, sc->sc_bas.regshft, 0, 0, unit)); } @@ -118,6 +118,4 @@ octeon_uart_identify(driver_t * drv, device_t parent) BUS_ADD_CHILD(parent, 0, "uart", 0); } - - DRIVER_MODULE(uart, obio, uart_octeon_driver, uart_devclass, 0, 0); diff --git a/sys/mips/octeon1/uart_cpu_octeonusart.c b/sys/mips/octeon1/uart_cpu_octeonusart.c index fbbe9a7fda1..7b0cdbf29b6 100644 --- a/sys/mips/octeon1/uart_cpu_octeonusart.c +++ b/sys/mips/octeon1/uart_cpu_octeonusart.c @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2009 M. Warner Losh * Copyright (c) 2006 Wojciech A. Koszek * All rights reserved. * @@ -25,14 +26,6 @@ * * $Id$ */ -/* - * Skeleton of this file was based on respective code for ARM - * code written by Olivier Houchard. - */ -/* - * XXXMIPS: This file is hacked from arm/... . XXXMIPS here means this file is - * experimental and was written for MIPS32 port. - */ #include "opt_uart.h" #include @@ -49,42 +42,150 @@ __FBSDID("$FreeBSD$"); #include #include +#include bus_space_tag_t uart_bus_space_io; bus_space_tag_t uart_bus_space_mem; +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +/* + * Specailized uart bus space. We present a 1 apart byte oriented + * bus to the outside world, but internally translate to/from the 8-apart + * 64-bit word bus that's on the octeon. We only support simple read/write + * in this space. Everything else is undefined. + */ + +static uint8_t +ou_bs_r_1(void *t, bus_space_handle_t handle, bus_size_t offset) +{ + + return (oct_read64(handle + (offset << 3))); +} + +static uint16_t +ou_bs_r_2(void *t, bus_space_handle_t handle, bus_size_t offset) +{ + + return (oct_read64(handle + (offset << 3))); +} + +static uint32_t +ou_bs_r_4(void *t, bus_space_handle_t handle, bus_size_t offset) +{ + + return (oct_read64(handle + (offset << 3))); +} + +static uint64_t +ou_bs_r_8(void *t, bus_space_handle_t handle, bus_size_t offset) +{ + + return (oct_read64(handle + (offset << 3))); +} + +static void +ou_bs_w_1(void *t, bus_space_handle_t bsh, bus_size_t offset, uint8_t value) +{ + + oct_write64(bsh + (offset << 3), value); +} + +static void +ou_bs_w_2(void *t, bus_space_handle_t bsh, bus_size_t offset, uint16_t value) +{ + + oct_write64(bsh + (offset << 3), value); +} + +static void +ou_bs_w_4(void *t, bus_space_handle_t bsh, bus_size_t offset, uint32_t value) +{ + + oct_write64(bsh + (offset << 3), value); +} + +static void +ou_bs_w_8(void *t, bus_space_handle_t bsh, bus_size_t offset, uint64_t value) +{ + + oct_write64(bsh + (offset << 3), value); +} + +static struct bus_space octeon_uart_tag = { + .bs_map = generic_bs_map, + .bs_unmap = generic_bs_unmap, + .bs_subregion = generic_bs_subregion, + .bs_barrier = generic_bs_barrier, + .bs_r_1 = ou_bs_r_1, + .bs_r_2 = ou_bs_r_2, + .bs_r_4 = ou_bs_r_4, + .bs_r_8 = ou_bs_r_8, + .bs_w_1 = ou_bs_w_1, + .bs_w_2 = ou_bs_w_2, + .bs_w_4 = ou_bs_w_4, + .bs_w_8 = ou_bs_w_8, +}; + extern struct uart_class uart_oct16550_class; -extern struct uart_ops octeon_usart_ops; -extern struct bus_space octeon_bs_tag; int uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) { + return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0); - return (0); } int uart_cpu_getdev(int devtype, struct uart_devinfo *di) { - struct uart_class *class; + struct uart_class *class = &uart_oct16550_class; - class = &uart_oct16550_class; + /* + * These fields need to be setup corretly for uart_getenv to + * work in all cases. + */ + uart_bus_space_io = NULL; /* No io map for this device */ + uart_bus_space_mem = &octeon_uart_tag; + di->bas.bst = uart_bus_space_mem; + + /* + * If env specification for UART exists it takes precedence: + * hw.uart.console="mm:0xf1012000" or similar + */ + if (uart_getenv(devtype, di, class) == 0) + return (0); + + /* + * Fallback to UART0 for console. + */ di->ops = uart_getops(class); - di->bas.bst = 0; di->bas.chan = 0; - di->bas.regshft = 3; /* Each UART reg is 8 byte addresss apart. 1 - * << 3 */ + if (bus_space_map(di->bas.bst, OCTEON_UART0ADR, OCTEON_UART_SIZE, + 0, &di->bas.bsh) != 0) + return (ENXIO); + di->bas.regshft = 0; di->bas.rclk = 0; di->baudrate = 115200; di->databits = 8; di->stopbits = 1; di->parity = UART_PARITY_NONE; - di->bas.bsh = OCTEON_UART0ADR; - uart_getenv(devtype, di, class); - - uart_bus_space_io = NULL; - uart_bus_space_mem = mips_bus_space_generic; return (0); } From 4a2199914f9334f867f024ca9a343cb6912f0544 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 24 Nov 2009 08:21:23 +0000 Subject: [PATCH 346/380] remove bogus panic. Don't use fortran style line control. --- sys/mips/octeon1/octeon_machdep.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/mips/octeon1/octeon_machdep.c b/sys/mips/octeon1/octeon_machdep.c index c1f90a1393f..db563530f72 100644 --- a/sys/mips/octeon1/octeon_machdep.c +++ b/sys/mips/octeon1/octeon_machdep.c @@ -682,7 +682,7 @@ platform_start(__register_t a0, __register_t a1, memset(&edata, 0, kernend - (vm_offset_t)(&edata)); octeon_ciu_reset(); - octeon_uart_write_string(0, "\nPlatform Starting"); + octeon_uart_write_string(0, "Platform Starting\n"); /* From here on down likely is bogus */ /* @@ -722,9 +722,12 @@ platform_start(__register_t a0, __register_t a1, platform_counter_freq = 330000000UL; /* XXX: from idt */ mips_timer_init_params(platform_counter_freq, 1); cninit(); + printf("Now is the time to get happy!\n"); /* Panic here, after cninit */ +#if 0 if (mem == 0) panic("No mem=XX parameter in arguments"); +#endif printf("cmd line: "); for (i=0; i < argc; i++) From 29a21af3726d48af6e9fde6b590d21dd728fe0e4 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 24 Nov 2009 08:21:48 +0000 Subject: [PATCH 347/380] TARGET_OCTEON reqiures opt_cputype.h. --- sys/mips/mips/cache.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/mips/mips/cache.c b/sys/mips/mips/cache.c index 946166032c9..5710449d543 100644 --- a/sys/mips/mips/cache.c +++ b/sys/mips/mips/cache.c @@ -76,6 +76,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include "opt_cputype.h" + struct mips_cache_ops mips_cache_ops; void From 96a25a70ad3f74a62614eb4a5d4a6b3c23de040d Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 24 Nov 2009 08:35:11 +0000 Subject: [PATCH 348/380] Move the hard-wiring of the dcache on octeon outside of the if statement. When no caches support was added, it looks like TARGET_OCTEON was bogusly moved inside the if. Also, include opt_cputype.h to make TARGET_OCTEON actually active. # now we die in pmap init somewhere... Most likely because 32MB of RAM is # too tight given the load address we're using. --- sys/mips/mips/cpu.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/sys/mips/mips/cpu.c b/sys/mips/mips/cpu.c index 0f3d8ad43f4..ff59cb4f4d7 100644 --- a/sys/mips/mips/cpu.c +++ b/sys/mips/mips/cpu.c @@ -49,6 +49,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include "opt_cputype.h" + static struct mips_cpuinfo cpuinfo; union cpuprid cpu_id; @@ -113,18 +115,18 @@ mips_get_identity(struct mips_cpuinfo *cpuinfo) (((cfg1 & MIPS_CONFIG1_DA_MASK) >> MIPS_CONFIG1_DA_SHIFT)) + 1; cpuinfo->l1.dc_nsets = 1 << (((cfg1 & MIPS_CONFIG1_DS_MASK) >> MIPS_CONFIG1_DS_SHIFT) + 6); -#ifdef TARGET_OCTEON - /* - * Octeon does 128 byte line-size. But Config-Sel1 doesn't show - * 128 line-size, 1 Set, 64 ways. - */ - cpuinfo->l1.dc_linesize = 128; - cpuinfo->l1.dc_nsets = 1; - cpuinfo->l1.dc_nways = 64; -#endif - cpuinfo->l1.dc_size = cpuinfo->l1.dc_linesize - * cpuinfo->l1.dc_nsets * cpuinfo->l1.dc_nways; } +#ifdef TARGET_OCTEON + /* + * Octeon does 128 byte line-size. But Config-Sel1 doesn't show + * 128 line-size, 1 Set, 64 ways. + */ + cpuinfo->l1.dc_linesize = 128; + cpuinfo->l1.dc_nsets = 1; + cpuinfo->l1.dc_nways = 64; +#endif + cpuinfo->l1.dc_size = cpuinfo->l1.dc_linesize + * cpuinfo->l1.dc_nsets * cpuinfo->l1.dc_nways; } void From 715f0e291bc3accc708f4e72c071a1e3e18e89da Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 24 Nov 2009 14:57:50 +0000 Subject: [PATCH 349/380] Get rid of redundant .kernel in these names. --- ...cript.mips.octeon1.kernel.32 => ldscript.mips.octeon1.32} | 0 ...cript.mips.octeon1.kernel.64 => ldscript.mips.octeon1.64} | 0 ...ipt.mips.octeon1.kernel.n32 => ldscript.mips.octeon1.n32} | 0 sys/mips/conf/OCTEON1 | 5 +++-- sys/mips/conf/OCTEON1-32 | 2 +- 5 files changed, 4 insertions(+), 3 deletions(-) rename sys/conf/{ldscript.mips.octeon1.kernel.32 => ldscript.mips.octeon1.32} (100%) rename sys/conf/{ldscript.mips.octeon1.kernel.64 => ldscript.mips.octeon1.64} (100%) rename sys/conf/{ldscript.mips.octeon1.kernel.n32 => ldscript.mips.octeon1.n32} (100%) diff --git a/sys/conf/ldscript.mips.octeon1.kernel.32 b/sys/conf/ldscript.mips.octeon1.32 similarity index 100% rename from sys/conf/ldscript.mips.octeon1.kernel.32 rename to sys/conf/ldscript.mips.octeon1.32 diff --git a/sys/conf/ldscript.mips.octeon1.kernel.64 b/sys/conf/ldscript.mips.octeon1.64 similarity index 100% rename from sys/conf/ldscript.mips.octeon1.kernel.64 rename to sys/conf/ldscript.mips.octeon1.64 diff --git a/sys/conf/ldscript.mips.octeon1.kernel.n32 b/sys/conf/ldscript.mips.octeon1.n32 similarity index 100% rename from sys/conf/ldscript.mips.octeon1.kernel.n32 rename to sys/conf/ldscript.mips.octeon1.n32 diff --git a/sys/mips/conf/OCTEON1 b/sys/mips/conf/OCTEON1 index 6c7810c6f0b..0694afbbec8 100644 --- a/sys/mips/conf/OCTEON1 +++ b/sys/mips/conf/OCTEON1 @@ -22,14 +22,15 @@ cpu CPU_MIPS4KC ident OCTEON1 makeoptions ARCH_FLAGS="-march=mips64 -mabi=64" -makeoptions LDSCRIPT_NAME= ldscript.mips.mips64 +makeoptions LDSCRIPT_NAME=ldscript.mips.octeon.64 # Don't build any modules yet. makeoptions MODULES_OVERRIDE="" makeoptions TARGET_BIG_ENDIAN=defined makeoptions TARGET_64BIT=defined +makeoptions KERNLOADADDR=0xffffffff80100000 -options KERNVIRTADDR=0x80100000 +options KERNVIRTADDR=0xffffffff80100000 include "../octeon1/std.octeon1" hints "OCTEON1.hints" #Default places to look for devices. diff --git a/sys/mips/conf/OCTEON1-32 b/sys/mips/conf/OCTEON1-32 index a75015e2ee1..361964ec3a0 100644 --- a/sys/mips/conf/OCTEON1-32 +++ b/sys/mips/conf/OCTEON1-32 @@ -27,7 +27,7 @@ ident OCTEON1 # Don't build any modules yet. makeoptions MODULES_OVERRIDE="" makeoptions TARGET_BIG_ENDIAN=defined -makeoptions LDSCRIPT_NAME=ldscript.mips.octeon1.kernel.32 +makeoptions LDSCRIPT_NAME=ldscript.mips.octeon1.32 #makeoptions TARGET_64BIT=defined options KERNVIRTADDR=0x80100000 From bf718921ac2e6340b609a9a7c427fe52472d45e9 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 24 Nov 2009 16:29:23 +0000 Subject: [PATCH 350/380] Make sure kstack0 is page aligned. # this may have been from neel@ for the sibyte stuff --- sys/mips/mips/machdep.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c index 61e0da544e1..13382345648 100644 --- a/sys/mips/mips/machdep.c +++ b/sys/mips/mips/machdep.c @@ -42,6 +42,7 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_cputype.h" #include "opt_ddb.h" #include "opt_md.h" #include "opt_msgbuf.h" @@ -259,8 +260,12 @@ void mips_proc0_init(void) { proc_linkup(&proc0, &thread0); + + KASSERT((kstack0 & PAGE_MASK) == 0, + ("kstack0 is not aligned on a page boundary: %#lx\n", + (unsigned long)kstack0)); thread0.td_kstack = kstack0; - thread0.td_kstack_pages = KSTACK_PAGES - 1; + thread0.td_kstack_pages = KSTACK_PAGES; thread0.td_md.md_realstack = roundup2(thread0.td_kstack, PAGE_SIZE * 2); /* Initialize pcpu info of cpu-zero */ #ifdef SMP From 8fccbb54b6a9f6b73f21b8a6a7099948cc4fc0bf Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 24 Nov 2009 16:30:29 +0000 Subject: [PATCH 351/380] Remove a comment that's bogus. Include opt_cputype.h since TARGET_OCTEON moved there. --- sys/mips/mips/mainbus.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/mips/mips/mainbus.c b/sys/mips/mips/mainbus.c index d1571e4cdba..abee72b6d36 100644 --- a/sys/mips/mips/mainbus.c +++ b/sys/mips/mips/mainbus.c @@ -44,6 +44,8 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_cputype.h" + #include #include #include @@ -265,7 +267,6 @@ mainbus_activate_resource(device_t bus, device_t child, int type, int rid, + poffs; } rman_set_virtual(r, vaddr); - /* IBM-PC: the type of bus_space_handle_t is u_int */ #ifdef TARGET_OCTEON temp = 0x0000000000000000; temp |= (uint32_t)vaddr; From 04c50bba10514954376b980fdbb1df0b59021fab Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 24 Nov 2009 16:32:31 +0000 Subject: [PATCH 352/380] Include opt_cputype.h for all .c and .S files referencing TARGET_OCTEON. Spell ld script name right. # for the most part, we need to enhance infrastructure to obviate the need # for such an intrusive option. --- sys/mips/conf/OCTEON1 | 2 +- sys/mips/include/cpufunc.h | 13 +++++++------ sys/mips/mips/cache.c | 4 ++-- sys/mips/mips/cache_mipsNN.c | 2 ++ sys/mips/mips/cpu.c | 4 ++-- sys/mips/mips/exception.S | 2 ++ sys/mips/mips/pm_machdep.c | 2 ++ sys/mips/mips/psraccess.S | 2 ++ sys/mips/mips/support.S | 1 + sys/mips/mips/tick.c | 2 ++ sys/mips/mips/vm_machdep.c | 2 ++ 11 files changed, 25 insertions(+), 11 deletions(-) diff --git a/sys/mips/conf/OCTEON1 b/sys/mips/conf/OCTEON1 index 0694afbbec8..1e94e2f2875 100644 --- a/sys/mips/conf/OCTEON1 +++ b/sys/mips/conf/OCTEON1 @@ -22,7 +22,7 @@ cpu CPU_MIPS4KC ident OCTEON1 makeoptions ARCH_FLAGS="-march=mips64 -mabi=64" -makeoptions LDSCRIPT_NAME=ldscript.mips.octeon.64 +makeoptions LDSCRIPT_NAME=ldscript.mips.octeon1.64 # Don't build any modules yet. makeoptions MODULES_OVERRIDE="" diff --git a/sys/mips/include/cpufunc.h b/sys/mips/include/cpufunc.h index 28d47332c10..cd4d3e5e695 100644 --- a/sys/mips/include/cpufunc.h +++ b/sys/mips/include/cpufunc.h @@ -208,12 +208,13 @@ mips_wr_ ## n ## s(uint32_t a0) \ #ifdef TARGET_OCTEON static __inline void mips_sync_icache (void) { - __asm __volatile ( - ".set mips64\n" - ".word 0x041f0000\n" - "nop\n" - ".set mips0\n" - : : ); + __asm __volatile ( + ".set push\n" + ".set mips64\n" + ".word 0x041f0000\n" /* xxx ICACHE */ + "nop\n" + ".set pop\n" + : : ); } #endif diff --git a/sys/mips/mips/cache.c b/sys/mips/mips/cache.c index 5710449d543..087e22c0c6e 100644 --- a/sys/mips/mips/cache.c +++ b/sys/mips/mips/cache.c @@ -73,11 +73,11 @@ __FBSDID("$FreeBSD$"); #include #include +#include "opt_cputype.h" + #include #include -#include "opt_cputype.h" - struct mips_cache_ops mips_cache_ops; void diff --git a/sys/mips/mips/cache_mipsNN.c b/sys/mips/mips/cache_mipsNN.c index 822079b9423..e2d3ffb2e36 100644 --- a/sys/mips/mips/cache_mipsNN.c +++ b/sys/mips/mips/cache_mipsNN.c @@ -38,6 +38,8 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_cputype.h" + #include #include #include diff --git a/sys/mips/mips/cpu.c b/sys/mips/mips/cpu.c index ff59cb4f4d7..6ba356a0836 100644 --- a/sys/mips/mips/cpu.c +++ b/sys/mips/mips/cpu.c @@ -27,6 +27,8 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_cputype.h" + #include #include #include @@ -49,8 +51,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include "opt_cputype.h" - static struct mips_cpuinfo cpuinfo; union cpuprid cpu_id; diff --git a/sys/mips/mips/exception.S b/sys/mips/mips/exception.S index 8ea732b0023..1271658cade 100644 --- a/sys/mips/mips/exception.S +++ b/sys/mips/mips/exception.S @@ -62,6 +62,8 @@ #include #include +#include "opt_cputype.h" + #include "assym.s" #if defined(ISA_MIPS32) diff --git a/sys/mips/mips/pm_machdep.c b/sys/mips/mips/pm_machdep.c index 7abef936e09..712763b1020 100644 --- a/sys/mips/mips/pm_machdep.c +++ b/sys/mips/mips/pm_machdep.c @@ -39,6 +39,8 @@ __FBSDID("$FreeBSD$"); #include "opt_compat.h" +#include "opt_cputype.h" + #include #include #include diff --git a/sys/mips/mips/psraccess.S b/sys/mips/mips/psraccess.S index 003c1d534ec..0bcb04d3d33 100644 --- a/sys/mips/mips/psraccess.S +++ b/sys/mips/mips/psraccess.S @@ -41,6 +41,8 @@ #include #include +#include "opt_cputype.h" + #include "assym.s" /* diff --git a/sys/mips/mips/support.S b/sys/mips/mips/support.S index 5bde74034fb..526f95776f1 100644 --- a/sys/mips/mips/support.S +++ b/sys/mips/mips/support.S @@ -55,6 +55,7 @@ * assembly language support routines. */ +#include "opt_cputype.h" #include "opt_ddb.h" #include #include diff --git a/sys/mips/mips/tick.c b/sys/mips/mips/tick.c index c91b1abf68d..b03c4d438ec 100644 --- a/sys/mips/mips/tick.c +++ b/sys/mips/mips/tick.c @@ -33,6 +33,8 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_cputype.h" + #include #include #include diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c index 44a4133d409..bde96188ee3 100644 --- a/sys/mips/mips/vm_machdep.c +++ b/sys/mips/mips/vm_machdep.c @@ -41,6 +41,8 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_cputype.h" + #include #include #include From 73ee766076f5eb5847934af099605afe8b52d13e Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 24 Nov 2009 16:53:58 +0000 Subject: [PATCH 353/380] looks like there's more to this patch than just this one file. I'll leave it to neel@ to get all the relevant pieces into the tree. # we now get well into mi_start before we die --- sys/mips/mips/machdep.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c index 13382345648..fdd95135f49 100644 --- a/sys/mips/mips/machdep.c +++ b/sys/mips/mips/machdep.c @@ -261,11 +261,8 @@ mips_proc0_init(void) { proc_linkup(&proc0, &thread0); - KASSERT((kstack0 & PAGE_MASK) == 0, - ("kstack0 is not aligned on a page boundary: %#lx\n", - (unsigned long)kstack0)); thread0.td_kstack = kstack0; - thread0.td_kstack_pages = KSTACK_PAGES; + thread0.td_kstack_pages = KSTACK_PAGES - 1; thread0.td_md.md_realstack = roundup2(thread0.td_kstack, PAGE_SIZE * 2); /* Initialize pcpu info of cpu-zero */ #ifdef SMP From 0ff75e4f847d51a281e3dafe1e3f14b819d11f44 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 24 Nov 2009 17:06:11 +0000 Subject: [PATCH 354/380] Only all critical_enter()/critical_exit() if curthread has been set. Otherwise we dereference a null pointer and can't get useful panic info early in boot. --- sys/kern/kern_shutdown.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c index 3d963213597..5e192b9d4fd 100644 --- a/sys/kern/kern_shutdown.c +++ b/sys/kern/kern_shutdown.c @@ -516,7 +516,8 @@ panic(const char *fmt, ...) va_list ap; static char buf[256]; - critical_enter(); + if (td) + critical_enter(); #ifdef SMP /* * We don't want multiple CPU's to panic at the same time, so we @@ -575,7 +576,8 @@ panic(const char *fmt, ...) /* thread_unlock(td); */ if (!sync_on_panic) bootopt |= RB_NOSYNC; - critical_exit(); + if (td) + critical_exit(); boot(bootopt); } From 6adde0259094c5e6552eda6b46964acf54e7a8a6 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 24 Nov 2009 17:14:23 +0000 Subject: [PATCH 355/380] kill stray printf --- sys/mips/octeon1/octeon_machdep.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/mips/octeon1/octeon_machdep.c b/sys/mips/octeon1/octeon_machdep.c index db563530f72..0b83901c36a 100644 --- a/sys/mips/octeon1/octeon_machdep.c +++ b/sys/mips/octeon1/octeon_machdep.c @@ -722,7 +722,6 @@ platform_start(__register_t a0, __register_t a1, platform_counter_freq = 330000000UL; /* XXX: from idt */ mips_timer_init_params(platform_counter_freq, 1); cninit(); - printf("Now is the time to get happy!\n"); /* Panic here, after cninit */ #if 0 if (mem == 0) From c64b37ff1f9aea5a2eec9cd362563034a7211fc4 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 24 Nov 2009 17:15:22 +0000 Subject: [PATCH 356/380] Add in Cavium's CID. Report what the unknown CID is. --- sys/mips/include/locore.h | 1 + sys/mips/mips/cpu.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/mips/include/locore.h b/sys/mips/include/locore.h index ce60353196a..b1b9f590589 100644 --- a/sys/mips/include/locore.h +++ b/sys/mips/include/locore.h @@ -60,6 +60,7 @@ typedef int mips_prid_t; /* 0x09 unannounced */ /* 0x0a unannounced */ #define MIPS_PRID_CID_LEXRA 0x0b /* Lexra */ +#define MIPS_PRID_CID_CAVIUM 0x0d /* Cavium */ #define MIPS_PRID_COPTS(x) (((x) >> 24) & 0x00ff) /* Company Options */ #ifdef _KERNEL diff --git a/sys/mips/mips/cpu.c b/sys/mips/mips/cpu.c index 6ba356a0836..1b490e6b591 100644 --- a/sys/mips/mips/cpu.c +++ b/sys/mips/mips/cpu.c @@ -178,9 +178,12 @@ cpu_identify(void) case MIPS_PRID_CID_LEXRA: printf("Lexra"); break; + case MIPS_PRID_CID_CAVIUM: + printf("Cavium"); + break; case MIPS_PRID_CID_PREHISTORIC: default: - printf("Unknown"); + printf("Unknown cid %#x", cpuinfo.cpu_vendor); break; } printf(" processor v%d.%d\n", cpuinfo.cpu_rev, cpuinfo.cpu_impl); From 6bd8c4ff58c4aebb1421feeef1b3b0a8e81dedbe Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 26 Nov 2009 15:50:52 +0000 Subject: [PATCH 357/380] This file is OBE and should have been removed when we renamed things to OCTEON1.hints. Submitted by: jmallet --- sys/mips/conf/OCTEON.hints | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 sys/mips/conf/OCTEON.hints diff --git a/sys/mips/conf/OCTEON.hints b/sys/mips/conf/OCTEON.hints deleted file mode 100644 index d8bc18c250d..00000000000 --- a/sys/mips/conf/OCTEON.hints +++ /dev/null @@ -1,13 +0,0 @@ -# /* -# * This product includes software developed by the University of - -# * California, Berkeley and its contributors." -# */ -# device.hints -hw.uart.console="io:0x1" -hint.obio.0.at="nexus" -hint.obio.0.maddr="0x1" -hint.obio.0.flags="0x1" -hint.uart.0.at="obio" -hint.uart.0.maddr="0x1" -hint.uart.0.flags="0x1" From e6e7f898ddbf59fa556d6c0a6f158843ebef3eda Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 10 Dec 2009 01:42:44 +0000 Subject: [PATCH 358/380] app_descriptor_addr is unused (I know it is referened still). And unnecessary since we pass in a3 unmodified to platform_start. Eliminate it from here and kill one more TARGET_OCTEON in the process. --- sys/mips/mips/locore.S | 9 +-------- sys/mips/mips/machdep.c | 18 +++++++++--------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/sys/mips/mips/locore.S b/sys/mips/mips/locore.S index b742bb96091..a332325cc91 100644 --- a/sys/mips/mips/locore.S +++ b/sys/mips/mips/locore.S @@ -83,10 +83,6 @@ GLOBAL(cfe_handle) GLOBAL(cfe_vector) .space 4 #endif -#if defined(TARGET_OCTEON) -GLOBAL(app_descriptor_addr) - .space 8 -#endif GLOBAL(stackspace) .space NBPG /* Smaller than it should be since it's temp. */ .align 8 @@ -189,10 +185,6 @@ VECTOR(_locore, unknown) sw a0, _C_LABEL(cfe_handle)/* Firmware data segment */ sw a2, _C_LABEL(cfe_vector)/* Firmware entry vector */ no_cfe: -#endif -#if defined(TARGET_OCTEON) - PTR_LA a0, app_descriptor_addr - sw a3, 0(a0) /* Store app descriptor ptr */ #endif /* @@ -203,6 +195,7 @@ no_cfe: /* * Block all the slave CPUs */ + /* XXX a0, a1, a2 shouldn't be used here */ /* * Read the cpu id from the cp0 config register * cpuid[9:4], thrid[3: 0] diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c index fdd95135f49..356e52821df 100644 --- a/sys/mips/mips/machdep.c +++ b/sys/mips/mips/machdep.c @@ -154,7 +154,6 @@ extern char edata[], end[]; u_int32_t bootdev; struct bootinfo bootinfo; - static void cpu_startup(void *dummy) { @@ -259,17 +258,11 @@ SYSCTL_INT(_machdep, CPU_WALLCLOCK, wall_cmos_clock, CTLFLAG_RW, void mips_proc0_init(void) { - proc_linkup(&proc0, &thread0); + proc_linkup0(&proc0, &thread0); thread0.td_kstack = kstack0; thread0.td_kstack_pages = KSTACK_PAGES - 1; thread0.td_md.md_realstack = roundup2(thread0.td_kstack, PAGE_SIZE * 2); - /* Initialize pcpu info of cpu-zero */ -#ifdef SMP - pcpu_init(&__pcpu[0], 0, sizeof(struct pcpu)); -#else - pcpu_init(pcpup, 0, sizeof(struct pcpu)); -#endif /* * Do not use cpu_thread_alloc to initialize these fields * thread0 is the only thread that has kstack located in KSEG0 @@ -279,6 +272,13 @@ mips_proc0_init(void) (thread0.td_kstack_pages - 1) * PAGE_SIZE) - 1; thread0.td_frame = &thread0.td_pcb->pcb_regs; + /* Initialize pcpu info of cpu-zero */ +#ifdef SMP + pcpu_init(&__pcpu[0], 0, sizeof(struct pcpu)); +#else + pcpu_init(pcpup, 0, sizeof(struct pcpu)); +#endif + /* Steal memory for the dynamic per-cpu area. */ dpcpu_init((void *)pmap_steal_memory(DPCPU_SIZE), 0); @@ -295,7 +295,7 @@ mips_proc0_init(void) void cpu_initclocks(void) { - platform_initclocks(); + platform_initclocks(); } struct msgbuf *msgbufp=0; From 41d3506b152c38d87439d9dd453a16a60b40435f Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 10 Dec 2009 01:44:11 +0000 Subject: [PATCH 359/380] Get the sense of this right. We use uintpr_t for bus_addr_t when we're building everything except octeon && 32-bit. As note before, we need a clearner way, but at least now the hack is right. --- sys/mips/include/_bus.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/include/_bus.h b/sys/mips/include/_bus.h index 3ba6e2cc1ee..54b0cbb6563 100644 --- a/sys/mips/include/_bus.h +++ b/sys/mips/include/_bus.h @@ -35,7 +35,7 @@ * Bus address and size types */ #include "opt_cputype.h" -#if !(defined(TARGET_OCTEON) || defined(ISA_MIPS32)) +#if !(defined(TARGET_OCTEON) && defined(ISA_MIPS32)) typedef uintptr_t bus_addr_t; #else typedef uint64_t bus_addr_t; From 912012d34af622bc0165cfd48c77c1b28aad2c5d Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 10 Dec 2009 01:45:06 +0000 Subject: [PATCH 360/380] Hook up parsing of the boot records. --- sys/mips/octeon1/octeon_machdep.c | 242 +++++++++++++----------------- 1 file changed, 108 insertions(+), 134 deletions(-) diff --git a/sys/mips/octeon1/octeon_machdep.c b/sys/mips/octeon1/octeon_machdep.c index 0b83901c36a..43b1c60f6d7 100644 --- a/sys/mips/octeon1/octeon_machdep.c +++ b/sys/mips/octeon1/octeon_machdep.c @@ -80,6 +80,8 @@ __FBSDID("$FreeBSD$"); extern int *edata; extern int *end; +static void octeon_boot_params_init(register_t ptr); + void platform_cpu_init() { @@ -669,7 +671,7 @@ void ciu_enable_interrupts (int core_num, int intx, int enx, uint64_t set_these_ void platform_start(__register_t a0, __register_t a1, - __register_t a2 __unused, __register_t a3 __unused) + __register_t a2 __unused, __register_t a3) { uint64_t platform_counter_freq; vm_offset_t kernend; @@ -681,10 +683,11 @@ platform_start(__register_t a0, __register_t a1, kernend = round_page((vm_offset_t)&end); memset(&edata, 0, kernend - (vm_offset_t)(&edata)); + octeon_boot_params_init(a3); + /* XXX octeon boot decriptor has args in it... */ octeon_ciu_reset(); octeon_uart_write_string(0, "Platform Starting\n"); -/* From here on down likely is bogus */ /* * Looking for mem=XXM argument */ @@ -702,9 +705,8 @@ platform_start(__register_t a0, __register_t a1, else realmem = btoc(32 << 20); - for (i = 0; i < 10; i++) { + for (i = 0; i < 10; i++) phys_avail[i] = 0; - } /* phys_avail regions are in bytes */ phys_avail[0] = MIPS_KSEG0_TO_PHYS((vm_offset_t)&end); @@ -712,31 +714,20 @@ platform_start(__register_t a0, __register_t a1, physmem = realmem; - /* - * ns8250 uart code uses DELAY so ticker should be inititalized - * before cninit. And tick_init_params refers to hz, so * init_param1 - * should be called first. - */ + pmap_bootstrap(); + mips_proc0_init(); + init_param1(); /* TODO: parse argc,argv */ platform_counter_freq = 330000000UL; /* XXX: from idt */ mips_timer_init_params(platform_counter_freq, 1); cninit(); - /* Panic here, after cninit */ -#if 0 - if (mem == 0) - panic("No mem=XX parameter in arguments"); -#endif - printf("cmd line: "); for (i=0; i < argc; i++) printf("%s ", argv[i]); printf("\n"); - init_param2(physmem); mips_cpu_init(); - pmap_bootstrap(); - mips_proc0_init(); mutex_init(); #ifdef DDB kdb_init(); @@ -773,73 +764,71 @@ platform_start(__register_t a0, __register_t a1, typedef struct { - /* Start of block referenced by assembly code - do not change! */ - uint32_t desc_version; - uint32_t desc_size; + /* Start of block referenced by assembly code - do not change! */ + uint32_t desc_version; + uint32_t desc_size; - uint64_t stack_top; - uint64_t heap_base; - uint64_t heap_end; - uint64_t entry_point; /* Only used by bootloader */ - uint64_t desc_vaddr; - /* End of This block referenced by assembly code - do not change! */ - - uint32_t exception_base_addr; - uint32_t stack_size; - uint32_t heap_size; - uint32_t argc; /* Argc count for application */ - uint32_t argv[OCTEON_ARGV_MAX_ARGS]; - uint32_t flags; - uint32_t core_mask; - uint32_t dram_size; /**< DRAM size in megabyes */ - uint32_t phy_mem_desc_addr; /**< physical address of free memory descriptor block*/ - uint32_t debugger_flags_base_addr; /**< used to pass flags from app to debugger */ - uint32_t eclock_hz; /**< CPU clock speed, in hz */ - uint32_t dclock_hz; /**< DRAM clock speed, in hz */ - uint32_t spi_clock_hz; /**< SPI4 clock in hz */ - uint16_t board_type; - uint8_t board_rev_major; - uint8_t board_rev_minor; - uint16_t chip_type; - uint8_t chip_rev_major; - uint8_t chip_rev_minor; - char board_serial_number[OCTOEN_SERIAL_LEN]; - uint8_t mac_addr_base[6]; - uint8_t mac_addr_count; - uint64_t cvmx_desc_vaddr; + uint64_t stack_top; + uint64_t heap_base; + uint64_t heap_end; + uint64_t entry_point; /* Only used by bootloader */ + uint64_t desc_vaddr; + /* End of This block referenced by assembly code - do not change! */ + uint32_t exception_base_addr; + uint32_t stack_size; + uint32_t heap_size; + uint32_t argc; /* Argc count for application */ + uint32_t argv[OCTEON_ARGV_MAX_ARGS]; + uint32_t flags; + uint32_t core_mask; + uint32_t dram_size; /**< DRAM size in megabyes */ + uint32_t phy_mem_desc_addr; /**< physical address of free memory descriptor block*/ + uint32_t debugger_flags_base_addr; /**< used to pass flags from app to debugger */ + uint32_t eclock_hz; /**< CPU clock speed, in hz */ + uint32_t dclock_hz; /**< DRAM clock speed, in hz */ + uint32_t spi_clock_hz; /**< SPI4 clock in hz */ + uint16_t board_type; + uint8_t board_rev_major; + uint8_t board_rev_minor; + uint16_t chip_type; + uint8_t chip_rev_major; + uint8_t chip_rev_minor; + char board_serial_number[OCTOEN_SERIAL_LEN]; + uint8_t mac_addr_base[6]; + uint8_t mac_addr_count; + uint64_t cvmx_desc_vaddr; } octeon_boot_descriptor_t; typedef struct { - uint32_t major_version; - uint32_t minor_version; + uint32_t major_version; + uint32_t minor_version; - uint64_t stack_top; - uint64_t heap_base; - uint64_t heap_end; - uint64_t desc_vaddr; - - uint32_t exception_base_addr; - uint32_t stack_size; - uint32_t flags; - uint32_t core_mask; - uint32_t dram_size; /**< DRAM size in megabyes */ - uint32_t phy_mem_desc_addr; /**< physical address of free memory descriptor block*/ - uint32_t debugger_flags_base_addr; /**< used to pass flags from app to debugger */ - uint32_t eclock_hz; /**< CPU clock speed, in hz */ - uint32_t dclock_hz; /**< DRAM clock speed, in hz */ - uint32_t spi_clock_hz; /**< SPI4 clock in hz */ - uint16_t board_type; - uint8_t board_rev_major; - uint8_t board_rev_minor; - uint16_t chip_type; - uint8_t chip_rev_major; - uint8_t chip_rev_minor; - char board_serial_number[OCTOEN_SERIAL_LEN]; - uint8_t mac_addr_base[6]; - uint8_t mac_addr_count; + uint64_t stack_top; + uint64_t heap_base; + uint64_t heap_end; + uint64_t desc_vaddr; + uint32_t exception_base_addr; + uint32_t stack_size; + uint32_t flags; + uint32_t core_mask; + uint32_t dram_size; /**< DRAM size in megabyes */ + uint32_t phy_mem_desc_addr; /**< physical address of free memory descriptor block*/ + uint32_t debugger_flags_base_addr; /**< used to pass flags from app to debugger */ + uint32_t eclock_hz; /**< CPU clock speed, in hz */ + uint32_t dclock_hz; /**< DRAM clock speed, in hz */ + uint32_t spi_clock_hz; /**< SPI4 clock in hz */ + uint16_t board_type; + uint8_t board_rev_major; + uint8_t board_rev_minor; + uint16_t chip_type; + uint8_t chip_rev_major; + uint8_t chip_rev_minor; + char board_serial_number[OCTOEN_SERIAL_LEN]; + uint8_t mac_addr_base[6]; + uint8_t mac_addr_count; } cvmx_bootinfo_t; uint32_t octeon_cpu_clock; @@ -849,11 +838,7 @@ uint8_t octeon_mac_addr[6] = { 0 }; int octeon_core_mask, octeon_mac_addr_count; int octeon_chip_rev_major = 0, octeon_chip_rev_minor = 0, octeon_chip_type = 0; -#if defined(__mips_n64) -extern uint64_t app_descriptor_addr; -#else -extern uint32_t app_descriptor_addr; -#endif +extern int32_t app_descriptor_addr; static octeon_boot_descriptor_t *app_desc_ptr; static cvmx_bootinfo_t *cvmx_desc_ptr; @@ -867,47 +852,49 @@ static cvmx_bootinfo_t *cvmx_desc_ptr; #define OCTEON_DRAM_MAX 3000 -int octeon_board_real (void) +int +octeon_board_real(void) { - if ((octeon_board_type == OCTEON_BOARD_TYPE_NONE) || - (octeon_board_type == OCTEON_BOARD_TYPE_SIM) || - !octeon_board_rev_major) { - return 0; - } - return 1; + if ((octeon_board_type == OCTEON_BOARD_TYPE_NONE) || + (octeon_board_type == OCTEON_BOARD_TYPE_SIM) || + !octeon_board_rev_major) + return 0; + return 1; } -static void octeon_process_app_desc_ver_unknown (void) +static void +octeon_process_app_desc_ver_unknown(void) { printf(" Unknown Boot-Descriptor: Using Defaults\n"); octeon_cpu_clock = OCTEON_CLOCK_DEFAULT; octeon_dram = OCTEON_DRAM_DEFAULT; octeon_board_rev_major = octeon_board_rev_minor = octeon_board_type = 0; - octeon_core_mask = 1; octeon_cpu_clock = OCTEON_CLOCK_DEFAULT; octeon_chip_type = octeon_chip_rev_major = octeon_chip_rev_minor = 0; - octeon_mac_addr[0] = 0x00; octeon_mac_addr[1] = 0x0f; octeon_mac_addr[2] = 0xb7; octeon_mac_addr[3] = 0x10; octeon_mac_addr[4] = 0x09; octeon_mac_addr[5] = 0x06; octeon_mac_addr_count = 1; } -static int octeon_process_app_desc_ver_6 (void) +static int +octeon_process_app_desc_ver_6(void) { - cvmx_desc_ptr = (cvmx_bootinfo_t *) ((long) app_desc_ptr->cvmx_desc_vaddr); - - if ((cvmx_desc_ptr == NULL) || (cvmx_desc_ptr == (cvmx_bootinfo_t *)0xffffffff)) { + /* XXX Why is 0x00000000ffffffffULL a bad value? */ + if (app_desc_ptr->cvmx_desc_vaddr == 0 || + app_desc_ptr->cvmx_desc_vaddr == 0xfffffffful) { printf ("Bad cvmx_desc_ptr %p\n", cvmx_desc_ptr); return 1; - } - - cvmx_desc_ptr = (cvmx_bootinfo_t *) (((long) cvmx_desc_ptr) | MIPS_KSEG0_START); + } + cvmx_desc_ptr = + (cvmx_bootinfo_t *)(intptr_t)app_desc_ptr->cvmx_desc_vaddr; + cvmx_desc_ptr = + (cvmx_bootinfo_t *) ((intptr_t)cvmx_desc_ptr | MIPS_KSEG0_START); octeon_cvmx_bd_ver = (cvmx_desc_ptr->major_version * 100) + - cvmx_desc_ptr->minor_version; - + cvmx_desc_ptr->minor_version; + /* Too early for panic? */ if (cvmx_desc_ptr->major_version != 1) { printf("Incompatible CVMX descriptor from bootloader: %d.%d %p\n", (int) cvmx_desc_ptr->major_version, @@ -932,31 +919,28 @@ static int octeon_process_app_desc_ver_6 (void) octeon_mac_addr[5] = cvmx_desc_ptr->mac_addr_base[5]; octeon_mac_addr_count = cvmx_desc_ptr->mac_addr_count; - if (app_desc_ptr->dram_size > 16*1024*1024) { + if (app_desc_ptr->dram_size > 16*1024*1024) octeon_dram = (uint64_t)app_desc_ptr->dram_size; - } else { - octeon_dram = (uint64_t)app_desc_ptr->dram_size * 1024 * 1024; - } + else + octeon_dram = (uint64_t)app_desc_ptr->dram_size << 20; return 0; } -static int octeon_process_app_desc_ver_3_4_5 (void) +static int +octeon_process_app_desc_ver_3_4_5(void) { octeon_cvmx_bd_ver = octeon_bd_ver; octeon_core_mask = app_desc_ptr->core_mask; - if (app_desc_ptr->desc_version > 3) { + if (app_desc_ptr->desc_version > 3) octeon_cpu_clock = app_desc_ptr->eclock_hz; - } else { + else octeon_cpu_clock = OCTEON_CLOCK_DEFAULT; - } - - if (app_desc_ptr->dram_size > 16*1024*1024) { + if (app_desc_ptr->dram_size > 16*1024*1024) octeon_dram = (uint64_t)app_desc_ptr->dram_size; - } else { - octeon_dram = (uint64_t)app_desc_ptr->dram_size * 1024 * 1024; - } + else + octeon_dram = (uint64_t)app_desc_ptr->dram_size << 20; if (app_desc_ptr->desc_version > 4) { octeon_board_type = app_desc_ptr->board_type; @@ -978,31 +962,21 @@ static int octeon_process_app_desc_ver_3_4_5 (void) } -void mips_boot_params_init(void); - -void mips_boot_params_init (void) +static void +octeon_boot_params_init(register_t ptr) { - int descriptor_not_parsed = 1; + int bad_desc = 1; - if ((app_descriptor_addr == 0) || (app_descriptor_addr >= MAX_APP_DESC_ADDR)) { - - } else { - - app_desc_ptr = (octeon_boot_descriptor_t *) app_descriptor_addr; + if (ptr != 0 && ptr < MAX_APP_DESC_ADDR) { + app_desc_ptr = (octeon_boot_descriptor_t *)(intptr_t)ptr; octeon_bd_ver = app_desc_ptr->desc_version; - - if ((octeon_bd_ver >= 3) && (octeon_bd_ver <= 5)) { - descriptor_not_parsed = octeon_process_app_desc_ver_3_4_5(); - - } else if (app_desc_ptr->desc_version == 6) { - descriptor_not_parsed = octeon_process_app_desc_ver_6(); - } - + if ((octeon_bd_ver >= 3) && (octeon_bd_ver <= 5)) + bad_desc = octeon_process_app_desc_ver_3_4_5(); + else if (app_desc_ptr->desc_version == 6) + bad_desc = octeon_process_app_desc_ver_6(); } - - if (descriptor_not_parsed) { + if (bad_desc) octeon_process_app_desc_ver_unknown(); - } printf("Boot Descriptor Ver: %u -> %u/%u", octeon_bd_ver, octeon_cvmx_bd_ver/100, octeon_cvmx_bd_ver%100); From eb1b8eeafe5e7f3bf09771d42bfa07cdcb492f2c Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 15 Dec 2009 00:44:33 +0000 Subject: [PATCH 361/380] Should have been copied frmo OCTEON.hints, but I botched that, so we're stuck with this. Given that this branch will soon be merged and retired, I don't think it matters much. --- sys/mips/conf/OCTEON1.hints | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 sys/mips/conf/OCTEON1.hints diff --git a/sys/mips/conf/OCTEON1.hints b/sys/mips/conf/OCTEON1.hints new file mode 100644 index 00000000000..d8bc18c250d --- /dev/null +++ b/sys/mips/conf/OCTEON1.hints @@ -0,0 +1,13 @@ +# /* +# * This product includes software developed by the University of + +# * California, Berkeley and its contributors." +# */ +# device.hints +hw.uart.console="io:0x1" +hint.obio.0.at="nexus" +hint.obio.0.maddr="0x1" +hint.obio.0.flags="0x1" +hint.uart.0.at="obio" +hint.uart.0.maddr="0x1" +hint.uart.0.flags="0x1" From c643f1e35d1946673e6d48c62834fa95f45b3736 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 15 Dec 2009 23:22:19 +0000 Subject: [PATCH 362/380] Remove the now-obsolete comments about compile-with. There are no compile-with lines in this file at all. So we don't need two warnings about them. --- sys/conf/files.mips | 8 -------- 1 file changed, 8 deletions(-) diff --git a/sys/conf/files.mips b/sys/conf/files.mips index ded5db8fdf6..30deba26f43 100644 --- a/sys/conf/files.mips +++ b/sys/conf/files.mips @@ -5,10 +5,6 @@ # All rights reserved. # JNPR: files.mips,v 1.11 2007/08/09 12:25:35 katta # -# The long compile-with and dependency lines are required because of -# limitations in config: backslash-newline doesn't work in strings, and -# dependency lines other than the first are silently ignored. -# # ---------------------------------------------------------------------- # Phase 2 # ---------------------------------------------------------------------- @@ -20,10 +16,6 @@ # JNPR: files.mips,v 1.11 2007/08/09 12:25:35 katta # $FreeBSD$ # -# The long compile-with and dependency lines are required because of -# limitations in config: backslash-newline doesn't work in strings, and -# dependency lines other than the first are silently ignored. -# # ---------------------------------------------------------------------- # Phase 2 # ---------------------------------------------------------------------- From 488141d9e8ce176006a1cda9c6b3d7413709b206 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 17 Dec 2009 23:55:49 +0000 Subject: [PATCH 363/380] Place holder ptrace mips module. Not entirely sure what's required here yet, so I've not connected it to the build. I think that we'll need to move something into the processor specific part of the mips port by requiring mips_cpu_ptrace or platform_cpu_ptrace be provided by the ports to get/set processor specific registers, ala SSE registers on x86. --- sys/mips/mips/ptrace_machdep.c | 37 ++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 sys/mips/mips/ptrace_machdep.c diff --git a/sys/mips/mips/ptrace_machdep.c b/sys/mips/mips/ptrace_machdep.c new file mode 100644 index 00000000000..2c268d8b12b --- /dev/null +++ b/sys/mips/mips/ptrace_machdep.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2009 M. Warner Losh. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#if 0 +#include +__FBSDID("$FreeBSD$"); + +/* + * This file is a place holder for MIPS. Some models of MIPS may need special + * functions here, but for now nothing is needed. The MI parts of ptrace + * suffice. + */ +#endif From 2be832193dcd55f82fb1139172fb3d22d626a8d6 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Sun, 20 Dec 2009 17:53:35 +0000 Subject: [PATCH 364/380] Adds JC's fix to get rid of stray intr's. Obtained from: JC - jayachandraanc@netlogicmicro.com --- sys/mips/rmi/iodi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/mips/rmi/iodi.c b/sys/mips/rmi/iodi.c index 65045c071f6..0983fe71547 100644 --- a/sys/mips/rmi/iodi.c +++ b/sys/mips/rmi/iodi.c @@ -119,7 +119,7 @@ iodi_setup_intr(device_t dev, device_t child, xlr_write_reg(mmio, PIC_IRT_1_UART_0, ((1 << 31) | (level << 30) | (1 << 6) | (PIC_UART_0_IRQ))); if (rmi_spin_mutex_safe) mtx_unlock_spin(&xlr_pic_lock); - cpu_establish_hardintr("uart", NULL, + cpu_establish_hardintr("uart", filt, (driver_intr_t *) intr, (void *)arg, PIC_UART_0_IRQ, flags, cookiep); } else if (strcmp(device_get_name(child), "rge") == 0) { @@ -133,7 +133,7 @@ iodi_setup_intr(device_t dev, device_t child, xlr_write_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE, reg | (1 << 6) | (1 << 30) | (1 << 31)); if (rmi_spin_mutex_safe) mtx_unlock_spin(&xlr_pic_lock); - cpu_establish_hardintr("rge", NULL, (driver_intr_t *) intr, (void *)arg, irq, flags, cookiep); + cpu_establish_hardintr("rge", filt, (driver_intr_t *) intr, (void *)arg, irq, flags, cookiep); } else if (strcmp(device_get_name(child), "ehci") == 0) { if (rmi_spin_mutex_safe) @@ -142,7 +142,7 @@ iodi_setup_intr(device_t dev, device_t child, xlr_write_reg(mmio, PIC_IRT_1_BASE + PIC_USB_IRQ - PIC_IRQ_BASE, reg | (1 << 6) | (1 << 30) | (1 << 31)); if (rmi_spin_mutex_safe) mtx_unlock_spin(&xlr_pic_lock); - cpu_establish_hardintr("ehci", NULL, (driver_intr_t *) intr, (void *)arg, PIC_USB_IRQ, flags, cookiep); + cpu_establish_hardintr("ehci", filt, (driver_intr_t *) intr, (void *)arg, PIC_USB_IRQ, flags, cookiep); } /* * This causes a panic and looks recursive to me (RRS). From c33e262ffe6ca76080c456e3178a637675fed30e Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Mon, 21 Dec 2009 11:29:30 +0000 Subject: [PATCH 365/380] Fixes so kdb works. --- sys/mips/rmi/xlr_machdep.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/mips/rmi/xlr_machdep.c b/sys/mips/rmi/xlr_machdep.c index 0882f9f208a..52306d9019c 100644 --- a/sys/mips/rmi/xlr_machdep.c +++ b/sys/mips/rmi/xlr_machdep.c @@ -28,6 +28,8 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_ddb.h" + #include #include #include @@ -49,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include #include /* cinit() */ +#include #include #include #include @@ -363,7 +366,7 @@ mips_init(void) #endif /* SMP */ kdb_init(); if (boothowto & RB_KDB) { - kdb_enter("Boot flags requested debugger"); + kdb_enter("Boot flags requested debugger", NULL); } #endif } From 5599367b47b5f2c34dc2cd1fd93c7dcd4793f61e Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 23 Dec 2009 08:13:44 +0000 Subject: [PATCH 366/380] Load gp for N32 and N64 operations. Obtained from: Cavium's Octeon port --- lib/csu/mips/crtn.S | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/csu/mips/crtn.S b/lib/csu/mips/crtn.S index 4803994027f..96a02109662 100644 --- a/lib/csu/mips/crtn.S +++ b/lib/csu/mips/crtn.S @@ -9,6 +9,9 @@ __FBSDID("$FreeBSD$"); .section .fini,"ax",%progbits lw ra, 28(sp) +#if defined(__mips_n64) || defined(__mips_n32) + lw gp, 16(sp) +#endif .set noreorder j ra addu sp, sp, 32 From a321ad5e62d6f55b563fd6453f49d23755ac9dc8 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 23 Dec 2009 08:16:53 +0000 Subject: [PATCH 367/380] Start to add support for N32 and N64 ABIs. In addition, add a work around for (or maybe you would call it increase compatibility with) Cavium toolchain: the .cprestore macro references fp rather than sp, so we need to copy sp to fp in a couple of places. Also add a couple of comments to explain what's going on. Obtained from: Cavium FreeBSD/octeon port. --- lib/csu/mips/crti.S | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/lib/csu/mips/crti.S b/lib/csu/mips/crti.S index 1a0d23e5a33..a46a4f08283 100644 --- a/lib/csu/mips/crti.S +++ b/lib/csu/mips/crti.S @@ -5,6 +5,13 @@ __FBSDID("$FreeBSD$"); .align 4 .globl _init .type _init,%function + + /* + * The Cavium toolchain apparently has code that references $fp + * instead of $sp for the .cprestore 16 macro. The move doesn't + * hurt on other toolchains, so unconditionally compile it in for + * now. + */ _init: #ifdef __ABICALLS__ .set noreorder @@ -13,7 +20,7 @@ _init: subu sp, sp, 32 .cprestore 16 sw ra, 28(sp) - + move s8, sp /* See note above */ #else subu sp, sp, 32 sw ra, 28(sp) @@ -24,14 +31,30 @@ _init: .globl _fini .type _fini,%function _fini: + +#if defined (__mips_n64) || defined (__mips_n32) +#ifdef __ABICALLS__ + subu sp, sp, 32 + sw gp, 16(sp) + sw ra, 28(sp) + move s8, sp +#else + subu sp, sp, 32 + sw ra, 28(sp) +#endif /*__ABICALLS__*/ + +#else #ifdef __ABICALLS__ .set noreorder .cpload $25 .set reorder subu sp, sp, 32 - .cprestore 16 + move s8, sp /* See note above */ + .cprestore 16 /* xxx missing in Cavium's version -- why? */ sw ra, 28(sp) #else subu sp, sp, 32 sw ra, 28(sp) -#endif +#endif /* __ABICALLS__ */ + +#endif /* __mips_n64 || __mips_n32 */ From 0eb9a6955c508786303e32390f0cdc6e3f0c4628 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 23 Dec 2009 08:22:48 +0000 Subject: [PATCH 368/380] Bring in support for n64 and n32 ABIs, at least at the base. o Rename __start to __start_mips and change the args a little o Create a new __start written in assembler that copes with the different ABIs and rewrites the args a little to make their passing more abi agnostic. o Add an alias _start for __start for the Cavium toolchain (in the cavium port, a custom ld script is used which references _start instead of the traditional mips __start). o call _init_tls() when we aren't being an a.out shared library (which is the only time _DYNAMIC is != NULL, I think). We could likely retire support for a.out shared libraries entirely, but that will be in the future when I'm sure there's not some subtle reason to keep them around. # Note: the reason mips starts at __start instead of _start is purely # historical, but I didn't want to change it here and in the # toolchain. The Cavium build process is kind of the odd duck here, # but it is trivial to support both, so why not... --- lib/csu/mips/crt1.c | 91 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 73 insertions(+), 18 deletions(-) diff --git a/lib/csu/mips/crt1.c b/lib/csu/mips/crt1.c index 746cee2aa18..61734048032 100644 --- a/lib/csu/mips/crt1.c +++ b/lib/csu/mips/crt1.c @@ -1,6 +1,4 @@ /*- - * Copyright 1996-1998 John D. Polstra. - * All rights reserved. * Copyright (c) 1995 Christopher G. Demetriou * All rights reserved. * @@ -65,37 +63,94 @@ extern int etext; char **environ; const char *__progname = ""; +struct ps_strings *__ps_strings; void __gccmain(void) {} void __main(void) {} -/* The entry function. */ -void -__start(char **ap, - void (*cleanup)(void), /* from shared loader */ - struct Struct_Obj_Entry *obj, /* from shared loader */ - struct ps_strings *ps_strings) -{ - int argc; - char **argv; - char **env; +/* + * Historically, mips has used __start for the beginning address of programs. + * However, the Cavium toolchain (and maybe others) use _start. Define both + * here. The assembler code here tries to juggle the arguments such that they + * are right for all ABIs and then calls __start_mips which is what used to + * be just plain __start, and still is on other BSD ports. + */ - argc = * (long *) ap; - argv = ap + 1; - env = ap + 2 + argc; +/* The entry function. */ +__asm(" .text \n" +" .align 8 \n" +" .globl _start \n" +" _start: \n" +" .globl __start \n" +" __start: \n" +#if defined(__mips_n32) || defined(__mips_n64) +" .cpsetup $25, $24, __start\n" +#else +" .set noreorder \n" +" .cpload $25 \n" +" .set reorder \n" +#endif +" /* Get cleanup routine and main object set by rtld */\n" +" /* Note that a2 is already set to ps_string by _rtld_start */\n" +" /* move a3, a0 */\n" +" /* move t0, a1 */\n" +" /* Get argc, argv from stack */ \n" +" /* lw a0, 0(sp) */\n" +" /* move a1, sp */\n" +" /* addu a1, 4 */\n" +" \n" +" /* Stack should 8bytes aligned */\n" +" /* required by ABI to pass */\n" +" /* 64-bits arguments */\n" +" /* and sp, ~8 */\n" +" /* subu sp, sp, 20 */\n" +" /* sw t0, 16(sp) */\n" +" \n" +" move $7, $4 /* atexit */\n" +" move $8, $5 /* main_obj entry */\n" +#if defined(__mips_n64) +" ld $4, 0($29) \n" +" move $5, $29 \n" +" addu $5, 8 \n" +#else +" lw $4, 0($29) \n" +" move $5, $29 \n" +" addu $5, 4 \n" +#endif +" \n" +" and $29, 0xfffffff8 \n" +" subu $29, $29, 24 /* args slot + cleanup + 4 bytes padding */ \n" +" sw $8, 16($29) \n" +"\n" +" la $25, __start_mips \n" +" nop \n" +" j $25\n"); +/* ARGSUSED */ + +void +__start_mips(int argc, char **argv, struct ps_strings *ps_strings, + void (*cleanup)(void), struct Struct_Obj_Entry *obj __unused) +{ + char **env; + const char *s; + + env = argv + argc + 1; environ = env; + if(argc > 0 && argv[0] != NULL) { - const char *s; __progname = argv[0]; for (s = __progname; *s != '\0'; s++) if (*s == '/') __progname = s + 1; } -#ifndef NOSHARED + __ps_strings = ps_strings; + if (&_DYNAMIC != NULL) atexit(cleanup); -#endif + else + _init_tls(); + #ifdef GCRT atexit(_mcleanup); #endif From d0a679ea35abf9f02b735932c37ebbe2f82a5458 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Wed, 23 Dec 2009 14:48:26 +0000 Subject: [PATCH 369/380] This is a list of the files for RMI's md_root file system to get to multi-user. There are still some rough edges, rge has an issue. And someone held a spin lock to long.. But its coming along :-) --- sys/mips/rmi/rootfs_list.txt | 676 +++++++++++++++++++++++++++++++++++ 1 file changed, 676 insertions(+) create mode 100644 sys/mips/rmi/rootfs_list.txt diff --git a/sys/mips/rmi/rootfs_list.txt b/sys/mips/rmi/rootfs_list.txt new file mode 100644 index 00000000000..5cfd2e99a0b --- /dev/null +++ b/sys/mips/rmi/rootfs_list.txt @@ -0,0 +1,676 @@ +# This is the list of files that +# should be in your rootfs (copy it from +# the build world nfsmount dir. When the rge0 +# driver gets fixed we should be able to start +# using nfs mount... for now we need to use MD_ROOT +./.cshrc +./.profile +./COPYRIGHT +./bin +./bin/cat +./bin/chflags +./bin/chio +./bin/chmod +./bin/cp +./bin/csh +./bin/tcsh +./bin/date +./bin/dd +./bin/df +./bin/domainname +./bin/echo +./bin/ed +./bin/red +./bin/expr +./bin/getfacl +./bin/hostname +./bin/kenv +./bin/kill +./bin/ln +./bin/link +./bin/ls +./bin/mkdir +./bin/mv +./bin/pax +./bin/pkill +./bin/pgrep +./bin/ps +./bin/pwd +./bin/rcp +./bin/realpath +./bin/rm +./bin/unlink +./bin/rmail +./bin/rmdir +./bin/setfacl +./bin/sh +./bin/sleep +./bin/stty +./bin/sync +./bin/test +./bin/[ +./bin/uuidgen +./etc +./etc/bluetooth +./etc/bluetooth/hcsecd.conf +./etc/bluetooth/hosts +./etc/bluetooth/protocols +./etc/defaults +./etc/defaults/bluetooth.device.conf +./etc/defaults/devfs.rules +./etc/defaults/periodic.conf +./etc/defaults/rc.conf +./etc/devd +./etc/devd/asus.conf +./etc/gnats +./etc/gnats/freefall +./etc/gss +./etc/gss/mech +./etc/gss/qop +./etc/mail +./etc/mail/mailer.conf +./etc/mail/freebsd.mc +./etc/mail/freebsd.cf +./etc/mail/freebsd.submit.mc +./etc/mail/freebsd.submit.cf +./etc/mail/helpfile +./etc/mail/sendmail.cf +./etc/mail/submit.cf +./etc/mail/Makefile +./etc/mail/README +./etc/mail/access.sample +./etc/mail/virtusertable.sample +./etc/mail/mailertable.sample +./etc/mail/aliases +./etc/mtree +./etc/mtree/BSD.include.dist +./etc/mtree/BSD.root.dist +./etc/mtree/BSD.usr.dist +./etc/mtree/BSD.var.dist +./etc/mtree/BSD.sendmail.dist +./etc/mtree/BIND.chroot.dist +./etc/pam.d +./etc/pam.d/README +./etc/pam.d/atrun +./etc/pam.d/cron +./etc/pam.d/ftpd +./etc/pam.d/imap +./etc/pam.d/kde +./etc/pam.d/login +./etc/pam.d/other +./etc/pam.d/passwd +./etc/pam.d/pop3 +./etc/pam.d/rsh +./etc/pam.d/sshd +./etc/pam.d/su +./etc/pam.d/system +./etc/pam.d/telnetd +./etc/pam.d/xdm +./etc/pam.d/ftp +./etc/periodic +./etc/periodic/daily +./etc/periodic/daily/100.clean-disks +./etc/periodic/daily/110.clean-tmps +./etc/periodic/daily/120.clean-preserve +./etc/periodic/daily/200.backup-passwd +./etc/periodic/daily/330.news +./etc/periodic/daily/400.status-disks +./etc/periodic/daily/404.status-zfs +./etc/periodic/daily/405.status-ata-raid +./etc/periodic/daily/406.status-gmirror +./etc/periodic/daily/407.status-graid3 +./etc/periodic/daily/408.status-gstripe +./etc/periodic/daily/409.status-gconcat +./etc/periodic/daily/420.status-network +./etc/periodic/daily/450.status-security +./etc/periodic/daily/999.local +./etc/periodic/daily/310.accounting +./etc/periodic/daily/470.status-named +./etc/periodic/daily/300.calendar +./etc/periodic/daily/130.clean-msgs +./etc/periodic/daily/480.status-ntpd +./etc/periodic/daily/140.clean-rwho +./etc/periodic/daily/430.status-rwho +./etc/periodic/daily/150.clean-hoststat +./etc/periodic/daily/210.backup-aliases +./etc/periodic/daily/440.status-mailq +./etc/periodic/daily/460.status-mail-rejects +./etc/periodic/daily/500.queuerun +./etc/periodic/monthly +./etc/periodic/monthly/999.local +./etc/periodic/monthly/200.accounting +./etc/periodic/security +./etc/periodic/security/100.chksetuid +./etc/periodic/security/200.chkmounts +./etc/periodic/security/300.chkuid0 +./etc/periodic/security/400.passwdless +./etc/periodic/security/410.logincheck +./etc/periodic/security/700.kernelmsg +./etc/periodic/security/800.loginfail +./etc/periodic/security/900.tcpwrap +./etc/periodic/security/security.functions +./etc/periodic/security/510.ipfdenied +./etc/periodic/security/500.ipfwdenied +./etc/periodic/security/550.ipfwlimit +./etc/periodic/security/520.pfdenied +./etc/periodic/weekly +./etc/periodic/weekly/340.noid +./etc/periodic/weekly/999.local +./etc/periodic/weekly/310.locate +./etc/periodic/weekly/320.whatis +./etc/periodic/weekly/330.catman +./etc/periodic/weekly/400.status-pkg +./etc/ppp +./etc/ppp/ppp.conf +./etc/rc.d +./etc/rc.d/DAEMON +./etc/rc.d/FILESYSTEMS +./etc/rc.d/LOGIN +./etc/rc.d/NETWORKING +./etc/rc.d/SERVERS +./etc/rc.d/abi +./etc/rc.d/accounting +./etc/rc.d/addswap +./etc/rc.d/adjkerntz +./etc/rc.d/amd +./etc/rc.d/apm +./etc/rc.d/apmd +./etc/rc.d/archdep +./etc/rc.d/atm1 +./etc/rc.d/atm2 +./etc/rc.d/atm3 +./etc/rc.d/auditd +./etc/rc.d/bgfsck +./etc/rc.d/bluetooth +./etc/rc.d/bootparams +./etc/rc.d/bridge +./etc/rc.d/bthidd +./etc/rc.d/ccd +./etc/rc.d/cleanvar +./etc/rc.d/cleartmp +./etc/rc.d/cron +./etc/rc.d/ddb +./etc/rc.d/defaultroute +./etc/rc.d/devd +./etc/rc.d/devfs +./etc/rc.d/dhclient +./etc/rc.d/dmesg +./etc/rc.d/dumpon +./etc/rc.d/encswap +./etc/rc.d/faith +./etc/rc.d/fsck +./etc/rc.d/ftp-proxy +./etc/rc.d/ftpd +./etc/rc.d/gbde +./etc/rc.d/geli +./etc/rc.d/geli2 +./etc/rc.d/gssd +./etc/rc.d/hcsecd +./etc/rc.d/hostapd +./etc/rc.d/hostid +./etc/rc.d/hostid_save +./etc/rc.d/hostname +./etc/rc.d/inetd +./etc/rc.d/initrandom +./etc/rc.d/ip6addrctl +./etc/rc.d/ip6fw +./etc/rc.d/ipfilter +./etc/rc.d/ipfs +./etc/rc.d/ipfw +./etc/rc.d/ipmon +./etc/rc.d/ipnat +./etc/rc.d/ipsec +./etc/rc.d/ipxrouted +./etc/rc.d/jail +./etc/rc.d/kadmind +./etc/rc.d/kerberos +./etc/rc.d/keyserv +./etc/rc.d/kldxref +./etc/rc.d/kpasswdd +./etc/rc.d/ldconfig +./etc/rc.d/local +./etc/rc.d/localpkg +./etc/rc.d/lockd +./etc/rc.d/lpd +./etc/rc.d/mixer +./etc/rc.d/motd +./etc/rc.d/mountcritlocal +./etc/rc.d/mountcritremote +./etc/rc.d/mountlate +./etc/rc.d/mdconfig +./etc/rc.d/mdconfig2 +./etc/rc.d/mountd +./etc/rc.d/moused +./etc/rc.d/mroute6d +./etc/rc.d/mrouted +./etc/rc.d/msgs +./etc/rc.d/named +./etc/rc.d/natd +./etc/rc.d/netif +./etc/rc.d/netoptions +./etc/rc.d/newsyslog +./etc/rc.d/pf +./etc/rc.d/nfscbd +./etc/rc.d/nfsclient +./etc/rc.d/nfsd +./etc/rc.d/nfsserver +./etc/rc.d/nfsuserd +./etc/rc.d/nisdomain +./etc/rc.d/nsswitch +./etc/rc.d/ntpd +./etc/rc.d/ntpdate +./etc/rc.d/othermta +./etc/rc.d/pflog +./etc/rc.d/pfsync +./etc/rc.d/powerd +./etc/rc.d/power_profile +./etc/rc.d/ppp +./etc/rc.d/pppoed +./etc/rc.d/pwcheck +./etc/rc.d/quota +./etc/rc.d/random +./etc/rc.d/rarpd +./etc/rc.d/resolv +./etc/rc.d/rfcomm_pppd_server +./etc/rc.d/root +./etc/rc.d/route6d +./etc/rc.d/routed +./etc/rc.d/routing +./etc/rc.d/rpcbind +./etc/rc.d/rtadvd +./etc/rc.d/rwho +./etc/rc.d/savecore +./etc/rc.d/sdpd +./etc/rc.d/securelevel +./etc/rc.d/sendmail +./etc/rc.d/serial +./etc/rc.d/sppp +./etc/rc.d/statd +./etc/rc.d/static_arp +./etc/rc.d/stf +./etc/rc.d/swap1 +./etc/rc.d/syscons +./etc/rc.d/sysctl +./etc/rc.d/syslogd +./etc/rc.d/timed +./etc/rc.d/tmp +./etc/rc.d/ugidfw +./etc/rc.d/var +./etc/rc.d/virecover +./etc/rc.d/watchdogd +./etc/rc.d/wpa_supplicant +./etc/rc.d/ypbind +./etc/rc.d/yppasswdd +./etc/rc.d/ypserv +./etc/rc.d/ypset +./etc/rc.d/ypupdated +./etc/rc.d/ypxfrd +./etc/rc.d/zfs +./etc/rc.d/zvol +./etc/rc.d/sshd +./etc/rc.d/nscd +./etc/security +./etc/security/audit_class +./etc/security/audit_event +./etc/security/audit_control +./etc/security/audit_user +./etc/security/audit_warn +./etc/ssh +./etc/ssh/ssh_config +./etc/ssh/sshd_config +./etc/ssh/moduli +./etc/ssl +./etc/ssl/openssl.cnf +./etc/auth.conf +./etc/crontab +./etc/devd.conf +./etc/devfs.conf +./etc/ddb.conf +./etc/dhclient.conf +./etc/disktab +./etc/fbtab +./etc/ftpusers +./etc/gettytab +./etc/group +./etc/hosts +./etc/hosts.allow +./etc/hosts.equiv +./etc/inetd.conf +./etc/libalias.conf +./etc/login.access +./etc/login.conf +./etc/mac.conf +./etc/motd +./etc/netconfig +./etc/network.subr +./etc/networks +./etc/newsyslog.conf +./etc/nsswitch.conf +./etc/phones +./etc/profile +./etc/protocols +./etc/rc +./etc/rc.bsdextended +./etc/rc.firewall +./etc/rc.firewall6 +./etc/rc.initdiskless +./etc/rc.sendmail +./etc/rc.shutdown +./etc/rc.subr +./etc/remote +./etc/rpc +./etc/services +./etc/shells +./etc/sysctl.conf +./etc/syslog.conf +./etc/ttys +./etc/amd.map +./etc/apmd.conf +./etc/freebsd-update.conf +./etc/locate.rc +./etc/hosts.lpd +./etc/printcap +./etc/mail.rc +./etc/manpath.config +./etc/ntp.conf +./etc/nscd.conf +./etc/portsnap.conf +./etc/pf.os +./etc/csh.cshrc +./etc/csh.login +./etc/csh.logout +./etc/regdomain.xml +./etc/login.conf.db +./etc/pwd.db +./etc/netstart +./etc/pccard_ether +./etc/rc.suspend +./etc/rc.resume +./etc/master.passwd +./etc/nsmb.conf +./etc/opieaccess +./etc/spwd.db +./etc/passwd +./etc/dumpdates +./etc/fstab +./etc/rc.conf +./etc/resolv.conf +./etc/termcap +./lib +./lib/geom +./lib/geom/geom_cache.so +./lib/geom/geom_concat.so +./lib/geom/geom_eli.so +./lib/geom/geom_journal.so +./lib/geom/geom_label.so +./lib/geom/geom_mirror.so +./lib/geom/geom_multipath.so +./lib/geom/geom_nop.so +./lib/geom/geom_part.so +./lib/geom/geom_raid3.so +./lib/geom/geom_shsec.so +./lib/geom/geom_stripe.so +./lib/geom/geom_virstor.so +./lib/libc.so.7 +./lib/libcrypt.so.5 +./lib/libkvm.so.5 +./lib/libm.so.5 +./lib/libmd.so.5 +./lib/libncurses.so.8 +./lib/libncursesw.so.8 +./lib/libsbuf.so.5 +./lib/libutil.so.8 +./lib/libalias.so.7 +./lib/libalias_cuseeme.so +./lib/libalias_dummy.so +./lib/libalias_ftp.so +./lib/libalias_irc.so +./lib/libalias_nbt.so +./lib/libalias_pptp.so +./lib/libalias_skinny.so +./lib/libalias_smedia.so +./lib/libbegemot.so.4 +./lib/libcam.so.5 +./lib/libdevstat.so.7 +./lib/libedit.so.7 +./lib/libbsdxml.so.4 +./lib/libgeom.so.5 +./lib/libipsec.so.4 +./lib/libipx.so.5 +./lib/libjail.so.1 +./lib/libkiconv.so.4 +./lib/libpcap.so.7 +./lib/libthr.so.3 +./lib/libufs.so.5 +./lib/libz.so.5 +./lib/libgcc_s.so.1 +./lib/libreadline.so.8 +./lib/libssp.so.0 +./lib/libcrypto.so.6 +./libexec +./libexec/ld-elf.so.1 +./libexec/ld-elf.so.1.old +./sbin +./sbin/adjkerntz +./sbin/atacontrol +./sbin/badsect +./sbin/bsdlabel +./sbin/camcontrol +./sbin/ccdconfig +./sbin/clri +./sbin/comcontrol +./sbin/conscontrol +./sbin/devd +./sbin/devfs +./sbin/dhclient +./sbin/dhclient-script +./sbin/dmesg +./sbin/dump +./sbin/rdump +./sbin/dumpfs +./sbin/dumpon +./sbin/fdisk +./sbin/ffsinfo +./sbin/fsck +./sbin/fsck_ffs +./sbin/fsck_ufs +./sbin/fsck_4.2bsd +./sbin/fsdb +./sbin/fsirand +./sbin/gbde +./sbin/fsck_msdosfs +./sbin/geom +./sbin/gcache +./sbin/gconcat +./sbin/geli +./sbin/gjournal +./sbin/glabel +./sbin/gmirror +./sbin/gmultipath +./sbin/gnop +./sbin/gpart +./sbin/graid3 +./sbin/gshsec +./sbin/gstripe +./sbin/gvirstor +./sbin/ggatec +./sbin/ggated +./sbin/ggatel +./sbin/growfs +./sbin/gvinum +./sbin/ifconfig +./sbin/init +./sbin/ipf +./sbin/ipfs +./sbin/ipfstat +./sbin/ipftest +./sbin/ipmon +./sbin/ipnat +./sbin/ippool +./sbin/md5 +./sbin/ipfw +./sbin/ipresend +./sbin/iscontrol +./sbin/kldconfig +./sbin/kldload +./sbin/kldstat +./sbin/kldunload +./sbin/ldconfig +./sbin/rmd160 +./sbin/sha1 +./sbin/sha256 +./sbin/mdconfig +./sbin/mdmfs +./sbin/mount_mfs +./sbin/mknod +./sbin/mksnap_ffs +./sbin/mount +./sbin/mount_cd9660 +./sbin/mount_msdosfs +./sbin/mount_nfs +./sbin/mount_newnfs +./sbin/mount_ntfs +./sbin/mount_nullfs +./sbin/mount_udf +./sbin/mount_unionfs +./sbin/natd +./sbin/ddb +./sbin/newfs +./sbin/newfs_msdos +./sbin/nfsiod +./sbin/nos-tun +./sbin/pfctl +./sbin/pflogd +./sbin/ping +./sbin/ping6 +./sbin/quotacheck +./sbin/rcorder +./sbin/reboot +./sbin/nextboot +./sbin/halt +./sbin/fastboot +./sbin/fasthalt +./sbin/recoverdisk +./sbin/restore +./sbin/rrestore +./sbin/route +./sbin/routed +./sbin/rtquery +./sbin/rtsol +./sbin/savecore +./sbin/setkey +./sbin/shutdown +./sbin/spppcontrol +./sbin/swapon +./sbin/swapoff +./sbin/swapctl +./sbin/sysctl +./sbin/tunefs +./sbin/umount +./sbin/init.bak +./var +./var/crash +./var/crash/minfree +./var/db +./var/db/locate.database +./var/log +./var/log/sendmail.st +./var/named +./var/named/etc +./var/named/etc/namedb +./var/named/etc/namedb/master +./var/named/etc/namedb/master/empty.db +./var/named/etc/namedb/master/localhost-forward.db +./var/named/etc/namedb/master/localhost-reverse.db +./var/named/etc/namedb/named.conf +./var/named/etc/namedb/named.root +./var/yp +./var/yp/Makefile.dist +./var/run +./var/cron +./var/cron/tabs +./root +./root/.k5login +./root/.profile +./root/.cshrc +./root/.login +./list +./dev +./usr +./usr/sbin +./usr/sbin/newsyslog +./usr/sbin/syslogd +./usr/sbin/ip6addrctl +./usr/sbin/sendmail +./usr/sbin/cron +./usr/lib +./usr/lib/libpam.so.5 +./usr/lib/libpam.so +./usr/lib/pam_opie.so.5 +./usr/lib/libbsm.so.3 +./usr/lib/libbsm.so +./usr/lib/pam_chroot.so.5 +./usr/lib/pam_tacplus.so.5 +./usr/lib/pam_ssh.so.5 +./usr/lib/pam_self.so.5 +./usr/lib/pam_securetty.so.5 +./usr/lib/pam_rootok.so.5 +./usr/lib/pam_rhosts.so.5 +./usr/lib/pam_radius.so.5 +./usr/lib/pam_permit.so.5 +./usr/lib/pam_passwdqc.so.5 +./usr/lib/libcom_err.so.5 +./usr/lib/libcom_err.so +./usr/lib/pam_opieaccess.so.5 +./usr/lib/pam_nologin.so.5 +./usr/lib/libc.so.7 +./usr/lib/pam_login_access.so.5 +./usr/lib/pam_lastlog.so.5 +./usr/lib/pam_ksu.so.5 +./usr/lib/pam_krb5.so.5 +./usr/lib/pam_guest.so.5 +./usr/lib/pam_group.so.5 +./usr/lib/pam_ftpusers.so.5 +./usr/lib/pam_exec.so.5 +./usr/lib/pam_echo.so.5 +./usr/lib/pam_deny.so.5 +./usr/lib/pam_unix.so.5 +./usr/lib/pam_chroot.so +./usr/lib/libopie.so +./usr/lib/pam_deny.so +./usr/lib/pam_echo.so +./usr/lib/pam_exec.so +./usr/lib/pam_ftpusers.so +./usr/lib/pam_group.so +./usr/lib/pam_guest.so +./usr/lib/pam_krb5.so +./usr/lib/pam_ksu.so +./usr/lib/pam_lastlog.so +./usr/lib/pam_login_access.so +./usr/lib/pam_nologin.so +./usr/lib/pam_opie.so +./usr/lib/pam_opieaccess.so +./usr/lib/pam_passwdqc.so +./usr/lib/pam_permit.so +./usr/lib/pam_radius.so +./usr/lib/pam_rhosts.so +./usr/lib/pam_rootok.so +./usr/lib/pam_securetty.so +./usr/lib/pam_self.so +./usr/lib/pam_ssh.so +./usr/lib/pam_tacplus.so +./usr/lib/pam_unix.so +./usr/lib/libmd.so.5 +./usr/lib/libbz2.so.4 +./usr/lib/libgnuregex.so.5 +./usr/lib/libypclnt.so.4 +./usr/bin +./usr/bin/mktemp +./usr/bin/login +./usr/bin/uname +./usr/bin/awk +./usr/bin/logger +./usr/bin/grep +./usr/bin/ftp +./usr/libexec +./usr/libexec/getty From 0e39bbc4dd2ae38d35a37cd8f1d498d4bc473668 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Wed, 23 Dec 2009 14:55:33 +0000 Subject: [PATCH 370/380] Add missing function that doesintr naming and init. --- sys/mips/rmi/intr_machdep.c | 41 ++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/sys/mips/rmi/intr_machdep.c b/sys/mips/rmi/intr_machdep.c index 07a9dab76f9..dc34fda9c7c 100644 --- a/sys/mips/rmi/intr_machdep.c +++ b/sys/mips/rmi/intr_machdep.c @@ -50,8 +50,9 @@ __FBSDID("$FreeBSD$"); #include /*#include */ - +static mips_intrcnt_t mips_intr_counters[XLR_MAX_INTR]; struct mips_intrhand mips_intr_handlers[XLR_MAX_INTR]; +static int intrcnt_index; static void mips_mask_hard_irq(void *source) @@ -113,8 +114,6 @@ cpu_establish_softintr(const char *name, driver_filter_t * filt, cpu_establish_hardintr(name, filt, handler, arg, irq, flags, cookiep); } - - void cpu_intr(struct trapframe *tf) { @@ -180,3 +179,39 @@ cpu_intr(struct trapframe *tf) } critical_exit(); } + +void +mips_intrcnt_setname(mips_intrcnt_t counter, const char *name) +{ + int idx = counter - intrcnt; + + KASSERT(counter != NULL, ("mips_intrcnt_setname: NULL counter")); + + snprintf(intrnames + (MAXCOMLEN + 1) * idx, + MAXCOMLEN + 1, "%-*s", MAXCOMLEN, name); +} + +mips_intrcnt_t +mips_intrcnt_create(const char* name) +{ + mips_intrcnt_t counter = &intrcnt[intrcnt_index++]; + + mips_intrcnt_setname(counter, name); + return counter; +} + +void +cpu_init_interrupts() +{ + int i; + char name[MAXCOMLEN + 1]; + + /* + * Initialize all available vectors so spare IRQ + * would show up in systat output + */ + for (i = 0; i < XLR_MAX_INTR; i++) { + snprintf(name, MAXCOMLEN + 1, "int%d:", i); + mips_intr_counters[i] = mips_intrcnt_create(name); + } +} From 85e6efa229534f864caadd3a3abb3f575d819c78 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 4 Jan 2010 20:34:15 +0000 Subject: [PATCH 371/380] Style(9) pass. --- sys/mips/octeon1/octeon_machdep.c | 513 ++++++++++++++---------------- 1 file changed, 241 insertions(+), 272 deletions(-) diff --git a/sys/mips/octeon1/octeon_machdep.c b/sys/mips/octeon1/octeon_machdep.c index 43b1c60f6d7..f7b4448082e 100644 --- a/sys/mips/octeon1/octeon_machdep.c +++ b/sys/mips/octeon1/octeon_machdep.c @@ -80,7 +80,12 @@ __FBSDID("$FreeBSD$"); extern int *edata; extern int *end; +uint64_t ciu_get_en_reg_addr_new(int corenum, int intx, int enx, int ciu_ip); +void ciu_dump_interrutps_enabled(int core_num, int intx, int enx, int ciu_ip); + static void octeon_boot_params_init(register_t ptr); +static uint64_t ciu_get_intr_sum_reg_addr(int core_num, int intx, int enx); +static uint64_t ciu_get_intr_en_reg_addr(int core_num, int intx, int enx); void platform_cpu_init() @@ -90,7 +95,6 @@ platform_cpu_init() /* * Perform a board-level soft-reset. - * Note that this is not emulated by gxemul. */ void platform_reset(void) @@ -99,85 +103,95 @@ platform_reset(void) } -static inline uint32_t octeon_disable_interrupts (void) +static inline uint32_t +octeon_disable_interrupts(void) { - uint32_t status_bits; + uint32_t status_bits; - status_bits = mips_rd_status(); - mips_wr_status(status_bits & ~MIPS_SR_INT_IE); - return (status_bits); + status_bits = mips_rd_status(); + mips_wr_status(status_bits & ~MIPS_SR_INT_IE); + return (status_bits); } -static inline void octeon_set_interrupts (uint32_t status_bits) +static inline void +octeon_set_interrupts(uint32_t status_bits) { - mips_wr_status(status_bits); + mips_wr_status(status_bits); } -void octeon_led_write_char (int char_position, char val) +void +octeon_led_write_char(int char_position, char val) { - uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8); + uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8); - if (!octeon_board_real()) return; + if (!octeon_board_real()) + return; - char_position &= 0x7; /* only 8 chars */ - ptr += char_position; - oct_write8_x8(ptr, val); + char_position &= 0x7; /* only 8 chars */ + ptr += char_position; + oct_write8_x8(ptr, val); } -void octeon_led_write_char0 (char val) +void +octeon_led_write_char0(char val) { - uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8); + uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8); - if (!octeon_board_real()) return; - - oct_write8_x8(ptr, val); + if (!octeon_board_real()) + return; + oct_write8_x8(ptr, val); } -void octeon_led_write_hexchar (int char_position, char hexval) +void +octeon_led_write_hexchar(int char_position, char hexval) { - uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8); - char char1, char2; + uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8); + char char1, char2; - if (!octeon_board_real()) return; + if (!octeon_board_real()) + return; - char1 = (hexval >> 4) & 0x0f; char1 = (char1 < 10)?char1+'0':char1+'7'; - char2 = (hexval & 0x0f); char2 = (char2 < 10)?char2+'0':char2+'7'; - char_position &= 0x7; /* only 8 chars */ - if (char_position > 6) char_position = 6; - ptr += char_position; - oct_write8_x8(ptr, char1); - ptr++; - oct_write8_x8(ptr, char2); + char1 = (hexval >> 4) & 0x0f; char1 = (char1 < 10)?char1+'0':char1+'7'; + char2 = (hexval & 0x0f); char2 = (char2 < 10)?char2+'0':char2+'7'; + char_position &= 0x7; /* only 8 chars */ + if (char_position > 6) + char_position = 6; + ptr += char_position; + oct_write8_x8(ptr, char1); + ptr++; + oct_write8_x8(ptr, char2); } -void octeon_led_write_string (const char *str) +void +octeon_led_write_string(const char *str) { - uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8); - int i; + uint64_t ptr = (OCTEON_CHAR_LED_BASE_ADDR | 0xf8); + int i; - if (!octeon_board_real()) return; + if (!octeon_board_real()) + return; - for (i=0; i<8; i++, ptr++) { - if (str && *str) { - oct_write8_x8(ptr, *str++); - } else { - oct_write8_x8(ptr, ' '); - } - oct_read64(OCTEON_MIO_BOOT_BIST_STAT); - } + for (i=0; i<8; i++, ptr++) { + if (str && *str) + oct_write8_x8(ptr, *str++); + else + oct_write8_x8(ptr, ' '); + oct_read64(OCTEON_MIO_BOOT_BIST_STAT); + } } static char progress[8] = { '-', '/', '|', '\\', '-', '/', '|', '\\'}; -void octeon_led_run_wheel (/*int count, */int *prog_count, int led_position) +void +octeon_led_run_wheel(int *prog_count, int led_position) { - if (!octeon_board_real()) return; - - octeon_led_write_char(led_position, progress[*prog_count]); - *prog_count += 1; - *prog_count &= 0x7; + if (!octeon_board_real()) + return; + octeon_led_write_char(led_position, progress[*prog_count]); + *prog_count += 1; + *prog_count &= 0x7; } #define LSR_DATAREADY 0x01 /* Data ready */ @@ -191,160 +205,116 @@ void octeon_led_run_wheel (/*int count, */int *prog_count, int led_position) * Put out a single byte off of uart port. */ -void octeon_uart_write_byte (int uart_index, uint8_t ch) +void +octeon_uart_write_byte(int uart_index, uint8_t ch) { - uint64_t val, val2; - if ((uart_index < 0) || (uart_index > 1)) { - return; - } + uint64_t val, val2; + if (uart_index < 0 || uart_index > 1) + return; - while (1) { - val = oct_read64(OCTEON_MIO_UART0_LSR + (uart_index * 0x400)); - val2 = oct_read64(OCTEON_MIO_UART0_USR + (uart_index * 0x400)); - if ((((uint8_t) val) & LSR_THRE) || - (((uint8_t) val2) & USR_TXFIFO_NOTFULL)) { - break; - } - } + while (1) { + val = oct_read64(OCTEON_MIO_UART0_LSR + (uart_index * 0x400)); + val2 = oct_read64(OCTEON_MIO_UART0_USR + (uart_index * 0x400)); + if ((((uint8_t) val) & LSR_THRE) || + (((uint8_t) val2) & USR_TXFIFO_NOTFULL)) { + break; + } + } - /* Write the byte */ - oct_write8(OCTEON_MIO_UART0_THR + (uart_index * 0x400), (uint64_t) ch); + /* Write the byte */ + oct_write8(OCTEON_MIO_UART0_THR + (uart_index * 0x400), (uint64_t) ch); - /* Force Flush the IOBus */ - oct_read64(OCTEON_MIO_BOOT_BIST_STAT); + /* Force Flush the IOBus */ + oct_read64(OCTEON_MIO_BOOT_BIST_STAT); } -void octeon_uart_write_byte0 (uint8_t ch) +void +octeon_uart_write_byte0(uint8_t ch) { - uint64_t val, val2; + uint64_t val, val2; - while (1) { - val = oct_read64(OCTEON_MIO_UART0_LSR); - val2 = oct_read64(OCTEON_MIO_UART0_USR); - if ((((uint8_t) val) & LSR_THRE) || - (((uint8_t) val2) & USR_TXFIFO_NOTFULL)) { - break; - } - } + while (1) { + val = oct_read64(OCTEON_MIO_UART0_LSR); + val2 = oct_read64(OCTEON_MIO_UART0_USR); + if ((((uint8_t) val) & LSR_THRE) || + (((uint8_t) val2) & USR_TXFIFO_NOTFULL)) { + break; + } + } - /* Write the byte */ - oct_write8(OCTEON_MIO_UART0_THR, (uint64_t) ch); + /* Write the byte */ + oct_write8(OCTEON_MIO_UART0_THR, (uint64_t) ch); - /* Force Flush the IOBus */ - oct_read64(OCTEON_MIO_BOOT_BIST_STAT); + /* Force Flush the IOBus */ + oct_read64(OCTEON_MIO_BOOT_BIST_STAT); } /* * octeon_uart_write_string * */ -void octeon_uart_write_string (int uart_index, const char *str) +void +octeon_uart_write_string(int uart_index, const char *str) { - /* Just loop writing one byte at a time */ + /* Just loop writing one byte at a time */ - while (*str) - { - octeon_uart_write_byte(uart_index, *str); - if (*str == '\n') { - octeon_uart_write_byte(uart_index, '\r'); - } - str++; - } - } + while (*str) { + octeon_uart_write_byte(uart_index, *str); + if (*str == '\n') { + octeon_uart_write_byte(uart_index, '\r'); + } + str++; + } +} static char wstr[30]; -void octeon_led_write_hex (uint32_t wl) +void +octeon_led_write_hex(uint32_t wl) { - char nbuf[80]; + char nbuf[80]; - sprintf(nbuf, "%X", wl); - octeon_led_write_string(nbuf); + sprintf(nbuf, "%X", wl); + octeon_led_write_string(nbuf); } -void octeon_uart_write_hex2 (uint32_t wl, uint32_t wh) +void octeon_uart_write_hex2(uint32_t wl, uint32_t wh) { - sprintf(wstr, "0x%X-0x%X ", wh, wl); - octeon_uart_write_string(0, wstr); + sprintf(wstr, "0x%X-0x%X ", wh, wl); + octeon_uart_write_string(0, wstr); } -void octeon_uart_write_hex (uint32_t wl) +void +octeon_uart_write_hex(uint32_t wl) { - sprintf(wstr, " 0x%X ", wl); - octeon_uart_write_string(0, wstr); + sprintf(wstr, " 0x%X ", wl); + octeon_uart_write_string(0, wstr); } -#ifdef __not_used__ -#define OCT_CONS_BUFLEN 200 -static char console_str_buff0[OCT_CONS_BUFLEN + 1]; -#include - -//#define USE_KERN_SUBR_PRINTF -#ifndef USE_KERN_SUBR_PRINTF -static int oct_printf (const char *fmt, va_list ap); -#endif - -int kern_cons_printf(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); -#ifndef USE_KERN_SUBR_PRINTF - oct_printf(fmt, ap); -#else - ker_printf(fmt, ap); -#endif - va_end(ap); - return (0); -} - -#ifndef USE_KERN_SUBR_PRINTF -static int oct_printf(const char *fmt, va_list ap) -{ - snprintf(console_str_buff0, OCT_CONS_BUFLEN, fmt, ap); - octeon_uart_write_string(0, console_str_buff0); - return (0); -} -#endif - -int console_printf(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - sprintf(console_str_buff0, fmt, ap); - va_end(ap); - octeon_uart_write_string(0, console_str_buff0); - return (0); -} -#endif - - /* * octeon_wait_uart_flush */ -void octeon_wait_uart_flush (int uart_index, uint8_t ch) +void +octeon_wait_uart_flush(int uart_index, uint8_t ch) { - uint64_t val; - int64_t val3; - uint32_t cpu_status_bits; + uint64_t val; + int64_t val3; + uint32_t cpu_status_bits; - if ((uart_index < 0) || (uart_index > 1)) { - return; - } + if (uart_index < 0 || uart_index > 1) + return; - cpu_status_bits = octeon_disable_interrupts(); - /* Force Flush the IOBus */ - oct_read64(OCTEON_MIO_BOOT_BIST_STAT); - for (val3 = 0xfffffffff; val3 > 0; val3--) { - val = oct_read64(OCTEON_MIO_UART0_LSR + (uart_index * 0x400)); - if (((uint8_t) val) & LSR_TEMT) { - break; - } - } - octeon_set_interrupts(cpu_status_bits); + cpu_status_bits = octeon_disable_interrupts(); + /* Force Flush the IOBus */ + oct_read64(OCTEON_MIO_BOOT_BIST_STAT); + for (val3 = 0xfffffffff; val3 > 0; val3--) { + val = oct_read64(OCTEON_MIO_UART0_LSR + (uart_index * 0x400)); + if (((uint8_t) val) & LSR_TEMT) + break; + } + octeon_set_interrupts(cpu_status_bits); } @@ -354,16 +324,19 @@ void octeon_wait_uart_flush (int uart_index, uint8_t ch) * Does nothing. * Used to mark the point for simulator to begin tracing */ -void octeon_debug_symbol (void) +void +octeon_debug_symbol(void) { } -void octeon_ciu_stop_gtimer (int timer) +void +octeon_ciu_stop_gtimer(int timer) { - oct_write64(OCTEON_CIU_GENTIMER_ADDR(timer), 0ll); + oct_write64(OCTEON_CIU_GENTIMER_ADDR(timer), 0ll); } -void octeon_ciu_start_gtimer (int timer, u_int one_shot, uint64_t time_cycles) +void +octeon_ciu_start_gtimer(int timer, u_int one_shot, uint64_t time_cycles) { octeon_ciu_gentimer gentimer; @@ -378,22 +351,23 @@ void octeon_ciu_start_gtimer (int timer, u_int one_shot, uint64_t time_cycles) * * Shutdown all CIU to IP2, IP3 mappings */ -void octeon_ciu_reset (void) +void +octeon_ciu_reset(void) { - octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_0); - octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_1); - octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_2); - octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_3); + octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_0); + octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_1); + octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_2); + octeon_ciu_stop_gtimer(CIU_GENTIMER_NUM_3); - ciu_disable_intr(CIU_THIS_CORE, CIU_INT_0, CIU_EN_0); - ciu_disable_intr(CIU_THIS_CORE, CIU_INT_0, CIU_EN_1); - ciu_disable_intr(CIU_THIS_CORE, CIU_INT_1, CIU_EN_0); - ciu_disable_intr(CIU_THIS_CORE, CIU_INT_1, CIU_EN_1); + ciu_disable_intr(CIU_THIS_CORE, CIU_INT_0, CIU_EN_0); + ciu_disable_intr(CIU_THIS_CORE, CIU_INT_0, CIU_EN_1); + ciu_disable_intr(CIU_THIS_CORE, CIU_INT_1, CIU_EN_0); + ciu_disable_intr(CIU_THIS_CORE, CIU_INT_1, CIU_EN_1); - ciu_clear_int_summary(CIU_THIS_CORE, CIU_INT_0, CIU_EN_0, 0ll); - ciu_clear_int_summary(CIU_THIS_CORE, CIU_INT_1, CIU_EN_0, 0ll); - ciu_clear_int_summary(CIU_THIS_CORE, CIU_INT_1, CIU_EN_1, 0ll); + ciu_clear_int_summary(CIU_THIS_CORE, CIU_INT_0, CIU_EN_0, 0ll); + ciu_clear_int_summary(CIU_THIS_CORE, CIU_INT_1, CIU_EN_0, 0ll); + ciu_clear_int_summary(CIU_THIS_CORE, CIU_INT_1, CIU_EN_1, 0ll); } /* @@ -401,55 +375,49 @@ void octeon_ciu_reset (void) * * Disable interrupts in the CPU controller */ -void mips_disable_interrupt_controls (void) +void +mips_disable_interrupt_controls(void) { - /* - * Disable interrupts in CIU. - */ - octeon_ciu_reset(); + /* + * Disable interrupts in CIU. + */ + octeon_ciu_reset(); } -static uint64_t ciu_get_intr_sum_reg_addr(int core_num, int intx, int enx); - /* * ciu_get_intr_sum_reg_addr */ -static uint64_t ciu_get_intr_sum_reg_addr (int core_num, int intx, int enx) +static uint64_t +ciu_get_intr_sum_reg_addr(int core_num, int intx, int enx) { - uint64_t ciu_intr_sum_reg_addr; + uint64_t ciu_intr_sum_reg_addr; - if (enx == CIU_EN_0) { - ciu_intr_sum_reg_addr = OCTEON_CIU_SUMMARY_BASE_ADDR + (core_num * 0x10) + - (intx * 0x8); - } else { + if (enx == CIU_EN_0) + ciu_intr_sum_reg_addr = OCTEON_CIU_SUMMARY_BASE_ADDR + + (core_num * 0x10) + (intx * 0x8); + else ciu_intr_sum_reg_addr = OCTEON_CIU_SUMMARY_INT1_ADDR; - } return (ciu_intr_sum_reg_addr); } -static uint64_t ciu_get_intr_en_reg_addr(int core_num, int intx, int enx); - /* * ciu_get_intr_en_reg_addr */ -static uint64_t ciu_get_intr_en_reg_addr (int core_num, int intx, int enx) +static uint64_t +ciu_get_intr_en_reg_addr(int core_num, int intx, int enx) { - uint64_t ciu_intr_reg_addr; - - - ciu_intr_reg_addr = OCTEON_CIU_ENABLE_BASE_ADDR + ((enx == 0) ? 0x0 : 0x8) + - (intx * 0x10) + (core_num * 0x20); + uint64_t ciu_intr_reg_addr; + ciu_intr_reg_addr = OCTEON_CIU_ENABLE_BASE_ADDR + + ((enx == 0) ? 0x0 : 0x8) + (intx * 0x10) + (core_num * 0x20); return (ciu_intr_reg_addr); } -uint64_t ciu_get_en_reg_addr_new (int corenum, int intx, int enx, int ciu_ip); - /* * ciu_get_intr_reg_addr * @@ -465,45 +433,46 @@ uint64_t ciu_get_en_reg_addr_new (int corenum, int intx, int enx, int ciu_ip); * 238 ---int1,en1 ip3 * */ -uint64_t ciu_get_en_reg_addr_new (int corenum, int intx, int enx, int ciu_ip) +uint64_t +ciu_get_en_reg_addr_new(int corenum, int intx, int enx, int ciu_ip) { - uint64_t ciu_intr_reg_addr = OCTEON_CIU_ENABLE_BASE_ADDR; + uint64_t ciu_intr_reg_addr = OCTEON_CIU_ENABLE_BASE_ADDR; - if (enx < CIU_EN_0 || enx > CIU_EN_1) { - printf("%s: invalid enx value %d, should be %d or %d\n", - __FUNCTION__, enx, CIU_EN_0, CIU_EN_1); - return 0; - } - if (intx < CIU_INT_0 || intx > CIU_INT_1) { - printf("%s: invalid intx value %d, should be %d or %d\n", - __FUNCTION__, enx, CIU_INT_0, CIU_INT_1); - return 0; - } - if (ciu_ip < CIU_MIPS_IP2 || ciu_ip > CIU_MIPS_IP3) { - printf("%s: invalid ciu_ip value %d, should be %d or %d\n", - __FUNCTION__, ciu_ip, CIU_MIPS_IP2, CIU_MIPS_IP3); - return 0; - } + /* XXX kasserts? */ + if (enx < CIU_EN_0 || enx > CIU_EN_1) { + printf("%s: invalid enx value %d, should be %d or %d\n", + __FUNCTION__, enx, CIU_EN_0, CIU_EN_1); + return 0; + } + if (intx < CIU_INT_0 || intx > CIU_INT_1) { + printf("%s: invalid intx value %d, should be %d or %d\n", + __FUNCTION__, enx, CIU_INT_0, CIU_INT_1); + return 0; + } + if (ciu_ip < CIU_MIPS_IP2 || ciu_ip > CIU_MIPS_IP3) { + printf("%s: invalid ciu_ip value %d, should be %d or %d\n", + __FUNCTION__, ciu_ip, CIU_MIPS_IP2, CIU_MIPS_IP3); + return 0; + } - ciu_intr_reg_addr += (enx * 0x8); - ciu_intr_reg_addr += (ciu_ip * 0x10); - ciu_intr_reg_addr += (intx * 0x20); - - return (ciu_intr_reg_addr); + ciu_intr_reg_addr += (enx * 0x8); + ciu_intr_reg_addr += (ciu_ip * 0x10); + ciu_intr_reg_addr += (intx * 0x20); + return (ciu_intr_reg_addr); } /* * ciu_get_int_summary */ -uint64_t ciu_get_int_summary (int core_num, int intx, int enx) +uint64_t +ciu_get_int_summary(int core_num, int intx, int enx) { - uint64_t ciu_intr_sum_reg_addr; + uint64_t ciu_intr_sum_reg_addr; - if (core_num == CIU_THIS_CORE) { + if (core_num == CIU_THIS_CORE) core_num = octeon_get_core_num(); - } - ciu_intr_sum_reg_addr = ciu_get_intr_sum_reg_addr(core_num, intx, enx); - return (oct_read64(ciu_intr_sum_reg_addr)); + ciu_intr_sum_reg_addr = ciu_get_intr_sum_reg_addr(core_num, intx, enx); + return (oct_read64(ciu_intr_sum_reg_addr)); } //#define DEBUG_CIU 1 @@ -517,74 +486,75 @@ uint64_t ciu_get_int_summary (int core_num, int intx, int enx) /* * ciu_clear_int_summary */ -void ciu_clear_int_summary (int core_num, int intx, int enx, uint64_t write_bits) +void +ciu_clear_int_summary(int core_num, int intx, int enx, uint64_t write_bits) { - uint32_t cpu_status_bits; - uint64_t ciu_intr_sum_reg_addr; + uint32_t cpu_status_bits; + uint64_t ciu_intr_sum_reg_addr; //#define DEBUG_CIU_SUM 1 #ifdef DEBUG_CIU_SUM - uint64_t ciu_intr_sum_bits; + uint64_t ciu_intr_sum_bits; #endif - if (core_num == CIU_THIS_CORE) { + if (core_num == CIU_THIS_CORE) { core_num = octeon_get_core_num(); - } + } #ifdef DEBUG_CIU_SUM printf(" CIU: core %u clear sum IntX %u Enx %u Bits: 0x%llX\n", - core_num, intx, enx, write_bits); + core_num, intx, enx, write_bits); #endif - cpu_status_bits = octeon_disable_interrupts(); + cpu_status_bits = octeon_disable_interrupts(); - ciu_intr_sum_reg_addr = ciu_get_intr_sum_reg_addr(core_num, intx, enx); + ciu_intr_sum_reg_addr = ciu_get_intr_sum_reg_addr(core_num, intx, enx); #ifdef DEBUG_CIU_SUM ciu_intr_sum_bits = oct_read64(ciu_intr_sum_reg_addr); /* unneeded dummy read */ printf(" CIU: status: 0x%X reg_addr: 0x%llX Val: 0x%llX -> 0x%llX", - cpu_status_bits, ciu_intr_sum_reg_addr, ciu_intr_sum_bits, - ciu_intr_sum_bits | write_bits); + cpu_status_bits, ciu_intr_sum_reg_addr, ciu_intr_sum_bits, + ciu_intr_sum_bits | write_bits); #endif - oct_write64(ciu_intr_sum_reg_addr, write_bits); - oct_read64(OCTEON_MIO_BOOT_BIST_STAT); /* Bus Barrier */ + oct_write64(ciu_intr_sum_reg_addr, write_bits); + oct_read64(OCTEON_MIO_BOOT_BIST_STAT); /* Bus Barrier */ #ifdef DEBUG_CIU_SUM printf(" Readback: 0x%llX\n\n ", (uint64_t) oct_read64(ciu_intr_sum_reg_addr)); #endif - octeon_set_interrupts(cpu_status_bits); + octeon_set_interrupts(cpu_status_bits); } /* * ciu_disable_intr */ -void ciu_disable_intr (int core_num, int intx, int enx) +void +ciu_disable_intr(int core_num, int intx, int enx) { - uint32_t cpu_status_bits; - uint64_t ciu_intr_reg_addr; + uint32_t cpu_status_bits; + uint64_t ciu_intr_reg_addr; - if (core_num == CIU_THIS_CORE) { + if (core_num == CIU_THIS_CORE) core_num = octeon_get_core_num(); - } - cpu_status_bits = octeon_disable_interrupts(); + cpu_status_bits = octeon_disable_interrupts(); - ciu_intr_reg_addr = ciu_get_intr_en_reg_addr(core_num, intx, enx); + ciu_intr_reg_addr = ciu_get_intr_en_reg_addr(core_num, intx, enx); - oct_read64(ciu_intr_reg_addr); /* Dummy read */ + oct_read64(ciu_intr_reg_addr); /* Dummy read */ - oct_write64(ciu_intr_reg_addr, 0LL); - oct_read64(OCTEON_MIO_BOOT_BIST_STAT); /* Bus Barrier */ + oct_write64(ciu_intr_reg_addr, 0LL); + oct_read64(OCTEON_MIO_BOOT_BIST_STAT); /* Bus Barrier */ - octeon_set_interrupts(cpu_status_bits); + octeon_set_interrupts(cpu_status_bits); } -void ciu_dump_interrutps_enabled (int core_num, int intx, int enx, int ciu_ip); -void ciu_dump_interrutps_enabled (int core_num, int intx, int enx, int ciu_ip) +void +ciu_dump_interrutps_enabled(int core_num, int intx, int enx, int ciu_ip) { uint64_t ciu_intr_reg_addr; @@ -616,23 +586,21 @@ void ciu_dump_interrutps_enabled (int core_num, int intx, int enx, int ciu_ip) /* * ciu_enable_interrupts */ -void ciu_enable_interrupts (int core_num, int intx, int enx, uint64_t set_these_interrupt_bits, - int ciu_ip) +void ciu_enable_interrupts(int core_num, int intx, int enx, + uint64_t set_these_interrupt_bits, int ciu_ip) { - uint32_t cpu_status_bits; uint64_t ciu_intr_reg_addr; uint64_t ciu_intr_bits; - if (core_num == CIU_THIS_CORE) { + if (core_num == CIU_THIS_CORE) core_num = octeon_get_core_num(); - } //#define DEBUG_CIU_EN 1 #ifdef DEBUG_CIU_EN printf(" CIU: core %u enabling Intx %u Enx %u IP %d Bits: 0x%llX\n", - core_num, intx, enx, ciu_ip, set_these_interrupt_bits); + core_num, intx, enx, ciu_ip, set_these_interrupt_bits); #endif cpu_status_bits = octeon_disable_interrupts(); @@ -644,16 +612,16 @@ void ciu_enable_interrupts (int core_num, int intx, int enx, uint64_t set_these_ #endif if (!ciu_intr_reg_addr) { - printf("Bad call to %s\n", __FUNCTION__); - while(1); - return; + printf("Bad call to %s\n", __FUNCTION__); + while(1); + return; /* XXX */ } ciu_intr_bits = oct_read64(ciu_intr_reg_addr); #ifdef DEBUG_CIU_EN printf(" CIU: status: 0x%X reg_addr: 0x%llX Val: 0x%llX -> 0x%llX", - cpu_status_bits, ciu_intr_reg_addr, ciu_intr_bits, ciu_intr_bits | set_these_interrupt_bits); + cpu_status_bits, ciu_intr_reg_addr, ciu_intr_bits, ciu_intr_bits | set_these_interrupt_bits); #endif ciu_intr_bits |= set_these_interrupt_bits; oct_write64(ciu_intr_reg_addr, ciu_intr_bits); @@ -663,15 +631,16 @@ void ciu_enable_interrupts (int core_num, int intx, int enx, uint64_t set_these_ oct_read64(OCTEON_MIO_BOOT_BIST_STAT); /* Bus Barrier */ #ifdef DEBUG_CIU_EN - printf(" Readback: 0x%llX\n\n ", (uint64_t) oct_read64(ciu_intr_reg_addr)); + printf(" Readback: 0x%llX\n\n ", + (uint64_t)oct_read64(ciu_intr_reg_addr)); #endif octeon_set_interrupts(cpu_status_bits); } void -platform_start(__register_t a0, __register_t a1, - __register_t a2 __unused, __register_t a3) +platform_start(__register_t a0, __register_t a1, __register_t a2 __unused, + __register_t a3) { uint64_t platform_counter_freq; vm_offset_t kernend; From db905b7f6fba2e952081425cd3e299836f565271 Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Tue, 5 Jan 2010 06:58:54 +0000 Subject: [PATCH 372/380] This change increases the size of the kernel stack for thread0 from PAGE_SIZE to (2 * PAGE_SIZE). It depends on the memory allocated by pmap_steal_memory() being aligned to a PAGE_SIZE boundary. Approved by: imp (mentor) --- sys/mips/mips/machdep.c | 5 ++++- sys/mips/mips/pmap.c | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c index 356e52821df..eebe4411712 100644 --- a/sys/mips/mips/machdep.c +++ b/sys/mips/mips/machdep.c @@ -260,8 +260,11 @@ mips_proc0_init(void) { proc_linkup0(&proc0, &thread0); + KASSERT((kstack0 & PAGE_MASK) == 0, + ("kstack0 is not aligned on a page boundary: 0x%0lx", + (long)kstack0)); thread0.td_kstack = kstack0; - thread0.td_kstack_pages = KSTACK_PAGES - 1; + thread0.td_kstack_pages = KSTACK_PAGES; thread0.td_md.md_realstack = roundup2(thread0.td_kstack, PAGE_SIZE * 2); /* * Do not use cpu_thread_alloc to initialize these fields diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index 137f5fce2fa..671413ba9ba 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -291,6 +291,12 @@ pmap_bootstrap(void) /* Sort. */ again: for (i = 0; phys_avail[i + 1] != 0; i += 2) { + /* + * Keep the memory aligned on page boundary. + */ + phys_avail[i] = round_page(phys_avail[i]); + phys_avail[i + 1] = trunc_page(phys_avail[i + 1]); + if (phys_avail[i + 1] >= MIPS_KSEG0_LARGEST_PHYS) memory_larger_than_512meg++; if (i < 2) From 64b53d19bd46b742d125fd0b04fa16da7cc79764 Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Wed, 6 Jan 2010 06:42:08 +0000 Subject: [PATCH 373/380] Remove all CFE-specific code from locore.S. The CFE entrypoint initialization is now done in platform-specific code. Approved by: imp (mentor) --- sys/mips/mips/locore.S | 16 ---------------- sys/mips/sentry5/s5_machdep.c | 22 +++++++++------------- sys/mips/sibyte/sb_machdep.c | 22 +++++++++------------- 3 files changed, 18 insertions(+), 42 deletions(-) diff --git a/sys/mips/mips/locore.S b/sys/mips/mips/locore.S index a332325cc91..11d9cdca96a 100644 --- a/sys/mips/mips/locore.S +++ b/sys/mips/mips/locore.S @@ -77,12 +77,6 @@ GLOBAL(fenvp) .space 4 # Assumes mips32? Is that OK? #endif -#ifdef CFE /* Assumes MIPS32, bad? */ -GLOBAL(cfe_handle) - .space 4 -GLOBAL(cfe_vector) - .space 4 -#endif GLOBAL(stackspace) .space NBPG /* Smaller than it should be since it's temp. */ .align 8 @@ -175,16 +169,6 @@ VECTOR(_locore, unknown) #ifdef YAMON /* Save YAMON boot environment pointer */ sw a2, _C_LABEL(fenvp) -#endif -#ifdef CFE - /* - * Save the CFE context passed to us by the loader. - */ - li t1, 0x43464531 - bne a3, t1, no_cfe /* Check for "CFE1" signature */ - sw a0, _C_LABEL(cfe_handle)/* Firmware data segment */ - sw a2, _C_LABEL(cfe_vector)/* Firmware entry vector */ -no_cfe: #endif /* diff --git a/sys/mips/sentry5/s5_machdep.c b/sys/mips/sentry5/s5_machdep.c index d326f73ee3e..8a76bdac5df 100644 --- a/sys/mips/sentry5/s5_machdep.c +++ b/sys/mips/sentry5/s5_machdep.c @@ -79,11 +79,6 @@ __FBSDID("$FreeBSD$"); #include #endif -#ifdef CFE -extern uint32_t cfe_handle; -extern uint32_t cfe_vector; -#endif - extern int *edata; extern int *end; @@ -183,8 +178,8 @@ platform_trap_exit(void) } void -platform_start(__register_t a0 __unused, __register_t a1 __unused, - __register_t a2 __unused, __register_t a3 __unused) +platform_start(__register_t a0, __register_t a1, __register_t a2, + __register_t a3) { vm_offset_t kernend; uint64_t platform_counter_freq; @@ -197,16 +192,17 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, /* * Initialize CFE firmware trampolines before * we initialize the low-level console. + * + * CFE passes the following values in registers: + * a0: firmware handle + * a2: firmware entry point + * a3: entry point seal */ - if (cfe_handle != 0) - cfe_init(cfe_handle, cfe_vector); + if (a3 == CFE_EPTSEAL) + cfe_init(a0, a2); #endif cninit(); -#ifdef CFE - if (cfe_handle == 0) - panic("CFE was not detected by locore.\n"); -#endif mips_init(); # if 0 diff --git a/sys/mips/sibyte/sb_machdep.c b/sys/mips/sibyte/sb_machdep.c index d6bee7692a8..3a2b5557dcf 100644 --- a/sys/mips/sibyte/sb_machdep.c +++ b/sys/mips/sibyte/sb_machdep.c @@ -86,11 +86,6 @@ __FBSDID("$FreeBSD$"); #endif #endif -#ifdef CFE -extern uint32_t cfe_handle; -extern uint32_t cfe_vector; -#endif - #ifdef CFE_ENV extern void cfe_env_init(void); #endif @@ -236,8 +231,8 @@ platform_trap_exit(void) } void -platform_start(__register_t a0 __unused, __register_t a1 __unused, - __register_t a2 __unused, __register_t a3 __unused) +platform_start(__register_t a0, __register_t a1, __register_t a2, + __register_t a3) { vm_offset_t kernend; @@ -249,16 +244,17 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, /* * Initialize CFE firmware trampolines before * we initialize the low-level console. + * + * CFE passes the following values in registers: + * a0: firmware handle + * a2: firmware entry point + * a3: entry point seal */ - if (cfe_handle != 0) - cfe_init(cfe_handle, cfe_vector); + if (a3 == CFE_EPTSEAL) + cfe_init(a0, a2); #endif cninit(); -#ifdef CFE - if (cfe_handle == 0) - panic("CFE was not detected by locore.\n"); -#endif mips_init(); mips_timer_init_params(sb_cpu_speed(), 0); From 4228cb8044a0f7484382597a0fc127df671cd538 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 6 Jan 2010 12:15:10 +0000 Subject: [PATCH 374/380] Revert r200892, 200893 and 200894. There's companion changes elsewhere that aren't quite ready, and these break the world in the mean time. --- lib/csu/mips/crt1.c | 83 ++++++++------------------------------------- lib/csu/mips/crti.S | 29 ++-------------- lib/csu/mips/crtn.S | 3 -- 3 files changed, 17 insertions(+), 98 deletions(-) diff --git a/lib/csu/mips/crt1.c b/lib/csu/mips/crt1.c index 61734048032..746cee2aa18 100644 --- a/lib/csu/mips/crt1.c +++ b/lib/csu/mips/crt1.c @@ -1,4 +1,6 @@ /*- + * Copyright 1996-1998 John D. Polstra. + * All rights reserved. * Copyright (c) 1995 Christopher G. Demetriou * All rights reserved. * @@ -63,94 +65,37 @@ extern int etext; char **environ; const char *__progname = ""; -struct ps_strings *__ps_strings; void __gccmain(void) {} void __main(void) {} -/* - * Historically, mips has used __start for the beginning address of programs. - * However, the Cavium toolchain (and maybe others) use _start. Define both - * here. The assembler code here tries to juggle the arguments such that they - * are right for all ABIs and then calls __start_mips which is what used to - * be just plain __start, and still is on other BSD ports. - */ - /* The entry function. */ -__asm(" .text \n" -" .align 8 \n" -" .globl _start \n" -" _start: \n" -" .globl __start \n" -" __start: \n" -#if defined(__mips_n32) || defined(__mips_n64) -" .cpsetup $25, $24, __start\n" -#else -" .set noreorder \n" -" .cpload $25 \n" -" .set reorder \n" -#endif -" /* Get cleanup routine and main object set by rtld */\n" -" /* Note that a2 is already set to ps_string by _rtld_start */\n" -" /* move a3, a0 */\n" -" /* move t0, a1 */\n" -" /* Get argc, argv from stack */ \n" -" /* lw a0, 0(sp) */\n" -" /* move a1, sp */\n" -" /* addu a1, 4 */\n" -" \n" -" /* Stack should 8bytes aligned */\n" -" /* required by ABI to pass */\n" -" /* 64-bits arguments */\n" -" /* and sp, ~8 */\n" -" /* subu sp, sp, 20 */\n" -" /* sw t0, 16(sp) */\n" -" \n" -" move $7, $4 /* atexit */\n" -" move $8, $5 /* main_obj entry */\n" -#if defined(__mips_n64) -" ld $4, 0($29) \n" -" move $5, $29 \n" -" addu $5, 8 \n" -#else -" lw $4, 0($29) \n" -" move $5, $29 \n" -" addu $5, 4 \n" -#endif -" \n" -" and $29, 0xfffffff8 \n" -" subu $29, $29, 24 /* args slot + cleanup + 4 bytes padding */ \n" -" sw $8, 16($29) \n" -"\n" -" la $25, __start_mips \n" -" nop \n" -" j $25\n"); -/* ARGSUSED */ - void -__start_mips(int argc, char **argv, struct ps_strings *ps_strings, - void (*cleanup)(void), struct Struct_Obj_Entry *obj __unused) +__start(char **ap, + void (*cleanup)(void), /* from shared loader */ + struct Struct_Obj_Entry *obj, /* from shared loader */ + struct ps_strings *ps_strings) { + int argc; + char **argv; char **env; - const char *s; - env = argv + argc + 1; + argc = * (long *) ap; + argv = ap + 1; + env = ap + 2 + argc; environ = env; - if(argc > 0 && argv[0] != NULL) { + const char *s; __progname = argv[0]; for (s = __progname; *s != '\0'; s++) if (*s == '/') __progname = s + 1; } - __ps_strings = ps_strings; - +#ifndef NOSHARED if (&_DYNAMIC != NULL) atexit(cleanup); - else - _init_tls(); - +#endif #ifdef GCRT atexit(_mcleanup); #endif diff --git a/lib/csu/mips/crti.S b/lib/csu/mips/crti.S index a46a4f08283..1a0d23e5a33 100644 --- a/lib/csu/mips/crti.S +++ b/lib/csu/mips/crti.S @@ -5,13 +5,6 @@ __FBSDID("$FreeBSD$"); .align 4 .globl _init .type _init,%function - - /* - * The Cavium toolchain apparently has code that references $fp - * instead of $sp for the .cprestore 16 macro. The move doesn't - * hurt on other toolchains, so unconditionally compile it in for - * now. - */ _init: #ifdef __ABICALLS__ .set noreorder @@ -20,7 +13,7 @@ _init: subu sp, sp, 32 .cprestore 16 sw ra, 28(sp) - move s8, sp /* See note above */ + #else subu sp, sp, 32 sw ra, 28(sp) @@ -31,30 +24,14 @@ _init: .globl _fini .type _fini,%function _fini: - -#if defined (__mips_n64) || defined (__mips_n32) -#ifdef __ABICALLS__ - subu sp, sp, 32 - sw gp, 16(sp) - sw ra, 28(sp) - move s8, sp -#else - subu sp, sp, 32 - sw ra, 28(sp) -#endif /*__ABICALLS__*/ - -#else #ifdef __ABICALLS__ .set noreorder .cpload $25 .set reorder subu sp, sp, 32 - move s8, sp /* See note above */ - .cprestore 16 /* xxx missing in Cavium's version -- why? */ + .cprestore 16 sw ra, 28(sp) #else subu sp, sp, 32 sw ra, 28(sp) -#endif /* __ABICALLS__ */ - -#endif /* __mips_n64 || __mips_n32 */ +#endif diff --git a/lib/csu/mips/crtn.S b/lib/csu/mips/crtn.S index 96a02109662..4803994027f 100644 --- a/lib/csu/mips/crtn.S +++ b/lib/csu/mips/crtn.S @@ -9,9 +9,6 @@ __FBSDID("$FreeBSD$"); .section .fini,"ax",%progbits lw ra, 28(sp) -#if defined(__mips_n64) || defined(__mips_n32) - lw gp, 16(sp) -#endif .set noreorder j ra addu sp, sp, 32 From 375cce48d44fa29fd53bb84fba558fdd0f3d259c Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Fri, 8 Jan 2010 05:53:11 +0000 Subject: [PATCH 375/380] Add a DDB command "show pcb" to dump out the contents of a thread's PCB. Approved by: imp (mentor) --- sys/mips/mips/vm_machdep.c | 97 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c index bde96188ee3..57fe355c8b8 100644 --- a/sys/mips/mips/vm_machdep.c +++ b/sys/mips/mips/vm_machdep.c @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include "opt_cputype.h" +#include "opt_ddb.h" #include #include @@ -588,3 +589,99 @@ cpu_throw(struct thread *old, struct thread *new) func_2args_asmmacro(&mips_cpu_throw, old, new); panic("mips_cpu_throw() returned"); } + +#ifdef DDB +#include + +#define DB_PRINT_REG(ptr, regname) \ + db_printf(" %-12s 0x%lx\n", #regname, (long)((ptr)->regname)) + +#define DB_PRINT_REG_ARRAY(ptr, arrname, regname) \ + db_printf(" %-12s 0x%lx\n", #regname, (long)((ptr)->arrname[regname])) + +DB_SHOW_COMMAND(pcb, ddb_dump_pcb) +{ + struct thread *td; + struct pcb *pcb; + struct trapframe *trapframe; + + /* Determine which thread to examine. */ + if (have_addr) + td = db_lookup_thread(addr, FALSE); + else + td = curthread; + + pcb = td->td_pcb; + + db_printf("Thread %d at %p\n", td->td_tid, td); + + db_printf("PCB at %p\n", pcb); + + trapframe = &pcb->pcb_regs; + db_printf("Trapframe at %p\n", trapframe); + DB_PRINT_REG(trapframe, zero); + DB_PRINT_REG(trapframe, ast); + DB_PRINT_REG(trapframe, v0); + DB_PRINT_REG(trapframe, v1); + DB_PRINT_REG(trapframe, a0); + DB_PRINT_REG(trapframe, a1); + DB_PRINT_REG(trapframe, a2); + DB_PRINT_REG(trapframe, a3); + DB_PRINT_REG(trapframe, t0); + DB_PRINT_REG(trapframe, t1); + DB_PRINT_REG(trapframe, t2); + DB_PRINT_REG(trapframe, t3); + DB_PRINT_REG(trapframe, t4); + DB_PRINT_REG(trapframe, t5); + DB_PRINT_REG(trapframe, t6); + DB_PRINT_REG(trapframe, t7); + DB_PRINT_REG(trapframe, s0); + DB_PRINT_REG(trapframe, s1); + DB_PRINT_REG(trapframe, s2); + DB_PRINT_REG(trapframe, s3); + DB_PRINT_REG(trapframe, s4); + DB_PRINT_REG(trapframe, s5); + DB_PRINT_REG(trapframe, s6); + DB_PRINT_REG(trapframe, s7); + DB_PRINT_REG(trapframe, t8); + DB_PRINT_REG(trapframe, t9); + DB_PRINT_REG(trapframe, k0); + DB_PRINT_REG(trapframe, k1); + DB_PRINT_REG(trapframe, gp); + DB_PRINT_REG(trapframe, sp); + DB_PRINT_REG(trapframe, s8); + DB_PRINT_REG(trapframe, ra); + DB_PRINT_REG(trapframe, sr); + DB_PRINT_REG(trapframe, mullo); + DB_PRINT_REG(trapframe, mulhi); + DB_PRINT_REG(trapframe, badvaddr); + DB_PRINT_REG(trapframe, cause); + DB_PRINT_REG(trapframe, pc); + + db_printf("PCB Context:\n"); + DB_PRINT_REG_ARRAY(pcb, pcb_context, PCB_REG_S0); + DB_PRINT_REG_ARRAY(pcb, pcb_context, PCB_REG_S1); + DB_PRINT_REG_ARRAY(pcb, pcb_context, PCB_REG_S2); + DB_PRINT_REG_ARRAY(pcb, pcb_context, PCB_REG_S3); + DB_PRINT_REG_ARRAY(pcb, pcb_context, PCB_REG_S4); + DB_PRINT_REG_ARRAY(pcb, pcb_context, PCB_REG_S5); + DB_PRINT_REG_ARRAY(pcb, pcb_context, PCB_REG_S6); + DB_PRINT_REG_ARRAY(pcb, pcb_context, PCB_REG_S7); + DB_PRINT_REG_ARRAY(pcb, pcb_context, PCB_REG_SP); + DB_PRINT_REG_ARRAY(pcb, pcb_context, PCB_REG_S8); + DB_PRINT_REG_ARRAY(pcb, pcb_context, PCB_REG_RA); + DB_PRINT_REG_ARRAY(pcb, pcb_context, PCB_REG_SR); + DB_PRINT_REG_ARRAY(pcb, pcb_context, PCB_REG_GP); + DB_PRINT_REG_ARRAY(pcb, pcb_context, PCB_REG_PC); + + db_printf("PCB onfault = %d\n", pcb->pcb_onfault); + db_printf("md_saved_intr = 0x%0lx\n", (long)td->td_md.md_saved_intr); + db_printf("md_spinlock_count = %d\n", td->td_md.md_spinlock_count); + + if (td->td_frame != trapframe) { + db_printf("td->td_frame %p is not the same as pcb_regs %p\n", + td->td_frame, trapframe); + } +} + +#endif /* DDB */ From a096e4b36bbc568e311547f1810eb82eaed2fce5 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 8 Jan 2010 22:48:21 +0000 Subject: [PATCH 376/380] Centralize initialization of pcpu, and set curthread early... --- sys/mips/adm5120/adm5120_machdep.c | 3 +++ sys/mips/alchemy/alchemy_machdep.c | 3 +++ sys/mips/atheros/ar71xx_machdep.c | 3 +++ sys/mips/idt/idt_machdep.c | 3 +++ sys/mips/mips/machdep.c | 26 ++++++++++++++++---------- sys/mips/octeon1/octeon_machdep.c | 3 +++ sys/mips/rmi/xlr_machdep.c | 3 +++ sys/mips/sentry5/s5_machdep.c | 3 +++ sys/mips/sibyte/sb_machdep.c | 3 +++ 9 files changed, 40 insertions(+), 10 deletions(-) diff --git a/sys/mips/adm5120/adm5120_machdep.c b/sys/mips/adm5120/adm5120_machdep.c index c30be2fc6ec..94639385b38 100644 --- a/sys/mips/adm5120/adm5120_machdep.c +++ b/sys/mips/adm5120/adm5120_machdep.c @@ -154,6 +154,9 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, kernend = round_page((vm_offset_t)&end); memset(&edata, 0, kernend - (vm_offset_t)(&edata)); + /* Initialize pcpu stuff */ + mips_pcpu_init(); + cninit(); mips_init(); mips_timer_init_params(platform_counter_freq, 0); diff --git a/sys/mips/alchemy/alchemy_machdep.c b/sys/mips/alchemy/alchemy_machdep.c index 2f4f1f6ca3d..bf03947e111 100644 --- a/sys/mips/alchemy/alchemy_machdep.c +++ b/sys/mips/alchemy/alchemy_machdep.c @@ -154,6 +154,9 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, kernend = round_page((vm_offset_t)&end); memset(&edata, 0, kernend - (vm_offset_t)(&edata)); + /* Initialize pcpu stuff */ + mips_pcpu_init(); + cninit(); mips_init(); /* Set counter_freq for tick_init_params() */ diff --git a/sys/mips/atheros/ar71xx_machdep.c b/sys/mips/atheros/ar71xx_machdep.c index 0791e687bbe..2736018809a 100644 --- a/sys/mips/atheros/ar71xx_machdep.c +++ b/sys/mips/atheros/ar71xx_machdep.c @@ -152,6 +152,9 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, kernend = round_page((vm_offset_t)&end); memset(&edata, 0, kernend - (vm_offset_t)(&edata)); + /* Initialize pcpu stuff */ + mips_pcpu_init(); + argc = a0; argv = (char**)a1; envp = (char**)a2; diff --git a/sys/mips/idt/idt_machdep.c b/sys/mips/idt/idt_machdep.c index 776bc502d42..0d83dc5e422 100644 --- a/sys/mips/idt/idt_machdep.c +++ b/sys/mips/idt/idt_machdep.c @@ -137,6 +137,9 @@ platform_start(__register_t a0, __register_t a1, kernend = round_page((vm_offset_t)&end); memset(&edata, 0, kernend - (vm_offset_t)(&edata)); + /* Initialize pcpu stuff */ + mips_pcpu_init(); + /* * Looking for mem=XXM argument */ diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c index eebe4411712..6bd430d7cef 100644 --- a/sys/mips/mips/machdep.c +++ b/sys/mips/mips/machdep.c @@ -252,6 +252,21 @@ SYSCTL_INT(_machdep, CPU_WALLCLOCK, wall_cmos_clock, CTLFLAG_RW, &wall_cmos_clock, 0, "Wall CMOS clock assumed"); #endif /* PORT_TO_JMIPS */ +/* + * Initialize per cpu data structures, include curthread. + */ +void +mips_pcpu_init() +{ + /* Initialize pcpu info of cpu-zero */ +#ifdef SMP + pcpu_init(&__pcpu[0], 0, sizeof(struct pcpu)); +#else + pcpu_init(pcpup, 0, sizeof(struct pcpu)); +#endif + PCPU_SET(curthread, &thread0); +} + /* * Initialize mips and configure to run kernel */ @@ -275,24 +290,15 @@ mips_proc0_init(void) (thread0.td_kstack_pages - 1) * PAGE_SIZE) - 1; thread0.td_frame = &thread0.td_pcb->pcb_regs; - /* Initialize pcpu info of cpu-zero */ -#ifdef SMP - pcpu_init(&__pcpu[0], 0, sizeof(struct pcpu)); -#else - pcpu_init(pcpup, 0, sizeof(struct pcpu)); -#endif - /* Steal memory for the dynamic per-cpu area. */ dpcpu_init((void *)pmap_steal_memory(DPCPU_SIZE), 0); + PCPU_SET(curpcb, thread0.td_pcb); /* * There is no need to initialize md_upte array for thread0 as it's * located in .bss section and should be explicitly zeroed during * kernel initialization. */ - - PCPU_SET(curthread, &thread0); - PCPU_SET(curpcb, thread0.td_pcb); } void diff --git a/sys/mips/octeon1/octeon_machdep.c b/sys/mips/octeon1/octeon_machdep.c index f7b4448082e..8da0c3c13b7 100644 --- a/sys/mips/octeon1/octeon_machdep.c +++ b/sys/mips/octeon1/octeon_machdep.c @@ -652,6 +652,9 @@ platform_start(__register_t a0, __register_t a1, __register_t a2 __unused, kernend = round_page((vm_offset_t)&end); memset(&edata, 0, kernend - (vm_offset_t)(&edata)); + /* Initialize pcpu stuff */ + mips_pcpu_init(); + octeon_boot_params_init(a3); /* XXX octeon boot decriptor has args in it... */ octeon_ciu_reset(); diff --git a/sys/mips/rmi/xlr_machdep.c b/sys/mips/rmi/xlr_machdep.c index 52306d9019c..5de015f7c50 100644 --- a/sys/mips/rmi/xlr_machdep.c +++ b/sys/mips/rmi/xlr_machdep.c @@ -385,7 +385,10 @@ platform_start(__register_t a0 __unused, void (*wakeup) (void *, void *, unsigned int); #endif + /* XXX no zeroing of BSS? */ + /* Initialize pcpu stuff */ + mips_pcpu_init(); /* XXX FIXME the code below is not 64 bit clean */ /* Save boot loader and other stuff from scratch regs */ diff --git a/sys/mips/sentry5/s5_machdep.c b/sys/mips/sentry5/s5_machdep.c index 8a76bdac5df..e3cb9eba9d2 100644 --- a/sys/mips/sentry5/s5_machdep.c +++ b/sys/mips/sentry5/s5_machdep.c @@ -188,6 +188,9 @@ platform_start(__register_t a0, __register_t a1, __register_t a2, kernend = round_page((vm_offset_t)&end); memset(&edata, 0, kernend - (vm_offset_t)(&edata)); + /* Initialize pcpu stuff */ + mips_pcpu_init(); + #ifdef CFE /* * Initialize CFE firmware trampolines before diff --git a/sys/mips/sibyte/sb_machdep.c b/sys/mips/sibyte/sb_machdep.c index 3a2b5557dcf..4cb42cdb826 100644 --- a/sys/mips/sibyte/sb_machdep.c +++ b/sys/mips/sibyte/sb_machdep.c @@ -240,6 +240,9 @@ platform_start(__register_t a0, __register_t a1, __register_t a2, memset(&edata, 0, (vm_offset_t)&end - (vm_offset_t)&edata); kernend = round_page((vm_offset_t)&end); + /* Initialize pcpu stuff */ + mips_pcpu_init(); + #ifdef CFE /* * Initialize CFE firmware trampolines before From 46b2483132b920ba005d0c63f116188289e07e3f Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 8 Jan 2010 22:52:02 +0000 Subject: [PATCH 377/380] Revert r199758. It pointed out that we were calling pcpu_init way too late... --- sys/kern/kern_shutdown.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c index 5e192b9d4fd..3d963213597 100644 --- a/sys/kern/kern_shutdown.c +++ b/sys/kern/kern_shutdown.c @@ -516,8 +516,7 @@ panic(const char *fmt, ...) va_list ap; static char buf[256]; - if (td) - critical_enter(); + critical_enter(); #ifdef SMP /* * We don't want multiple CPU's to panic at the same time, so we @@ -576,8 +575,7 @@ panic(const char *fmt, ...) /* thread_unlock(td); */ if (!sync_on_panic) bootopt |= RB_NOSYNC; - if (td) - critical_exit(); + critical_exit(); boot(bootopt); } From 15258244de2a5df411e7318a5c6d813ec9166d5e Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Sat, 9 Jan 2010 02:17:14 +0000 Subject: [PATCH 378/380] Compute the target of the jump in the 'J' and 'JAL' instructions correctly. The 256MB segment is formed by taking the top 4 bits of the address of the instruction in the "branch delay" slot as opposed to the 'J' or 'JAL' instruction itself. Approved by: imp (mentor) --- sys/mips/mips/trap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c index 76b5d1fa563..6f5b2aeebb8 100644 --- a/sys/mips/mips/trap.c +++ b/sys/mips/mips/trap.c @@ -1091,7 +1091,7 @@ MipsEmulateBranch(struct trapframe *framePtr, uintptr_t instPC, int fpcCSR, case OP_J: case OP_JAL: retAddr = (inst.JType.target << 2) | - ((unsigned)instPC & 0xF0000000); + ((unsigned)(instPC + 4) & 0xF0000000); break; case OP_BEQ: From 3ad9e328b838cc10f05060aa736af4bcf2a4cf3e Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 9 Jan 2010 03:08:22 +0000 Subject: [PATCH 379/380] Rename mips_pcpu_init to mips_pcpu0_init since it applies only to the BSP. Provide a missing prototype. --- sys/mips/adm5120/adm5120_machdep.c | 2 +- sys/mips/alchemy/alchemy_machdep.c | 2 +- sys/mips/atheros/ar71xx_machdep.c | 2 +- sys/mips/idt/idt_machdep.c | 2 +- sys/mips/include/md_var.h | 1 + sys/mips/malta/malta_machdep.c | 1 + sys/mips/mips/machdep.c | 2 +- sys/mips/octeon1/octeon_machdep.c | 2 +- sys/mips/rmi/xlr_machdep.c | 2 +- sys/mips/sentry5/s5_machdep.c | 2 +- sys/mips/sibyte/sb_machdep.c | 2 +- 11 files changed, 11 insertions(+), 9 deletions(-) diff --git a/sys/mips/adm5120/adm5120_machdep.c b/sys/mips/adm5120/adm5120_machdep.c index 94639385b38..15ecef26005 100644 --- a/sys/mips/adm5120/adm5120_machdep.c +++ b/sys/mips/adm5120/adm5120_machdep.c @@ -155,7 +155,7 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, memset(&edata, 0, kernend - (vm_offset_t)(&edata)); /* Initialize pcpu stuff */ - mips_pcpu_init(); + mips_pcpu0_init(); cninit(); mips_init(); diff --git a/sys/mips/alchemy/alchemy_machdep.c b/sys/mips/alchemy/alchemy_machdep.c index bf03947e111..119c93ea03e 100644 --- a/sys/mips/alchemy/alchemy_machdep.c +++ b/sys/mips/alchemy/alchemy_machdep.c @@ -155,7 +155,7 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, memset(&edata, 0, kernend - (vm_offset_t)(&edata)); /* Initialize pcpu stuff */ - mips_pcpu_init(); + mips_pcpu0_init(); cninit(); mips_init(); diff --git a/sys/mips/atheros/ar71xx_machdep.c b/sys/mips/atheros/ar71xx_machdep.c index 2736018809a..eaf08f27e78 100644 --- a/sys/mips/atheros/ar71xx_machdep.c +++ b/sys/mips/atheros/ar71xx_machdep.c @@ -153,7 +153,7 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, memset(&edata, 0, kernend - (vm_offset_t)(&edata)); /* Initialize pcpu stuff */ - mips_pcpu_init(); + mips_pcpu0_init(); argc = a0; argv = (char**)a1; diff --git a/sys/mips/idt/idt_machdep.c b/sys/mips/idt/idt_machdep.c index 0d83dc5e422..eebe608e811 100644 --- a/sys/mips/idt/idt_machdep.c +++ b/sys/mips/idt/idt_machdep.c @@ -138,7 +138,7 @@ platform_start(__register_t a0, __register_t a1, memset(&edata, 0, kernend - (vm_offset_t)(&edata)); /* Initialize pcpu stuff */ - mips_pcpu_init(); + mips_pcpu0_init(); /* * Looking for mem=XXM argument diff --git a/sys/mips/include/md_var.h b/sys/mips/include/md_var.h index f7210ffa26c..a523851ca5f 100644 --- a/sys/mips/include/md_var.h +++ b/sys/mips/include/md_var.h @@ -66,6 +66,7 @@ int is_physical_memory(vm_offset_t addr); void mips_vector_init(void); void cpu_identify(void); void mips_cpu_init(void); +void mips_pcpu0_init(void); void mips_proc0_init(void); /* Platform call-downs. */ diff --git a/sys/mips/malta/malta_machdep.c b/sys/mips/malta/malta_machdep.c index d67f2492fb7..c596d4f936d 100644 --- a/sys/mips/malta/malta_machdep.c +++ b/sys/mips/malta/malta_machdep.c @@ -294,6 +294,7 @@ platform_start(__register_t a0, __register_t a1, __register_t a2, kernend = round_page((vm_offset_t)&end); memset(&edata, 0, kernend - (vm_offset_t)(&edata)); + mips_pcpu0_init(); platform_counter_freq = malta_cpu_freq(); mips_timer_early_init(platform_counter_freq); diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c index 6bd430d7cef..65b4cfb7e9e 100644 --- a/sys/mips/mips/machdep.c +++ b/sys/mips/mips/machdep.c @@ -256,7 +256,7 @@ SYSCTL_INT(_machdep, CPU_WALLCLOCK, wall_cmos_clock, CTLFLAG_RW, * Initialize per cpu data structures, include curthread. */ void -mips_pcpu_init() +mips_pcpu0_init() { /* Initialize pcpu info of cpu-zero */ #ifdef SMP diff --git a/sys/mips/octeon1/octeon_machdep.c b/sys/mips/octeon1/octeon_machdep.c index 8da0c3c13b7..adec47b0741 100644 --- a/sys/mips/octeon1/octeon_machdep.c +++ b/sys/mips/octeon1/octeon_machdep.c @@ -653,7 +653,7 @@ platform_start(__register_t a0, __register_t a1, __register_t a2 __unused, memset(&edata, 0, kernend - (vm_offset_t)(&edata)); /* Initialize pcpu stuff */ - mips_pcpu_init(); + mips_pcpu0_init(); octeon_boot_params_init(a3); /* XXX octeon boot decriptor has args in it... */ diff --git a/sys/mips/rmi/xlr_machdep.c b/sys/mips/rmi/xlr_machdep.c index 5de015f7c50..80827b57baf 100644 --- a/sys/mips/rmi/xlr_machdep.c +++ b/sys/mips/rmi/xlr_machdep.c @@ -388,7 +388,7 @@ platform_start(__register_t a0 __unused, /* XXX no zeroing of BSS? */ /* Initialize pcpu stuff */ - mips_pcpu_init(); + mips_pcpu0_init(); /* XXX FIXME the code below is not 64 bit clean */ /* Save boot loader and other stuff from scratch regs */ diff --git a/sys/mips/sentry5/s5_machdep.c b/sys/mips/sentry5/s5_machdep.c index e3cb9eba9d2..6c4264dc220 100644 --- a/sys/mips/sentry5/s5_machdep.c +++ b/sys/mips/sentry5/s5_machdep.c @@ -189,7 +189,7 @@ platform_start(__register_t a0, __register_t a1, __register_t a2, memset(&edata, 0, kernend - (vm_offset_t)(&edata)); /* Initialize pcpu stuff */ - mips_pcpu_init(); + mips_pcpu0_init(); #ifdef CFE /* diff --git a/sys/mips/sibyte/sb_machdep.c b/sys/mips/sibyte/sb_machdep.c index 4cb42cdb826..8bb265c5a66 100644 --- a/sys/mips/sibyte/sb_machdep.c +++ b/sys/mips/sibyte/sb_machdep.c @@ -241,7 +241,7 @@ platform_start(__register_t a0, __register_t a1, __register_t a2, kernend = round_page((vm_offset_t)&end); /* Initialize pcpu stuff */ - mips_pcpu_init(); + mips_pcpu0_init(); #ifdef CFE /* From 02dd93427076909488ba99df596d6ab7e0f54a09 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 9 Jan 2010 17:16:19 +0000 Subject: [PATCH 380/380] Fix comment, which was missed in an earlier commit... --- sys/conf/kern.mk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/conf/kern.mk b/sys/conf/kern.mk index afff7c9d22b..0013dd2b5c8 100644 --- a/sys/conf/kern.mk +++ b/sys/conf/kern.mk @@ -86,8 +86,7 @@ INLINE_LIMIT?= 15000 .endif # -# For MIPS we also tell gcc to use floating point emulation and -# disable MIPS DSP ASE Instruction set. +# For MIPS we also tell gcc to use floating point emulation # .if ${MACHINE_ARCH} == "mips" CFLAGS+= -msoft-float