diff --git a/libexec/rtld-elf/powerpc64/reloc.c b/libexec/rtld-elf/powerpc64/reloc.c index 0c75a2a9a1f6..c428d6b2a975 100644 --- a/libexec/rtld-elf/powerpc64/reloc.c +++ b/libexec/rtld-elf/powerpc64/reloc.c @@ -338,26 +338,19 @@ static int reloc_plt_object(Obj_Entry *obj, const Elf_Rela *rela) { Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset); -#if !defined(_CALL_ELF) || _CALL_ELF == 1 - Elf_Addr *glink; -#endif long reloff; reloff = rela - obj->pltrela; + dbg(" reloc_plt_object: where=%p,reloff=%lx,glink=%#lx", (void *)where, + reloff, obj->glink); + #if !defined(_CALL_ELF) || _CALL_ELF == 1 - if (obj->priv == NULL) - obj->priv = xmalloc(obj->pltrelasize); - glink = obj->priv + reloff*sizeof(Elf_Addr)*2; - - dbg(" reloc_plt_object: where=%p,reloff=%lx,glink=%p", (void *)where, reloff, glink); - - memcpy(where, _rtld_bind_start, sizeof(struct funcdesc)); - ((struct funcdesc *)(where))->env = (Elf_Addr)glink; - *(glink++) = (Elf_Addr)obj; - *(glink++) = reloff*sizeof(Elf_Rela); + /* Glink code is 3 instructions after the first 32k, 2 before */ + *where = (Elf_Addr)obj->glink + 32 + + 8*((reloff < 0x8000) ? reloff : 0x8000) + + 12*((reloff < 0x8000) ? 0 : (reloff - 0x8000)); #else - dbg(" reloc_plt_object: where=%p,reloff=%lx,glink=%#lx", (void *)where, reloff, obj->glink); *where = (Elf_Addr)obj->glink + 4*reloff + 32; #endif @@ -416,13 +409,6 @@ reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockState *lockstate) target = (Elf_Addr)(defobj->relocbase + def->st_value); -#if 0 - /* PG XXX */ - dbg("\"%s\" in \"%s\" --> %p in \"%s\"", - defobj->strtab + def->st_name, basename(obj->path), - (void *)target, basename(defobj->path)); -#endif - if (def == &sym_zero) { /* Zero undefined weak symbols */ #if !defined(_CALL_ELF) || _CALL_ELF == 1 @@ -461,12 +447,28 @@ reloc_jmpslot(Elf_Addr *wherep, Elf_Addr target, const Obj_Entry *defobj, (void *)wherep, (void *)target, *(Elf_Addr *)target, (Elf_Addr)defobj->relocbase); + /* + * For the trampoline, the second two elements of the function + * descriptor are unused, so we are fine replacing those at any time + * with the real ones with no thread safety implications. However, we + * need to make sure the main entry point pointer ([0]) is seen to be + * modified *after* the second two elements. This can't be done in + * general, since there are no barriers in the reading code, but put in + * some isyncs to at least make it a little better. + */ memcpy(wherep, (void *)target, sizeof(struct funcdesc)); + wherep[2] = ((Elf_Addr *)target)[2]; + wherep[1] = ((Elf_Addr *)target)[1]; + __asm __volatile ("isync" : : : "memory"); + wherep[0] = ((Elf_Addr *)target)[0]; + __asm __volatile ("isync" : : : "memory"); + if (((struct funcdesc *)(wherep))->addr < (Elf_Addr)defobj->relocbase) { /* - * XXX: It is possible (e.g. LD_BIND_NOW) that the function + * It is possible (LD_BIND_NOW) that the function * descriptor we are copying has not yet been relocated. - * If this happens, fix it. + * If this happens, fix it. Don't worry about threading in + * this case since LD_BIND_NOW makes it irrelevant. */ ((struct funcdesc *)(wherep))->addr += @@ -481,8 +483,6 @@ reloc_jmpslot(Elf_Addr *wherep, Elf_Addr target, const Obj_Entry *defobj, *wherep = target; #endif - __asm __volatile("sync" ::: "memory"); - return (target); } @@ -506,7 +506,6 @@ reloc_gnu_ifunc(Obj_Entry *obj, int flags, void init_pltgot(Obj_Entry *obj) { -#if defined(_CALL_ELF) && _CALL_ELF == 2 Elf_Addr *pltcall; pltcall = obj->pltgot; @@ -515,10 +514,12 @@ init_pltgot(Obj_Entry *obj) return; } +#if defined(_CALL_ELF) && _CALL_ELF == 2 pltcall[0] = (Elf_Addr)&_rtld_bind_start; pltcall[1] = (Elf_Addr)obj; - - __asm __volatile("sync" ::: "memory"); +#else + memcpy(pltcall, _rtld_bind_start, sizeof(struct funcdesc)); + pltcall[2] = (Elf_Addr)obj; #endif } diff --git a/libexec/rtld-elf/powerpc64/rtld_start.S b/libexec/rtld-elf/powerpc64/rtld_start.S index ee04d978157e..c274b6f617e0 100644 --- a/libexec/rtld-elf/powerpc64/rtld_start.S +++ b/libexec/rtld-elf/powerpc64/rtld_start.S @@ -111,10 +111,7 @@ _ENTRY(_rtld_start) * * Call into the MI binder. This routine is reached via the PLT call cell * - * For ELFv1, on entry, %r11 contains a pointer to the (object, relocation) - * tuple. - * - * For ELFv2, %r11 contains an object pointer and %r0 contains the PLT index. + * On entry, %r11 contains an object pointer and %r0 contains the PLT index. * * Save all registers, call into the binder to resolve and fixup the external * routine, and then transfer to the external routine on return. @@ -122,7 +119,7 @@ _ENTRY(_rtld_start) .globl _rtld_bind _ENTRY(_rtld_bind_start) - mr %r12,%r0 # shunt r0 immediately to r12 for ELFv2 + mr %r12,%r0 # save r0 (index) immediately to r12 mflr %r0 std %r0,16(%r1) # save lr mfcr %r0 @@ -139,13 +136,9 @@ _ENTRY(_rtld_bind_start) std %r9,64+6*8(%r1) std %r10,64+7*8(%r1) -#if !defined(_CALL_ELF) || _CALL_ELF == 1 - ld %r3,0(%r11) - ld %r4,8(%r11) -#else mr %r3,%r11 - mulli %r4,%r12,24 /* Multiply index by sizeof(Elf_Rela) */ -#endif + mulli %r4,%r12,24 # Multiply index by sizeof(Elf_Rela) + bl _rtld_bind # target addr = _rtld_bind(obj, reloff) nop diff --git a/share/man/man4/splash.4 b/share/man/man4/splash.4 index 5c3d6e62a616..fdc770f65ea8 100644 --- a/share/man/man4/splash.4 +++ b/share/man/man4/splash.4 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 29, 2010 +.Dd December 31, 2015 .Dt SPLASH 4 .Os .Sh NAME @@ -130,6 +130,8 @@ the screen will also be powered off. Animated graphical .Fx logo. +.It Pa plasma_saver.ko +Draws an animated interference pattern. .It Pa rain_saver.ko Draws a shower on the screen. .It Pa snake_saver.ko @@ -282,6 +284,14 @@ based on the code, with some additional inspiration from the .Pa daemon_saver code. +The +.Pa logo_saver , +.Pa plasma_saver , +.Pa rain_saver +and +.Pa warp_saver +modules were written by +.An Dag-Erling Sm\(/orgrav Aq Mt des@FreeBSD.org . .Sh CAVEATS Both the splash screen and the screen saver work with .Xr syscons 4 diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk index 50000c5e50f2..819a955fe692 100644 --- a/sys/conf/kmod.mk +++ b/sys/conf/kmod.mk @@ -28,6 +28,9 @@ # # KMODUNLOAD Command to unload a kernel module [/sbin/kldunload] # +# KMODISLOADED Command to check whether a kernel module is +# loaded [/sbin/kldstat -q -n] +# # PROG The name of the kernel module to build. # If not supplied, ${KMOD}.ko is used. # @@ -56,10 +59,14 @@ # unload: # Unload a module. # +# reload: +# Unload if loaded, then load. +# AWK?= awk KMODLOAD?= /sbin/kldload KMODUNLOAD?= /sbin/kldunload +KMODISLOADED?= /sbin/kldstat -q -n OBJCOPY?= objcopy .include @@ -325,7 +332,11 @@ load: ${PROG} .if !target(unload) unload: - ${KMODUNLOAD} -v ${PROG} + if ${KMODISLOADED} ${PROG} ; then ${KMODUNLOAD} -v ${PROG} ; fi +.endif + +.if !target(reload) +reload: unload load .endif .if defined(KERNBUILDDIR) diff --git a/sys/dev/syscons/plasma/fp16.c b/sys/dev/syscons/plasma/fp16.c new file mode 100644 index 000000000000..f0f97e34303c --- /dev/null +++ b/sys/dev/syscons/plasma/fp16.c @@ -0,0 +1,131 @@ +/*- + * Copyright (c) 2015 Dag-Erling Smørgrav + * 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifdef _KERNEL +#include +#else +#include +#include +#endif + +#include "fp16.h" + +/* + * Compute the quare root of x, using Newton's method with 2^(log2(x)/2) + * as the initial estimate. + */ +fp16_t +fp16_sqrt(fp16_t x) +{ + fp16_t y, delta; + signed int log2x; + + /* special case */ + if (x == 0) + return (0); + + /* shift toward 0 by half the logarithm */ + log2x = flsl(x) - 1; + if (log2x >= 16) { + y = x >> (log2x - 16) / 2; + } else { +#if 0 + y = x << (16 - log2x) / 2; +#else + /* XXX for now, return 0 for anything < 1 */ + return (0); +#endif + } + while (y > 0) { + /* delta = y^2 / 2y */ + delta = fp16_div(fp16_sub(fp16_mul(y, y), x), y * 2); + if (delta == 0) + break; + y = fp16_sub(y, delta); + } + return (y); +} + +static fp16_t fp16_cos_table[256] = { + 65536, 65534, 65531, 65524, 65516, 65505, 65491, 65475, + 65457, 65436, 65412, 65386, 65358, 65327, 65294, 65258, + 65220, 65179, 65136, 65091, 65043, 64992, 64939, 64884, + 64826, 64766, 64703, 64638, 64571, 64501, 64428, 64353, + 64276, 64197, 64115, 64030, 63943, 63854, 63762, 63668, + 63571, 63473, 63371, 63268, 63162, 63053, 62942, 62829, + 62714, 62596, 62475, 62353, 62228, 62100, 61971, 61839, + 61705, 61568, 61429, 61288, 61144, 60998, 60850, 60700, + 60547, 60392, 60235, 60075, 59913, 59749, 59583, 59414, + 59243, 59070, 58895, 58718, 58538, 58356, 58172, 57986, + 57797, 57606, 57414, 57219, 57022, 56822, 56621, 56417, + 56212, 56004, 55794, 55582, 55368, 55152, 54933, 54713, + 54491, 54266, 54040, 53811, 53581, 53348, 53114, 52877, + 52639, 52398, 52155, 51911, 51665, 51416, 51166, 50914, + 50660, 50403, 50146, 49886, 49624, 49360, 49095, 48828, + 48558, 48288, 48015, 47740, 47464, 47186, 46906, 46624, + 46340, 46055, 45768, 45480, 45189, 44897, 44603, 44308, + 44011, 43712, 43412, 43110, 42806, 42501, 42194, 41885, + 41575, 41263, 40950, 40636, 40319, 40002, 39682, 39362, + 39039, 38716, 38390, 38064, 37736, 37406, 37075, 36743, + 36409, 36074, 35738, 35400, 35061, 34721, 34379, 34036, + 33692, 33346, 32999, 32651, 32302, 31952, 31600, 31247, + 30893, 30538, 30181, 29824, 29465, 29105, 28745, 28383, + 28020, 27656, 27291, 26925, 26557, 26189, 25820, 25450, + 25079, 24707, 24334, 23960, 23586, 23210, 22833, 22456, + 22078, 21699, 21319, 20938, 20557, 20175, 19792, 19408, + 19024, 18638, 18253, 17866, 17479, 17091, 16702, 16313, + 15923, 15533, 15142, 14751, 14359, 13966, 13573, 13179, + 12785, 12390, 11995, 11600, 11204, 10807, 10410, 10013, + 9616, 9218, 8819, 8421, 8022, 7623, 7223, 6823, + 6423, 6023, 5622, 5222, 4821, 4420, 4018, 3617, + 3215, 2814, 2412, 2010, 1608, 1206, 804, 402, +}; + +/* + * Compute the cosine of theta. + */ +fp16_t +fp16_cos(fp16_t theta) +{ + unsigned int i; + + i = 1024 * (theta % FP16_2PI) / FP16_2PI; + switch (i / 256) { + case 0: + return (fp16_cos_table[i % 256]); + case 1: + return (-fp16_cos_table[255 - i % 256]); + case 2: + return (-fp16_cos_table[i % 256]); + case 3: + return (fp16_cos_table[255 - i % 256]); + default: + /* inconceivable! */ + return (0); + } +} diff --git a/sys/dev/syscons/plasma/fp16.h b/sys/dev/syscons/plasma/fp16.h new file mode 100644 index 000000000000..bc0c117e3eb4 --- /dev/null +++ b/sys/dev/syscons/plasma/fp16.h @@ -0,0 +1,84 @@ +/*- + * Copyright (c) 2015 Dag-Erling Smørgrav + * 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef FP16_H_INCLUDED +#define FP16_H_INCLUDED + +typedef signed long long fp16_t; + +#define ItoFP16(n) ((signed long long)(n) << 16) +#define FP16toI(n) ((signed long long)(n) >> 16) + +#ifndef _KERNEL +#define FP16toF(n) ((n) / 65536.0) +#endif + +/* add a and b */ +static inline fp16_t +fp16_add(fp16_t a, fp16_t b) +{ + + return (a + b); +} + +/* subtract b from a */ +static inline fp16_t +fp16_sub(fp16_t a, fp16_t b) +{ + + return (a - b); +} + +/* multiply a by b */ +static inline fp16_t +fp16_mul(fp16_t a, fp16_t b) +{ + + return (a * b >> 16); +} + +/* divide a by b */ +static inline fp16_t +fp16_div(fp16_t a, fp16_t b) +{ + + return ((a << 16) / b); +} + +/* square root */ +fp16_t fp16_sqrt(fp16_t); + +#define FP16_2PI 411774 +#define FP16_PI 205887 +#define FP16_PI_2 102943 +#define FP16_PI_4 51471 + +/* cosine */ +fp16_t fp16_cos(fp16_t); + +#endif diff --git a/sys/dev/syscons/plasma/plasma_saver.c b/sys/dev/syscons/plasma/plasma_saver.c new file mode 100644 index 000000000000..b5ed02fb028e --- /dev/null +++ b/sys/dev/syscons/plasma/plasma_saver.c @@ -0,0 +1,239 @@ +/*- + * Copyright (c) 2015 Dag-Erling Smørgrav + * 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 AUTHOR 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. + * + * $FreeBSD$ + * + * To CJA, in appreciation of Nighthawk brunches past and future. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define SAVER_NAME "plasma_saver" + +#include "fp16.h" + +/* + * Preferred video modes + */ +static int modes[] = { + M_VGA_CG640, + M_PC98_PEGC640x480, + M_PC98_PEGC640x400, + M_VGA_CG320, + -1 +}; + +/* + * Display parameters + */ +static unsigned char *vid; +static unsigned int banksize, scrmode, scrw, scrh; +static unsigned int blanked; + +/* + * List of foci + */ +#define FOCI 3 +static struct { + int x, y; /* coordinates */ + int vx, vy; /* velocity */ +} plasma_foci[FOCI]; + +/* + * Palette + */ +static struct { + unsigned char r, g, b; +} plasma_pal[256]; + +/* + * Draw a new frame + */ +static void +plasma_update(video_adapter_t *adp) +{ + unsigned int x, y; /* coordinates */ + signed int dx, dy; /* horizontal / vertical distance */ + fp16_t sqd, d; /* square of distance and distance */ + fp16_t m; /* magnitude */ + unsigned int org, off; /* origin and offset */ + unsigned int i; /* loop index */ + + /* switch to bank 0 */ + vidd_set_win_org(adp, 0); + /* for each scan line */ + for (y = org = off = 0; y < scrh; ++y) { + /* for each pixel on scan line */ + for (x = 0; x < scrw; ++x, ++off) { + /* for each focus */ + for (i = m = 0; i < FOCI; ++i) { + dx = x - plasma_foci[i].x; + dy = y - plasma_foci[i].y; + sqd = ItoFP16(dx * dx + dy * dy); + d = fp16_sqrt(sqd); + /* divide by 4 to stretch out the pattern */ + m = fp16_add(m, fp16_cos(d / 4)); + } + /* + * m is now in the range +/- FOCI, but we need a + * value between 0 and 255. We scale to +/- 127 + * and add 127, which moves it into the range [0, + * 254]. + */ + m = fp16_mul(m, ItoFP16(127)); + m = fp16_div(m, ItoFP16(FOCI)); + m = fp16_add(m, ItoFP16(127)); + /* switch banks if necessary */ + if (off > banksize) { + off -= banksize; + org += banksize; + vidd_set_win_org(adp, org); + } + /* plot */ + vid[off] = FP16toI(m); + } + } + /* now move the foci */ + for (i = 0; i < FOCI; ++i) { + plasma_foci[i].x += plasma_foci[i].vx; + if (plasma_foci[i].x < 0) { + /* bounce against left wall */ + plasma_foci[i].vx = -plasma_foci[i].vx; + plasma_foci[i].x = -plasma_foci[i].x; + } else if (plasma_foci[i].x >= scrw) { + /* bounce against right wall */ + plasma_foci[i].vx = -plasma_foci[i].vx; + plasma_foci[i].x = scrw - (plasma_foci[i].x - scrw); + } + plasma_foci[i].y += plasma_foci[i].vy; + if (plasma_foci[i].y < 0) { + /* bounce against ceiling */ + plasma_foci[i].vy = -plasma_foci[i].vy; + plasma_foci[i].y = -plasma_foci[i].y; + } else if (plasma_foci[i].y >= scrh) { + /* bounce against floor */ + plasma_foci[i].vy = -plasma_foci[i].vy; + plasma_foci[i].y = scrh - (plasma_foci[i].y - scrh); + } + } +} + +/* + * Start or stop the screensaver + */ +static int +plasma_saver(video_adapter_t *adp, int blank) +{ + int pl; + + if (blank) { + /* switch to graphics mode */ + if (blanked <= 0) { + pl = splhigh(); + vidd_set_mode(adp, scrmode); + vidd_load_palette(adp, (unsigned char *)plasma_pal); + vidd_set_border(adp, 0); + blanked++; + vid = (unsigned char *)adp->va_window; + banksize = adp->va_window_size; + splx(pl); + vidd_clear(adp); + } + /* update display */ + plasma_update(adp); + } else { + blanked = 0; + } + return (0); +} + +/* + * Initialize on module load + */ +static int +plasma_init(video_adapter_t *adp) +{ + video_info_t info; + int i; + + /* select video mode */ + for (i = 0; modes[i] >= 0; ++i) + if (vidd_get_info(adp, modes[i], &info) == 0) + break; + if (modes[i] < 0) { + log(LOG_NOTICE, "%s: no supported video modes\n", SAVER_NAME); + return (ENODEV); + } + scrmode = modes[i]; + scrw = info.vi_width; + scrh = info.vi_height; + + /* initialize the palette */ + for (i = 0; i < 256; ++i) + plasma_pal[i].r = plasma_pal[i].g = plasma_pal[i].b = i; + + /* randomize the foci */ + for (i = 0; i < FOCI; i++) { + plasma_foci[i].x = random() % scrw; + plasma_foci[i].y = random() % scrh; + plasma_foci[i].vx = random() % 5 - 2; + plasma_foci[i].vy = random() % 5 - 2; + } + + return (0); +} + +/* + * Clean up before module unload + */ +static int +plasma_term(video_adapter_t *adp) +{ + + return (0); +} + +/* + * Boilerplate + */ +static scrn_saver_t plasma_module = { + SAVER_NAME, + plasma_init, + plasma_term, + plasma_saver, + NULL +}; + +SAVER_MODULE(plasma_saver, plasma_module); diff --git a/sys/modules/rtwn/Makefile b/sys/modules/rtwn/Makefile new file mode 100644 index 000000000000..f5d230caab5f --- /dev/null +++ b/sys/modules/rtwn/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../dev/rtwn + +KMOD = if_rtwn +SRCS = if_rtwn.c device_if.h bus_if.h pci_if.h + +.include diff --git a/sys/modules/syscons/Makefile b/sys/modules/syscons/Makefile index b047845deced..85e513d5f898 100644 --- a/sys/modules/syscons/Makefile +++ b/sys/modules/syscons/Makefile @@ -9,6 +9,7 @@ SUBDIR= ${_apm} \ ${_fire} \ green \ ${_logo} \ + ${_plasma} \ ${_rain} \ ${_snake} \ ${_star} \ @@ -25,6 +26,7 @@ _daemon= daemon _dragon= dragon _fire= fire _logo= logo +_plasma= plasma _rain= rain _snake= snake _star= star diff --git a/sys/modules/syscons/plasma/Makefile b/sys/modules/syscons/plasma/Makefile new file mode 100644 index 000000000000..c71c864349fd --- /dev/null +++ b/sys/modules/syscons/plasma/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../../dev/syscons/plasma + +KMOD= plasma_saver +SRCS= fp16.c plasma_saver.c + +.include diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index 5186406248d9..2b82ecc20459 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -324,6 +324,10 @@ ether_output(struct ifnet *ifp, struct mbuf *m, /* * Add local net header. If no space in first mbuf, * allocate another. + * + * Note that we do prepend regardless of RT_HAS_HEADER flag. + * This is done because BPF code shifts m_data pointer + * to the end of ethernet header prior to calling if_output(). */ M_PREPEND(m, hlen, M_NOWAIT); if (m == NULL) diff --git a/sys/net80211/ieee80211_freebsd.h b/sys/net80211/ieee80211_freebsd.h index f660c17abf51..6d47ccd6bf20 100644 --- a/sys/net80211/ieee80211_freebsd.h +++ b/sys/net80211/ieee80211_freebsd.h @@ -246,9 +246,11 @@ void ieee80211_vap_destroy(struct ieee80211vap *); (((_ifp)->if_flags & IFF_UP) && \ ((_ifp)->if_drv_flags & IFF_DRV_RUNNING)) +/* XXX TODO: cap these at 1, as hz may not be 1000 */ #define msecs_to_ticks(ms) (((ms)*hz)/1000) #define ticks_to_msecs(t) (1000*(t) / hz) #define ticks_to_secs(t) ((t) / hz) + #define time_after(a,b) ((long)(b) - (long)(a) < 0) #define time_before(a,b) time_after(b,a) #define time_after_eq(a,b) ((long)(a) - (long)(b) >= 0) diff --git a/sys/net80211/ieee80211_scan_sw.c b/sys/net80211/ieee80211_scan_sw.c index eb58386fc907..163633ccd20b 100644 --- a/sys/net80211/ieee80211_scan_sw.c +++ b/sys/net80211/ieee80211_scan_sw.c @@ -641,7 +641,7 @@ scan_task(void *arg, int pending) * XXX Should use M_TXCB mechanism to eliminate this. */ cv_timedwait(&SCAN_PRIVATE(ss)->ss_scan_cv, - IEEE80211_LOCK_OBJ(ic), hz / 1000); + IEEE80211_LOCK_OBJ(ic), msecs_to_ticks(1)); if (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_ABORT) goto done; } diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h index cd27ead97f67..1dd57eef7817 100644 --- a/sys/net80211/ieee80211_var.h +++ b/sys/net80211/ieee80211_var.h @@ -84,6 +84,7 @@ #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) #define IEEE80211_TU_TO_MS(x) (((x) * 1024) / 1000) +/* XXX TODO: cap this at 1, in case hz is not 1000 */ #define IEEE80211_TU_TO_TICKS(x)(((x) * 1024 * hz) / (1000 * 1000)) /* diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index 0bf5cecb8eec..7a06beaf7cc0 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -1334,8 +1334,5 @@ arp_init(void) if (IS_DEFAULT_VNET(curvnet)) iflladdr_tag = EVENTHANDLER_REGISTER(iflladdr_event, arp_iflladdr, NULL, EVENTHANDLER_PRI_ANY); - if (IS_DEFAULT_VNET(curvnet)) - iflladdr_tag = EVENTHANDLER_REGISTER(iflladdr_event, - arp_iflladdr, NULL, EVENTHANDLER_PRI_ANY); } SYSINIT(arp, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, arp_init, 0); diff --git a/sys/powerpc/include/platform.h b/sys/powerpc/include/platform.h index 28f83ccd9f66..8c92e26221ae 100644 --- a/sys/powerpc/include/platform.h +++ b/sys/powerpc/include/platform.h @@ -57,6 +57,8 @@ void platform_smp_ap_init(void); const char *installed_platform(void); void platform_probe_and_attach(void); +void platform_cpu_idle(int); + void platform_sleep(void); #endif /* _MACHINE_PLATFORM_H_ */ diff --git a/sys/powerpc/mpc85xx/mpc85xx.h b/sys/powerpc/mpc85xx/mpc85xx.h index ac8b8ff8ba55..e806225618ee 100644 --- a/sys/powerpc/mpc85xx/mpc85xx.h +++ b/sys/powerpc/mpc85xx/mpc85xx.h @@ -131,6 +131,12 @@ extern vm_offset_t ccsrbar_va; */ #define OCP85XX_RSTCR (CCSRBAR_VA + 0xe00b0) +/* + * Run Control/Power Management Registers. + */ +#define OCP85XX_RCPM_CDOZSR (CCSRBAR_VA + 0xe2004) +#define OCP85XX_RCPM_CDOZCR (CCSRBAR_VA + 0xe200c) + /* * Prototypes. */ diff --git a/sys/powerpc/mpc85xx/platform_mpc85xx.c b/sys/powerpc/mpc85xx/platform_mpc85xx.c index c84561d09c75..3a36e6dbbe77 100644 --- a/sys/powerpc/mpc85xx/platform_mpc85xx.c +++ b/sys/powerpc/mpc85xx/platform_mpc85xx.c @@ -80,6 +80,8 @@ static int mpc85xx_smp_first_cpu(platform_t, struct cpuref *cpuref); static int mpc85xx_smp_next_cpu(platform_t, struct cpuref *cpuref); static int mpc85xx_smp_get_bsp(platform_t, struct cpuref *cpuref); static int mpc85xx_smp_start_cpu(platform_t, struct pcpu *cpu); +static void mpc85xx_idle(platform_t, int cpu); +static int mpc85xx_idle_wakeup(platform_t plat, int cpu); static void mpc85xx_reset(platform_t); @@ -95,6 +97,8 @@ static platform_method_t mpc85xx_methods[] = { PLATFORMMETHOD(platform_smp_start_cpu, mpc85xx_smp_start_cpu), PLATFORMMETHOD(platform_reset, mpc85xx_reset), + PLATFORMMETHOD(platform_idle, mpc85xx_idle), + PLATFORMMETHOD(platform_idle_wakeup, mpc85xx_idle_wakeup), PLATFORMMETHOD_END }; @@ -478,3 +482,36 @@ mpc85xx_reset(platform_t plat) ; } +static void +mpc85xx_idle(platform_t plat, int cpu) +{ +#ifdef QORIQ_DPAA + uint32_t reg; + + reg = ccsr_read4(OCP85XX_RCPM_CDOZCR); + ccsr_write4(OCP85XX_RCPM_CDOZCR, reg | (1 << cpu)); + ccsr_read4(OCP85XX_RCPM_CDOZCR); +#else + register_t msr; + + msr = mfmsr(); + /* Freescale E500 core RM section 6.4.1. */ + __asm __volatile("msync; mtmsr %0; isync" :: + "r" (msr | PSL_WE)); +#endif +} + +static int +mpc85xx_idle_wakeup(platform_t plat, int cpu) +{ +#ifdef QORIQ_DPAA + uint32_t reg; + + reg = ccsr_read4(OCP85XX_RCPM_CDOZCR); + ccsr_write4(OCP85XX_RCPM_CDOZCR, reg & ~(1 << cpu)); + ccsr_read4(OCP85XX_RCPM_CDOZCR); + + return (1); +#endif + return (0); +} diff --git a/sys/powerpc/powerpc/cpu.c b/sys/powerpc/powerpc/cpu.c index 43190ae98a4e..1d685315b496 100644 --- a/sys/powerpc/powerpc/cpu.c +++ b/sys/powerpc/powerpc/cpu.c @@ -607,12 +607,6 @@ cpu_idle(int busy) busy, curcpu); } -int -cpu_idle_wakeup(int cpu) -{ - return (0); -} - static void cpu_idle_60x(sbintime_t sbt) { @@ -651,14 +645,9 @@ cpu_idle_60x(sbintime_t sbt) static void cpu_idle_booke(sbintime_t sbt) { - register_t msr; - - msr = mfmsr(); #ifdef E500 - /* Freescale E500 core RM section 6.4.1. */ - __asm __volatile("msync; mtmsr %0; isync" :: - "r" (msr | PSL_WE)); + platform_cpu_idle(PCPU_GET(cpuid)); #endif } diff --git a/sys/powerpc/powerpc/platform.c b/sys/powerpc/powerpc/platform.c index 8168758f885a..b29ad92eb629 100644 --- a/sys/powerpc/powerpc/platform.c +++ b/sys/powerpc/powerpc/platform.c @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -252,6 +253,19 @@ cpu_reset() PLATFORM_RESET(plat_obj); } +int +cpu_idle_wakeup(int cpu) +{ + return (PLATFORM_IDLE_WAKEUP(plat_obj, cpu)); +} + +void +platform_cpu_idle(int cpu) +{ + + PLATFORM_IDLE(plat_obj, cpu); +} + /* * Platform install routines. Highest priority wins, using the same * algorithm as bus attachment. diff --git a/sys/powerpc/powerpc/platform_if.m b/sys/powerpc/powerpc/platform_if.m index dfa2be1baa61..a562b321a92b 100644 --- a/sys/powerpc/powerpc/platform_if.m +++ b/sys/powerpc/powerpc/platform_if.m @@ -84,6 +84,14 @@ CODE { { return; } + static void platform_null_idle(platform_t plat, int cpu) + { + return; + } + static int platform_null_idle_wakeup(platform_t plat, int cpu) + { + return (0); + } }; /** @@ -210,6 +218,22 @@ METHOD void reset { platform_t _plat; }; +/** + * @brief Idle a CPU + */ +METHOD void idle { + platform_t _plat; + int _cpu; +} DEFAULT platform_null_idle; + +/** + * @brief Wake up an idle CPU + */ +METHOD int idle_wakeup { + platform_t _plat; + int _cpu; +} DEFAULT platform_null_idle_wakeup; + /** * @brief Suspend the CPU */ diff --git a/tools/regression/geom_concat/conf.sh b/tools/regression/geom_concat/conf.sh index 0eaf1baac464..c8692bbc84da 100644 --- a/tools/regression/geom_concat/conf.sh +++ b/tools/regression/geom_concat/conf.sh @@ -1,7 +1,7 @@ #!/bin/sh # $FreeBSD$ -name="test" +name="$(mktemp -u concat.XXXXXX)" class="concat" base=`basename $0` diff --git a/tools/regression/geom_mirror/conf.sh b/tools/regression/geom_mirror/conf.sh index 8a60a16360ee..5e7e15a1d4d9 100644 --- a/tools/regression/geom_mirror/conf.sh +++ b/tools/regression/geom_mirror/conf.sh @@ -1,7 +1,7 @@ #!/bin/sh # $FreeBSD$ -name="test" +name="$(mktemp -u mirror.XXXXXX)" class="mirror" base=`basename $0` diff --git a/tools/regression/geom_raid3/conf.sh b/tools/regression/geom_raid3/conf.sh index 93e7deaf1c73..ff6485c9d030 100644 --- a/tools/regression/geom_raid3/conf.sh +++ b/tools/regression/geom_raid3/conf.sh @@ -1,7 +1,7 @@ #!/bin/sh # $FreeBSD$ -name="test" +name="$(mktemp -u graid3.XXXXXX)" class="raid3" base=`basename $0` diff --git a/tools/regression/geom_shsec/conf.sh b/tools/regression/geom_shsec/conf.sh index 7648862422f7..dc416db6434a 100644 --- a/tools/regression/geom_shsec/conf.sh +++ b/tools/regression/geom_shsec/conf.sh @@ -1,7 +1,7 @@ #!/bin/sh # $FreeBSD$ -name="test" +name="$(mktemp -u shsec.XXXXXX)" class="shsec" base=`basename $0` diff --git a/tools/regression/geom_stripe/conf.sh b/tools/regression/geom_stripe/conf.sh index 22e586498509..54a0c3646c20 100644 --- a/tools/regression/geom_stripe/conf.sh +++ b/tools/regression/geom_stripe/conf.sh @@ -1,7 +1,7 @@ #!/bin/sh # $FreeBSD$ -name="test" +name="$(mktemp -u stripe.XXXXXX)" class="stripe" base=`basename $0` diff --git a/tools/regression/geom_subr.sh b/tools/regression/geom_subr.sh index 60478297aa74..0ffb8c8c7049 100644 --- a/tools/regression/geom_subr.sh +++ b/tools/regression/geom_subr.sh @@ -1,7 +1,12 @@ #!/bin/sh # $FreeBSD$ -kldstat -q -m g_${class} || g${class} load || exit 1 +if [ $(id -u) -ne 0 ]; then + echo 'Tests must be run as root' + echo 'Bail out!' + exit 1 +fi +kldstat -q -m g_${class} || geom ${class} load || exit 1 devwait() { @@ -12,3 +17,32 @@ devwait() sleep 0.2 done } + +# Need to keep track of the test md devices to avoid the scenario where a test +# failing will cause the other tests to bomb out, or a test failing will leave +# a large number of md(4) devices lingering around +: ${TMPDIR=/tmp} +export TMPDIR +TEST_MDS_FILE=${TMPDIR}/test_mds + +attach_md() +{ + local test_md + + test_md=$(mdconfig -a "$@") || exit + echo $test_md >> $TEST_MDS_FILE || exit + echo $test_md +} + +geom_test_cleanup() +{ + local test_md + + if [ -f $TEST_MDS_FILE ]; then + while read test_md; do + # The "#" tells the TAP parser this is a comment + echo "# Removing test memory disk: $test_md" + mdconfig -d -u $test_md + done < $TEST_MDS_FILE + fi +}