From: Stafford Horne <shorne@gmail.com> To: Richard Henderson <rth@twiddle.net> Cc: QEMU Development <qemu-devel@nongnu.org>, Openrisc <openrisc@lists.librecores.org>, Stafford Horne <shorne@gmail.com> Subject: [Qemu-devel] [PATCH RFC v2] target/openrisc: Support non-busy idle state using PMR SPR Date: Tue, 25 Apr 2017 23:10:39 +0900 [thread overview] Message-ID: <20170425141039.11963-1-shorne@gmail.com> (raw) In-Reply-To: <f6a7d386-80a9-0cc3-e1ec-1b2058aa5bf9@twiddle.net> The OpenRISC architecture has the Power Management Register (PMR) special purpose register to manage cpu power states. The interesting modes are: * Doze Mode (DME) - Stop cpu except timer & pic - wake on interrupt * Sleep Mode (SME) - Stop cpu and all units - wake on interrupt * Suspend Model (SUME) - Stop cpu and all units - wake on reset The linux kernel will set DME when idle. This patch implements the PMR SPR and halts the qemu cpu when there is a change to DME or SME. This means that openrisc qemu in no longer peggs a host cpu at 100%. In order for this to work we need to kick the CPU when timers are expired. Update the cpu timer to kick the cpu upon each timer event. Signed-off-by: Stafford Horne <shorne@gmail.com> --- Hello, This patch seems work fine now. Changes since v1: * Changed to kick cpu in timer * Increment pc separate from restore hw/openrisc/cputimer.c | 1 + target/openrisc/cpu.c | 3 ++- target/openrisc/cpu.h | 10 ++++++++++ target/openrisc/interrupt.c | 2 ++ target/openrisc/machine.c | 1 + target/openrisc/sys_helper.c | 13 +++++++++++++ 6 files changed, 29 insertions(+), 1 deletion(-) diff --git a/hw/openrisc/cputimer.c b/hw/openrisc/cputimer.c index a98c799..febc469 100644 --- a/hw/openrisc/cputimer.c +++ b/hw/openrisc/cputimer.c @@ -61,6 +61,7 @@ void cpu_openrisc_timer_update(OpenRISCCPU *cpu) } next = now + (uint64_t)wait * TIMER_PERIOD; timer_mod(cpu->env.timer, next); + qemu_cpu_kick(CPU(cpu)); } void cpu_openrisc_count_start(OpenRISCCPU *cpu) diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c index c9b3f22..1d6330c 100644 --- a/target/openrisc/cpu.c +++ b/target/openrisc/cpu.c @@ -51,7 +51,8 @@ static void openrisc_cpu_reset(CPUState *s) cpu->env.lock_addr = -1; s->exception_index = -1; - cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP; + cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP | + UPR_PMP; cpu->env.dmmucfgr = (DMMUCFGR_NTW & (0 << 2)) | (DMMUCFGR_NTS & (6 << 2)); cpu->env.immucfgr = (IMMUCFGR_NTW & (0 << 2)) | (IMMUCFGR_NTS & (6 << 2)); diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h index 938ccc3..2721432 100644 --- a/target/openrisc/cpu.h +++ b/target/openrisc/cpu.h @@ -140,6 +140,15 @@ enum { IMMUCFGR_HTR = (1 << 11), }; +/* Power management register */ +enum { + PMR_SDF = (15 << 0), + PMR_DME = (1 << 4), + PMR_SME = (1 << 5), + PMR_DCGE = (1 << 6), + PMR_SUME = (1 << 7), +}; + /* Float point control status register */ enum { FPCSR_FPEE = 1, @@ -284,6 +293,7 @@ typedef struct CPUOpenRISCState { uint32_t immucfgr; /* IMMU configure register */ uint32_t esr; /* Exception supervisor register */ uint32_t evbar; /* Exception vector base address register */ + uint32_t pmr; /* Power Management Register */ uint32_t fpcsr; /* Float register */ float_status fp_status; diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c index 2c91fab..3959671 100644 --- a/target/openrisc/interrupt.c +++ b/target/openrisc/interrupt.c @@ -60,6 +60,8 @@ void openrisc_cpu_do_interrupt(CPUState *cs) env->sr |= SR_SM; env->sr &= ~SR_IEE; env->sr &= ~SR_TEE; + env->pmr &= ~PMR_DME; + env->pmr &= ~PMR_SME; env->tlb->cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu; env->tlb->cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu; env->lock_addr = -1; diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c index a82be62..a20cce7 100644 --- a/target/openrisc/machine.c +++ b/target/openrisc/machine.c @@ -138,6 +138,7 @@ static const VMStateDescription vmstate_env = { VMSTATE_UINT32(dmmucfgr, CPUOpenRISCState), VMSTATE_UINT32(immucfgr, CPUOpenRISCState), VMSTATE_UINT32(evbar, CPUOpenRISCState), + VMSTATE_UINT32(pmr, CPUOpenRISCState), VMSTATE_UINT32(esr, CPUOpenRISCState), VMSTATE_UINT32(fpcsr, CPUOpenRISCState), VMSTATE_UINT64(mac, CPUOpenRISCState), diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c index fa3d6a4..44acf0d 100644 --- a/target/openrisc/sys_helper.c +++ b/target/openrisc/sys_helper.c @@ -22,6 +22,7 @@ #include "cpu.h" #include "exec/exec-all.h" #include "exec/helper-proto.h" +#include "exception.h" #define TO_SPR(group, number) (((group) << 11) + (number)) @@ -141,6 +142,15 @@ void HELPER(mtspr)(CPUOpenRISCState *env, case TO_SPR(5, 2): /* MACHI */ env->mac = deposit64(env->mac, 32, 32, rb); break; + case TO_SPR(8, 0): /* PMR */ + env->pmr = rb; + if (env->pmr & PMR_DME || env->pmr & PMR_SME) { + cpu_restore_state(cs, GETPC()); + env->pc += 4; + cs->halted = 1; + raise_exception(cpu, EXCP_HLT); + } + break; case TO_SPR(9, 0): /* PICMR */ env->picmr |= rb; break; @@ -287,6 +297,9 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, return env->mac >> 32; break; + case TO_SPR(8, 0): /* PMR */ + return env->pmr; + case TO_SPR(9, 0): /* PICMR */ return env->picmr; -- 2.9.3
WARNING: multiple messages have this Message-ID (diff)
From: Stafford Horne <shorne@gmail.com> To: openrisc@lists.librecores.org Subject: [OpenRISC] [PATCH RFC v2] target/openrisc: Support non-busy idle state using PMR SPR Date: Tue, 25 Apr 2017 23:10:39 +0900 [thread overview] Message-ID: <20170425141039.11963-1-shorne@gmail.com> (raw) In-Reply-To: <f6a7d386-80a9-0cc3-e1ec-1b2058aa5bf9@twiddle.net> The OpenRISC architecture has the Power Management Register (PMR) special purpose register to manage cpu power states. The interesting modes are: * Doze Mode (DME) - Stop cpu except timer & pic - wake on interrupt * Sleep Mode (SME) - Stop cpu and all units - wake on interrupt * Suspend Model (SUME) - Stop cpu and all units - wake on reset The linux kernel will set DME when idle. This patch implements the PMR SPR and halts the qemu cpu when there is a change to DME or SME. This means that openrisc qemu in no longer peggs a host cpu at 100%. In order for this to work we need to kick the CPU when timers are expired. Update the cpu timer to kick the cpu upon each timer event. Signed-off-by: Stafford Horne <shorne@gmail.com> --- Hello, This patch seems work fine now. Changes since v1: * Changed to kick cpu in timer * Increment pc separate from restore hw/openrisc/cputimer.c | 1 + target/openrisc/cpu.c | 3 ++- target/openrisc/cpu.h | 10 ++++++++++ target/openrisc/interrupt.c | 2 ++ target/openrisc/machine.c | 1 + target/openrisc/sys_helper.c | 13 +++++++++++++ 6 files changed, 29 insertions(+), 1 deletion(-) diff --git a/hw/openrisc/cputimer.c b/hw/openrisc/cputimer.c index a98c799..febc469 100644 --- a/hw/openrisc/cputimer.c +++ b/hw/openrisc/cputimer.c @@ -61,6 +61,7 @@ void cpu_openrisc_timer_update(OpenRISCCPU *cpu) } next = now + (uint64_t)wait * TIMER_PERIOD; timer_mod(cpu->env.timer, next); + qemu_cpu_kick(CPU(cpu)); } void cpu_openrisc_count_start(OpenRISCCPU *cpu) diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c index c9b3f22..1d6330c 100644 --- a/target/openrisc/cpu.c +++ b/target/openrisc/cpu.c @@ -51,7 +51,8 @@ static void openrisc_cpu_reset(CPUState *s) cpu->env.lock_addr = -1; s->exception_index = -1; - cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP; + cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP | + UPR_PMP; cpu->env.dmmucfgr = (DMMUCFGR_NTW & (0 << 2)) | (DMMUCFGR_NTS & (6 << 2)); cpu->env.immucfgr = (IMMUCFGR_NTW & (0 << 2)) | (IMMUCFGR_NTS & (6 << 2)); diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h index 938ccc3..2721432 100644 --- a/target/openrisc/cpu.h +++ b/target/openrisc/cpu.h @@ -140,6 +140,15 @@ enum { IMMUCFGR_HTR = (1 << 11), }; +/* Power management register */ +enum { + PMR_SDF = (15 << 0), + PMR_DME = (1 << 4), + PMR_SME = (1 << 5), + PMR_DCGE = (1 << 6), + PMR_SUME = (1 << 7), +}; + /* Float point control status register */ enum { FPCSR_FPEE = 1, @@ -284,6 +293,7 @@ typedef struct CPUOpenRISCState { uint32_t immucfgr; /* IMMU configure register */ uint32_t esr; /* Exception supervisor register */ uint32_t evbar; /* Exception vector base address register */ + uint32_t pmr; /* Power Management Register */ uint32_t fpcsr; /* Float register */ float_status fp_status; diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c index 2c91fab..3959671 100644 --- a/target/openrisc/interrupt.c +++ b/target/openrisc/interrupt.c @@ -60,6 +60,8 @@ void openrisc_cpu_do_interrupt(CPUState *cs) env->sr |= SR_SM; env->sr &= ~SR_IEE; env->sr &= ~SR_TEE; + env->pmr &= ~PMR_DME; + env->pmr &= ~PMR_SME; env->tlb->cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu; env->tlb->cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu; env->lock_addr = -1; diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c index a82be62..a20cce7 100644 --- a/target/openrisc/machine.c +++ b/target/openrisc/machine.c @@ -138,6 +138,7 @@ static const VMStateDescription vmstate_env = { VMSTATE_UINT32(dmmucfgr, CPUOpenRISCState), VMSTATE_UINT32(immucfgr, CPUOpenRISCState), VMSTATE_UINT32(evbar, CPUOpenRISCState), + VMSTATE_UINT32(pmr, CPUOpenRISCState), VMSTATE_UINT32(esr, CPUOpenRISCState), VMSTATE_UINT32(fpcsr, CPUOpenRISCState), VMSTATE_UINT64(mac, CPUOpenRISCState), diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c index fa3d6a4..44acf0d 100644 --- a/target/openrisc/sys_helper.c +++ b/target/openrisc/sys_helper.c @@ -22,6 +22,7 @@ #include "cpu.h" #include "exec/exec-all.h" #include "exec/helper-proto.h" +#include "exception.h" #define TO_SPR(group, number) (((group) << 11) + (number)) @@ -141,6 +142,15 @@ void HELPER(mtspr)(CPUOpenRISCState *env, case TO_SPR(5, 2): /* MACHI */ env->mac = deposit64(env->mac, 32, 32, rb); break; + case TO_SPR(8, 0): /* PMR */ + env->pmr = rb; + if (env->pmr & PMR_DME || env->pmr & PMR_SME) { + cpu_restore_state(cs, GETPC()); + env->pc += 4; + cs->halted = 1; + raise_exception(cpu, EXCP_HLT); + } + break; case TO_SPR(9, 0): /* PICMR */ env->picmr |= rb; break; @@ -287,6 +297,9 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, return env->mac >> 32; break; + case TO_SPR(8, 0): /* PMR */ + return env->pmr; + case TO_SPR(9, 0): /* PICMR */ return env->picmr; -- 2.9.3
next prev parent reply other threads:[~2017-04-25 14:11 UTC|newest] Thread overview: 69+ messages / expand[flat|nested] mbox.gz Atom feed top 2017-04-16 23:23 [Qemu-devel] [PATCH 0/7] Openrisc misc features / fixes Stafford Horne 2017-04-16 23:23 ` [OpenRISC] " Stafford Horne 2017-04-16 23:23 ` [Qemu-devel] [PATCH 1/7] target/openrisc: Fixes for memory debugging Stafford Horne 2017-04-16 23:23 ` [OpenRISC] " Stafford Horne 2017-04-18 7:47 ` [Qemu-devel] " Richard Henderson 2017-04-18 7:47 ` [OpenRISC] " Richard Henderson 2017-04-18 14:18 ` Stafford Horne 2017-04-18 14:18 ` [OpenRISC] " Stafford Horne 2017-04-18 15:00 ` Richard Henderson 2017-04-18 15:00 ` [OpenRISC] " Richard Henderson 2017-04-19 20:06 ` Stafford Horne 2017-04-19 20:06 ` [OpenRISC] " Stafford Horne 2017-04-16 23:23 ` [Qemu-devel] [PATCH 2/7] target/openrisc: add shutdown logic Stafford Horne 2017-04-16 23:23 ` [OpenRISC] " Stafford Horne 2017-04-18 7:52 ` [Qemu-devel] " Richard Henderson 2017-04-18 7:52 ` [OpenRISC] " Richard Henderson 2017-04-18 14:20 ` Stafford Horne 2017-04-18 14:20 ` [OpenRISC] " Stafford Horne 2017-04-22 10:09 ` Stafford Horne 2017-04-22 10:09 ` [OpenRISC] " Stafford Horne 2017-04-22 15:25 ` Richard Henderson 2017-04-22 15:25 ` [OpenRISC] " Richard Henderson 2017-04-23 21:28 ` [OpenRISC] [PATCH PMR] target/openrisc: Support non-busy idle state using PMR SPR Stafford Horne 2017-04-23 21:54 ` [Qemu-devel] [PATCH RFC] " Stafford Horne 2017-04-23 21:54 ` [OpenRISC] " Stafford Horne 2017-04-25 10:11 ` [Qemu-devel] " Richard Henderson 2017-04-25 10:11 ` [OpenRISC] " Richard Henderson 2017-04-25 14:10 ` Stafford Horne [this message] 2017-04-25 14:10 ` [OpenRISC] [PATCH RFC v2] " Stafford Horne 2017-04-25 14:18 ` [Qemu-devel] [PATCH RFC] " Stafford Horne 2017-04-25 14:18 ` [OpenRISC] " Stafford Horne 2017-04-25 14:51 ` [Qemu-devel] " Richard Henderson 2017-04-25 14:51 ` [OpenRISC] " Richard Henderson 2022-04-27 17:44 ` [Qemu-devel] [PATCH 2/7] target/openrisc: add shutdown logic Jason A. Donenfeld 2022-04-27 17:44 ` [OpenRISC] " Jason A. Donenfeld 2022-04-27 18:47 ` Peter Maydell 2022-04-27 18:47 ` [OpenRISC] " Peter Maydell 2022-04-27 21:48 ` Stafford Horne 2022-04-27 21:48 ` [OpenRISC] " Stafford Horne 2022-04-28 0:04 ` Jason A. Donenfeld 2022-04-28 0:04 ` [OpenRISC] " Jason A. Donenfeld 2022-04-28 11:16 ` Jason A. Donenfeld 2022-04-28 11:16 ` [OpenRISC] " Jason A. Donenfeld 2022-04-28 11:47 ` Stafford Horne 2022-04-28 11:47 ` [OpenRISC] " Stafford Horne 2022-04-28 9:19 ` Peter Maydell 2022-04-28 9:19 ` [OpenRISC] " Peter Maydell 2017-04-16 23:23 ` [Qemu-devel] [PATCH 3/7] target/openrisc: add numcores and coreid support Stafford Horne 2017-04-16 23:23 ` [OpenRISC] " Stafford Horne 2017-04-18 8:01 ` [Qemu-devel] " Richard Henderson 2017-04-18 8:01 ` [OpenRISC] " Richard Henderson 2017-04-16 23:23 ` [Qemu-devel] [PATCH 4/7] target/openrisc: implement shadow registers Stafford Horne 2017-04-16 23:23 ` [OpenRISC] " Stafford Horne 2017-04-18 8:11 ` [Qemu-devel] " Richard Henderson 2017-04-18 8:11 ` [OpenRISC] " Richard Henderson 2017-04-18 14:26 ` Stafford Horne 2017-04-18 14:26 ` [OpenRISC] " Stafford Horne 2017-04-16 23:23 ` [Qemu-devel] [PATCH 5/7] migration: Add VMSTATE_UINTTL_2DARRAY() Stafford Horne 2017-04-16 23:23 ` [OpenRISC] " Stafford Horne 2017-04-16 23:23 ` [Qemu-devel] [PATCH 6/7] migration: Add VMSTATE_STRUCT_2DARRAY() Stafford Horne 2017-04-16 23:23 ` [OpenRISC] " Stafford Horne 2017-04-16 23:23 ` [Qemu-devel] [PATCH 7/7] target/openrisc: Implement full vmstate serialization Stafford Horne 2017-04-16 23:23 ` [OpenRISC] " Stafford Horne 2017-04-18 8:14 ` [Qemu-devel] " Richard Henderson 2017-04-18 8:14 ` [OpenRISC] " Richard Henderson 2017-04-18 14:27 ` Stafford Horne 2017-04-18 14:27 ` [OpenRISC] " Stafford Horne 2017-04-16 23:33 ` [Qemu-devel] [PATCH 0/7] Openrisc misc features / fixes no-reply 2017-04-16 23:33 ` [OpenRISC] " no-reply
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20170425141039.11963-1-shorne@gmail.com \ --to=shorne@gmail.com \ --cc=openrisc@lists.librecores.org \ --cc=qemu-devel@nongnu.org \ --cc=rth@twiddle.net \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.