Hello tech@ list! With this diff, it becomes possible to build macppc kernel with base-clang. The default compiler for macppc is base-gcc.
rgc <rgci...@disroot.org> mailed the ppc@ list to report problems with clang kernel, and got a working kernel with clang -Oz (to stop clang inlining some functions in openfirm.c) and my modified ppc_mftb(). In this diff, I use __attribute__((noinline)) so I don't need -Oz. I built my kernel with # clang CC=clang COMPILER_VERSION=clang because someone has already prepared the Makefile for macppc to pass different flags when COMPILER_VERSION is clang. I booted my clang kernel and it worked well enough to build another kernel with the same diff, but with gcc. In the second half of the diff, I change ppc_mftb(), because "mftb %0+1" doesn't always work in clang. For example, clang can put "=r"(tb) in register pair r27:r29, but 27+1 isn't 29. I don't know the syntax for the 2nd register of a pair, so I instead split "=r"(tb) into 2 variables. We use ppc_mftb() as timecounter. (gcc and clang emit different machine code for "mftbu" and "mftb", but both forms work for me. "objdump -dlr obj/clock.o" ppc_mftb() would show "mftb" from gcc or "mfspr" from clang. Power ISA 2.03 says that mfspr time base can't work on 601 or POWER3. A few Old World Mac models had PowerPC 601, but we only run on New World models.) Is the ppc_mftb() change by itself OK to commit? I am less sure about the first half of the diff, the noinline part. I don't like the design of this code. These functions call ofw_stack() like noinline int OF_peer(int phandle) { static struct ... args = ...; ofw_stack(); args.phandle = phandle; if (openfirmware(&args) == -1) return 0; return args.sibling; } but ofw_stack() is assembly code that changes the cpu's msr, moves the stack pointer %r1 to a different stack, copies the stack frame of OF_peer() to this new stack, and hijacks the saved return address so that, when OF_peer() returns, it switches back to the old stack and restores the msr. If clang inlines a function like OF_peer(), it no longer has its own stack frame, so the return-hijack stops working. We don't have retguard on powerpc, but if OF_peer() would use retguard to protect its return address, then the return-hijack might become impossible. Perhaps the code should look like msr = do_something_to_msr(); args.phandle = phandle; if (openfirmware(&args) == -1) ret = 0; else ret = args.sibling; ppc_mtmsr(msr); return ret; and openfirmware() should do the stack-switching, but I have not yet tried to make such a change. (I suspect that we need the msr to disable interrupts and protect the static args.) After the diff, I put my dmesg; my iMac G3 isn't GENERIC.MP and doesn't have radeondrm. --George Index: arch/macppc/macppc/openfirm.c =================================================================== RCS file: /cvs/src/sys/arch/macppc/macppc/openfirm.c,v retrieving revision 1.12 diff -u -p -r1.12 openfirm.c --- arch/macppc/macppc/openfirm.c 3 Sep 2019 17:51:52 -0000 1.12 +++ arch/macppc/macppc/openfirm.c 11 Mar 2020 22:21:50 -0000 @@ -38,10 +38,13 @@ #include <dev/ofw/openfirm.h> +/* Callers of ofw_stack() must not be inline. */ +#define noinline __attribute__((noinline)) + extern void ofw_stack(void); extern void ofbcopy(const void *, void *, size_t); -int +noinline int OF_peer(int phandle) { static struct { @@ -63,7 +66,7 @@ OF_peer(int phandle) return args.sibling; } -int +noinline int OF_child(int phandle) { static struct { @@ -85,7 +88,7 @@ OF_child(int phandle) return args.child; } -int +noinline int OF_parent(int phandle) { static struct { @@ -107,7 +110,7 @@ OF_parent(int phandle) return args.parent; } -int +noinline int OF_getproplen(int handle, char *prop) { static struct { @@ -131,7 +134,7 @@ OF_getproplen(int handle, char *prop) return args.size; } -int +noinline int OF_getprop(int handle, char *prop, void *buf, int buflen) { static struct { @@ -163,7 +166,7 @@ OF_getprop(int handle, char *prop, void return args.size; } -int +noinline int OF_setprop(int handle, char *prop, const void *buf, int buflen) { static struct { @@ -194,7 +197,7 @@ OF_setprop(int handle, char *prop, const return args.size; } -int +noinline int OF_nextprop(int handle, char *prop, void *nextprop) { static struct { @@ -221,7 +224,7 @@ OF_nextprop(int handle, char *prop, void return args.flag; } -int +noinline int OF_interpret(char *cmd, int nreturns, ...) { va_list ap; @@ -258,7 +261,7 @@ OF_interpret(char *cmd, int nreturns, .. } -int +noinline int OF_finddevice(char *name) { static struct { @@ -281,7 +284,7 @@ OF_finddevice(char *name) } static void OF_rboot(char *bootspec); -static void +static noinline void OF_rboot(char *bootspec) { static struct { @@ -312,7 +315,7 @@ OF_boot(char *bootspec) while(1); } -void +noinline void OF_exit(void) { static struct { @@ -331,7 +334,7 @@ OF_exit(void) while (1); } -void +noinline void OF_quiesce(void) { static struct { Index: arch/powerpc/include/cpu.h =================================================================== RCS file: /cvs/src/sys/arch/powerpc/include/cpu.h,v retrieving revision 1.65 diff -u -p -r1.65 cpu.h --- arch/powerpc/include/cpu.h 23 Mar 2019 05:27:53 -0000 1.65 +++ arch/powerpc/include/cpu.h 11 Mar 2020 22:21:50 -0000 @@ -333,12 +333,11 @@ ppc_mftbl (void) static __inline u_int64_t ppc_mftb(void) { - u_long scratch; - u_int64_t tb; + u_long high, low, scratch; - __asm volatile ("1: mftbu %0; mftb %0+1; mftbu %1;" - " cmpw 0,%0,%1; bne 1b" : "=r"(tb), "=r"(scratch)); - return tb; + __asm volatile ("1: mftbu %0; mftb %1; mftbu %2;" + " cmpw 0,%0,%2; bne 1b" : "=r"(high), "=r"(low), "=r"(scratch)); + return ((u_int64_t)high << 32) | low; } static __inline void [ using 1137300 bytes of bsd ELF symbol table ] console out [ATY,Rage128k] console in [keyboard], using USB : memaddr 94000000, size 4000000 : consaddr 94008000 : ioaddr 90020000, size 20000: width 800 linebytes 1024 height 600 depth 8 Copyright (c) 1982, 1986, 1989, 1991, 1993 The Regents of the University of California. All rights reserved. Copyright (c) 1995-2020 OpenBSD. All rights reserved. https://www.OpenBSD.org OpenBSD 6.6-current (GENERIC) #0: Fri Mar 13 21:18:43 EDT 2020 r...@fishport.my.domain:/sys/arch/macppc/compile/GENERIC real mem = 536870912 (512MB) avail mem = 503971840 (480MB) mpath0 at root scsibus0 at mpath0: 256 targets mainbus0 at root: model PowerMac2,1 cpu0 at mainbus0: 750 (Revision 0x202): 400 MHz: 512KB backside cache mem0 at mainbus0 spdmem0 at mem0: 256MB SDRAM non-parity PC133CL2 spdmem1 at mem0: 256MB SDRAM non-parity PC133CL2 memc0 at mainbus0: uni-n rev 0x3 kiic0 at memc0 offset 0xf8001000 iic0 at kiic0 mpcpcibr0 at mainbus0 pci: uni-north pci0 at mpcpcibr0 bus 0 pchb0 at pci0 dev 11 function 0 "Apple Uni-N AGP" rev 0x00 agp at pchb0 not configured vgafb0 at pci0 dev 16 function 0 "ATI Rage 128" rev 0x00, mmio wsdisplay0 at vgafb0 mux 1: console (std, vt100 emulation) wsdisplay0: screen 1-5 added (std, vt100 emulation) mpcpcibr1 at mainbus0 pci: uni-north pci1 at mpcpcibr1 bus 0 macobio0 at pci1 dev 23 function 0 "Apple Keylargo" rev 0x02 openpic0 at macobio0 offset 0x40000: version 0x4614 feature 3f0302 LE macgpio0 at macobio0 offset 0x50 macgpio1 at macgpio0: irq 47 pgs0 at macgpio0: irq 55 "escc-legacy" at macobio0 offset 0x12000 not configured zs0 at macobio0 offset 0x13000: irq 22,50 zstty0 at zs0 channel 0 zstty1 at zs0 channel 1 awacs0 at macobio0 offset 0x14000: irq 24,9,10 speaker audio0 at awacs0 "timer" at macobio0 offset 0x15000 not configured adb0 at macobio0 offset 0x16000 apm0 at adb0: battery flags 0x9, 0% charged kiic1 at macobio0 offset 0x18000 iic1 at kiic1 wdc0 at macobio0 offset 0x1f000 irq 19: DMA wd0 at wdc0 channel 0 drive 0: <Maxtor 91020U3> wd0: 16-sector PIO, LBA, 9736MB, 19941264 sectors atapiscsi0 at wdc0 channel 0 drive 1 scsibus1 at atapiscsi0: 2 targets cd0 at scsibus1 targ 0 lun 0: <MATSHITA, DVD-ROM SR-8184, AA27> removable wd0(wdc0:0:0): using PIO mode 4, DMA mode 2, Ultra-DMA mode 2 cd0(wdc0:0:1): using PIO mode 4, DMA mode 2, Ultra-DMA mode 2 wdc1 at macobio0 offset 0x20000 irq 20: DMA wdc2 at macobio0 offset 0x21000 irq 21: DMA "TI TSB12LV23 FireWire" rev 0x00 at pci1 dev 18 function 0 not configured ohci0 at pci1 dev 24 function 0 "Apple USB" rev 0x00: irq 27, version 1.0 ohci1 at pci1 dev 25 function 0 "Apple USB" rev 0x00: irq 28, version 1.0 usb0 at ohci0: USB revision 1.0 uhub0 at usb0 configuration 1 interface 0 "Apple OHCI root hub" rev 1.00/1.00 addr 1 usb1 at ohci1: USB revision 1.0 uhub1 at usb1 configuration 1 interface 0 "Apple OHCI root hub" rev 1.00/1.00 addr 1 mpcpcibr2 at mainbus0 pci: uni-north pci2 at mpcpcibr2 bus 0 gem0 at pci2 dev 15 function 0 "Apple Uni-N GMAC" rev 0x00: irq 41, address 00:0a:27:b1:66:00 bmtphy0 at gem0 phy 0: BCM5201 10/100 PHY, rev. 2 uhidev0 at uhub0 port 1 configuration 1 interface 0 "Logitech USB-PS/2 Optical Mouse" rev 2.00/11.10 addr 2 uhidev0: iclass 3/1 ums0 at uhidev0: 3 buttons, Z dir wsmouse0 at ums0 mux 0 uhidev1 at uhub1 port 1 configuration 1 interface 0 "CHESEN USB Keyboard" rev 1.10/1.10 addr 2 uhidev1: iclass 3/1 ukbd0 at uhidev1: 8 variable keys, 6 key codes, country code 33 wskbd0 at ukbd0: console keyboard, using wsdisplay0 uhidev2 at uhub1 port 1 configuration 1 interface 1 "CHESEN USB Keyboard" rev 1.10/1.10 addr 2 uhidev2: iclass 3/0, 3 report ids uhid0 at uhidev2 reportid 2: input=1, output=0, feature=0 uhid1 at uhidev2 reportid 3: input=3, output=0, feature=0 vscsi0 at root scsibus2 at vscsi0: 256 targets softraid0 at root scsibus3 at softraid0: 256 targets bootpath: /pci@f2000000/mac-io@17/ata-4@1f000/disk@0:/bsd root on wd0a (c3db149b5ec148e9.a) swap on wd0b dump on wd0b