Index: head/stand/powerpc/ofw/Makefile =================================================================== --- head/stand/powerpc/ofw/Makefile (revision 350484) +++ head/stand/powerpc/ofw/Makefile (revision 350485) @@ -1,48 +1,53 @@ # $FreeBSD$ LOADER_CD9660_SUPPORT?= yes LOADER_EXT2FS_SUPPORT?= no LOADER_MSDOS_SUPPORT?= no LOADER_UFS_SUPPORT?= yes LOADER_NET_SUPPORT?= yes LOADER_NFS_SUPPORT?= yes LOADER_TFTP_SUPPORT?= no LOADER_GZIP_SUPPORT?= yes LOADER_BZIP2_SUPPORT?= no .include PROG= loader NEWVERSWHAT= "Open Firmware loader" ${MACHINE_ARCH} INSTALLFLAGS= -b # Architecture-specific loader code SRCS= conf.c vers.c main.c elf_freebsd.c ppc64_elf_freebsd.c start.c SRCS+= ucmpdi2.c .include "${BOOTSRC}/fdt.mk" .if ${MK_FDT} == "yes" SRCS+= ofwfdt.c .endif +.if ${MACHINE_ARCH} == "powerpc64" +SRCS+= cas.c +CFLAGS+= -DCAS +.endif + HELP_FILES= ${FDTSRC}/help.fdt # Always add MI sources .include "${BOOTSRC}/loader.mk" .PATH: ${SYSDIR}/libkern # load address. set in linker script RELOC?= 0x1C00000 -CFLAGS+= -DRELOC=${RELOC} +CFLAGS+= -DRELOC=${RELOC} -g LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.powerpc # Open Firmware standalone support library LIBOFW= ${BOOTOBJ}/ofw/libofw/libofw.a CFLAGS+= -I${BOOTSRC}/ofw/libofw DPADD= ${LDR_INTERP} ${LIBOFW} ${LIBFDT} ${LIBSA} LDADD= ${LDR_INTERP} ${LIBOFW} ${LIBFDT} ${LIBSA} .include Index: head/stand/powerpc/ofw/cas.c =================================================================== --- head/stand/powerpc/ofw/cas.c (nonexistent) +++ head/stand/powerpc/ofw/cas.c (revision 350485) @@ -0,0 +1,225 @@ +/*- + * Copyright (c) 2019 Leandro Lupori + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +/* PVR */ +#define PVR_VER_P8E 0x004b0000 +#define PVR_VER_P8NVL 0x004c0000 +#define PVR_VER_P8 0x004d0000 +#define PVR_VER_P9 0x004e0000 +#define PVR_VER_MASK 0xffff0000 + +/* loader version of kernel's CPU_MAXSIZE */ +#define MAX_CPUS ((uint32_t)256u) + +/* Option Vectors' settings */ + +/* length of ignored OV */ +#define OV_IGN_LEN 0 + +/* byte 1 (of any OV) */ +#define OV_IGN 0x80 + +/* Option Vector 5 */ + +/* byte 2 */ +#define OV5_LPAR 0x80 +#define OV5_SPLPAR 0x40 +#define OV5_DRMEM 0x20 +#define OV5_LP 0x10 +#define OV5_ALPHA_PART 0x08 +#define OV5_DMA_DELAY 0x04 +#define OV5_DONATE_CPU 0x02 +#define OV5_MSI 0x01 + +/* 9-12: max cpus */ +#define OV5_MAX_CPUS(n) ((MAX_CPUS >> (3*8 - (n)*8)) & 0xff) + +/* 13-14: LoPAPR Level */ +#define LOPAPR_LEVEL 0x0101 /* 1.1 */ +#define OV5_LOPAPR_LEVEL(n) ((LOPAPR_LEVEL >> (8 - (n)*8)) & 0xff) + +/* byte 17: Platform Facilities */ +#define OV5_RNG 0x80 +#define OV5_COMP_ENG 0x40 +#define OV5_ENC_ENG 0x20 + +/* byte 21: Sub-Processors */ +#define OV5_NO_SUBPROCS 0 +#define OV5_SUBPROCS 1 + +/* byte 23: interrupt controller */ +#define OV5_INTC_XICS 0 + +/* byte 24: MMU */ +#define OV5_MMU_HPT 0 + +/* byte 25: HPT MMU Extensions */ +#define OV5_HPT_EXT_NONE 0 + +/* byte 26: Radix MMU Extensions */ +#define OV5_RPT_EXT_NONE 0 + + +struct pvr { + uint32_t mask; + uint32_t val; +}; + +struct opt_vec_ignore { + char data[2]; +} __packed; + +struct opt_vec4 { + char data[3]; +} __packed; + +struct opt_vec5 { + char data[27]; +} __packed; + +static struct ibm_arch_vec { + struct pvr pvr_list[5]; + uint8_t num_opts; + struct opt_vec_ignore vec1; + struct opt_vec_ignore vec2; + struct opt_vec_ignore vec3; + struct opt_vec4 vec4; + struct opt_vec5 vec5; +} __packed ibm_arch_vec = { + /* pvr_list */ { + { PVR_VER_MASK, PVR_VER_P8 }, /* POWER8 */ + { PVR_VER_MASK, PVR_VER_P8E }, /* POWER8E */ + { PVR_VER_MASK, PVR_VER_P8NVL }, /* POWER8NVL */ + { PVR_VER_MASK, PVR_VER_P9 }, /* POWER9 */ + { 0, 0xffffffffu } /* terminator */ + }, + 4, /* num_opts (4 actually means 5 option vectors) */ + { OV_IGN_LEN, OV_IGN }, /* OV1 */ + { OV_IGN_LEN, OV_IGN }, /* OV2 */ + { OV_IGN_LEN, OV_IGN }, /* OV3 */ + /* OV4 (can't be ignored) */ { + sizeof(struct opt_vec4) - 2, /* length (n-2) */ + 0, + 10 /* Minimum VP entitled capacity percentage * 100 + * (if absent assume 10%) */ + }, + /* OV5 */ { + sizeof(struct opt_vec5) - 2, /* length (n-2) */ + 0, /* don't ignore */ + OV5_LPAR | OV5_SPLPAR | OV5_LP | OV5_MSI, + 0, + 0, /* Cooperative Memory Over-commitment */ + 0, /* Associativity Information Option */ + 0, /* Binary Option Controls */ + 0, /* Reserved */ + 0, /* Reserved */ + OV5_MAX_CPUS(0), + OV5_MAX_CPUS(1), /* 10 */ + OV5_MAX_CPUS(2), + OV5_MAX_CPUS(3), + OV5_LOPAPR_LEVEL(0), + OV5_LOPAPR_LEVEL(1), + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Platform Facilities */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ /* 20 */ + OV5_NO_SUBPROCS, + 0, /* DRMEM_V2 */ + OV5_INTC_XICS, + OV5_MMU_HPT, + OV5_HPT_EXT_NONE, + OV5_RPT_EXT_NONE + } +}; + +static __inline register_t +mfpvr(void) +{ + register_t value; + + __asm __volatile ("mfpvr %0" : "=r"(value)); + + return (value); +} + +static __inline int +ppc64_hv(void) +{ + int hv; + + /* PSL_HV is bit 3 of 64-bit MSR */ + __asm __volatile ("mfmsr %0\n\t" + "rldicl %0,%0,4,63" : "=r"(hv)); + + return (hv); +} + +int +ppc64_cas(void) +{ + int rc; + ihandle_t ihandle; + cell_t err; + + /* Skip CAS when running on PowerNV */ + if (!ppc64_hv()) + return (0); + + /* Perform CAS only for POWER8 and later cores */ + switch (mfpvr() & PVR_VER_MASK) { + case PVR_VER_P8: + case PVR_VER_P8E: + case PVR_VER_P8NVL: + case PVR_VER_P9: + break; + default: + return (0); + } + + ihandle = OF_open("/"); + if (ihandle == -1) { + printf("cas: failed to open / node\n"); + return (-1); + } + + if (rc = OF_call_method("ibm,client-architecture-support", + ihandle, 1, 1, &ibm_arch_vec, &err)) + printf("cas: failed to call CAS method\n"); + else if (err) { + printf("cas: error: 0x%08lX\n", err); + rc = -1; + } + + OF_close(ihandle); + return (rc); +} Property changes on: head/stand/powerpc/ofw/cas.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/stand/powerpc/ofw/main.c =================================================================== --- head/stand/powerpc/ofw/main.c (revision 350484) +++ head/stand/powerpc/ofw/main.c (revision 350485) @@ -1,199 +1,219 @@ /*- * Copyright (c) 2000 Benno Rice * Copyright (c) 2000 Stephane Potvin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include "openfirm.h" #include "libofw.h" #include "bootstrap.h" #include struct arch_switch archsw; /* MI/MD interface boundary */ extern char end[]; uint32_t acells, scells; static char bootargs[128]; #define HEAP_SIZE 0x800000 static char heap[HEAP_SIZE]; // In BSS, so uses no space #define OF_puts(fd, text) OF_write(fd, text, strlen(text)) static __inline register_t mfmsr(void) { register_t value; __asm __volatile ("mfmsr %0" : "=r"(value)); return (value); } void init_heap(void) { bzero(heap, HEAP_SIZE); setheap(heap, (void *)((int)heap + HEAP_SIZE)); } uint64_t memsize(void) { phandle_t memoryp; cell_t reg[24]; int i, sz; uint64_t memsz; memsz = 0; memoryp = OF_instance_to_package(memory); sz = OF_getprop(memoryp, "reg", ®, sizeof(reg)); sz /= sizeof(reg[0]); for (i = 0; i < sz; i += (acells + scells)) { if (scells > 1) memsz += (uint64_t)reg[i + acells] << 32; memsz += reg[i + acells + scells - 1]; } return (memsz); } +#ifdef CAS +extern int ppc64_cas(void); + +static int +ppc64_autoload(void) +{ + const char *cas; + + if ((cas = getenv("cas")) && cas[0] == '1') + if (ppc64_cas() != 0) + return (-1); + return (ofw_autoload()); +} +#endif + int main(int (*openfirm)(void *)) { phandle_t root; int i; char bootpath[64]; char *ch; int bargc; char **bargv; /* * Initialise the Open Firmware routines by giving them the entry point. */ OF_init(openfirm); root = OF_finddevice("/"); scells = acells = 1; OF_getprop(root, "#address-cells", &acells, sizeof(acells)); OF_getprop(root, "#size-cells", &scells, sizeof(scells)); /* * Initialise the heap as early as possible. Once this is done, * alloc() is usable. The stack is buried inside us, so this is * safe. */ init_heap(); /* * Set up console. */ cons_probe(); /* * March through the device switch probing for things. */ for (i = 0; devsw[i] != NULL; i++) if (devsw[i]->dv_init != NULL) (devsw[i]->dv_init)(); printf("\n%s", bootprog_info); printf("Memory: %lldKB\n", memsize() / 1024); OF_getprop(chosen, "bootpath", bootpath, 64); ch = strchr(bootpath, ':'); *ch = '\0'; printf("Booted from: %s\n", bootpath); printf("\n"); /* * Only parse the first bootarg if present. It should * be simple to handle extra arguments */ OF_getprop(chosen, "bootargs", bootargs, sizeof(bootargs)); bargc = 0; parse(&bargc, &bargv, bootargs); if (bargc == 1) env_setenv("currdev", EV_VOLATILE, bargv[0], ofw_setcurrdev, env_nounset); else env_setenv("currdev", EV_VOLATILE, bootpath, ofw_setcurrdev, env_nounset); env_setenv("loaddev", EV_VOLATILE, bootpath, env_noset, env_nounset); setenv("LINES", "24", 1); /* optional */ /* * On non-Apple hardware, where it works reliably, pass flattened * device trees to the kernel by default instead of OF CI pointers. * Apple hardware is the only virtual-mode OF implementation in * existence, so far as I am aware, so use that as a flag. */ if (!(mfmsr() & PSL_DR)) setenv("usefdt", "1", 1); archsw.arch_getdev = ofw_getdev; archsw.arch_copyin = ofw_copyin; archsw.arch_copyout = ofw_copyout; archsw.arch_readin = ofw_readin; +#ifdef CAS + setenv("cas", "1", 0); + archsw.arch_autoload = ppc64_autoload; +#else archsw.arch_autoload = ofw_autoload; +#endif interact(); /* doesn't return */ OF_exit(); return 0; } COMMAND_SET(halt, "halt", "halt the system", command_halt); static int command_halt(int argc, char *argv[]) { OF_exit(); return (CMD_OK); } COMMAND_SET(memmap, "memmap", "print memory map", command_memmap); int command_memmap(int argc, char **argv) { ofw_memmap(acells); return (CMD_OK); }