From: Paul Mackerras <hidden> Date: 2021-06-14 23:08:43
This series of patches adds support for the Microwatt soft-core.
Microwatt is an open-source 64-bit Power ISA processor written in VHDL
which targets medium-sized FPGAs such as the Xilinx Artix-7 or the
Lattice ECP5. Microwatt currently implements the scalar fixed plus
floating-point subset of Power ISA v3.0B plus the radix MMU, but not
logical partitioning (i.e. it does not have hypervisor mode, the
partition table or nested radix translation).
Paul.
arch/powerpc/Kconfig | 2 +-
arch/powerpc/boot/Makefile | 4 +
arch/powerpc/boot/devtree.c | 59 ++++---
arch/powerpc/boot/dts/microwatt.dts | 145 +++++++++++++++++
arch/powerpc/boot/microwatt.c | 19 +++
arch/powerpc/boot/ns16550.c | 9 +-
arch/powerpc/boot/wrapper | 5 +
arch/powerpc/configs/microwatt_defconfig | 98 ++++++++++++
arch/powerpc/include/asm/archrandom.h | 12 +-
arch/powerpc/include/asm/reg.h | 1 +
arch/powerpc/kernel/udbg_16550.c | 39 +++++
arch/powerpc/mm/book3s64/radix_pgtable.c | 13 +-
arch/powerpc/platforms/Kconfig | 1 +
arch/powerpc/platforms/Makefile | 1 +
arch/powerpc/platforms/microwatt/Kconfig | 13 ++
arch/powerpc/platforms/microwatt/Makefile | 1 +
arch/powerpc/platforms/microwatt/rng.c | 48 ++++++
arch/powerpc/platforms/microwatt/setup.c | 41 +++++
arch/powerpc/sysdev/xics/Kconfig | 3 +
arch/powerpc/sysdev/xics/Makefile | 1 +
arch/powerpc/sysdev/xics/ics-native.c | 257 ++++++++++++++++++++++++++++++
arch/powerpc/sysdev/xics/xics-common.c | 2 +
22 files changed, 741 insertions(+), 33 deletions(-)
@@ -0,0 +1,98 @@+# CONFIG_SWAP is not set+# CONFIG_CROSS_MEMORY_ATTACH is not set+CONFIG_HIGH_RES_TIMERS=y+CONFIG_PREEMPT_VOLUNTARY=y+CONFIG_TICK_CPU_ACCOUNTING=y+CONFIG_LOG_BUF_SHIFT=16+CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=12+CONFIG_BLK_DEV_INITRD=y+CONFIG_CC_OPTIMIZE_FOR_SIZE=y+CONFIG_KALLSYMS_ALL=y+CONFIG_EMBEDDED=y+# CONFIG_VM_EVENT_COUNTERS is not set+# CONFIG_SLUB_DEBUG is not set+# CONFIG_COMPAT_BRK is not set+# CONFIG_SLAB_MERGE_DEFAULT is not set+CONFIG_PPC64=y+# CONFIG_PPC_KUEP is not set+# CONFIG_PPC_KUAP is not set+CONFIG_CPU_LITTLE_ENDIAN=y+CONFIG_NR_IRQS=64+CONFIG_PANIC_TIMEOUT=10+# CONFIG_PPC_POWERNV is not set+# CONFIG_PPC_PSERIES is not set+CONFIG_PPC_MICROWATT=y+# CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set+CONFIG_CPU_FREQ=y+CONFIG_HZ_100=y+# CONFIG_PPC_MEM_KEYS is not set+# CONFIG_SECCOMP is not set+# CONFIG_MQ_IOSCHED_KYBER is not set+# CONFIG_COREDUMP is not set+# CONFIG_COMPACTION is not set+# CONFIG_MIGRATION is not set+CONFIG_NET=y+CONFIG_PACKET=y+CONFIG_PACKET_DIAG=y+CONFIG_UNIX=y+CONFIG_UNIX_DIAG=y+CONFIG_INET=y+CONFIG_INET_UDP_DIAG=y+CONFIG_INET_RAW_DIAG=y+# CONFIG_WIRELESS is not set+CONFIG_DEVTMPFS=y+CONFIG_DEVTMPFS_MOUNT=y+# CONFIG_STANDALONE is not set+# CONFIG_PREVENT_FIRMWARE_BUILD is not set+# CONFIG_FW_LOADER is not set+# CONFIG_ALLOW_DEV_COREDUMP is not set+CONFIG_MTD=y+CONFIG_MTD_BLOCK=y+CONFIG_MTD_PARTITIONED_MASTER=y+CONFIG_MTD_SPI_NOR=y+CONFIG_BLK_DEV_LOOP=y+CONFIG_BLK_DEV_RAM=y+CONFIG_NETDEVICES=y+# CONFIG_WLAN is not set+# CONFIG_INPUT is not set+# CONFIG_SERIO is not set+# CONFIG_VT is not set+CONFIG_SERIAL_8250=y+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set+CONFIG_SERIAL_8250_CONSOLE=y+CONFIG_SERIAL_OF_PLATFORM=y+CONFIG_SERIAL_NONSTANDARD=y+# CONFIG_NVRAM is not set+CONFIG_RANDOM_TRUST_CPU=y+CONFIG_SPI=y+CONFIG_SPI_DEBUG=y+CONFIG_SPI_BITBANG=y+CONFIG_SPI_SPIDEV=y+# CONFIG_HWMON is not set+# CONFIG_USB_SUPPORT is not set+# CONFIG_VIRTIO_MENU is not set+# CONFIG_IOMMU_SUPPORT is not set+# CONFIG_NVMEM is not set+CONFIG_EXT4_FS=y+# CONFIG_FILE_LOCKING is not set+# CONFIG_DNOTIFY is not set+# CONFIG_INOTIFY_USER is not set+# CONFIG_MISC_FILESYSTEMS is not set+# CONFIG_CRYPTO_HW is not set+# CONFIG_XZ_DEC_X86 is not set+# CONFIG_XZ_DEC_IA64 is not set+# CONFIG_XZ_DEC_ARM is not set+# CONFIG_XZ_DEC_ARMTHUMB is not set+# CONFIG_XZ_DEC_SPARC is not set+CONFIG_PRINTK_TIME=y+# CONFIG_SYMBOLIC_ERRNAME is not set+# CONFIG_DEBUG_BUGVERBOSE is not set+# CONFIG_DEBUG_MISC is not set+# CONFIG_SCHED_DEBUG is not set+# CONFIG_FTRACE is not set+# CONFIG_STRICT_DEVMEM is not set+CONFIG_PPC_DISABLE_WERROR=y+CONFIG_XMON=y+CONFIG_XMON_DEFAULT=y+# CONFIG_XMON_DEFAULT_RO_MODE is not set+# CONFIG_RUNTIME_TESTING_MENU is not set
From: Paul Mackerras <hidden> Date: 2021-06-14 23:06:52
From: Joel Stanley <joel@jms.id.au>
This allows microwatt's kernel to be built with an embedded device tree.
Load to arch/powerpc/boot/dtbImage.microwatt to 0x500000:
mw_debug -b fpga stop load arch/powerpc/boot/dtbImage.microwatt 500000 start
Signed-off-by: Joel Stanley <joel@jms.id.au>
---
arch/powerpc/boot/Makefile | 4 ++++
arch/powerpc/boot/microwatt.c | 18 ++++++++++++++++++
arch/powerpc/boot/wrapper | 5 +++++
3 files changed, 27 insertions(+)
create mode 100644 arch/powerpc/boot/microwatt.c
@@ -355,6 +357,8 @@ image-$(CONFIG_MVME5100) += dtbImage.mvme5100# Board port in arch/powerpc/platform/amigaone/Kconfigimage-$(CONFIG_AMIGAONE)+=cuImage.amigaone+image-$(CONFIG_PPC_MICROWATT)+=dtbImage.microwatt+# For 32-bit powermacs, build the COFF and miboot images# as well as the ELF images.ifdef CONFIG_PPC32
From: Paul Mackerras <hidden> Date: 2021-06-14 23:07:15
Microwatt is a FPGA-based implementation of the Power ISA. It
currently only implements little-endian 64-bit mode, and does
not (yet) support SMP, VMX, VSX or transactional memory.
This adds a new machine type to support FPGA-based SoCs with a
Microwatt core.
Signed-off-by: Paul Mackerras <redacted>
---
arch/powerpc/Kconfig | 2 +-
arch/powerpc/platforms/Kconfig | 1 +
arch/powerpc/platforms/Makefile | 1 +
arch/powerpc/platforms/microwatt/Kconfig | 9 +++++++++
arch/powerpc/platforms/microwatt/Makefile | 1 +
arch/powerpc/platforms/microwatt/setup.c | 23 +++++++++++++++++++++++
6 files changed, 36 insertions(+), 1 deletion(-)
create mode 100644 arch/powerpc/platforms/microwatt/Kconfig
create mode 100644 arch/powerpc/platforms/microwatt/Makefile
create mode 100644 arch/powerpc/platforms/microwatt/setup.c
@@ -240,7 +249,6 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr,return0;dt_get_reg_format(parent,&naddr,&nsize);-if(nsize>2)return0;
@@ -252,10 +260,10 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr,copy_val(last_addr,prop_buf+offset,naddr);-ret_size=prop_buf[offset+naddr];+ret_size=be32_to_cpu(prop_buf[offset+naddr]);if(nsize==2){ret_size<<=32;-ret_size|=prop_buf[offset+naddr+1];+ret_size|=be32_to_cpu(prop_buf[offset+naddr+1]);}for(;;){
@@ -278,7 +286,6 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr,offset=find_range(last_addr,prop_buf,prev_naddr,naddr,prev_nsize,buflen/4);-if(offset<0)return0;
@@ -296,8 +303,7 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr,if(naddr>2)return0;-ret_addr=((u64)last_addr[2]<<32)|last_addr[3];-+ret_addr=((u64)be32_to_cpu(last_addr[2])<<32)|be32_to_cpu(last_addr[3]);if(sizeof(void*)==4&&(ret_addr>=0x100000000ULL||ret_size>0x100000000ULL||ret_addr+ret_size>0x100000000ULL))
@@ -350,11 +356,14 @@ int dt_is_compatible(void *node, const char *compat)intdt_get_virtual_reg(void*node,void**addr,intnres){unsignedlongxaddr;-intn;+intn,i;n=getprop(node,"virtual-reg",addr,nres*4);-if(n>0)+if(n>0){+for(i=0;i<n/4;i++)+((u32*)addr)[i]=be32_to_cpu(((u32*)addr)[i]);returnn/4;+}for(n=0;n<nres;n++){if(!dt_xlate_reg(node,n,&xaddr,NULL))
From: Paul Mackerras <hidden> Date: 2021-06-14 23:07:59
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This adds support to the Microwatt platform to use the standard
1655-style UART which available in the standalone Microwatt FPGA.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/boot/dts/microwatt.dts | 25 ++++++++++++---
arch/powerpc/kernel/udbg_16550.c | 39 ++++++++++++++++++++++++
arch/powerpc/platforms/microwatt/Kconfig | 1 +
arch/powerpc/platforms/microwatt/setup.c | 2 ++
4 files changed, 62 insertions(+), 5 deletions(-)
From: Paul Mackerras <hidden> Date: 2021-06-14 23:08:21
This is accessed using the DARN instruction and should probably be
done more generically.
Signed-off-by: Paul Mackerras <redacted>
---
arch/powerpc/include/asm/archrandom.h | 12 +++++-
arch/powerpc/platforms/microwatt/Kconfig | 1 +
arch/powerpc/platforms/microwatt/Makefile | 2 +-
arch/powerpc/platforms/microwatt/rng.c | 48 +++++++++++++++++++++++
4 files changed, 61 insertions(+), 2 deletions(-)
create mode 100644 arch/powerpc/platforms/microwatt/rng.c
@@ -0,0 +1,48 @@+// SPDX-License-Identifier: GPL-2.0-or-later+/*+*Derivedfromarch/powerpc/platforms/powernv/rng.c,whichis:+*Copyright2013,MichaelEllerman,IBMCorporation.+*/++#define pr_fmt(fmt) "microwatt-rng: " fmt++#include<linux/kernel.h>+#include<linux/smp.h>+#include<asm/archrandom.h>+#include<asm/cputable.h>+#include<asm/machdep.h>++#define DARN_ERR 0xFFFFFFFFFFFFFFFFul++intmicrowatt_get_random_darn(unsignedlong*v)+{+unsignedlongval;++/* Using DARN with L=1 - 64-bit conditioned random number */+asmvolatile(PPC_DARN(%0,1):"=r"(val));++if(val==DARN_ERR)+return0;++*v=val;++return1;+}++static__initintrng_init(void)+{+unsignedlongval;+inti;++for(i=0;i<10;i++){+if(microwatt_get_random_darn(&val)){+ppc_md.get_random_seed=microwatt_get_random_darn;+return0;+}+}++pr_warn("Unable to use DARN for get_random_seed()\n");++return-EIO;+}+machine_subsys_initcall(,rng_init);
From: Paul Mackerras <hidden> Date: 2021-06-14 23:09:05
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Just like any other embedded platform.
Add an empty soc node.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/boot/dts/microwatt.dts | 7 +++++++
arch/powerpc/platforms/microwatt/setup.c | 8 ++++++++
2 files changed, 15 insertions(+)
From: Paul Mackerras <hidden> Date: 2021-06-14 23:09:27
Microwatt currently doesn't implement hypervisor mode and therefore
doesn't implement the partition table. It does implement the process
table and radix page table walks.
This adds code to write the base address of the process table to the
PRTBL SPR, which has been assigned SPR 720 for now, as that is in the
range of SPR numbers assigned for experimental use. PRTBL is only
written when we have neither the FW_FEATURE_LPAR feature nor the
CPU_FTR_HVMODE feature.
Signed-off-by: Paul Mackerras <redacted>
---
arch/powerpc/include/asm/reg.h | 1 +
arch/powerpc/mm/book3s64/radix_pgtable.c | 13 +++++++++----
2 files changed, 10 insertions(+), 4 deletions(-)
@@ -0,0 +1,257 @@+// SPDX-License-Identifier: GPL-2.0-or-later+/*+*ICSbackendforOPALmanagedinterrupts.+*+*Copyright2011IBMCorp.+*/++//#define DEBUG++#include<linux/types.h>+#include<linux/kernel.h>+#include<linux/irq.h>+#include<linux/smp.h>+#include<linux/interrupt.h>+#include<linux/init.h>+#include<linux/cpu.h>+#include<linux/of.h>+#include<linux/spinlock.h>+#include<linux/msi.h>+#include<linux/list.h>++#include<asm/prom.h>+#include<asm/smp.h>+#include<asm/machdep.h>+#include<asm/irq.h>+#include<asm/errno.h>+#include<asm/xics.h>+#include<asm/opal.h>+#include<asm/firmware.h>++structics_native{+structicsics;+structdevice_node*node;+void__iomem*base;+u32ibase;+u32icount;+};+#define to_ics_native(_ics) container_of(_ics, struct ics_native, ics)++staticvoid__iomem*ics_native_xive(structics_native*in,unsignedintvec)+{+returnin->base+0x800+((vec-in->ibase)<<2);+}++staticvoidics_native_unmask_irq(structirq_data*d)+{+unsignedintvec=(unsignedint)irqd_to_hwirq(d);+structics*ics=irq_data_get_irq_chip_data(d);+structics_native*in=to_ics_native(ics);+unsignedintserver;++pr_devel("ics-native: unmask virq %d [hw 0x%x]\n",d->irq,vec);++if(vec<in->ibase||vec>=(in->ibase+in->icount))+return;++server=xics_get_irq_server(d->irq,irq_data_get_affinity_mask(d),0);+out_be32(ics_native_xive(in,vec),(server<<8)|DEFAULT_PRIORITY);+}++staticunsignedintics_native_startup(structirq_data*d)+{+#ifdef CONFIG_PCI_MSI+/*+*ThegenericMSIcodereturnswiththeinterruptdisabledonthe+*card,usingtheMSImaskbits.Firmwaredoesn'tappeartounmask+*atthatlevel,sowedoitherebyhand.+*/+if(irq_data_get_msi_desc(d))+pci_msi_unmask_irq(d);+#endif++/* unmask it */+ics_native_unmask_irq(d);+return0;+}++staticvoidics_native_do_mask(structics_native*in,unsignedintvec)+{+out_be32(ics_native_xive(in,vec),0xff);+}++staticvoidics_native_mask_irq(structirq_data*d)+{+unsignedintvec=(unsignedint)irqd_to_hwirq(d);+structics*ics=irq_data_get_irq_chip_data(d);+structics_native*in=to_ics_native(ics);++pr_devel("ics-native: mask virq %d [hw 0x%x]\n",d->irq,vec);++if(vec<in->ibase||vec>=(in->ibase+in->icount))+return;+ics_native_do_mask(in,vec);+}++staticintics_native_set_affinity(structirq_data*d,+conststructcpumask*cpumask,+boolforce)+{+unsignedintvec=(unsignedint)irqd_to_hwirq(d);+structics*ics=irq_data_get_irq_chip_data(d);+structics_native*in=to_ics_native(ics);+intserver;+u32xive;++if(vec<in->ibase||vec>=(in->ibase+in->icount))+return-EINVAL;++server=xics_get_irq_server(d->irq,cpumask,1);+if(server==-1){+pr_warn("%s: No online cpus in the mask %*pb for irq %d\n",+__func__,cpumask_pr_args(cpumask),d->irq);+return-1;+}++xive=in_be32(ics_native_xive(in,vec));+xive=(xive&0xff)|(server<<8);+out_be32(ics_native_xive(in,vec),xive);++returnIRQ_SET_MASK_OK;+}++staticstructirq_chipics_native_irq_chip={+.name="ICS",+.irq_startup=ics_native_startup,+.irq_mask=ics_native_mask_irq,+.irq_unmask=ics_native_unmask_irq,+.irq_eoi=NULL,/* Patched at init time */+.irq_set_affinity=ics_native_set_affinity,+.irq_set_type=xics_set_irq_type,+.irq_retrigger=xics_retrigger,+};++staticintics_native_map(structics*ics,unsignedintvirq)+{+unsignedintvec=(unsignedint)virq_to_hw(virq);+structics_native*in=to_ics_native(ics);++pr_devel("%s: vec=0x%x\n",__func__,vec);++if(vec<in->ibase||vec>=(in->ibase+in->icount))+return-EINVAL;++irq_set_chip_and_handler(virq,&ics_native_irq_chip,handle_fasteoi_irq);+irq_set_chip_data(virq,ics);++return0;+}++staticvoidics_native_mask_unknown(structics*ics,unsignedlongvec)+{+structics_native*in=to_ics_native(ics);++if(vec<in->ibase||vec>=(in->ibase+in->icount))+return;++ics_native_do_mask(in,vec);+}++staticlongics_native_get_server(structics*ics,unsignedlongvec)+{+structics_native*in=to_ics_native(ics);+u32xive;++if(vec<in->ibase||vec>=(in->ibase+in->icount))+return-EINVAL;++xive=in_be32(ics_native_xive(in,vec));+return(xive>>8)&0xfff;+}++staticintics_native_host_match(structics*ics,structdevice_node*node)+{+structics_native*in=to_ics_native(ics);++returnin->node==node;+}++staticstructicsics_native_template={+.map=ics_native_map,+.mask_unknown=ics_native_mask_unknown,+.get_server=ics_native_get_server,+.host_match=ics_native_host_match,+};++staticint__initics_native_add_one(structdevice_node*np)+{+structics_native*ics;+u32ranges[2];+intrc,count;++ics=kzalloc(sizeof(structics_native),GFP_KERNEL);+if(!ics)+return-ENOMEM;+ics->node=of_node_get(np);+memcpy(&ics->ics,&ics_native_template,sizeof(structics));++ics->base=of_iomap(np,0);+if(!ics->base){+pr_err("Failed to map %pOFP\n",np);+rc=-ENOMEM;+gotofail;+}++count=of_property_count_u32_elems(np,"interrupt-ranges");+if(count<2||count&1){+pr_err("Failed to read interrupt-ranges of %pOFP\n",np);+rc=-EINVAL;+gotofail;+}+if(count>2){+pr_warn("ICS %pOFP has %d ranges, only one supported\n",+np,count>>1);+}+rc=of_property_read_u32_array(np,"interrupt-ranges",+ranges,2);+if(rc){+pr_err("Failed to read interrupt-ranges of %pOFP\n",np);+gotofail;+}+ics->ibase=ranges[0];+ics->icount=ranges[1];++pr_info("ICS native initialized for sources %d..%d\n",+ics->ibase,ics->ibase+ics->icount-1);++/* Register ourselves */+xics_register_ics(&ics->ics);++return0;+fail:+of_node_put(ics->node);+kfree(ics);+returnrc;+}++int__initics_native_init(void)+{+structdevice_node*ics;+boolfound_one=false;++/* We need to patch our irq chip's EOI to point to the+*rightICP+*/+ics_native_irq_chip.irq_eoi=icp_ops->eoi;++/* Find native ICS in the device-tree */+for_each_compatible_node(ics,NULL,"openpower,xics-sources"){+if(ics_native_add_one(ics)==0)+found_one=true;+}++if(found_one)+pr_info("ICS native backend registered\n");++returnfound_one?0:-ENODEV;+}
From: Paul Mackerras <hidden> Date: 2021-06-14 23:10:18
This ensures that we don't get a decrementer interrupt arriving before
we have set up a handler for it.
Signed-off-by: Paul Mackerras <redacted>
---
arch/powerpc/boot/microwatt.c | 1 +
1 file changed, 1 insertion(+)
@@ -12,6 +12,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5){unsignedlongheapsize=16*1024*1024-(unsignedlong)_end;+__asm__volatile("mtmsrd %0,1"::"r"(0));simple_alloc_init(_end,heapsize,32,64);fdt_init(_dtb_start);serial_console_init();
From: Nicholas Piggin <npiggin@gmail.com> Date: 2021-06-15 01:13:00
Excerpts from Paul Mackerras's message of June 15, 2021 8:59 am:
Microwatt currently doesn't implement hypervisor mode and therefore
doesn't implement the partition table. It does implement the process
table and radix page table walks.
This adds code to write the base address of the process table to the
PRTBL SPR,
Is there a particular reason you haven't called it PRTCR or similar to
match PTCR?
which has been assigned SPR 720 for now, as that is in the
range of SPR numbers assigned for experimental use. PRTBL is only
written when we have neither the FW_FEATURE_LPAR feature nor the
CPU_FTR_HVMODE feature.
Seems like reasonable architecture for a non-HV platform.
Could it have a comment to say it's not architected, and a microwatt
ifdef until that changes?
The patch also does avoid touching LPCR or initing amor...
Thanks,
Nick
@@ -12,6 +12,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5){unsignedlongheapsize=16*1024*1024-(unsignedlong)_end;+__asm__volatile("mtmsrd %0,1"::"r"(0));simple_alloc_init(_end,heapsize,32,64);fdt_init(_dtb_start);serial_console_init();
From: Nicholas Piggin <npiggin@gmail.com> Date: 2021-06-15 01:40:58
Excerpts from Paul Mackerras's message of June 15, 2021 9:02 am:
quoted hunk
This is accessed using the DARN instruction and should probably be
done more generically.
Signed-off-by: Paul Mackerras <redacted>
---
arch/powerpc/include/asm/archrandom.h | 12 +++++-
arch/powerpc/platforms/microwatt/Kconfig | 1 +
arch/powerpc/platforms/microwatt/Makefile | 2 +-
arch/powerpc/platforms/microwatt/rng.c | 48 +++++++++++++++++++++++
4 files changed, 61 insertions(+), 2 deletions(-)
create mode 100644 arch/powerpc/platforms/microwatt/rng.c
I would be happier if you didn't change this (or at least put it in its
own patch explaining why it's not going to slow down other platforms).
I'm assuming the main problem you have is seeding the rngs at boot? It
should be enough to have ppc_md.get_random_seed for that.
(BTW I wonder should lib/random32.c be changed to call
arch_get_random_seed_long() for seeding)
quoted hunk
static inline bool __must_check arch_get_random_seed_long(unsigned long *v)
@@ -0,0 +1,48 @@+// SPDX-License-Identifier: GPL-2.0-or-later+/*+*Derivedfromarch/powerpc/platforms/powernv/rng.c,whichis:+*Copyright2013,MichaelEllerman,IBMCorporation.+*/++#define pr_fmt(fmt) "microwatt-rng: " fmt++#include<linux/kernel.h>+#include<linux/smp.h>+#include<asm/archrandom.h>+#include<asm/cputable.h>+#include<asm/machdep.h>++#define DARN_ERR 0xFFFFFFFFFFFFFFFFul++intmicrowatt_get_random_darn(unsignedlong*v)+{+unsignedlongval;++/* Using DARN with L=1 - 64-bit conditioned random number */+asmvolatile(PPC_DARN(%0,1):"=r"(val));++if(val==DARN_ERR)+return0;++*v=val;++return1;+}++static__initintrng_init(void)+{+unsignedlongval;+inti;++for(i=0;i<10;i++){+if(microwatt_get_random_darn(&val)){+ppc_md.get_random_seed=microwatt_get_random_darn;+return0;+}+}++pr_warn("Unable to use DARN for get_random_seed()\n");++return-EIO;+}+machine_subsys_initcall(,rng_init);
From: Michael Ellerman <mpe@ellerman.id.au> Date: 2021-06-16 13:16:32
Nicholas Piggin [off-list ref] writes:
Excerpts from Paul Mackerras's message of June 15, 2021 9:02 am:
quoted
This is accessed using the DARN instruction and should probably be
done more generically.
Signed-off-by: Paul Mackerras <redacted>
---
arch/powerpc/include/asm/archrandom.h | 12 +++++-
arch/powerpc/platforms/microwatt/Kconfig | 1 +
arch/powerpc/platforms/microwatt/Makefile | 2 +-
arch/powerpc/platforms/microwatt/rng.c | 48 +++++++++++++++++++++++
4 files changed, 61 insertions(+), 2 deletions(-)
create mode 100644 arch/powerpc/platforms/microwatt/rng.c
I would be happier if you didn't change this (or at least put it in its
own patch explaining why it's not going to slow down other platforms).
It would essentially be a revert of 01c9348c7620 ("powerpc: Use hardware
RNG for arch_get_random_seed_* not arch_get_random_*")
Which would be ironic :)
cheers
From: Paul Mackerras <hidden> Date: 2021-06-16 22:22:53
On Wed, Jun 16, 2021 at 11:16:02PM +1000, Michael Ellerman wrote:
Nicholas Piggin [off-list ref] writes:
quoted
I would be happier if you didn't change this (or at least put it in its
own patch explaining why it's not going to slow down other platforms).
It would essentially be a revert of 01c9348c7620 ("powerpc: Use hardware
RNG for arch_get_random_seed_* not arch_get_random_*")
Which would be ironic :)
You expect me to remember things I did 6 years ago? :)
I'll take this part out. My thinking originally was that since darn
on Microwatt is a single-cycle instruction, it would be faster to use
darn every time rather than run a software PRNG seeded from darn.
It's not critical though.
Paul.
Why do you need this / want this, since you have FP hardware?
The FPU is optional, and doesn't fit in the smaller (-35T) version of
the Artix-7 that is readily available.
I should mention this in the commit message.
Paul.
From: Nicholas Piggin <npiggin@gmail.com> Date: 2021-06-17 01:41:18
Excerpts from Segher Boessenkool's message of June 17, 2021 9:37 am:
On Tue, Jun 15, 2021 at 09:05:27AM +1000, Paul Mackerras wrote:
quoted
This ensures that we don't get a decrementer interrupt arriving before
we have set up a handler for it.
Maybe add a comment saying this is setting MSR[EE]=0 for that? Or do
other bits here matter as well?
Hmm, it actually clears MSR[RI] as well.
__hard_irq_disable() is what we want here, unless the MSR[RI] clearing
is required as well, in which case there is __hard_EE_RI_disable().
Thanks,
Nick
From: Michael Ellerman <mpe@ellerman.id.au> Date: 2021-06-17 04:07:08
Nicholas Piggin [off-list ref] writes:
Excerpts from Segher Boessenkool's message of June 17, 2021 9:37 am:
quoted
On Tue, Jun 15, 2021 at 09:05:27AM +1000, Paul Mackerras wrote:
quoted
This ensures that we don't get a decrementer interrupt arriving before
we have set up a handler for it.
Maybe add a comment saying this is setting MSR[EE]=0 for that? Or do
other bits here matter as well?
Hmm, it actually clears MSR[RI] as well.
__hard_irq_disable() is what we want here, unless the MSR[RI] clearing
is required as well, in which case there is __hard_EE_RI_disable().
But neither of those exist in the boot wrapper (yet).
cheers
I guess you just copied that from skiboot.
The binding says it's required, but AFAICS the kernel doesn't use it.
And isa = 0 mean ISA_BASE, according to the skiboot source.
On Thu, Jun 17, 2021 at 11:40:23AM +1000, Nicholas Piggin wrote:
Excerpts from Segher Boessenkool's message of June 17, 2021 9:37 am:
quoted
On Tue, Jun 15, 2021 at 09:05:27AM +1000, Paul Mackerras wrote:
quoted
This ensures that we don't get a decrementer interrupt arriving before
we have set up a handler for it.
Maybe add a comment saying this is setting MSR[EE]=0 for that? Or do
other bits here matter as well?
Hmm, it actually clears MSR[RI] as well.
__hard_irq_disable() is what we want here, unless the MSR[RI] clearing
is required as well, in which case there is __hard_EE_RI_disable().
I don't think it matters if MSR[RI] is set or not here, nothing will try
to recover from an actual reboot I hope :-)
Segher
That's for a machine with hypervisor mode - if I make it 6 here, then
the kernel prints a message about "HV feature passed to guest" and
then another about "missing dependency" and ends up not enabling the
feature.
Note that microwatt usually has MSR[HV] = 0 (you can set it to 1 but
it doesn't do anything). Arguably it should force it to 1 always, but
if I do that, then the kernel starts trying to execute hrfid
instructions, which microwatt doesn't have (for example in
masked_Hinterrupt).
I guess you just copied that from skiboot.
The binding says it's required, but AFAICS the kernel doesn't use it.
And isa = 0 mean ISA_BASE, according to the skiboot source.
I changed it to 2050 since true little-endian mode was introduced for
POWER6.