Questions about writing memory mapped registers of L2 Cache Controller

Since jh7110 is using U74MC, so I read the datasheet provided by SiFive and found that users can config the L2 cache and prefetcher (such as enable/disable specific cache way, turn on/off the prefetcher, which is meaningful for researches on microarchitecture) by writing to the controlled registers of L2 Cache Controller.

I’m looking for methods to write these control registers. I found the memory mapped address of L2 Cache Controller(which is 0x0201_0000-0x0201_3FFF) and L2 prefetcher(for hart 1, it’s 0x0203_0000-0x0203_1FFF) in page 96. However, directly read from these addresses(such as *((unsigned long long*)(0x02010000))) got a segment fault.

After reading the source code of freedom-metal of SiFive, I found they get the memory mapped base addr from the dtb file. So I checked the dts file of the linux repo of Starfive and found the right cache controller definitions in the upstream branch(not in devel branch, which may be the reason for the failed direct read mentioned above).

ccache: cache-controller@2010000 {
			compatible = "starfive,jh7110-ccache", "sifive,ccache0", "cache";
			reg = <0x0 0x2010000 0x0 0x4000>;
			interrupts = <1>, <3>, <4>, <2>;
			cache-block-size = <64>;
			cache-level = <2>;
			cache-sets = <2048>;
			cache-size = <2097152>;

So I want to ask 2 questions(especially for the second):

1.Can I get access to the memory mapped registers of L2 Cache Controller after I replace the kernel and dtb file builded from the upstream branch? If so, is the usage of “*((unsigned long long*)(0x02010000))” right?

2. How can I get access to the L2 prefetcher? I didn’t find the l2pf item and its corresponding address in the dts file. (Since the SiFive U74 core provides many config options to the L2 prefetcher, a lot of performance tuning work can be done. I’m in this area and have great interest in that.)

I also noticed that engineers of StarFive are submitting dtb related patches to the mainline recently. Thanks for your work. By the way, do you have the plan of supporting L2 prefetcher configurations?

Any suggestion will be appreciated!


Are you trying to access controller directly from user space? That’s not allowed by kernel.


There’s no way you’ll get access to those registers from user space (even by mmap’ing /dev/mem). You’ll need to hack the kernel or write a kernel module for that. If you just want to play with it and have fun, then I suggest you directly read/write it from u-boot. In u-boot you run in S mode, and don’t need to worry about paging.


Thank you for your advices. I realized that “0x02010000” is a physical address, not virtual.

What about question 2? I didn’t find the “l2pf@2030000” item (or something like that) in the dts file. Does that mean access to control registers of L2 prefetcher (from kernel space) is not supported yet?

1 Like

Seems no existing driver supports it, but you can still access through uboot/kernel modules

1 Like

A starting point in creating your own module to access memory from user mode that you should only be able to access from supervisor mode might be to study the LiME ( Linux Memory Extractor) kernel module which is normally used for forensic memory dumps.

here is downstream sifive L2 cache driver. You can modify from there.