HiFive Unleashed Linux kernel port?

(Jim Straus) #1

Is the Linux Kernel port for the HiFive Unleashed publicly available? I have looked at

but I do not see a defconfig or device tree file that seems to correspond to the HiFive Unleashed.

We hope to build an OVP virtual platform of the board that can boot Linux, so just need to be able to build a kernel in order to get started.

(Jim Straus) #2

Thought I would update on what I have found on my own, for other’s reference:

I still have not found a HiFive Unleashed device tree file anywhere, but I have found there is a HiFIveUnleashed branch of the SiFive freedom-u-sdk repository here:


I have been able to build and run with this on an OVP virtual platform of the U54-MC Core Complex using a hand-coded device tree file.

We have ordered the HiFIve Unleashed early access board which should be delivered soon. Hoping to get the device tree for the full board from that once we have it.

(Palmer Dabbelt) #3

The master of freedom-u-sdk should boot on the HiFive Unleashed, that’s our primary target platform so it’s usually pretty solid. The device tree for the HiFive Unleashed is included in a memory on the board, but QEMU can emulate the FU540-C000 (and the corresponding device tree) so you should be able to find something in there.

(chengpeng0723) #4

Hi palmer,
I see that DTB are hard coded in the ROM on the boards, and also find the codes in qemu.

My question is I think some configurations maybe not good.
For example, the Timer which doesn’t have any node in the dts, so you don’t think it as a device? Just a part of CPU?
Is there anyway to change it to our own way?

(Wesley W. Terpstra) #5

We don’t actually use the DTB from the ROM. We are using a DTB embedded in the FSBL. Also, the RTC timer is described in the DTS in-so-far as it sets the timebase-frequency.

(chengpeng0723) #6

Hi terpstra,
Well, I did not have a board, I only showed the DTS with qemu.
I don’t think the embedded DTS is a good way. For example, you can modify it as you want for ARM Arch.
And I found the embedded DTS may be not good enough, but was very hard to modify.

For example, I think this is the good way it looks like.


Now it looks like this


(chengpeng0723) #7

Hi terpstra,

long time not received your reply.
I wonder that DTS embedded in ROM or written in firmware something like FSBL, is this a standard?
I mean it will be the same in the future?
I am a ARM software engineer. I am used to write DTS myself according to SPEC. So, driver code will
parse the DTS accordingly.
If the DTS is given by FSBL or ROM instead of my style, I must know how to parse it. is there a standard format of RISCV DTS?



(Jim Wilson) #8

See https://github.com/riscv/riscv-device-tree-doc

We are in the process of cleaning up the FSBL code so we can release it. More info will be available then.

(Wesley W. Terpstra) #9

There is no standardization yet as to how the boot process for RISC-V looks. At SiFive we have been following the policy that every boot-loader receives a0 is hartid a1 points to a DTB. Whether or not the boot-loader forwards/edits/discards that DTB is up to that boot loader stage. For example, on the HiFive Unleashed, the FSBL discards the DTB from the ROM and injects its own. BBL modifies the DTB and passes it to linux. The contents of the DTB is just the defacto standard format that the linux kernel expects. Since DTS does not have a complete specification for all bindings, this is no different than ARM.

(chengpeng0723) #10

Thanks Jim.

(chengpeng0723) #11

Thanks terpstra!

Talk about “At SiFive we have been following the policy that every boot-loader receives a0 is hartid a1 points to a DTB.”

Is this the only way for S-mode to get hartId?
I found there is no shartid similar to mhartid.


(Bruce Hoult) #12

S mode is intended to be virtualisable. A hypervisor must be able to lie to the S mode operating system about things such as how many harts there are and what hart number it is running on.

Therefore if S mode software wants to know what hart id it is, it should call an appropriate function from the SBI (Supervisor Binary Interface).

(chengpeng0723) #13

Hi bruce,

But I can’t see any SBI of hartid in linux.
Seems in linux, hartid are stored in threadinfo.cpu. per-CPU also uses this information.


(Bruce Hoult) #14

The hart id (possibly virtualised) is stored there for a thread, but that’s not where it comes from originally.

My understanding (maybe faulty) is that the FSBL code creates a device tree and then passes that to the linux kernel. Code in arch/riscv/kernel/smpboot.c:setup_smp then extracts the present hart IDs using of_find_node_by_type(dn, “cpu”)) and of_property_read_u32(node, “reg”, &hart) and then the architecture-independent set_cpu_possible() and set_cpu_present() (both in kernel/cpu.c)

(chengpeng0723) #15

Hi bruce,

Yes, set_cpu_possible() and set_cpu_present() set cpumask which used by smp_init.
And then smp_init calls __cpu_up which configure the idle task’s thread_info.cpu as cpu.
Then after these, can use macro showed below to get hartid.
#define raw_smp_processor_id() (((int)((char*)get_current() + TASK_TI_CPU)))

But I think this is a bad way, as you said, I think should implement a SBI call to get hartId. What do you think?

Also here, cpu, hartid, reg in dtb are become same. Little worried about this, what if hartid are too big. For example:
core0 : harid = 0
core1 : hartid = 0x100
core2 : hartid = 0x200
This will be disaster!


(Wesley W. Terpstra) #16

The whole area of boot (including SBI) is currently non-standard. If you propose a boot method that gains enough traction in the community, then that could become the standard. However, I don’t think SiFive will modify our boot flow until such a time as there is either a standard or a pressing technical need. Since the current mechanism provides information about all CPUs via DTB and the identity of the current CPU via ‘a1’, I don’t see a need to add another redundant API at this time.

(chengpeng0723) #17

linux use a trick to save hartid in threadinfo.cpu, and will update it when task switch,so hartid will always get through sp - current thread - cpu.
well,if we use other OS, this can not work, then how to? The only way is that it is get by SBI call.

(Wesley W. Terpstra) #18

You can just save the information from a1 during boot…

(chengpeng0723) #19

Sorry, maybe I didn’t make that clear.
I am talking about the OS runing in S-mode using bbl working in M-mode.
OS can get hartid from a0 during boot. But there is no place to store it.
Linux store it in threadinfo.cpu, because it can access the threadinfo with "sp“.
But other OSes may can’t.
I can save it in gp or somewhere, but when swith to processes in U-mode, I will clear gp.
But there is no place to hold this value.
It doesn’t look like tp with are backuped by sscratch.

(Wesley W. Terpstra) #20

There is always somewhere you can store it. This something that every OS or even thread library has a mechanism to solve. Regarding losing “gp”, when you switch between privilege modes you should use [ms]scratch to save your sp before you do an [ms]ret. Then you reload all your registers through sp. This is all standard OS stuff …