<feed xmlns='http://www.w3.org/2005/Atom'>
<title>starfive-tech/opensbi.git/lib, branch rtthread_AMP</title>
<subtitle>StarFive Tech OpenSBI for VisionFive (JH7110) boards (mirror)</subtitle>
<id>https://git.radix-linux.su/starfive-tech/opensbi.git/atom?h=rtthread_AMP</id>
<link rel='self' href='https://git.radix-linux.su/starfive-tech/opensbi.git/atom?h=rtthread_AMP'/>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/starfive-tech/opensbi.git/'/>
<updated>2023-12-05T06:08:57+00:00</updated>
<entry>
<title>sbi: add amp ipi call function support</title>
<updated>2023-12-05T06:08:57+00:00</updated>
<author>
<name>Minda Chen</name>
<email>minda.chen@starfivetech.com</email>
</author>
<published>2023-11-20T06:09:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/starfive-tech/opensbi.git/commit/?id=cc7f99946dad984b33259a3db8426deda9989ddd'/>
<id>urn:sha1:cc7f99946dad984b33259a3db8426deda9989ddd</id>
<content type='text'>
Add amp IPI call and set amp data address support.

Signed-off-by: Minda Chen &lt;minda.chen@starfivetech.com&gt;
</content>
</entry>
<entry>
<title>lib: sbi: Clear IPIs before init_warm_startup in non-boot harts</title>
<updated>2023-03-10T08:43:40+00:00</updated>
<author>
<name>Evgenii Shatokhin</name>
<email>e.shatokhin@yadro.com</email>
</author>
<published>2023-03-05T21:22:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/starfive-tech/opensbi.git/commit/?id=c6a092cd80112529cb2e92e180767ff5341b22a3'/>
<id>urn:sha1:c6a092cd80112529cb2e92e180767ff5341b22a3</id>
<content type='text'>
Since commit 50d4fde1c5a4 ("lib: Remove redundant sbi_platform_ipi_clear()
calls"), the IPI sent from the boot hart in wake_coldboot_harts() is not
cleared in the secondary harts until they reach sbi_ipi_init(). However,
sbi_hsm_init() and sbi_hsm_hart_wait() are called earlier, so a secondary
hart might enter sbi_hsm_hart_wait() with an already pending IPI.

sbi_hsm_hart_wait() makes sure the hart leaves the loop only when it is
actually ready, so a pending unrelated IPI should not cause safety issues.
However, it might be inefficient on certain hardware, because it prevents
"wfi" from stalling the hart even if the hardware supports this, making the
hart needlessly spin in a "busy-wait" loop.

This behaviour can be observed, for example, in a QEMU VM (QEMU 7.2.0) with
"-machine virt" running a Linux guest. Inserting delays in
sbi_hsm_hart_start() allows reproducing the issue more reliably.

The comment in wait_for_coldboot() suggests that the initial IPI is needed
in the warm resume path, so let us clear it before init_warm_startup()
only.

To do this, sbi_ipi_raw_clear() was created similar to sbi_ipi_raw_send().

Signed-off-by: Evgenii Shatokhin &lt;e.shatokhin@yadro.com&gt;
Reviewed-by: Anup Patel &lt;anup@brainfault.org&gt;
</content>
</entry>
<entry>
<title>lib: sbi: Set the state of a hart to START_PENDING after the hart is ready</title>
<updated>2023-03-10T08:42:43+00:00</updated>
<author>
<name>Evgenii Shatokhin</name>
<email>e.shatokhin@yadro.com</email>
</author>
<published>2023-03-05T21:22:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/starfive-tech/opensbi.git/commit/?id=e8e9ed3790feac05ec6fd5c279ec80b05293d67b'/>
<id>urn:sha1:e8e9ed3790feac05ec6fd5c279ec80b05293d67b</id>
<content type='text'>
When a boot hart executes sbi_hsm_hart_start() to start a secondary hart,
next_arg1, next_addr and next_mode for the latter are stored in the scratch
area after the state has been set to SBI_HSM_STATE_START_PENDING.

The secondary hart waits in the loop with wfi() in sbi_hsm_hart_wait() at
that time. However, "wfi" instruction is not guaranteed to wait for an
interrupt to be received by the hart, it is just a hint for the CPU.
According to RISC-V Privileged Architectures spec. v20211203, even an
implementation of "wfi" as "nop" is legal.

So, the secondary might leave the loop in sbi_hsm_hart_wait() as soon as
its state has been set to SBI_HSM_STATE_START_PENDING, even if it got no
IPI or it got an IPI unrelated to sbi_hsm_hart_start(). This could lead to
the following race condition when booting Linux, for example:

  Boot hart (#0)                        Secondary hart (#1)
  runs Linux startup code               waits in sbi_hsm_hart_wait()

  sbi_ecall(SBI_EXT_HSM,
            SBI_EXT_HSM_HART_START,
            ...)
  enters sbi_hsm_hart_start()
  sets state of hart #1 to START_PENDING
                                        leaves sbi_hsm_hart_wait()
                                        runs to the end of init_warmboot()
                                        returns to scratch-&gt;next_addr
                                        (next_addr can be garbage here)

  sets next_addr, etc. for hart #1
  (no good: hart #1 has already left)

  sends IPI to hart #1
  (no good either)

If this happens, the secondary hart jumps to a wrong next_addr at the end
of init_warmboot(), which leads to a system hang or crash.

To reproduce the issue more reliably, one could add a delay in
sbi_hsm_hart_start() after setting the hart's state but before sending
IPI to that hart:

    hstate = atomic_cmpxchg(&amp;hdata-&gt;state, SBI_HSM_STATE_STOPPED,
                            SBI_HSM_STATE_START_PENDING);
    ...
  + sbi_timer_mdelay(10);
    init_count = sbi_init_count(hartid);
    rscratch-&gt;next_arg1 = arg1;
    rscratch-&gt;next_addr = saddr;

The issue can be reproduced, for example, in a QEMU VM with '-machine virt'
and 2 or more CPUs, with Linux as the guest OS.

This patch moves writing of next_arg1, next_addr and next_mode for the
secondary hart before setting its state to SBI_HSM_STATE_START_PENDING.

In theory, it is possible that two or more harts enter sbi_hsm_hart_start()
for the same target hart simultaneously. To make sure the current hart has
exclusive access to the scratch area of the target hart at that point, a
per-hart 'start_ticket' is used. It is initially 0. The current hart tries
to acquire the ticket first (set it to 1) at the beginning of
sbi_hsm_hart_start() and only proceeds if it has successfully acquired it.

The target hart reads next_addr, etc., and then the releases the ticket
(sets it to 0) before calling sbi_hart_switch_mode(). This way, even if
some other hart manages to enter sbi_hsm_hart_start() after the ticket has
been released but before the target hart jumps to next_addr, it will not
cause problems.

atomic_cmpxchg() already has "acquire" semantics, among other things, so
no additional barriers are needed in hsm_start_ticket_acquire(). No hart
can perform or observe the update of *rscratch before setting of
'start_ticket' to 1.

atomic_write() only imposes ordering of writes, so an explicit barrier is
needed in hsm_start_ticket_release() to ensure its "release" semantics.
This guarantees that reads of scratch-&gt;next_addr, etc., in
sbi_hsm_hart_start_finish() cannot happen after 'start_ticket' has been
released.

Signed-off-by: Evgenii Shatokhin &lt;e.shatokhin@yadro.com&gt;
Reviewed-by: Anup Patel &lt;anup@brainfault.org&gt;
</content>
</entry>
<entry>
<title>lib: sbi: Refactor the calls to sbi_hart_switch_mode()</title>
<updated>2023-03-10T08:30:36+00:00</updated>
<author>
<name>Evgenii Shatokhin</name>
<email>e.shatokhin@yadro.com</email>
</author>
<published>2023-03-05T21:22:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/starfive-tech/opensbi.git/commit/?id=d56049e299cce3bca2022903a5550acdc323d8a4'/>
<id>urn:sha1:d56049e299cce3bca2022903a5550acdc323d8a4</id>
<content type='text'>
Move them into sbi_hsm_hart_start_finish() and sbi_hsm_hart_resume_finish()
to make them easier to manage.

This will be used by subsequent patches.

Suggested-by: Anup Patel &lt;anup@brainfault.org&gt;
Signed-off-by: Evgenii Shatokhin &lt;e.shatokhin@yadro.com&gt;
Reviewed-by: Anup Patel &lt;anup@brainfault.org&gt;
</content>
</entry>
<entry>
<title>lib: sbi_pmu: Add hartid parameter PMU device ops</title>
<updated>2023-03-10T08:30:33+00:00</updated>
<author>
<name>Mayuresh Chitale</name>
<email>mchitale@ventanamicro.com</email>
</author>
<published>2023-03-09T13:13:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/starfive-tech/opensbi.git/commit/?id=c631a7da279e735590231d2ae432fbc05743aa9e'/>
<id>urn:sha1:c631a7da279e735590231d2ae432fbc05743aa9e</id>
<content type='text'>
Platform specific firmware event handler may leverage the hartid to program
per hart specific registers for a given counter.

Signed-off-by: Mayuresh Chitale &lt;mchitale@ventanamicro.com&gt;
Reviewed-by: Atish Patra &lt;atishp@rivosinc.com&gt;
Reviewed-by: Anup Patel &lt;anup@brainfault.org&gt;
</content>
</entry>
<entry>
<title>lib: sbi_pmu: Introduce fw_counter_write_value API</title>
<updated>2023-03-10T08:30:30+00:00</updated>
<author>
<name>Mayuresh Chitale</name>
<email>mchitale@ventanamicro.com</email>
</author>
<published>2023-03-09T13:13:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/starfive-tech/opensbi.git/commit/?id=57d3aa3b0dbd534ab702dce61767df0e9dc7577f'/>
<id>urn:sha1:57d3aa3b0dbd534ab702dce61767df0e9dc7577f</id>
<content type='text'>
Add fw_counter_write_value API for platform specific firmware events
which separates setting the counter's initial value from starting the
counter. This is required so that the fw_event_data array can be reused
to save the event data received.

Signed-off-by: Mayuresh Chitale &lt;mchitale@ventanamicro.com&gt;
Reviewed-by: Anup Patel &lt;anup@brainfault.org&gt;
</content>
</entry>
<entry>
<title>lib: sbi_pmu: Use dedicated event code for platform firmware events</title>
<updated>2023-03-10T08:30:28+00:00</updated>
<author>
<name>Mayuresh Chitale</name>
<email>mchitale@ventanamicro.com</email>
</author>
<published>2023-03-09T13:13:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/starfive-tech/opensbi.git/commit/?id=641d2e9f38e085ccee77cfd866cae5c7222830fc'/>
<id>urn:sha1:641d2e9f38e085ccee77cfd866cae5c7222830fc</id>
<content type='text'>
For all platform specific firmware event operations use the dedicated
event code (0xFFFF) when matching against the input firmware event.
Furthermore save the real platform specific firmware event code received as
the event data for future use.

Signed-off-by: Mayuresh Chitale &lt;mchitale@ventanamicro.com&gt;
Reviewed-by: Anup Patel &lt;anup@brainfault.org&gt;
</content>
</entry>
<entry>
<title>lib: sbi_pmu: Update sbi_pmu dev ops</title>
<updated>2023-03-10T08:30:26+00:00</updated>
<author>
<name>Mayuresh Chitale</name>
<email>mchitale@ventanamicro.com</email>
</author>
<published>2023-03-09T13:13:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/starfive-tech/opensbi.git/commit/?id=b51ddffcc043fb94ebcbffce7682b2d0deef5afd'/>
<id>urn:sha1:b51ddffcc043fb94ebcbffce7682b2d0deef5afd</id>
<content type='text'>
Update fw_event_validate_code, fw_counter_match_code and fw_counter_start
ops which used a 32 bit event code to use the 64 bit event data instead.

Signed-off-by: Mayuresh Chitale &lt;mchitale@ventanamicro.com&gt;
Reviewed-by: Anup Patel &lt;anup@brainfault.org&gt;
</content>
</entry>
<entry>
<title>lib: sbi_pmu: Rename fw_counter_value</title>
<updated>2023-03-10T08:30:24+00:00</updated>
<author>
<name>Mayuresh Chitale</name>
<email>mchitale@ventanamicro.com</email>
</author>
<published>2023-03-09T13:13:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/starfive-tech/opensbi.git/commit/?id=548e4b4b28b96aa771c2f49a5b255ba6cc26777f'/>
<id>urn:sha1:548e4b4b28b96aa771c2f49a5b255ba6cc26777f</id>
<content type='text'>
Rename and reuse fw_counter_value array to save both the counter values
for the SBI firmware events and event data for the SBI platform specific
firmware events.

Signed-off-by: Mayuresh Chitale &lt;mchitale@ventanamicro.com&gt;
Reviewed-by: Anup Patel &lt;anup@brainfault.org&gt;
Reviewed-by: Andrew Jones &lt;ajones@ventanamicro.com&gt;
</content>
</entry>
<entry>
<title>lib: sbi_pmu: Implement sbi_pmu_counter_fw_read_hi</title>
<updated>2023-03-10T08:30:07+00:00</updated>
<author>
<name>Mayuresh Chitale</name>
<email>mchitale@ventanamicro.com</email>
</author>
<published>2023-03-09T13:13:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/starfive-tech/opensbi.git/commit/?id=51951d9e9af86c885cf5564bba7dd83a9a59a3b3'/>
<id>urn:sha1:51951d9e9af86c885cf5564bba7dd83a9a59a3b3</id>
<content type='text'>
To support 64 bit firmware counters on RV32 systems, we implement
sbi_pmu_counter_fw_read_hi() which returns the upper 32 bits of
the firmware counter value. On RV64 (or higher) systems, this
function will always return zero.

Signed-off-by: Mayuresh Chitale &lt;mchitale@ventanamicro.com&gt;
Reviewed-by: Atish Patra &lt;atishp@rivosinc.com&gt;
Reviewed-by: Anup Patel &lt;anup@brainfault.org&gt;
</content>
</entry>
</feed>
