Date: Sun, 17 Aug 2008 21:10:06 GMT From: Marius Strobl <marius@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 147673 for review Message-ID: <200808172110.m7HLA6Qp090529@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=147673 Change 147673 by marius@flak on 2008/08/17 21:09:44 Flesh out; this is self-hosting on Blade 1000 (USIII MP; CPUs at mixed speeds thought to be working but untested), Blade 1500 (USIIIi), Blade 2000 (USIII+ MP) and Fire V210 (USIIIi MP). Affected files ... .. //depot/projects/usiii/boot/common/dev_net.c#3 edit .. //depot/projects/usiii/boot/sparc64/loader/main.c#3 edit .. //depot/projects/usiii/conf/files.sparc64#6 edit .. //depot/projects/usiii/conf/options.sparc64#2 edit .. //depot/projects/usiii/sparc64/include/cache.h#3 edit .. //depot/projects/usiii/sparc64/include/clock.h#3 edit .. //depot/projects/usiii/sparc64/include/cpu.h#2 edit .. //depot/projects/usiii/sparc64/include/cpufunc.h#3 edit .. //depot/projects/usiii/sparc64/include/dcr.h#1 add .. //depot/projects/usiii/sparc64/include/pcpu.h#3 edit .. //depot/projects/usiii/sparc64/include/smp.h#3 edit .. //depot/projects/usiii/sparc64/include/tick.h#2 edit .. //depot/projects/usiii/sparc64/include/tlb.h#4 edit .. //depot/projects/usiii/sparc64/include/trap.h#2 edit .. //depot/projects/usiii/sparc64/include/tte.h#3 edit .. //depot/projects/usiii/sparc64/include/ver.h#2 edit .. //depot/projects/usiii/sparc64/pci/ofw_pci.h#3 edit .. //depot/projects/usiii/sparc64/pci/ofw_pcibus.c#8 edit .. //depot/projects/usiii/sparc64/pci/psycho.c#11 edit .. //depot/projects/usiii/sparc64/pci/schizo.c#9 edit .. //depot/projects/usiii/sparc64/pci/schizoreg.h#3 edit .. //depot/projects/usiii/sparc64/pci/schizovar.h#3 edit .. //depot/projects/usiii/sparc64/sparc64/cache.c#3 edit .. //depot/projects/usiii/sparc64/sparc64/cheetah.c#5 edit .. //depot/projects/usiii/sparc64/sparc64/clock.c#4 edit .. //depot/projects/usiii/sparc64/sparc64/exception.S#5 edit .. //depot/projects/usiii/sparc64/sparc64/genassym.c#3 edit .. //depot/projects/usiii/sparc64/sparc64/jbusppm.c#1 add .. //depot/projects/usiii/sparc64/sparc64/locore.S#3 edit .. //depot/projects/usiii/sparc64/sparc64/machdep.c#6 edit .. //depot/projects/usiii/sparc64/sparc64/mp_exception.S#2 edit .. //depot/projects/usiii/sparc64/sparc64/mp_locore.S#3 edit .. //depot/projects/usiii/sparc64/sparc64/mp_machdep.c#6 edit .. //depot/projects/usiii/sparc64/sparc64/pmap.c#7 edit .. //depot/projects/usiii/sparc64/sparc64/schppm.c#1 add .. //depot/projects/usiii/sparc64/sparc64/spitfire.c#4 edit .. //depot/projects/usiii/sparc64/sparc64/support.S#3 edit .. //depot/projects/usiii/sparc64/sparc64/swtch.S#3 edit .. //depot/projects/usiii/sparc64/sparc64/tick.c#5 edit .. //depot/projects/usiii/sparc64/sparc64/tlb.c#4 edit .. //depot/projects/usiii/sparc64/sparc64/trap.c#5 edit Differences ... ==== //depot/projects/usiii/boot/common/dev_net.c#3 (text+ko) ==== @@ -144,6 +144,9 @@ return (error); } } +#if defined(__sparc64__) + netdev_opens++; +#endif } netdev_opens++; f->f_devdata = &netdev_sock; ==== //depot/projects/usiii/boot/sparc64/loader/main.c#3 (text+ko) ==== @@ -6,9 +6,35 @@ * As long as the above copyright statement and this notice remain * unchanged, you can do what ever you want with this file. */ +/*- + * Copyright (c) 2008 Marius Strobl <marius@FreeBSD.org> + * 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 <sys/cdefs.h> __FBSDID("$FreeBSD: src/sys/boot/sparc64/loader/main.c,v 1.33 2008/08/07 22:46:25 marius Exp $"); + /* * FreeBSD/sparc64 kernel loader - machine dependent part * @@ -28,7 +54,6 @@ #include <vm/vm.h> #include <machine/asi.h> -#include <machine/atomic.h> #include <machine/cpufunc.h> #include <machine/elf.h> #include <machine/lsu.h> @@ -36,6 +61,8 @@ #include <machine/tte.h> #include <machine/tlb.h> #include <machine/upa.h> +#include <machine/ver.h> +#include <machine/vmparam.h> #include "bootstrap.h" #include "libofw.h" @@ -57,10 +84,13 @@ typedef void kernel_entry_t(vm_offset_t mdp, u_long o1, u_long o2, u_long o3, void *openfirmware); +static inline u_long dtlb_get_data_sun4u(int slot); static void dtlb_enter_sun4u(u_long vpn, u_long data); static vm_offset_t dtlb_va_to_pa_sun4u(vm_offset_t); +static inline u_long itlb_get_data_sun4u(int slot); static void itlb_enter_sun4u(u_long vpn, u_long data); static vm_offset_t itlb_va_to_pa_sun4u(vm_offset_t); +static void itlb_relocate_locked0_sun4u(void); extern vm_offset_t md_load(char *, vm_offset_t *); static int sparc64_autoload(void); static ssize_t sparc64_readin(const int, vm_offset_t, const size_t); @@ -92,6 +122,7 @@ struct tlb_entry *itlb_store; int dtlb_slot; int itlb_slot; +int cpu_impl; static int dtlb_slot_max; static int itlb_slot_max; @@ -365,6 +396,30 @@ panic("%s: exec returned", __func__); } +static inline u_long +dtlb_get_data_sun4u(int slot) +{ + + /* + * We read ASI_DTLB_DATA_ACCESS_REG twice in order to work + * around errata of USIII and beyond. + */ + (void)ldxa(TLB_DAR_SLOT(slot), ASI_DTLB_DATA_ACCESS_REG); + return (ldxa(TLB_DAR_SLOT(slot), ASI_DTLB_DATA_ACCESS_REG)); +} + +static inline u_long +itlb_get_data_sun4u(int slot) +{ + + /* + * We read ASI_ITLB_DATA_ACCESS_REG twice in order to work + * around errata of USIII and beyond. + */ + (void)ldxa(TLB_DAR_SLOT(slot), ASI_ITLB_DATA_ACCESS_REG); + return (ldxa(TLB_DAR_SLOT(slot), ASI_ITLB_DATA_ACCESS_REG)); +} + static vm_offset_t dtlb_va_to_pa_sun4u(vm_offset_t va) { @@ -375,7 +430,9 @@ reg = ldxa(TLB_DAR_SLOT(i), ASI_DTLB_TAG_READ_REG); if (TLB_TAR_VA(reg) != va) continue; - reg = ldxa(TLB_DAR_SLOT(i), ASI_DTLB_DATA_ACCESS_REG); + reg = dtlb_get_data_sun4u(i); + if (cpu_impl >= CPU_IMPL_ULTRASPARCIII) + return ((reg & TD_PA_CH_MASK) >> TD_PA_SHIFT); return ((reg & TD_PA_SF_MASK) >> TD_PA_SHIFT); } return (-1); @@ -391,38 +448,107 @@ reg = ldxa(TLB_DAR_SLOT(i), ASI_ITLB_TAG_READ_REG); if (TLB_TAR_VA(reg) != va) continue; - reg = ldxa(TLB_DAR_SLOT(i), ASI_ITLB_DATA_ACCESS_REG); + reg = itlb_get_data_sun4u(i); + if (cpu_impl >= CPU_IMPL_ULTRASPARCIII) + return ((reg & TD_PA_CH_MASK) >> TD_PA_SHIFT); return ((reg & TD_PA_SF_MASK) >> TD_PA_SHIFT); } return (-1); } static void -itlb_enter_sun4u(u_long vpn, u_long data) +dtlb_enter_sun4u(u_long vpn, u_long data) { u_long reg; reg = rdpr(pstate); wrpr(pstate, reg & ~PSTATE_IE, 0); - stxa(AA_IMMU_TAR, ASI_IMMU, vpn); - stxa(0, ASI_ITLB_DATA_IN_REG, data); + stxa(AA_DMMU_TAR, ASI_DMMU, + TLB_TAR_VA(vpn) | TLB_TAR_CTX(TLB_CTX_KERNEL)); + stxa(0, ASI_DTLB_DATA_IN_REG, data); membar(Sync); wrpr(pstate, reg, 0); } static void -dtlb_enter_sun4u(u_long vpn, u_long data) +itlb_enter_sun4u(u_long vpn, u_long data) { u_long reg; + int i; reg = rdpr(pstate); wrpr(pstate, reg & ~PSTATE_IE, 0); - stxa(AA_DMMU_TAR, ASI_DMMU, vpn); - stxa(0, ASI_DTLB_DATA_IN_REG, data); - membar(Sync); + + if (cpu_impl == CPU_IMPL_ULTRASPARCIIIp) { + /* + * Search an unused slot != 0 and explicitly enter the data + * and tag there in order to avoid Cheetah+ erratum 34. + */ + for (i = 1; i < itlb_slot_max; i++) { + if ((itlb_get_data_sun4u(i) & TD_V) != 0) + continue; + + stxa(AA_IMMU_TAR, ASI_IMMU, + TLB_TAR_VA(vpn) | TLB_TAR_CTX(TLB_CTX_KERNEL)); + stxa(TLB_DAR_SLOT(i), ASI_ITLB_DATA_ACCESS_REG, data); + flush(KERNBASE); + break; + } + wrpr(pstate, reg, 0); + if (i == itlb_slot_max) + panic("%s: could not find an unused slot", __func__); + return; + } + + stxa(AA_IMMU_TAR, ASI_IMMU, + TLB_TAR_VA(vpn) | TLB_TAR_CTX(TLB_CTX_KERNEL)); + stxa(0, ASI_ITLB_DATA_IN_REG, data); + flush(KERNBASE); wrpr(pstate, reg, 0); } +static void +itlb_relocate_locked0_sun4u(void) +{ + u_long data, pstate, tag; + int i; + + if (cpu_impl != CPU_IMPL_ULTRASPARCIIIp) + return; + + pstate = rdpr(pstate); + wrpr(pstate, pstate & ~PSTATE_IE, 0); + + data = itlb_get_data_sun4u(0); + if ((data & (TD_V | TD_L)) != (TD_V | TD_L)) { + wrpr(pstate, pstate, 0); + return; + } + + /* Flush the mapping of slot 0. */ + tag = ldxa(TLB_DAR_SLOT(0), ASI_ITLB_TAG_READ_REG); + stxa(TLB_DEMAP_VA(TLB_TAR_VA(tag)) | TLB_DEMAP_PRIMARY | + TLB_DEMAP_PAGE, ASI_IMMU_DEMAP, 0); + flush(0); /* The USIII-family ignores the address. */ + + /* + * Search a replacement slot != 0 and enter the data and tag + * that formerly were in slot 0. + */ + for (i = 1; i < itlb_slot_max; i++) { + if ((itlb_get_data_sun4u(i) & TD_V) != 0) + continue; + + stxa(AA_IMMU_TAR, ASI_IMMU, tag); + stxa(TLB_DAR_SLOT(i), ASI_ITLB_DATA_ACCESS_REG, data); + flush(0); /* The USIII-family ignores the address. */ + break; + } + wrpr(pstate, pstate, 0); + if (i == itlb_slot_max) + panic("%s: could not find a replacement slot", __func__); +} + static int mmu_mapin_sun4u(vm_offset_t va, vm_size_t len) { @@ -438,7 +564,7 @@ while (len) { if (dtlb_va_to_pa_sun4u(va) == (vm_offset_t)-1 || itlb_va_to_pa_sun4u(va) == (vm_offset_t)-1) { - /* Allocate a physical page, claim the virtual area */ + /* Allocate a physical page, claim the virtual area. */ if (pa == (vm_offset_t)-1) { pa = alloc_phys(PAGE_SIZE_4M, PAGE_SIZE_4M); if (pa == (vm_offset_t)-1) @@ -448,7 +574,9 @@ panic("%s: can't claim virtual page " "(wanted %#lx, got %#lx)", __func__, va, mva); - /* The mappings may have changed, be paranoid. */ + /* + * The mappings may have changed, be paranoid. + */ continue; } /* @@ -537,27 +665,46 @@ u_int bootcpu; u_int cpu; + cpu_impl = VER_IMPL(rdpr(ver)); bootcpu = UPA_CR_GET_MID(ldxa(0, ASI_UPA_CONFIG_REG)); for (child = OF_child(root); child != 0; child = OF_peer(child)) { - if (child == -1) - panic("%s: can't get child phandle", __func__); - if (OF_getprop(child, "device_type", buf, sizeof(buf)) > 0 && - strcmp(buf, "cpu") == 0) { - if (OF_getprop(child, "upa-portid", &cpu, - sizeof(cpu)) == -1 && OF_getprop(child, "portid", - &cpu, sizeof(cpu)) == -1) - panic("%s: can't get portid", __func__); - if (cpu == bootcpu) - break; - } + if (OF_getprop(child, "device_type", buf, sizeof(buf)) <= 0) + continue; + if (strcmp(buf, "cpu") != 0) + continue; + if (OF_getprop(child, cpu_impl < CPU_IMPL_ULTRASPARCIII ? + "upa-portid" : "portid", &cpu, sizeof(cpu)) <= 0) + continue; + if (cpu == bootcpu) + break; } if (cpu != bootcpu) panic("%s: no node for bootcpu?!?!", __func__); + if (OF_getprop(child, "#dtlb-entries", &dtlb_slot_max, sizeof(dtlb_slot_max)) == -1 || OF_getprop(child, "#itlb-entries", &itlb_slot_max, sizeof(itlb_slot_max)) == -1) panic("%s: can't get TLB slot max.", __func__); + + if (cpu_impl == CPU_IMPL_ULTRASPARCIIIp) { +#ifdef LOADER_DEBUG + printf("pre fixup:\n"); + pmap_print_tlb_sun4u(); +#endif + + /* + * Relocate the locked entry in it16 slot 0 (if existent) + * as part of working around Cheetah+ erratum 34. + */ + itlb_relocate_locked0_sun4u(); + +#ifdef LOADER_DEBUG + printf("post fixup:\n"); + pmap_print_tlb_sun4u(); +#endif + } + dtlb_store = malloc(dtlb_slot_max * sizeof(*dtlb_store)); itlb_store = malloc(itlb_slot_max * sizeof(*itlb_store)); if (dtlb_store == NULL || itlb_store == NULL) @@ -580,7 +727,7 @@ struct devsw **dp; /* - * Tell the Open Firmware functions where they find the ofw gate. + * Tell the Open Firmware functions where they find the OFW gate. */ OF_init(openfirm); @@ -709,10 +856,14 @@ pmap_print_tlb_sun4u(void) { tte_t tag, tte; + u_long pstate; int i; + pstate = rdpr(pstate); for (i = 0; i < itlb_slot_max; i++) { - tte = ldxa(TLB_DAR_SLOT(i), ASI_ITLB_DATA_ACCESS_REG); + wrpr(pstate, pstate & ~PSTATE_IE, 0); + tte = itlb_get_data_sun4u(i); + wrpr(pstate, pstate, 0); if (!(tte & TD_V)) continue; tag = ldxa(TLB_DAR_SLOT(i), ASI_ITLB_TAG_READ_REG); @@ -720,7 +871,9 @@ pmap_print_tte_sun4u(tag, tte); } for (i = 0; i < dtlb_slot_max; i++) { - tte = ldxa(TLB_DAR_SLOT(i), ASI_DTLB_DATA_ACCESS_REG); + wrpr(pstate, pstate & ~PSTATE_IE, 0); + tte = dtlb_get_data_sun4u(i); + wrpr(pstate, pstate, 0); if (!(tte & TD_V)) continue; tag = ldxa(TLB_DAR_SLOT(i), ASI_DTLB_TAG_READ_REG); ==== //depot/projects/usiii/conf/files.sparc64#6 (text+ko) ==== @@ -101,19 +101,23 @@ sparc64/sparc64/db_hwwatch.c optional ddb sparc64/sparc64/dump_machdep.c standard sparc64/sparc64/elf_machdep.c standard -sparc64/sparc64/exception.S standard no-obj +sparc64/sparc64/exception.S standard no-obj \ + compile-with "${NORMAL_S} -mcpu=ultrasparc" sparc64/sparc64/eeprom.c optional eeprom ebus | eeprom fhc | \ eeprom sbus sparc64/sparc64/gdb_machdep.c optional gdb sparc64/sparc64/identcpu.c standard sparc64/sparc64/in_cksum.c optional inet -sparc64/sparc64/interrupt.S standard no-obj +sparc64/sparc64/interrupt.S standard no-obj \ + compile-with "${NORMAL_S} -mcpu=ultrasparc" sparc64/sparc64/intr_machdep.c standard sparc64/sparc64/iommu.c standard +sparc64/sparc64/jbusppm.c standard sparc64/sparc64/locore.S standard no-obj sparc64/sparc64/machdep.c standard sparc64/sparc64/mem.c optional mem -sparc64/sparc64/mp_exception.S optional smp +sparc64/sparc64/mp_exception.S optional smp \ + compile-with "${NORMAL_S} -mcpu=ultrasparc" sparc64/sparc64/mp_locore.S optional smp sparc64/sparc64/mp_machdep.c optional smp sparc64/sparc64/nexus.c standard @@ -124,9 +128,11 @@ sparc64/sparc64/rtc.c optional rtc ebus | rtc isa sparc64/sparc64/rwindow.c standard sparc64/sparc64/sc_machdep.c optional sc +sparc64/sparc64/schppm.c standard sparc64/sparc64/spitfire.c standard sparc64/sparc64/stack_machdep.c optional ddb | stack -sparc64/sparc64/support.S standard +sparc64/sparc64/support.S standard \ + compile-with "${NORMAL_S} -mcpu=ultrasparc" sparc64/sparc64/sys_machdep.c standard sparc64/sparc64/swtch.S standard sparc64/sparc64/tick.c standard ==== //depot/projects/usiii/conf/options.sparc64#2 (text+ko) ==== @@ -1,22 +1,30 @@ # $FreeBSD: src/sys/conf/options.sparc64,v 1.14 2006/11/02 00:01:15 marius Exp $ -SUN4U opt_global.h - GFB_DEBUG opt_gfb.h GFB_NO_FONT_LOADING opt_gfb.h GFB_NO_MODE_CHANGE opt_gfb.h -PSYCHO_DEBUG opt_psycho.h -DEBUGGER_ON_POWERFAIL opt_psycho.h +SUN4U opt_global.h + +ATKBD_DFLT_KEYMAP opt_atkbd.h + +# Debug IOMMU inserts/removes using diagnostic accesses. This is very loud. +IOMMU_DIAG opt_iommu.h + +OFWCONS_POLL_HZ opt_ofw.h + OFW_PCI_DEBUG opt_ofw_pci.h -OFWCONS_POLL_HZ opt_ofw.h -# Debug IOMMU inserts/removes using diagnostic accesses. Very loud. -IOMMU_DIAG opt_iommu.h + PMAP_STATS opt_pmap.h -ATKBD_DFLT_KEYMAP opt_atkbd.h PSM_DEBUG opt_psm.h PSM_HOOKRESUME opt_psm.h PSM_RESETAFTERSUSPEND opt_psm.h + +DEBUGGER_ON_POWERFAIL opt_psycho.h +PSYCHO_DEBUG opt_psycho.h + +SCHIZO_DEBUG opt_schizo.h + SUNKBD_DFLT_KEYMAP opt_sunkbd.h SUNKBD_EMULATE_ATKBD opt_sunkbd.h ==== //depot/projects/usiii/sparc64/include/cache.h#3 (text+ko) ==== @@ -45,10 +45,6 @@ #ifndef _MACHINE_CACHE_H_ #define _MACHINE_CACHE_H_ -#ifndef LOCORE -#include <dev/ofw/openfirm.h> -#endif - #define DCACHE_COLOR_BITS (1) #define DCACHE_COLORS (1 << DCACHE_COLOR_BITS) #define DCACHE_COLOR_MASK (DCACHE_COLORS - 1) @@ -80,31 +76,27 @@ * Cache control information */ struct cacheinfo { - u_int c_enabled; /* true => cache is enabled */ u_int ic_size; /* instruction cache */ - u_int ic_set; - u_int ic_l2set; u_int ic_assoc; u_int ic_linesize; u_int dc_size; /* data cache */ - u_int dc_l2size; u_int dc_assoc; u_int dc_linesize; u_int ec_size; /* external cache info */ u_int ec_assoc; - u_int ec_l2set; u_int ec_linesize; - u_int ec_l2linesize; }; #ifdef _KERNEL +struct pcpu; + typedef void cache_enable_t(void); typedef void cache_flush_t(void); typedef void dcache_page_inval_t(vm_paddr_t pa); typedef void icache_page_inval_t(vm_paddr_t pa); -void cache_init(phandle_t node); +void cache_init(struct pcpu *pcpu); cache_enable_t cheetah_cache_enable; cache_flush_t cheetah_cache_flush; @@ -121,8 +113,6 @@ extern dcache_page_inval_t *dcache_page_inval; extern icache_page_inval_t *icache_page_inval; -extern struct cacheinfo cache; - #endif /* KERNEL */ #endif /* !LOCORE */ ==== //depot/projects/usiii/sparc64/include/clock.h#3 (text+ko) ==== @@ -29,8 +29,10 @@ #ifndef _MACHINE_CLOCK_H_ #define _MACHINE_CLOCK_H_ -extern u_long tick_increment; -extern u_long tick_freq; -extern u_long tick_MHz; +extern void (*delay_func)(int usec); +extern u_long clock_boot; + +void delay_boot(int usec); +void delay_tick(int usec); #endif /* !_MACHINE_CLOCK_H_ */ ==== //depot/projects/usiii/sparc64/include/cpu.h#2 (text+ko) ==== @@ -52,6 +52,7 @@ extern char btext[]; extern char etext[]; +void cheetah_init(void); void cpu_halt(void); void cpu_reset(void); void fork_trampoline(void); ==== //depot/projects/usiii/sparc64/include/cpufunc.h#3 (text+ko) ==== @@ -174,17 +174,28 @@ } while (0) /* + * Trick GAS/GCC into compiling access to STICK/STICK_COMPARE independently + * of the selected instruction set. + */ +#define rdstick() rd(asr24) +#define rdstickcmpr() rd(asr25) +#define wrstick(val, xor) wr(asr24, (val), (xor)) +#define wrstickcmpr(val, xor) wr(asr25, (val), (xor)) + +/* * Macro intended to be used instead of wr(asr23, val, xor) for writing to * the TICK_COMPARE register in order to avoid a bug in BlackBird CPUs that * can cause these writes to fail under certain condidtions which in turn - * causes the hardclock to stop. The workaround is to perform the write - * at the beginning of an I-Cache line directly followed by a dummy read. + * causes the hardclock to stop. The workaround is to read the TICK_COMPARE + * register back immediately after writing to it with these two instructions + * aligned to a quadword boundary in order to ensure that I$ misses won't + * split them up. */ #define wrtickcmpr(val, xor) ({ \ __asm __volatile( \ " ba,pt %%xcc, 1f ; " \ " nop ; " \ - " .align 64 ; " \ + " .align 128 ; " \ "1: wr %0, %1, %%asr23 ; " \ " rd %%asr23, %%g0 ; " \ : : "r" (val), "rI" (xor)); \ ==== //depot/projects/usiii/sparc64/include/pcpu.h#3 (text+ko) ==== @@ -33,6 +33,7 @@ #ifdef _KERNEL #include <machine/asmacros.h> +#include <machine/cache.h> #include <machine/frame.h> #include <machine/intr_machdep.h> @@ -45,6 +46,7 @@ * point at the globaldata structure. */ #define PCPU_MD_FIELDS \ + struct cacheinfo pc_cache; \ struct intr_request pc_irpool[IR_FREE]; \ struct intr_request *pc_irhead; \ struct intr_request **pc_irtail; \ @@ -53,6 +55,7 @@ vm_offset_t pc_addr; \ u_long pc_tickref; \ u_long pc_tickadj; \ + u_int pc_clock; \ u_int pc_mid; \ u_int pc_node; \ u_int pc_tlb_ctx; \ ==== //depot/projects/usiii/sparc64/include/smp.h#3 (text+ko) ==== @@ -29,9 +29,10 @@ #ifndef _MACHINE_SMP_H_ #define _MACHINE_SMP_H_ -#define CPU_CLKSYNC 1 -#define CPU_INIT 2 -#define CPU_BOOTSTRAP 3 +#define CPU_TICKSYNC 1 +#define CPU_STICKSYNC 2 +#define CPU_INIT 3 +#define CPU_BOOTSTRAP 4 #ifndef LOCORE @@ -62,6 +63,7 @@ u_int csa_state; vm_offset_t csa_pcpu; u_long csa_tick; + u_long csa_stick; u_long csa_ver; struct tte csa_ttes[PCPU_PAGES]; }; ==== //depot/projects/usiii/sparc64/include/tick.h#2 (text+ko) ==== @@ -29,7 +29,7 @@ #ifndef _MACHINE_TICK_H_ #define _MACHINE_TICK_H_ -void tick_init(u_long clock); +void tick_clear(void); void tick_start(void); void tick_stop(void); ==== //depot/projects/usiii/sparc64/include/tlb.h#4 (text+ko) ==== @@ -51,6 +51,26 @@ #define TLB_TAR_VA(va) ((va) & ~TAR_CTX_MASK) #define TLB_TAR_CTX(ctx) ((ctx) & TAR_CTX_MASK) +#define TLB_CXR_CTX_BITS (13) +#define TLB_CXR_CTX_MASK \ + (((1UL << TLB_CXR_CTX_BITS) - 1) << TLB_CXR_CTX_SHIFT) +#define TLB_CXR_CTX_SHIFT (0) +#define TLB_CXR_PGSZ_BITS (3) +#define TLB_PCXR_PGSZ_MASK \ + ((((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_PCXR_N_PGSZ0_SHIFT) | \ + (((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_PCXR_N_PGSZ1_SHIFT) | \ + (((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_PCXR_P_PGSZ0_SHIFT) | \ + (((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_PCXR_P_PGSZ1_SHIFT)) +#define TLB_PCXR_N_PGSZ0_SHIFT (61) +#define TLB_PCXR_N_PGSZ1_SHIFT (58) +#define TLB_PCXR_P_PGSZ0_SHIFT (16) +#define TLB_PCXR_P_PGSZ1_SHIFT (19) +#define TLB_SCXR_PGSZ_MASK \ + ((((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_SCXR_S_PGSZ0_SHIFT) | \ + (((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_SCXR_S_PGSZ1_SHIFT)) +#define TLB_SCXR_S_PGSZ1_SHIFT (19) +#define TLB_SCXR_S_PGSZ0_SHIFT (16) + #define TLB_DEMAP_ID_SHIFT (4) #define TLB_DEMAP_ID_PRIMARY (0) #define TLB_DEMAP_ID_SECONDARY (1) @@ -59,8 +79,7 @@ #define TLB_DEMAP_TYPE_SHIFT (6) #define TLB_DEMAP_TYPE_PAGE (0) #define TLB_DEMAP_TYPE_CONTEXT (1) -/* US-III and greater only */ -#define TLB_DEMAP_TYPE_ALL (2) +#define TLB_DEMAP_TYPE_ALL (2) /* USIII and beyond only */ #define TLB_DEMAP_VA(va) ((va) & ~PAGE_MASK) #define TLB_DEMAP_ID(id) ((id) << TLB_DEMAP_ID_SHIFT) ==== //depot/projects/usiii/sparc64/include/trap.h#2 (text+ko) ==== @@ -90,6 +90,7 @@ #define T_KERNEL 64 #ifndef LOCORE +void sun4u_set_traptable(void *tba_addr); extern const char *trap_msg[]; #endif ==== //depot/projects/usiii/sparc64/include/tte.h#3 (text+ko) ==== @@ -36,21 +36,24 @@ #define TD_SIZE_SHIFT (61) #define TD_SOFT2_SHIFT (50) -#define TD_DIAG_SHIFT (41) +#define TD_DIAG_SF_SHIFT (41) +#define TD_RSVD_CH_SHIFT (43) #define TD_PA_SHIFT (13) #define TD_SOFT_SHIFT (7) #define TD_SIZE_BITS (2) #define TD_SOFT2_BITS (9) -#define TD_DIAG_BITS (9) +#define TD_DIAG_SF_BITS (9) +#define TD_RSVD_CH_BITS (7) #define TD_PA_CH_BITS (30) #define TD_PA_SF_BITS (28) -#define TD_PA_BITS TD_PA_SF_BITS +#define TD_PA_BITS TD_PA_CH_BITS #define TD_SOFT_BITS (6) #define TD_SIZE_MASK ((1UL << TD_SIZE_BITS) - 1) #define TD_SOFT2_MASK ((1UL << TD_SOFT2_BITS) - 1) -#define TD_DIAG_MASK ((1UL << TD_DIAG_BITS) - 1) +#define TD_DIAG_SF_MASK ((1UL << TD_DIAG_SF_BITS) - 1) +#define TD_RSVD_CH_MASK ((1UL << TD_RSVD_CH_BITS) - 1) #define TD_PA_CH_MASK ((1UL << TD_PA_CH_BITS) - 1) #define TD_PA_SF_MASK ((1UL << TD_PA_SF_BITS) - 1) #define TD_PA_MASK ((1UL << TD_PA_BITS) - 1) ==== //depot/projects/usiii/sparc64/include/ver.h#2 (text+ko) ==== @@ -41,6 +41,8 @@ #define VER_MAXTL_SIZE (8) #define VER_MAXWIN_SIZE (5) +#ifndef LOCORE + #define VER_MANUF_MASK (((1L<<VER_MANUF_SIZE)-1)<<VER_MANUF_SHIFT) #define VER_IMPL_MASK (((1L<<VER_IMPL_SIZE)-1)<<VER_IMPL_SHIFT) #define VER_MASK_MASK (((1L<<VER_MASK_SIZE)-1)<<VER_MASK_SHIFT) @@ -61,6 +63,8 @@ extern int cpu_impl; extern char sparc64_model[]; +#endif /* !LOCORE */ + /* Known implementations. */ #define CPU_IMPL_SPARC64 0x01 #define CPU_IMPL_ULTRASPARCI 0x10 ==== //depot/projects/usiii/sparc64/pci/ofw_pci.h#3 (text+ko) ==== @@ -32,7 +32,7 @@ */ #ifndef _SPARC64_PCI_OFW_PCI_H_ -#define _SPARC64_PCI_OFW_PCI_H_ +#define _SPARC64_PCI_OFW_PCI_H_ #include <machine/ofw_bus.h> @@ -40,7 +40,7 @@ /* PCI range child spaces. XXX: are these MI? */ #define OFW_PCI_CS_CONFIG 0x00 -#define OFW_PCI_CS_IO 0x01 +#define OFW_PCI_CS_IO 0x01 #define OFW_PCI_CS_MEM32 0x02 #define OFW_PCI_CS_MEM64 0x03 @@ -62,4 +62,7 @@ (((uint64_t)(r)->size_hi << 32) | (uint64_t)(r)->size_lo) #define OFW_PCI_RANGE_CS(r) (((r)->cspace >> 24) & 0x03) +/* default values */ +#define OFW_PCI_LATENCY 64 + #endif /* ! _SPARC64_PCI_OFW_PCI_H_ */ ==== //depot/projects/usiii/sparc64/pci/ofw_pcibus.c#8 (text+ko) ==== @@ -60,10 +60,10 @@ #include "pcib_if.h" #include "pci_if.h" -/* Helper functions. */ +/* Helper functions */ static void ofw_pcibus_setup_device(device_t, u_int, u_int, u_int); -/* Methods. */ +/* Methods */ static device_probe_t ofw_pcibus_probe; static device_attach_t ofw_pcibus_attach; static pci_assign_interrupt_t ofw_pcibus_assign_interrupt; @@ -120,48 +120,82 @@ static void ofw_pcibus_setup_device(device_t bridge, u_int busno, u_int slot, u_int func) { +#ifndef SUN4V uint32_t reg; /* - * Initialize the latency timer register for busmaster devices to work - * properly. This is another task which the firmware does not always - * perform. The Min_Gnt register can be used to compute it's recommended - * value: it contains the desired latency in units of 1/4 us. To - * calculate the correct latency timer value, the clock frequency of - * the bus (defaulting to 33Mhz) should be used and no wait states - * should be assumed. + * Initialize the latency timer register for busmaster devices to + * work properly. This is another task which the firmware doesn't + * always perform. The Min_Gnt register can be used to compute its + * recommended value: it contains the desired latency in units of + * 1/4 us assuming a clock rate of 33MHz. To calculate the correct + * latency timer value, the clock frequency of the bus (defaulting + * to 33MHz) should be used and no wait states assumed. */ - if (OF_getprop(ofw_bus_get_node(bridge), "clock-frequency", ®, - sizeof(reg)) == -1) - reg = 33000000; - reg = PCIB_READ_CONFIG(bridge, busno, slot, func, PCIR_MINGNT, 1) * - reg / 1000000 / 4; - if (reg != 0) { + if ((PCIB_READ_CONFIG(bridge, busno, slot, func, PCIR_HDRTYPE, 1) & + PCIM_HDRTYPE) == PCIM_HDRTYPE_BRIDGE) { + reg = PCIB_READ_CONFIG(bridge, busno, slot, func, + PCIR_BRIDGECTL_1, 1); + reg |= PCIB_BCR_MASTER_ABORT_MODE | PCIB_BCR_SERR_ENABLE | + PCIB_BCR_PERR_ENABLE; +#ifdef OFW_PCI_DEBUG + device_printf(bridge, + "bridge %d/%d/%d: control 0x%x -> 0x%x\n", + busno, slot, func, PCIB_READ_CONFIG(bridge, busno, slot, + func, PCIR_SECLAT_1, 1), reg); +#endif /* OFW_PCI_DEBUG */ + PCIB_WRITE_CONFIG(bridge, busno, slot, func, PCIR_BRIDGECTL_1, + reg, 1); + + reg = OFW_PCI_LATENCY; +#ifdef OFW_PCI_DEBUG + device_printf(bridge, + "bridge %d/%d/%d: latency timer %d -> %d\n", + busno, slot, func, PCIB_READ_CONFIG(bridge, busno, slot, + func, PCIR_SECLAT_1, 1), reg); +#endif /* OFW_PCI_DEBUG */ + PCIB_WRITE_CONFIG(bridge, busno, slot, func, PCIR_SECLAT_1, + reg, 1); + } else { + if (OF_getprop(ofw_bus_get_node(bridge), "clock-frequency", + ®, sizeof(reg)) == -1) + reg = 33000000; + switch (reg) { + case 33000000: + reg = 8; + break; + case 66000000: + reg = 4; + break; + } + reg *= PCIB_READ_CONFIG(bridge, busno, slot, func, + PCIR_MINGNT, 1); + if (reg == 0) + reg = OFW_PCI_LATENCY; #ifdef OFW_PCI_DEBUG - device_printf(bridge, "device %d/%d/%d: latency timer %d -> " - "%d\n", busno, slot, func, - PCIB_READ_CONFIG(bridge, busno, slot, func, - PCIR_LATTIMER, 1), reg); + device_printf(bridge, + "device %d/%d/%d: latency timer %d -> %d\n", + busno, slot, func, PCIB_READ_CONFIG(bridge, busno, slot, + func, PCIR_LATTIMER, 1), reg); #endif /* OFW_PCI_DEBUG */ PCIB_WRITE_CONFIG(bridge, busno, slot, func, PCIR_LATTIMER, min(reg, 255), 1); } -#ifndef SUN4V /* * Compute a value to write into the cache line size register. * The role of the streaming cache is unclear in write invalidate - * transfers, so it is made sure that it's line size is always reached. - * Generally, the cache line size is fixed at 64 bytes by Fireplane/ - * Safari, JBus and UPA. + * transfers, so it is made sure that it's line size is always + * reached. Generally, the cache line size is fixed at 64 bytes + * by Fireplane/Safari, JBus and UPA. */ PCIB_WRITE_CONFIG(bridge, busno, slot, func, PCIR_CACHELNSZ, STRBUF_LINESZ / sizeof(uint32_t), 1); #endif /* - * The preset in the intline register is usually wrong. Reset it to 255, - * so that the PCI code will reroute the interrupt if needed. + * The preset in the intline register is usually wrong. Reset it to + * 255, so that the PCI code will reroute the interrupt if needed. */ PCIB_WRITE_CONFIG(bridge, busno, slot, func, PCIR_INTLINE, PCI_INVALID_IRQ, 1); @@ -237,7 +271,8 @@ } else if (intr >= 255) { /* * A fully specified interrupt (including IGN), as present on - * SPARCengine Ultra AX and e450. Extract the INO and return it. + * SPARCengine Ultra AX and e450. Extract the INO and return + * it. */ return (INTINO(intr)); #endif @@ -245,11 +280,12 @@ /* * If we got intr from a property, it may or may not be an intpin. * For on-board devices, it frequently is not, and is completely out - * of the valid intpin range. For PCI slots, it hopefully is, otherwise - * we will have trouble interfacing with non-OFW buses such as cardbus. + * of the valid intpin range. For PCI slots, it hopefully is, + * otherwise we will have trouble interfacing with non-OFW buses + * such as cardbus. * Since we cannot tell which it is without violating layering, we - * will always use the route_interrupt method, and treat exceptions on - * the level they become apparent. + * will always use the route_interrupt method, and treat exceptions + * on the level they become apparent. */ return (PCIB_ROUTE_INTERRUPT(device_get_parent(dev), child, intr)); } ==== //depot/projects/usiii/sparc64/pci/psycho.c#11 (text+ko) ==== @@ -281,7 +281,6 @@ device_set_desc(dev, "U2P UPA-PCI bridge"); return (0); } - return (ENXIO); } @@ -331,6 +330,7 @@ default: panic("%s: bogus PCI control register location", __func__); + /* NOTREACHED */ } } else { rid = 0; @@ -651,7 +651,7 @@ * firmware. */ PCIB_WRITE_CONFIG(dev, sc->sc_pci_secbus, PCS_DEVICE, PCS_FUNC, - PCIR_LATTIMER, 64, 1); + PCIR_LATTIMER, OFW_PCI_LATENCY, 1); for (n = PCIR_VENDOR; n < PCIR_STATUS; n += sizeof(uint16_t)) le16enc(&sc->sc_pci_hpbcfg[n], bus_space_read_2( @@ -966,6 +966,7 @@ break; default: panic("%s: bad width", __func__); + /* NOTREACHED */ } >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200808172110.m7HLA6Qp090529>