summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2014-05-14 04:14:58 +0000
committerian <ian@FreeBSD.org>2014-05-14 04:14:58 +0000
commitd168d59495df2455ad00bf4c5663f265523c3691 (patch)
tree2bed89e74df862f03b25c2c6e7f4eda94164d52f
parentf7cf17218ee8bf6a98118da7f5be833e053c2b36 (diff)
downloadFreeBSD-src-d168d59495df2455ad00bf4c5663f265523c3691.zip
FreeBSD-src-d168d59495df2455ad00bf4c5663f265523c3691.tar.gz
MFC r257995, r258244, r258246,
Rename the "bare" platform "mpc85xx" Also turn "bare" into a truly bare platform Move CCSR discovery into the platform module There is no reason Book-E needs to save XER and CTR on context switches.
-rw-r--r--sys/conf/files.powerpc3
-rw-r--r--sys/powerpc/booke/machdep.c8
-rw-r--r--sys/powerpc/booke/platform_bare.c223
-rw-r--r--sys/powerpc/include/pcb.h2
-rw-r--r--sys/powerpc/mpc85xx/mpc85xx.h3
-rw-r--r--sys/powerpc/mpc85xx/platform_mpc85xx.c409
-rw-r--r--sys/powerpc/powerpc/genassym.c2
-rw-r--r--sys/powerpc/powerpc/swtch32.S8
8 files changed, 422 insertions, 236 deletions
diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc
index fc04ab4..d921a48 100644
--- a/sys/conf/files.powerpc
+++ b/sys/conf/files.powerpc
@@ -105,7 +105,7 @@ powerpc/booke/locore.S optional booke no-obj
powerpc/booke/machdep.c optional booke
powerpc/booke/machdep_e500.c optional booke_e500
powerpc/booke/mp_cpudep.c optional booke smp
-powerpc/booke/platform_bare.c optional mpc85xx
+powerpc/booke/platform_bare.c optional booke
powerpc/booke/pmap.c optional booke
powerpc/booke/trap.c optional booke
powerpc/cpufreq/dfs.c optional cpufreq
@@ -131,6 +131,7 @@ powerpc/mpc85xx/i2c.c optional iicbus fdt
powerpc/mpc85xx/isa.c optional mpc85xx isa
powerpc/mpc85xx/lbc.c optional mpc85xx
powerpc/mpc85xx/mpc85xx.c optional mpc85xx
+powerpc/mpc85xx/platform_mpc85xx.c optional mpc85xx
powerpc/mpc85xx/pci_mpc85xx.c optional pci mpc85xx
powerpc/ofw/ofw_cpu.c optional aim
powerpc/ofw/ofw_machdep.c standard
diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/machdep.c
index 69a9ef6..b289fa1 100644
--- a/sys/powerpc/booke/machdep.c
+++ b/sys/powerpc/booke/machdep.c
@@ -387,14 +387,6 @@ booke_init(uint32_t arg1, uint32_t arg2)
/* Reset TLB1 to get rid of temporary mappings */
tlb1_init();
- /* Set up IMMR */
- if (fdt_immr_addr(0) == 0) {
- fdt_immr_va = pmap_early_io_map(fdt_immr_pa, fdt_immr_size);
- } else {
- printf("Warning: SOC base registers could not be found!\n");
- fdt_immr_va = 0;
- }
-
/* Reset Time Base */
mttb(0);
diff --git a/sys/powerpc/booke/platform_bare.c b/sys/powerpc/booke/platform_bare.c
index 743a157..7449732 100644
--- a/sys/powerpc/booke/platform_bare.c
+++ b/sys/powerpc/booke/platform_bare.c
@@ -35,65 +35,34 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/smp.h>
-#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/hid.h>
-#include <machine/platform.h>
-#include <machine/platformvar.h>
-#include <machine/smp.h>
-#include <machine/spr.h>
-#include <machine/vmparam.h>
-
-#include <dev/fdt/fdt_common.h>
-#include <dev/ofw/ofw_bus.h>
-#include <dev/ofw/ofw_bus_subr.h>
#include <dev/ofw/openfirm.h>
-#include <powerpc/mpc85xx/mpc85xx.h>
+#include <machine/platform.h>
+#include <machine/platformvar.h>
#include "platform_if.h"
-#ifdef SMP
-extern void *ap_pcpu;
-extern vm_paddr_t kernload; /* Kernel physical load address */
-extern uint8_t __boot_page[]; /* Boot page body */
-extern uint32_t bp_ntlb1s;
-extern uint32_t bp_tlb1[];
-extern uint32_t bp_tlb1_end[];
-#endif
-
extern uint32_t *bootinfo;
-static int cpu, maxcpu;
-
static int bare_probe(platform_t);
static void bare_mem_regions(platform_t, struct mem_region **phys, int *physsz,
struct mem_region **avail, int *availsz);
static u_long bare_timebase_freq(platform_t, struct cpuref *cpuref);
-static int bare_smp_first_cpu(platform_t, struct cpuref *cpuref);
-static int bare_smp_next_cpu(platform_t, struct cpuref *cpuref);
-static int bare_smp_get_bsp(platform_t, struct cpuref *cpuref);
-static int bare_smp_start_cpu(platform_t, struct pcpu *cpu);
-static void booke_reset(platform_t);
+static void bare_reset(platform_t);
static platform_method_t bare_methods[] = {
PLATFORMMETHOD(platform_probe, bare_probe),
PLATFORMMETHOD(platform_mem_regions, bare_mem_regions),
PLATFORMMETHOD(platform_timebase_freq, bare_timebase_freq),
- PLATFORMMETHOD(platform_smp_first_cpu, bare_smp_first_cpu),
- PLATFORMMETHOD(platform_smp_next_cpu, bare_smp_next_cpu),
- PLATFORMMETHOD(platform_smp_get_bsp, bare_smp_get_bsp),
- PLATFORMMETHOD(platform_smp_start_cpu, bare_smp_start_cpu),
-
- PLATFORMMETHOD(platform_reset, booke_reset),
+ PLATFORMMETHOD(platform_reset, bare_reset),
PLATFORMMETHOD_END
};
static platform_def_t bare_platform = {
- "bare metal",
+ "bare",
bare_methods,
0
};
@@ -103,65 +72,19 @@ PLATFORM_DEF(bare_platform);
static int
bare_probe(platform_t plat)
{
- phandle_t cpus, child;
- uint32_t sr;
- int i, law_max, tgt;
- if ((cpus = OF_finddevice("/cpus")) != 0) {
- for (maxcpu = 0, child = OF_child(cpus); child != 0;
- child = OF_peer(child), maxcpu++)
- ;
- } else
- maxcpu = 1;
-
- /*
- * Clear local access windows. Skip DRAM entries, so we don't shoot
- * ourselves in the foot.
- */
- law_max = law_getmax();
- for (i = 0; i < law_max; i++) {
- sr = ccsr_read4(OCP85XX_LAWSR(i));
- if ((sr & 0x80000000) == 0)
- continue;
- tgt = (sr & 0x01f00000) >> 20;
- if (tgt == OCP85XX_TGTIF_RAM1 || tgt == OCP85XX_TGTIF_RAM2 ||
- tgt == OCP85XX_TGTIF_RAM_INTL)
- continue;
-
- ccsr_write4(OCP85XX_LAWSR(i), sr & 0x7fffffff);
- }
+ if (OF_peer(0) == -1) /* Needs device tree to work */
+ return (ENXIO);
return (BUS_PROBE_GENERIC);
}
-#define MEM_REGIONS 8
-static struct mem_region avail_regions[MEM_REGIONS];
-
void
bare_mem_regions(platform_t plat, struct mem_region **phys, int *physsz,
struct mem_region **avail, int *availsz)
{
- uint32_t memsize;
- int i, rv;
- rv = fdt_get_mem_regions(avail_regions, availsz, &memsize);
- if (rv != 0)
- panic("%s: could not retrieve mem regions from the 'memory' "
- "node, error: %d", __func__, rv);
-
- for (i = 0; i < *availsz; i++) {
- if (avail_regions[i].mr_start < 1048576) {
- avail_regions[i].mr_size =
- avail_regions[i].mr_size -
- (1048576 - avail_regions[i].mr_start);
- avail_regions[i].mr_start = 1048576;
- }
- }
- *avail = avail_regions;
-
- /* On the bare metal platform phys == avail memory */
- *physsz = *availsz;
- *phys = *avail;
+ ofw_mem_regions(phys, physsz, avail, availsz);
}
static u_long
@@ -226,138 +149,10 @@ out:
return (ticks);
}
-static int
-bare_smp_first_cpu(platform_t plat, struct cpuref *cpuref)
-{
-
- cpu = 0;
- cpuref->cr_cpuid = cpu;
- cpuref->cr_hwref = cpuref->cr_cpuid;
- if (bootverbose)
- printf("powerpc_smp_first_cpu: cpuid %d\n", cpuref->cr_cpuid);
- cpu++;
-
- return (0);
-}
-
-static int
-bare_smp_next_cpu(platform_t plat, struct cpuref *cpuref)
-{
-
- if (cpu >= maxcpu)
- return (ENOENT);
-
- cpuref->cr_cpuid = cpu++;
- cpuref->cr_hwref = cpuref->cr_cpuid;
- if (bootverbose)
- printf("powerpc_smp_next_cpu: cpuid %d\n", cpuref->cr_cpuid);
-
- return (0);
-}
-
-static int
-bare_smp_get_bsp(platform_t plat, struct cpuref *cpuref)
-{
-
- cpuref->cr_cpuid = mfspr(SPR_PIR);
- cpuref->cr_hwref = cpuref->cr_cpuid;
-
- return (0);
-}
-
-static int
-bare_smp_start_cpu(platform_t plat, struct pcpu *pc)
-{
-#ifdef SMP
- uint32_t *tlb1;
- uint32_t bptr, eebpcr;
- int i, timeout;
-
- eebpcr = ccsr_read4(OCP85XX_EEBPCR);
- if ((eebpcr & (1 << (pc->pc_cpuid + 24))) != 0) {
- printf("SMP: CPU %d already out of hold-off state!\n",
- pc->pc_cpuid);
- return (ENXIO);
- }
-
- ap_pcpu = pc;
-
- i = 0;
- tlb1 = bp_tlb1;
- while (i < bp_ntlb1s && tlb1 < bp_tlb1_end) {
- mtspr(SPR_MAS0, MAS0_TLBSEL(1) | MAS0_ESEL(i));
- __asm __volatile("isync; tlbre");
- tlb1[0] = mfspr(SPR_MAS1);
- tlb1[1] = mfspr(SPR_MAS2);
- tlb1[2] = mfspr(SPR_MAS3);
- i++;
- tlb1 += 3;
- }
- if (i < bp_ntlb1s)
- bp_ntlb1s = i;
-
- /*
- * Set BPTR to the physical address of the boot page
- */
- bptr = ((uint32_t)__boot_page - KERNBASE) + kernload;
- KASSERT((bptr & 0xfff) == 0,
- ("%s: boot page is not aligned (%#x)", __func__, bptr));
- bptr = (bptr >> 12) | 0x80000000u;
- ccsr_write4(OCP85XX_BPTR, bptr);
- __asm __volatile("isync; msync");
-
- /* Flush caches to have our changes hit DRAM. */
- cpu_flush_dcache(__boot_page, 4096);
-
- /*
- * Release AP from hold-off state
- */
- eebpcr |= (1 << (pc->pc_cpuid + 24));
- ccsr_write4(OCP85XX_EEBPCR, eebpcr);
- __asm __volatile("isync; msync");
-
- timeout = 500;
- while (!pc->pc_awake && timeout--)
- DELAY(1000); /* wait 1ms */
-
- /*
- * Disable boot page translation so that the 4K page at the default
- * address (= 0xfffff000) isn't permanently remapped and thus not
- * usable otherwise.
- */
- ccsr_write4(OCP85XX_BPTR, 0);
- __asm __volatile("isync; msync");
-
- if (!pc->pc_awake)
- printf("SMP: CPU %d didn't wake up.\n", pc->pc_cpuid);
- return ((pc->pc_awake) ? 0 : EBUSY);
-#else
- /* No SMP support */
- return (ENXIO);
-#endif
-}
-
static void
-booke_reset(platform_t plat)
+bare_reset(platform_t plat)
{
- /*
- * Try the dedicated reset register first.
- * If the SoC doesn't have one, we'll fall
- * back to using the debug control register.
- */
- ccsr_write4(OCP85XX_RSTCR, 2);
-
- /* Clear DBCR0, disables debug interrupts and events. */
- mtspr(SPR_DBCR0, 0);
- __asm __volatile("isync");
-
- /* Enable Debug Interrupts in MSR. */
- mtmsr(mfmsr() | PSL_DE);
-
- /* Enable debug interrupts and issue reset. */
- mtspr(SPR_DBCR0, mfspr(SPR_DBCR0) | DBCR0_IDM | DBCR0_RST_SYSTEM);
-
printf("Reset failed...\n");
while (1)
;
diff --git a/sys/powerpc/include/pcb.h b/sys/powerpc/include/pcb.h
index 394d934..2076f42 100644
--- a/sys/powerpc/include/pcb.h
+++ b/sys/powerpc/include/pcb.h
@@ -70,8 +70,6 @@ struct pcb {
register_t usr_vsid; /* USER_SR segment */
} aim;
struct {
- register_t ctr;
- register_t xer;
register_t dbcr0;
} booke;
} pcb_cpu;
diff --git a/sys/powerpc/mpc85xx/mpc85xx.h b/sys/powerpc/mpc85xx/mpc85xx.h
index defb3bf..c3cbf55 100644
--- a/sys/powerpc/mpc85xx/mpc85xx.h
+++ b/sys/powerpc/mpc85xx/mpc85xx.h
@@ -33,7 +33,8 @@
/*
* Configuration control and status registers
*/
-#define CCSRBAR_VA fdt_immr_va
+extern vm_offset_t ccsrbar_va;
+#define CCSRBAR_VA ccsrbar_va
#define OCP85XX_CCSRBAR (CCSRBAR_VA + 0x0)
#define OCP85XX_BPTR (CCSRBAR_VA + 0x20)
diff --git a/sys/powerpc/mpc85xx/platform_mpc85xx.c b/sys/powerpc/mpc85xx/platform_mpc85xx.c
new file mode 100644
index 0000000..b190392
--- /dev/null
+++ b/sys/powerpc/mpc85xx/platform_mpc85xx.c
@@ -0,0 +1,409 @@
+/*-
+ * Copyright (c) 2008-2012 Semihalf.
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/smp.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/hid.h>
+#include <machine/platform.h>
+#include <machine/platformvar.h>
+#include <machine/smp.h>
+#include <machine/spr.h>
+#include <machine/vmparam.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/openfirm.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <powerpc/mpc85xx/mpc85xx.h>
+
+#include "platform_if.h"
+
+#ifdef SMP
+extern void *ap_pcpu;
+extern vm_paddr_t kernload; /* Kernel physical load address */
+extern uint8_t __boot_page[]; /* Boot page body */
+extern uint32_t bp_ntlb1s;
+extern uint32_t bp_tlb1[];
+extern uint32_t bp_tlb1_end[];
+#endif
+
+extern uint32_t *bootinfo;
+vm_offset_t ccsrbar_va;
+
+static int cpu, maxcpu;
+
+static int mpc85xx_probe(platform_t);
+static int mpc85xx_attach(platform_t);
+static void mpc85xx_mem_regions(platform_t, struct mem_region **phys,
+ int *physsz, struct mem_region **avail, int *availsz);
+static u_long mpc85xx_timebase_freq(platform_t, struct cpuref *cpuref);
+static int mpc85xx_smp_first_cpu(platform_t, struct cpuref *cpuref);
+static int mpc85xx_smp_next_cpu(platform_t, struct cpuref *cpuref);
+static int mpc85xx_smp_get_bsp(platform_t, struct cpuref *cpuref);
+static int mpc85xx_smp_start_cpu(platform_t, struct pcpu *cpu);
+
+static void mpc85xx_reset(platform_t);
+
+static platform_method_t mpc85xx_methods[] = {
+ PLATFORMMETHOD(platform_probe, mpc85xx_probe),
+ PLATFORMMETHOD(platform_attach, mpc85xx_attach),
+ PLATFORMMETHOD(platform_mem_regions, mpc85xx_mem_regions),
+ PLATFORMMETHOD(platform_timebase_freq, mpc85xx_timebase_freq),
+
+ PLATFORMMETHOD(platform_smp_first_cpu, mpc85xx_smp_first_cpu),
+ PLATFORMMETHOD(platform_smp_next_cpu, mpc85xx_smp_next_cpu),
+ PLATFORMMETHOD(platform_smp_get_bsp, mpc85xx_smp_get_bsp),
+ PLATFORMMETHOD(platform_smp_start_cpu, mpc85xx_smp_start_cpu),
+
+ PLATFORMMETHOD(platform_reset, mpc85xx_reset),
+
+ PLATFORMMETHOD_END
+};
+
+static platform_def_t mpc85xx_platform = {
+ "mpc85xx",
+ mpc85xx_methods,
+ 0
+};
+
+PLATFORM_DEF(mpc85xx_platform);
+
+static int
+mpc85xx_probe(platform_t plat)
+{
+ u_int pvr = mfpvr() >> 16;
+
+ if ((pvr & 0xfff0) == FSL_E500v1)
+ return (BUS_PROBE_DEFAULT);
+
+ return (ENXIO);
+}
+
+static int
+mpc85xx_attach(platform_t plat)
+{
+ phandle_t cpus, child, ccsr;
+ const char *soc_name_guesses[] = {"/soc", "soc", NULL};
+ const char **name;
+ pcell_t ranges[6], acells, pacells, scells;
+ uint32_t sr;
+ uint64_t ccsrbar, ccsrsize;
+ int i, law_max, tgt;
+
+ if ((cpus = OF_finddevice("/cpus")) != -1) {
+ for (maxcpu = 0, child = OF_child(cpus); child != 0;
+ child = OF_peer(child), maxcpu++)
+ ;
+ } else
+ maxcpu = 1;
+
+ /*
+ * Locate CCSR region. Irritatingly, there is no way to find it
+ * unless you already know where it is. Try to infer its location
+ * from the device tree.
+ */
+
+ ccsr = -1;
+ for (name = soc_name_guesses; *name != NULL && ccsr == -1; name++)
+ ccsr = OF_finddevice(*name);
+ if (ccsr == -1) {
+ char type[64];
+
+ /* That didn't work. Search for devices of type "soc" */
+ child = OF_child(OF_peer(0));
+ for (OF_child(child); child != 0; child = OF_peer(child)) {
+ if (OF_getprop(child, "device_type", type, sizeof(type))
+ <= 0)
+ continue;
+
+ if (strcmp(type, "soc") == 0) {
+ ccsr = child;
+ break;
+ }
+ }
+ }
+
+ if (ccsr == -1)
+ panic("Could not locate CCSR window!");
+
+ OF_getprop(ccsr, "#size-cells", &scells, sizeof(scells));
+ OF_getprop(ccsr, "#address-cells", &acells, sizeof(acells));
+ OF_searchprop(OF_parent(ccsr), "#address-cells", &pacells,
+ sizeof(pacells));
+ OF_getprop(ccsr, "ranges", ranges, sizeof(ranges));
+ ccsrbar = ccsrsize = 0;
+ for (i = acells; i < acells + pacells; i++) {
+ ccsrbar <<= 32;
+ ccsrbar |= ranges[i];
+ }
+ for (i = acells + pacells; i < acells + pacells + scells; i++) {
+ ccsrsize <<= 32;
+ ccsrsize |= ranges[i];
+ }
+ ccsrbar_va = pmap_early_io_map(ccsrbar, ccsrsize);
+
+ /*
+ * Clear local access windows. Skip DRAM entries, so we don't shoot
+ * ourselves in the foot.
+ */
+ law_max = law_getmax();
+ for (i = 0; i < law_max; i++) {
+ sr = ccsr_read4(OCP85XX_LAWSR(i));
+ if ((sr & 0x80000000) == 0)
+ continue;
+ tgt = (sr & 0x01f00000) >> 20;
+ if (tgt == OCP85XX_TGTIF_RAM1 || tgt == OCP85XX_TGTIF_RAM2 ||
+ tgt == OCP85XX_TGTIF_RAM_INTL)
+ continue;
+
+ ccsr_write4(OCP85XX_LAWSR(i), sr & 0x7fffffff);
+ }
+
+ return (0);
+}
+
+void
+mpc85xx_mem_regions(platform_t plat, struct mem_region **phys, int *physsz,
+ struct mem_region **avail, int *availsz)
+{
+
+ ofw_mem_regions(phys, physsz, avail, availsz);
+}
+
+static u_long
+mpc85xx_timebase_freq(platform_t plat, struct cpuref *cpuref)
+{
+ u_long ticks;
+ phandle_t cpus, child;
+ pcell_t freq;
+
+ if (bootinfo != NULL) {
+ if (bootinfo[0] == 1) {
+ /* Backward compatibility. See 8-STABLE. */
+ ticks = bootinfo[3] >> 3;
+ } else {
+ /* Compatibility with Juniper's loader. */
+ ticks = bootinfo[5] >> 3;
+ }
+ } else
+ ticks = 0;
+
+ if ((cpus = OF_finddevice("/cpus")) == -1)
+ goto out;
+
+ if ((child = OF_child(cpus)) == 0)
+ goto out;
+
+ switch (OF_getproplen(child, "timebase-frequency")) {
+ case 4:
+ {
+ uint32_t tbase;
+ OF_getprop(child, "timebase-frequency", &tbase, sizeof(tbase));
+ ticks = tbase;
+ return (ticks);
+ }
+ case 8:
+ {
+ uint64_t tbase;
+ OF_getprop(child, "timebase-frequency", &tbase, sizeof(tbase));
+ ticks = tbase;
+ return (ticks);
+ }
+ default:
+ break;
+ }
+
+ freq = 0;
+ if (OF_getprop(child, "bus-frequency", (void *)&freq,
+ sizeof(freq)) <= 0)
+ goto out;
+
+ /*
+ * Time Base and Decrementer are updated every 8 CCB bus clocks.
+ * HID0[SEL_TBCLK] = 0
+ */
+ if (freq != 0)
+ ticks = freq / 8;
+
+out:
+ if (ticks <= 0)
+ panic("Unable to determine timebase frequency!");
+
+ return (ticks);
+}
+
+static int
+mpc85xx_smp_first_cpu(platform_t plat, struct cpuref *cpuref)
+{
+
+ cpu = 0;
+ cpuref->cr_cpuid = cpu;
+ cpuref->cr_hwref = cpuref->cr_cpuid;
+ if (bootverbose)
+ printf("powerpc_smp_first_cpu: cpuid %d\n", cpuref->cr_cpuid);
+ cpu++;
+
+ return (0);
+}
+
+static int
+mpc85xx_smp_next_cpu(platform_t plat, struct cpuref *cpuref)
+{
+
+ if (cpu >= maxcpu)
+ return (ENOENT);
+
+ cpuref->cr_cpuid = cpu++;
+ cpuref->cr_hwref = cpuref->cr_cpuid;
+ if (bootverbose)
+ printf("powerpc_smp_next_cpu: cpuid %d\n", cpuref->cr_cpuid);
+
+ return (0);
+}
+
+static int
+mpc85xx_smp_get_bsp(platform_t plat, struct cpuref *cpuref)
+{
+
+ cpuref->cr_cpuid = mfspr(SPR_PIR);
+ cpuref->cr_hwref = cpuref->cr_cpuid;
+
+ return (0);
+}
+
+static int
+mpc85xx_smp_start_cpu(platform_t plat, struct pcpu *pc)
+{
+#ifdef SMP
+ uint32_t *tlb1;
+ uint32_t bptr, eebpcr;
+ int i, timeout;
+
+ eebpcr = ccsr_read4(OCP85XX_EEBPCR);
+ if ((eebpcr & (1 << (pc->pc_cpuid + 24))) != 0) {
+ printf("SMP: CPU %d already out of hold-off state!\n",
+ pc->pc_cpuid);
+ return (ENXIO);
+ }
+
+ ap_pcpu = pc;
+
+ i = 0;
+ tlb1 = bp_tlb1;
+ while (i < bp_ntlb1s && tlb1 < bp_tlb1_end) {
+ mtspr(SPR_MAS0, MAS0_TLBSEL(1) | MAS0_ESEL(i));
+ __asm __volatile("isync; tlbre");
+ tlb1[0] = mfspr(SPR_MAS1);
+ tlb1[1] = mfspr(SPR_MAS2);
+ tlb1[2] = mfspr(SPR_MAS3);
+ i++;
+ tlb1 += 3;
+ }
+ if (i < bp_ntlb1s)
+ bp_ntlb1s = i;
+
+ /*
+ * Set BPTR to the physical address of the boot page
+ */
+ bptr = ((uint32_t)__boot_page - KERNBASE) + kernload;
+ KASSERT((bptr & 0xfff) == 0,
+ ("%s: boot page is not aligned (%#x)", __func__, bptr));
+ bptr = (bptr >> 12) | 0x80000000u;
+ ccsr_write4(OCP85XX_BPTR, bptr);
+ __asm __volatile("isync; msync");
+
+ /* Flush caches to have our changes hit DRAM. */
+ cpu_flush_dcache(__boot_page, 4096);
+
+ /*
+ * Release AP from hold-off state
+ */
+ eebpcr |= (1 << (pc->pc_cpuid + 24));
+ ccsr_write4(OCP85XX_EEBPCR, eebpcr);
+ __asm __volatile("isync; msync");
+
+ timeout = 500;
+ while (!pc->pc_awake && timeout--)
+ DELAY(1000); /* wait 1ms */
+
+ /*
+ * Disable boot page translation so that the 4K page at the default
+ * address (= 0xfffff000) isn't permanently remapped and thus not
+ * usable otherwise.
+ */
+ ccsr_write4(OCP85XX_BPTR, 0);
+ __asm __volatile("isync; msync");
+
+ if (!pc->pc_awake)
+ printf("SMP: CPU %d didn't wake up.\n", pc->pc_cpuid);
+ return ((pc->pc_awake) ? 0 : EBUSY);
+#else
+ /* No SMP support */
+ return (ENXIO);
+#endif
+}
+
+static void
+mpc85xx_reset(platform_t plat)
+{
+
+ /*
+ * Try the dedicated reset register first.
+ * If the SoC doesn't have one, we'll fall
+ * back to using the debug control register.
+ */
+ ccsr_write4(OCP85XX_RSTCR, 2);
+
+ /* Clear DBCR0, disables debug interrupts and events. */
+ mtspr(SPR_DBCR0, 0);
+ __asm __volatile("isync");
+
+ /* Enable Debug Interrupts in MSR. */
+ mtmsr(mfmsr() | PSL_DE);
+
+ /* Enable debug interrupts and issue reset. */
+ mtspr(SPR_DBCR0, mfspr(SPR_DBCR0) | DBCR0_IDM | DBCR0_RST_SYSTEM);
+
+ printf("Reset failed...\n");
+ while (1)
+ ;
+}
+
diff --git a/sys/powerpc/powerpc/genassym.c b/sys/powerpc/powerpc/genassym.c
index 7f33dcb..f3b5092 100644
--- a/sys/powerpc/powerpc/genassym.c
+++ b/sys/powerpc/powerpc/genassym.c
@@ -193,8 +193,6 @@ ASSYM(PCB_FPU, PCB_FPU);
ASSYM(PCB_VEC, PCB_VEC);
ASSYM(PCB_AIM_USR_VSID, offsetof(struct pcb, pcb_cpu.aim.usr_vsid));
-ASSYM(PCB_BOOKE_CTR, offsetof(struct pcb, pcb_cpu.booke.ctr));
-ASSYM(PCB_BOOKE_XER, offsetof(struct pcb, pcb_cpu.booke.xer));
ASSYM(PCB_BOOKE_DBCR0, offsetof(struct pcb, pcb_cpu.booke.dbcr0));
ASSYM(TD_LOCK, offsetof(struct thread, td_lock));
diff --git a/sys/powerpc/powerpc/swtch32.S b/sys/powerpc/powerpc/swtch32.S
index 358586f..5d88c2f 100644
--- a/sys/powerpc/powerpc/swtch32.S
+++ b/sys/powerpc/powerpc/swtch32.S
@@ -90,10 +90,6 @@ ENTRY(cpu_switch)
mflr %r16 /* Save the link register */
stw %r16,PCB_LR(%r6)
#ifdef BOOKE
- mfctr %r16
- stw %r16,PCB_BOOKE_CTR(%r6)
- mfxer %r16
- stw %r16,PCB_BOOKE_XER(%r6)
mfspr %r16,SPR_DBCR0
stw %r16,PCB_BOOKE_DBCR0(%r6)
#endif
@@ -179,10 +175,6 @@ blocked_loop:
isync
#endif
#ifdef BOOKE
- lwz %r5,PCB_BOOKE_CTR(%r3)
- mtctr %r5
- lwz %r5,PCB_BOOKE_XER(%r3)
- mtctr %r5
lwz %r5,PCB_BOOKE_DBCR0(%r3)
mtspr SPR_DBCR0,%r5
#endif
OpenPOWER on IntegriCloud