PERFORCE change 147673 for review
Marius Strobl
marius at FreeBSD.org
Sun Aug 17 21:10:07 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=147673
Change 147673 by marius at 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 at 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) <<<
More information about the p4-projects
mailing list