From: Heiko Stuebner <heiko@sntech.de>
To: opensbi@lists.infradead.org
Subject: [PATCH v3 3/5] lib: sbi_pmu: add ability to override methods on non-standard platforms
Date: Sun, 25 Sep 2022 15:56:51 +0200 [thread overview]
Message-ID: <3173962.VdNmn5OnKV@phil> (raw)
In-Reply-To: <20220908160211.equ3nwjhocxzqncx@kamzik>
Hi Drew,
Am Donnerstag, 8. September 2022, 18:02:11 CEST schrieb Andrew Jones:
> On Thu, Sep 08, 2022 at 03:42:40PM +0200, Heiko Stuebner wrote:
> > Some platforms may not implement the PMU in a standard way,
> > but instead deviate on some functionality like overflow
> > handling.
> >
> > Implement an abstraction that those platforms can hook into.
> > This way they can still use the standard pmu interface between
> > kernel and firmware and profit from things like firmware counters,
> > without needing to create their own.
> >
> > Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> > ---
> > include/sbi/sbi_pmu.h | 13 +++++++++++++
> > lib/sbi/sbi_hart.c | 7 +++++++
> > lib/sbi/sbi_pmu.c | 21 +++++++++++++++++++++
> > 3 files changed, 41 insertions(+)
> >
> > diff --git a/include/sbi/sbi_pmu.h b/include/sbi/sbi_pmu.h
> > index 1c9a997..7c8cfe7 100644
> > --- a/include/sbi/sbi_pmu.h
> > +++ b/include/sbi/sbi_pmu.h
> > @@ -28,6 +28,16 @@
> > #define SBI_PMU_CTR_MAX (SBI_PMU_HW_CTR_MAX + SBI_PMU_FW_CTR_MAX)
> > #define SBI_PMU_FIXED_CTR_MASK 0x07
> >
> > +struct sbi_pmu_platform_ops {
> > + int (*ctr_enable_irq_hw)(int ctr_idx);
> > + int (*ctr_enable_ovf)(int ctr_idx);
> > + int (*irq_bit)(void);
> > + void (*counter_data)(unsigned int *count, unsigned int *bits);
> > +};
> > +
> > +/** Set platform-specific override ops */
> > +void sbi_pmu_set_platform_ops(struct sbi_pmu_platform_ops *ops);
> > +
> > /** Initialize PMU */
> > int sbi_pmu_init(struct sbi_scratch *scratch, bool cold_boot);
> >
> > @@ -37,6 +47,9 @@ void sbi_pmu_exit(struct sbi_scratch *scratch);
> > /** Return the pmu irq bit depending on extension existence */
> > int sbi_pmu_irq_bit(void);
> >
> > +/** Allow non-standard platforms to override probed counter information */
> > +void sbi_pmu_override_counter_data(unsigned int *count, unsigned int *bits);
> > +
> > /**
> > * Add the hardware event to counter mapping information. This should be called
> > * from the platform code to update the mapping table.
> > diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
> > index 45fbcde..6506a19 100644
> > --- a/lib/sbi/sbi_hart.c
> > +++ b/lib/sbi/sbi_hart.c
> > @@ -632,6 +632,13 @@ __mhpm_skip:
> > #undef __check_csr_2
> > #undef __check_csr
> >
> > + /**
> > + * Allow non-standard implementations to override the detected
> > + * values for number of counters and bits.
> > + */
> > + sbi_pmu_override_counter_data(&hfeatures->mhpm_count,
> > + &hfeatures->mhpm_bits);
> > +
> > /* Detect if hart supports Priv v1.10 */
> > val = csr_read_allowed(CSR_MCOUNTEREN, (unsigned long)&trap);
> > if (!trap.cause)
> > diff --git a/lib/sbi/sbi_pmu.c b/lib/sbi/sbi_pmu.c
> > index efbfbb6..08fb242 100644
> > --- a/lib/sbi/sbi_pmu.c
> > +++ b/lib/sbi/sbi_pmu.c
> > @@ -77,6 +77,8 @@ static uint32_t num_hw_ctrs;
> > /* Maximum number of counters available */
> > static uint32_t total_ctrs;
> >
> > +static struct sbi_pmu_platform_ops *pmu_platform_ops;
> > +
> > /* Helper macros to retrieve event idx and code type */
> > #define get_cidx_type(x) ((x & SBI_PMU_EVENT_IDX_TYPE_MASK) >> 16)
> > #define get_cidx_code(x) (x & SBI_PMU_EVENT_IDX_CODE_MASK)
> > @@ -358,6 +360,9 @@ static int pmu_ctr_start_hw(uint32_t cidx, uint64_t ival, bool ival_update)
> >
> > if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SSCOFPMF))
> > pmu_ctr_enable_irq_hw(cidx);
> > + else if (pmu_platform_ops && pmu_platform_ops->ctr_enable_irq_hw)
> > + pmu_platform_ops->ctr_enable_irq_hw(cidx);
> > +
> > csr_write(CSR_MCOUNTINHIBIT, mctr_inhbt);
> >
> > skip_inhibit_update:
> > @@ -373,6 +378,8 @@ int sbi_pmu_irq_bit(void)
> >
> > if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SSCOFPMF))
> > return MIP_LCOFIP;
> > + else if (pmu_platform_ops && pmu_platform_ops->irq_bit)
> > + return pmu_platform_ops->irq_bit();
> >
> > return 0;
> > }
> > @@ -534,6 +541,8 @@ static int pmu_update_hw_mhpmevent(struct sbi_pmu_hw_event *hw_evt, int ctr_idx,
> > if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SSCOFPMF))
> > mhpmevent_val = (mhpmevent_val & ~MHPMEVENT_SSCOF_MASK) |
> > MHPMEVENT_MINH | MHPMEVENT_OF;
> > + else if (pmu_platform_ops && pmu_platform_ops->ctr_enable_ovf)
> > + pmu_platform_ops->ctr_enable_ovf(ctr_idx);
> >
>
> Based on these 'if sscofpmf else pmu_platform' conditionals it looks like
> the pmu platform framework is actually specifically for a sscofpmf quirk.
> How about introducing a general quirk / pmu quirk framework and then
> adding a sscofpmf quirk. Then, where needed we'd have something like
>
> if (pmu_quirks[SSCOFPMF])
> sscofpmf_ops = (struct sscofpmf_quirk_ops *)pmu_quirks[SSCOFPMF];
>
> if sbi_hart_has_extension(scratch, SBI_HART_EXT_SSCOFPMF)
> ...
> else if (sscofpmf_ops && sscofpmf_ops->func_needed_here)
> sscofpmf_ops->func_needed_here(...);
as Anup wrote in his mail, the sbi-pmu meanwhile already got that
struct sbi_pmu_device as abstraction from somewhere else.
Which in turn handles separately from the sscofpmf extension
(similar to what I did here originally).
So for the next version I'll only use that with some extensions :-)
Heiko
> > /* Update the inhibit flags based on inhibit flags received from supervisor */
> > pmu_update_inhibit_flags(flags, &mhpmevent_val);
> > @@ -822,3 +831,15 @@ int sbi_pmu_init(struct sbi_scratch *scratch, bool cold_boot)
> >
> > return 0;
> > }
> > +
> > +void sbi_pmu_override_counter_data(unsigned int *count,
> > + unsigned int *bits)
> > +{
> > + if (pmu_platform_ops && pmu_platform_ops->counter_data)
> > + pmu_platform_ops->counter_data(count, bits);
> > +}
> > +
> > +void sbi_pmu_set_platform_ops(struct sbi_pmu_platform_ops *ops)
> > +{
> > + pmu_platform_ops = ops;
> > +}
>
next prev parent reply other threads:[~2022-09-25 13:56 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-08 13:42 [PATCH v3 0/5] Add support for T-HEAD C9xx PMU extensions Heiko Stuebner
2022-09-08 13:42 ` [PATCH v3 1/5] lib: sbi: do platform-specific extension population earlier Heiko Stuebner
2022-09-08 13:42 ` [PATCH v3 2/5] lib: sbi_pmu: move pmu irq information into pmu itself Heiko Stuebner
2022-09-08 13:42 ` [PATCH v3 3/5] lib: sbi_pmu: add ability to override methods on non-standard platforms Heiko Stuebner
2022-09-08 16:02 ` Andrew Jones
2022-09-25 13:56 ` Heiko Stuebner [this message]
2022-09-08 13:42 ` [PATCH v3 4/5] platform: generic: add extensions_init handler and platform-override Heiko Stuebner
2022-09-08 16:04 ` Andrew Jones
2022-09-08 13:42 ` [PATCH v3 5/5] platform: generic: allwinner: add support for c9xx pmu Heiko Stuebner
2022-09-08 16:07 ` [PATCH v3 0/5] Add support for T-HEAD C9xx PMU extensions Anup Patel
2022-09-08 16:18 ` Heiko Stübner
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=3173962.VdNmn5OnKV@phil \
--to=heiko@sntech.de \
--cc=opensbi@lists.infradead.org \
/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: link
Be 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.