Unbreak non-SMP builds. This was broken by r259284. Also, reorganize the
code introduced in that revision a bit. Reviewed by: nwhitehorn MFC after: 3 weeks
This commit is contained in:
parent
abe2ab2c7c
commit
b57e260317
@ -93,7 +93,7 @@ powerpc/aim/mmu_oea.c optional aim powerpc
|
||||
powerpc/aim/mmu_oea64.c optional aim
|
||||
powerpc/aim/moea64_if.m optional aim
|
||||
powerpc/aim/moea64_native.c optional aim
|
||||
powerpc/aim/mp_cpudep.c optional aim smp
|
||||
powerpc/aim/mp_cpudep.c optional aim
|
||||
powerpc/aim/slb.c optional aim powerpc64
|
||||
powerpc/aim/trap.c optional aim
|
||||
powerpc/aim/uma_machdep.c optional aim
|
||||
|
@ -142,6 +142,8 @@ int cacheline_size = 32;
|
||||
#endif
|
||||
int hw_direct_map = 1;
|
||||
|
||||
extern void *ap_pcpu;
|
||||
|
||||
struct pcpu __pcpu[MAXCPU];
|
||||
|
||||
static struct trapframe frame0;
|
||||
@ -235,9 +237,7 @@ extern void *rfid_patch, *rfi_patch1, *rfi_patch2;
|
||||
extern void *trapcode64;
|
||||
#endif
|
||||
|
||||
#ifdef SMP
|
||||
extern void *rstcode, *rstsize;
|
||||
#endif
|
||||
extern void *trapcode, *trapsize;
|
||||
extern void *slbtrap, *slbtrapsize;
|
||||
extern void *alitrap, *alisize;
|
||||
@ -491,11 +491,7 @@ powerpc_init(vm_offset_t startkernel, vm_offset_t endkernel,
|
||||
generictrap = &trapcode;
|
||||
#endif
|
||||
|
||||
#ifdef SMP
|
||||
bcopy(&rstcode, (void *)(EXC_RST + trap_offset), (size_t)&rstsize);
|
||||
#else
|
||||
bcopy(generictrap, (void *)EXC_RST, (size_t)&trapsize);
|
||||
#endif
|
||||
|
||||
#ifdef KDB
|
||||
bcopy(&dblow, (void *)(EXC_MCHK + trap_offset), (size_t)&dbsize);
|
||||
@ -786,3 +782,171 @@ pmap_early_io_map(vm_paddr_t pa, vm_size_t size)
|
||||
return (pa);
|
||||
}
|
||||
|
||||
/* From p3-53 of the MPC7450 RISC Microprocessor Family Reference Manual */
|
||||
void
|
||||
flush_disable_caches(void)
|
||||
{
|
||||
register_t msr;
|
||||
register_t msscr0;
|
||||
register_t cache_reg;
|
||||
volatile uint32_t *memp;
|
||||
uint32_t temp;
|
||||
int i;
|
||||
int x;
|
||||
|
||||
msr = mfmsr();
|
||||
powerpc_sync();
|
||||
mtmsr(msr & ~(PSL_EE | PSL_DR));
|
||||
msscr0 = mfspr(SPR_MSSCR0);
|
||||
msscr0 &= ~MSSCR0_L2PFE;
|
||||
mtspr(SPR_MSSCR0, msscr0);
|
||||
powerpc_sync();
|
||||
isync();
|
||||
__asm__ __volatile__("dssall; sync");
|
||||
powerpc_sync();
|
||||
isync();
|
||||
__asm__ __volatile__("dcbf 0,%0" :: "r"(0));
|
||||
__asm__ __volatile__("dcbf 0,%0" :: "r"(0));
|
||||
__asm__ __volatile__("dcbf 0,%0" :: "r"(0));
|
||||
|
||||
/* Lock the L1 Data cache. */
|
||||
mtspr(SPR_LDSTCR, mfspr(SPR_LDSTCR) | 0xFF);
|
||||
powerpc_sync();
|
||||
isync();
|
||||
|
||||
mtspr(SPR_LDSTCR, 0);
|
||||
|
||||
/*
|
||||
* Perform this in two stages: Flush the cache starting in RAM, then do it
|
||||
* from ROM.
|
||||
*/
|
||||
memp = (volatile uint32_t *)0x00000000;
|
||||
for (i = 0; i < 128 * 1024; i++) {
|
||||
temp = *memp;
|
||||
__asm__ __volatile__("dcbf 0,%0" :: "r"(memp));
|
||||
memp += 32/sizeof(*memp);
|
||||
}
|
||||
|
||||
memp = (volatile uint32_t *)0xfff00000;
|
||||
x = 0xfe;
|
||||
|
||||
for (; x != 0xff;) {
|
||||
mtspr(SPR_LDSTCR, x);
|
||||
for (i = 0; i < 128; i++) {
|
||||
temp = *memp;
|
||||
__asm__ __volatile__("dcbf 0,%0" :: "r"(memp));
|
||||
memp += 32/sizeof(*memp);
|
||||
}
|
||||
x = ((x << 1) | 1) & 0xff;
|
||||
}
|
||||
mtspr(SPR_LDSTCR, 0);
|
||||
|
||||
cache_reg = mfspr(SPR_L2CR);
|
||||
if (cache_reg & L2CR_L2E) {
|
||||
cache_reg &= ~(L2CR_L2IO_7450 | L2CR_L2DO_7450);
|
||||
mtspr(SPR_L2CR, cache_reg);
|
||||
powerpc_sync();
|
||||
mtspr(SPR_L2CR, cache_reg | L2CR_L2HWF);
|
||||
while (mfspr(SPR_L2CR) & L2CR_L2HWF)
|
||||
; /* Busy wait for cache to flush */
|
||||
powerpc_sync();
|
||||
cache_reg &= ~L2CR_L2E;
|
||||
mtspr(SPR_L2CR, cache_reg);
|
||||
powerpc_sync();
|
||||
mtspr(SPR_L2CR, cache_reg | L2CR_L2I);
|
||||
powerpc_sync();
|
||||
while (mfspr(SPR_L2CR) & L2CR_L2I)
|
||||
; /* Busy wait for L2 cache invalidate */
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
cache_reg = mfspr(SPR_L3CR);
|
||||
if (cache_reg & L3CR_L3E) {
|
||||
cache_reg &= ~(L3CR_L3IO | L3CR_L3DO);
|
||||
mtspr(SPR_L3CR, cache_reg);
|
||||
powerpc_sync();
|
||||
mtspr(SPR_L3CR, cache_reg | L3CR_L3HWF);
|
||||
while (mfspr(SPR_L3CR) & L3CR_L3HWF)
|
||||
; /* Busy wait for cache to flush */
|
||||
powerpc_sync();
|
||||
cache_reg &= ~L3CR_L3E;
|
||||
mtspr(SPR_L3CR, cache_reg);
|
||||
powerpc_sync();
|
||||
mtspr(SPR_L3CR, cache_reg | L3CR_L3I);
|
||||
powerpc_sync();
|
||||
while (mfspr(SPR_L3CR) & L3CR_L3I)
|
||||
; /* Busy wait for L3 cache invalidate */
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
mtspr(SPR_HID0, mfspr(SPR_HID0) & ~HID0_DCE);
|
||||
powerpc_sync();
|
||||
isync();
|
||||
|
||||
mtmsr(msr);
|
||||
}
|
||||
|
||||
void
|
||||
cpu_sleep()
|
||||
{
|
||||
static u_quad_t timebase = 0;
|
||||
static register_t sprgs[4];
|
||||
static register_t srrs[2];
|
||||
|
||||
jmp_buf resetjb;
|
||||
struct thread *fputd;
|
||||
struct thread *vectd;
|
||||
register_t hid0;
|
||||
register_t msr;
|
||||
register_t saved_msr;
|
||||
|
||||
ap_pcpu = pcpup;
|
||||
|
||||
PCPU_SET(restore, &resetjb);
|
||||
|
||||
saved_msr = mfmsr();
|
||||
fputd = PCPU_GET(fputhread);
|
||||
vectd = PCPU_GET(vecthread);
|
||||
if (fputd != NULL)
|
||||
save_fpu(fputd);
|
||||
if (vectd != NULL)
|
||||
save_vec(vectd);
|
||||
if (setjmp(resetjb) == 0) {
|
||||
sprgs[0] = mfspr(SPR_SPRG0);
|
||||
sprgs[1] = mfspr(SPR_SPRG1);
|
||||
sprgs[2] = mfspr(SPR_SPRG2);
|
||||
sprgs[3] = mfspr(SPR_SPRG3);
|
||||
srrs[0] = mfspr(SPR_SRR0);
|
||||
srrs[1] = mfspr(SPR_SRR1);
|
||||
timebase = mftb();
|
||||
powerpc_sync();
|
||||
flush_disable_caches();
|
||||
hid0 = mfspr(SPR_HID0);
|
||||
hid0 = (hid0 & ~(HID0_DOZE | HID0_NAP)) | HID0_SLEEP;
|
||||
powerpc_sync();
|
||||
isync();
|
||||
msr = mfmsr() | PSL_POW;
|
||||
mtspr(SPR_HID0, hid0);
|
||||
powerpc_sync();
|
||||
|
||||
while (1)
|
||||
mtmsr(msr);
|
||||
}
|
||||
mttb(timebase);
|
||||
PCPU_SET(curthread, curthread);
|
||||
PCPU_SET(curpcb, curthread->td_pcb);
|
||||
pmap_activate(curthread);
|
||||
powerpc_sync();
|
||||
mtspr(SPR_SPRG0, sprgs[0]);
|
||||
mtspr(SPR_SPRG1, sprgs[1]);
|
||||
mtspr(SPR_SPRG2, sprgs[2]);
|
||||
mtspr(SPR_SPRG3, sprgs[3]);
|
||||
mtspr(SPR_SRR0, srrs[0]);
|
||||
mtspr(SPR_SRR1, srrs[1]);
|
||||
mtmsr(saved_msr);
|
||||
if (fputd == curthread)
|
||||
enable_fpu(curthread);
|
||||
if (vectd == curthread)
|
||||
enable_vec(curthread);
|
||||
powerpc_sync();
|
||||
}
|
||||
|
@ -273,6 +273,14 @@ cpudep_ap_setup()
|
||||
|
||||
vers = mfpvr() >> 16;
|
||||
|
||||
/* The following is needed for restoring from sleep. */
|
||||
#ifdef __powerpc64__
|
||||
/* Writing to the time base register is hypervisor-privileged */
|
||||
if (mfmsr() & PSL_HV)
|
||||
mttb(0);
|
||||
#else
|
||||
mttb(0);
|
||||
#endif
|
||||
switch(vers) {
|
||||
case IBM970:
|
||||
case IBM970FX:
|
||||
|
@ -292,7 +292,6 @@ CNAME(restorebridge):
|
||||
isync
|
||||
CNAME(restorebridgesize) = .-CNAME(restorebridge)
|
||||
|
||||
#ifdef SMP
|
||||
/*
|
||||
* Processor reset exception handler. These are typically
|
||||
* the first instructions the processor executes after a
|
||||
@ -320,12 +319,21 @@ cpu_reset:
|
||||
bla CNAME(pmap_cpu_bootstrap)
|
||||
bla CNAME(cpudep_ap_bootstrap)
|
||||
mr %r1,%r3
|
||||
bla CNAME(cpudep_ap_setup)
|
||||
GET_CPUINFO(%r5)
|
||||
lwz %r3,(PC_RESTORE)(%r5)
|
||||
cmplwi %cr0,%r3,0
|
||||
beq %cr0,2f
|
||||
li %r4, 1
|
||||
b CNAME(longjmp)
|
||||
2:
|
||||
#ifdef SMP
|
||||
bla CNAME(machdep_ap_bootstrap)
|
||||
#endif
|
||||
|
||||
/* Should not be reached */
|
||||
9:
|
||||
b 9b
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This code gets copied to all the trap vectors
|
||||
|
@ -287,7 +287,6 @@ dtrace_invop_calltrap_addr:
|
||||
.text
|
||||
#endif
|
||||
|
||||
#ifdef SMP
|
||||
/*
|
||||
* Processor reset exception handler. These are typically
|
||||
* the first instructions the processor executes after a
|
||||
@ -322,13 +321,25 @@ cpu_reset:
|
||||
bl CNAME(cpudep_ap_bootstrap) /* Set up PCPU and stack */
|
||||
nop
|
||||
mr %r1,%r3 /* Use new stack */
|
||||
bl CNAME(cpudep_ap_setup)
|
||||
nop
|
||||
GET_CPUINFO(%r5)
|
||||
ld %r3,(PC_RESTORE)(%r5)
|
||||
cmpldi %cr0,%r3,0
|
||||
beq %cr0,2f
|
||||
nop
|
||||
li %r4,1
|
||||
b CNAME(longjmp)
|
||||
nop
|
||||
2:
|
||||
#ifdef SMP
|
||||
bl CNAME(machdep_ap_bootstrap) /* And away! */
|
||||
nop
|
||||
#endif
|
||||
|
||||
/* Should not be reached */
|
||||
9:
|
||||
b 9b
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This code gets copied to all the trap vectors
|
||||
|
@ -95,9 +95,9 @@ extern char etext[];
|
||||
|
||||
void cpu_halt(void);
|
||||
void cpu_reset(void);
|
||||
void cpu_sleep(void);
|
||||
void flush_disable_caches(void);
|
||||
void fork_trampoline(void);
|
||||
void swi_vm(void *);
|
||||
|
||||
void flush_disable_caches(void);
|
||||
|
||||
#endif /* _MACHINE_CPU_H_ */
|
||||
|
@ -56,5 +56,7 @@ void platform_smp_ap_init(void);
|
||||
|
||||
const char *installed_platform(void);
|
||||
void platform_probe_and_attach(void);
|
||||
|
||||
void platform_sleep(void);
|
||||
|
||||
#endif /* _MACHINE_PLATFORM_H_ */
|
||||
|
@ -38,11 +38,14 @@ __FBSDID("$FreeBSD$");
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
#include <machine/altivec.h> /* For save_vec() */
|
||||
#include <machine/bus.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/fpu.h> /* For save_fpu() */
|
||||
#include <machine/hid.h>
|
||||
#include <machine/platformvar.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <machine/setjmp.h>
|
||||
#include <machine/smp.h>
|
||||
#include <machine/spr.h>
|
||||
|
||||
@ -51,9 +54,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "platform_if.h"
|
||||
|
||||
#ifdef SMP
|
||||
extern void *ap_pcpu;
|
||||
#endif
|
||||
|
||||
static int powermac_probe(platform_t);
|
||||
static int powermac_attach(platform_t);
|
||||
@ -65,6 +66,7 @@ static int powermac_smp_next_cpu(platform_t, struct cpuref *cpuref);
|
||||
static int powermac_smp_get_bsp(platform_t, struct cpuref *cpuref);
|
||||
static int powermac_smp_start_cpu(platform_t, struct pcpu *cpu);
|
||||
static void powermac_reset(platform_t);
|
||||
static void powermac_sleep(platform_t);
|
||||
|
||||
static platform_method_t powermac_methods[] = {
|
||||
PLATFORMMETHOD(platform_probe, powermac_probe),
|
||||
@ -78,6 +80,7 @@ static platform_method_t powermac_methods[] = {
|
||||
PLATFORMMETHOD(platform_smp_start_cpu, powermac_smp_start_cpu),
|
||||
|
||||
PLATFORMMETHOD(platform_reset, powermac_reset),
|
||||
PLATFORMMETHOD(platform_sleep, powermac_sleep),
|
||||
|
||||
PLATFORMMETHOD_END
|
||||
};
|
||||
@ -376,113 +379,17 @@ powermac_smp_start_cpu(platform_t plat, struct pcpu *pc)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* From p3-53 of the MPC7450 RISC Microprocessor Family Reference Manual */
|
||||
void
|
||||
flush_disable_caches(void)
|
||||
{
|
||||
register_t msr;
|
||||
register_t msscr0;
|
||||
register_t cache_reg;
|
||||
volatile uint32_t *memp;
|
||||
uint32_t temp;
|
||||
int i;
|
||||
int x;
|
||||
|
||||
msr = mfmsr();
|
||||
powerpc_sync();
|
||||
mtmsr(msr & ~(PSL_EE | PSL_DR));
|
||||
msscr0 = mfspr(SPR_MSSCR0);
|
||||
msscr0 &= ~MSSCR0_L2PFE;
|
||||
mtspr(SPR_MSSCR0, msscr0);
|
||||
powerpc_sync();
|
||||
isync();
|
||||
__asm__ __volatile__("dssall; sync");
|
||||
powerpc_sync();
|
||||
isync();
|
||||
__asm__ __volatile__("dcbf 0,%0" :: "r"(0));
|
||||
__asm__ __volatile__("dcbf 0,%0" :: "r"(0));
|
||||
__asm__ __volatile__("dcbf 0,%0" :: "r"(0));
|
||||
|
||||
/* Lock the L1 Data cache. */
|
||||
mtspr(SPR_LDSTCR, mfspr(SPR_LDSTCR) | 0xFF);
|
||||
powerpc_sync();
|
||||
isync();
|
||||
|
||||
mtspr(SPR_LDSTCR, 0);
|
||||
|
||||
/*
|
||||
* Perform this in two stages: Flush the cache starting in RAM, then do it
|
||||
* from ROM.
|
||||
*/
|
||||
memp = (volatile uint32_t *)0x00000000;
|
||||
for (i = 0; i < 128 * 1024; i++) {
|
||||
temp = *memp;
|
||||
__asm__ __volatile__("dcbf 0,%0" :: "r"(memp));
|
||||
memp += 32/sizeof(*memp);
|
||||
}
|
||||
|
||||
memp = (volatile uint32_t *)0xfff00000;
|
||||
x = 0xfe;
|
||||
|
||||
for (; x != 0xff;) {
|
||||
mtspr(SPR_LDSTCR, x);
|
||||
for (i = 0; i < 128; i++) {
|
||||
temp = *memp;
|
||||
__asm__ __volatile__("dcbf 0,%0" :: "r"(memp));
|
||||
memp += 32/sizeof(*memp);
|
||||
}
|
||||
x = ((x << 1) | 1) & 0xff;
|
||||
}
|
||||
mtspr(SPR_LDSTCR, 0);
|
||||
|
||||
cache_reg = mfspr(SPR_L2CR);
|
||||
if (cache_reg & L2CR_L2E) {
|
||||
cache_reg &= ~(L2CR_L2IO_7450 | L2CR_L2DO_7450);
|
||||
mtspr(SPR_L2CR, cache_reg);
|
||||
powerpc_sync();
|
||||
mtspr(SPR_L2CR, cache_reg | L2CR_L2HWF);
|
||||
while (mfspr(SPR_L2CR) & L2CR_L2HWF)
|
||||
; /* Busy wait for cache to flush */
|
||||
powerpc_sync();
|
||||
cache_reg &= ~L2CR_L2E;
|
||||
mtspr(SPR_L2CR, cache_reg);
|
||||
powerpc_sync();
|
||||
mtspr(SPR_L2CR, cache_reg | L2CR_L2I);
|
||||
powerpc_sync();
|
||||
while (mfspr(SPR_L2CR) & L2CR_L2I)
|
||||
; /* Busy wait for L2 cache invalidate */
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
cache_reg = mfspr(SPR_L3CR);
|
||||
if (cache_reg & L3CR_L3E) {
|
||||
cache_reg &= ~(L3CR_L3IO | L3CR_L3DO);
|
||||
mtspr(SPR_L3CR, cache_reg);
|
||||
powerpc_sync();
|
||||
mtspr(SPR_L3CR, cache_reg | L3CR_L3HWF);
|
||||
while (mfspr(SPR_L3CR) & L3CR_L3HWF)
|
||||
; /* Busy wait for cache to flush */
|
||||
powerpc_sync();
|
||||
cache_reg &= ~L3CR_L3E;
|
||||
mtspr(SPR_L3CR, cache_reg);
|
||||
powerpc_sync();
|
||||
mtspr(SPR_L3CR, cache_reg | L3CR_L3I);
|
||||
powerpc_sync();
|
||||
while (mfspr(SPR_L3CR) & L3CR_L3I)
|
||||
; /* Busy wait for L3 cache invalidate */
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
mtspr(SPR_HID0, mfspr(SPR_HID0) & ~HID0_DCE);
|
||||
powerpc_sync();
|
||||
isync();
|
||||
|
||||
mtmsr(msr);
|
||||
}
|
||||
|
||||
static void
|
||||
powermac_reset(platform_t platform)
|
||||
{
|
||||
OF_reboot();
|
||||
}
|
||||
|
||||
void
|
||||
powermac_sleep(platform_t platform)
|
||||
{
|
||||
|
||||
*(unsigned long *)0x80 = 0x100;
|
||||
cpu_sleep();
|
||||
}
|
||||
|
||||
|
@ -45,17 +45,14 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/led/led.h>
|
||||
|
||||
#include <machine/_inttypes.h>
|
||||
#include <machine/altivec.h> /* For save_vec() */
|
||||
#include <machine/bus.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/fpu.h> /* For save_fpu() */
|
||||
#include <machine/hid.h>
|
||||
#include <machine/intr_machdep.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/pcb.h>
|
||||
#include <machine/pio.h>
|
||||
#include <machine/resource.h>
|
||||
#include <machine/setjmp.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
@ -106,7 +103,6 @@ static int pmu_acline_state(SYSCTL_HANDLER_ARGS);
|
||||
static int pmu_query_battery(struct pmu_softc *sc, int batt,
|
||||
struct pmu_battstate *info);
|
||||
static int pmu_battquery_sysctl(SYSCTL_HANDLER_ARGS);
|
||||
static void pmu_sleep_int(void);
|
||||
|
||||
/*
|
||||
* List of battery-related sysctls we might ask for
|
||||
@ -1031,72 +1027,6 @@ pmu_settime(device_t dev, struct timespec *ts)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static register_t sprgs[4];
|
||||
static register_t srrs[2];
|
||||
extern void *ap_pcpu;
|
||||
|
||||
void pmu_sleep_int(void)
|
||||
{
|
||||
static u_quad_t timebase = 0;
|
||||
jmp_buf resetjb;
|
||||
struct thread *fputd;
|
||||
struct thread *vectd;
|
||||
register_t hid0;
|
||||
register_t msr;
|
||||
register_t saved_msr;
|
||||
|
||||
ap_pcpu = pcpup;
|
||||
|
||||
PCPU_SET(restore, &resetjb);
|
||||
|
||||
*(unsigned long *)0x80 = 0x100;
|
||||
saved_msr = mfmsr();
|
||||
fputd = PCPU_GET(fputhread);
|
||||
vectd = PCPU_GET(vecthread);
|
||||
if (fputd != NULL)
|
||||
save_fpu(fputd);
|
||||
if (vectd != NULL)
|
||||
save_vec(vectd);
|
||||
if (setjmp(resetjb) == 0) {
|
||||
sprgs[0] = mfspr(SPR_SPRG0);
|
||||
sprgs[1] = mfspr(SPR_SPRG1);
|
||||
sprgs[2] = mfspr(SPR_SPRG2);
|
||||
sprgs[3] = mfspr(SPR_SPRG3);
|
||||
srrs[0] = mfspr(SPR_SRR0);
|
||||
srrs[1] = mfspr(SPR_SRR1);
|
||||
timebase = mftb();
|
||||
powerpc_sync();
|
||||
flush_disable_caches();
|
||||
hid0 = mfspr(SPR_HID0);
|
||||
hid0 = (hid0 & ~(HID0_DOZE | HID0_NAP)) | HID0_SLEEP;
|
||||
powerpc_sync();
|
||||
isync();
|
||||
msr = mfmsr() | PSL_POW;
|
||||
mtspr(SPR_HID0, hid0);
|
||||
powerpc_sync();
|
||||
|
||||
while (1)
|
||||
mtmsr(msr);
|
||||
}
|
||||
mttb(timebase);
|
||||
PCPU_SET(curthread, curthread);
|
||||
PCPU_SET(curpcb, curthread->td_pcb);
|
||||
pmap_activate(curthread);
|
||||
powerpc_sync();
|
||||
mtspr(SPR_SPRG0, sprgs[0]);
|
||||
mtspr(SPR_SPRG1, sprgs[1]);
|
||||
mtspr(SPR_SPRG2, sprgs[2]);
|
||||
mtspr(SPR_SPRG3, sprgs[3]);
|
||||
mtspr(SPR_SRR0, srrs[0]);
|
||||
mtspr(SPR_SRR1, srrs[1]);
|
||||
mtmsr(saved_msr);
|
||||
if (fputd == curthread)
|
||||
enable_fpu(curthread);
|
||||
if (vectd == curthread)
|
||||
enable_vec(curthread);
|
||||
powerpc_sync();
|
||||
}
|
||||
|
||||
int
|
||||
pmu_set_speed(int low_speed)
|
||||
{
|
||||
@ -1114,7 +1044,7 @@ pmu_set_speed(int low_speed)
|
||||
sleepcmd[4] = low_speed;
|
||||
pmu_send(sc, PMU_CPU_SPEED, 5, sleepcmd, 16, resp);
|
||||
unin_chip_sleep(NULL, 1);
|
||||
pmu_sleep_int();
|
||||
platform_sleep();
|
||||
unin_chip_wake(NULL);
|
||||
|
||||
mtdec(1); /* Force a decrementer exception */
|
||||
|
@ -62,6 +62,7 @@ ASSYM(PC_CURPMAP, offsetof(struct pcpu, pc_curpmap));
|
||||
ASSYM(PC_TEMPSAVE, offsetof(struct pcpu, pc_tempsave));
|
||||
ASSYM(PC_DISISAVE, offsetof(struct pcpu, pc_disisave));
|
||||
ASSYM(PC_DBSAVE, offsetof(struct pcpu, pc_dbsave));
|
||||
ASSYM(PC_RESTORE, offsetof(struct pcpu, pc_restore));
|
||||
|
||||
#if defined(BOOKE)
|
||||
ASSYM(PC_BOOKE_CRITSAVE, offsetof(struct pcpu, pc_booke_critsave));
|
||||
|
@ -72,29 +72,12 @@ int longfault(faultbuf, int);
|
||||
void
|
||||
machdep_ap_bootstrap(void)
|
||||
{
|
||||
jmp_buf *restore;
|
||||
|
||||
/* The following is needed for restoring from sleep. */
|
||||
#ifdef __powerpc64__
|
||||
/* Writing to the time base register is hypervisor-privileged */
|
||||
if (mfmsr() & PSL_HV)
|
||||
mttb(0);
|
||||
#else
|
||||
mttb(0);
|
||||
#endif
|
||||
/* Set up important bits on the CPU (HID registers, etc.) */
|
||||
cpudep_ap_setup();
|
||||
|
||||
/* Set PIR */
|
||||
PCPU_SET(pir, mfspr(SPR_PIR));
|
||||
PCPU_SET(awake, 1);
|
||||
__asm __volatile("msync; isync");
|
||||
|
||||
restore = PCPU_GET(restore);
|
||||
if (restore != NULL) {
|
||||
longjmp(*restore, 1);
|
||||
}
|
||||
|
||||
while (ap_letgo == 0)
|
||||
;
|
||||
|
||||
|
@ -196,6 +196,15 @@ platform_timebase_freq(struct cpuref *cpu)
|
||||
return (PLATFORM_TIMEBASE_FREQ(plat_obj, cpu));
|
||||
}
|
||||
|
||||
/*
|
||||
* Put the current CPU, as last step in suspend, to sleep
|
||||
*/
|
||||
void
|
||||
platform_sleep()
|
||||
{
|
||||
PLATFORM_SLEEP(plat_obj);
|
||||
}
|
||||
|
||||
int
|
||||
platform_smp_first_cpu(struct cpuref *cpu)
|
||||
{
|
||||
|
@ -210,3 +210,10 @@ METHOD void reset {
|
||||
platform_t _plat;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Suspend the CPU
|
||||
*/
|
||||
METHOD void sleep {
|
||||
platform_t _plat;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user