diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 2005-04-01 10:40:50 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 2005-04-01 10:40:50 +0000 |
commit | 086e003dd29b7c42921a44eb7af336bacfc10d4d (patch) | |
tree | a901551a395f9d10ee4d44cef80ec86a4dd5ae0c /sys/arch/hppa64/stand | |
parent | 4082d6812410636300be23e2010448febcf6e5d9 (diff) |
small batch early bottling hppa64 port
matured in mighty ukrainian oak for 23 months
Diffstat (limited to 'sys/arch/hppa64/stand')
29 files changed, 3983 insertions, 0 deletions
diff --git a/sys/arch/hppa64/stand/Makefile b/sys/arch/hppa64/stand/Makefile new file mode 100644 index 00000000000..296da014aa6 --- /dev/null +++ b/sys/arch/hppa64/stand/Makefile @@ -0,0 +1,11 @@ +# $OpenBSD: Makefile,v 1.1 2005/04/01 10:40:48 mickey Exp $ + +.if ${MACHINE} == "hppa64" +SUBDIR= libsa libkern libz +.endif +SUBDIR+= mkboot boot +.if ${MACHINE} == "hppa64" +#SUBDIR+= cdboot +.endif + +.include <bsd.subdir.mk> diff --git a/sys/arch/hppa64/stand/Makefile.inc b/sys/arch/hppa64/stand/Makefile.inc new file mode 100644 index 00000000000..2f7a45dcf73 --- /dev/null +++ b/sys/arch/hppa64/stand/Makefile.inc @@ -0,0 +1,44 @@ +# $OpenBSD: Makefile.inc,v 1.1 2005/04/01 10:40:48 mickey Exp $ + +CFLAGS=${DEBUG} -Os -Wall -Werror +CPPFLAGS+=-I${S} -I. -I${.CURDIR} -Derrno=errno +SACFLAGS=-nostdinc -fno-builtin -D_STANDALONE -I${STANDIR}/libsa +SACFLAGS+=-mdisable-fpregs -fno-stack-protector +#DEBUGFLAGS=-DDEBUG +#DEBUGFLAGS+=-DPDCDEBUG +#DEBUGFLAGS+=-DLIFDEBUG +#DEBUGFLAGS+=-DEXEC_DEBUG +#DEBUGFLAGS+=-DALLOC_TRACE +LINKADDR=0x780000 +LOADADDR=0x780000 +HEAP_LIMIT=0x7f8000 +CLEANFILES+= machine +DEBUGLIBS= no + +.if !make(libdep) && !make(sadep) && !make(salibdir) && !make(kernlibdir) && !make(obj) && !(defined(PROG) && ${PROG} == "mkboot") +.BEGIN: + @([ -h machine ] || ln -s $(S)/arch/hppa64/include machine) +.endif + +.if exists(${STANDIR}/libsa/libsa.a) +LIBSA=${STANDIR}/libsa/libsa.a +.else +LIBSA=${STANDIR}/libsa/${__objdir}/libsa.a +.endif +.if exists(${STANDIR}/libkern/libkern.a) +LIBKERN=${STANDIR}/libkern/libkern.a +.else +LIBKERN=${STANDIR}/libkern/${__objdir}/libkern.a +.endif +.if exists(${STANDIR}/libz/libz.a) +LIBZ=${STANDIR}/libz/libz.a +.else +LIBZ=${STANDIR}/libz/${__objdir}/libz.a +.endif +.if exists(${STANDIR}/mkboot/mkboot) +MKBOOT=${STANDIR}/mkboot/mkboot +.else +MKBOOT=${STANDIR}/mkboot/${__objdir}/mkboot +.endif + +BINDIR= /usr/mdec diff --git a/sys/arch/hppa64/stand/boot/Makefile b/sys/arch/hppa64/stand/boot/Makefile new file mode 100644 index 00000000000..dd9bc44c62f --- /dev/null +++ b/sys/arch/hppa64/stand/boot/Makefile @@ -0,0 +1,60 @@ +# $OpenBSD: Makefile,v 1.1 2005/04/01 10:40:48 mickey Exp $ + +MAN= boot.8 +MANSUBDIR=hppa64 +MLINKS= boot.8 boot.conf.8 +S =${.CURDIR}/../../../.. +CLEANFILES+= boot.gdb boot.map boot.lif + +.if ${MACHINE} == "hppa64" +PROG= boot +SRCS= srt0.S exec.c boot.c cmd.c vars.c bootarg.c conf.c +LD?= ld +LDFLAGS+=-Bstatic -nostartfiles -nostdlib -N -Ttext $(LINKADDR) +LDFLAGS+=-T ${.CURDIR}/ld.script -Map boot.map +LDFLAGS+=--warn-constructors --warn-common +SIZE?= size +STRIP?= strip +STANDIR=${.CURDIR}/.. +CRTBEGIN= +CRTEND= +LINKS= ${BINDIR}/boot.lif ${BINDIR}/sdboot \ + ${BINDIR}/boot.lif ${BINDIR}/stboot \ + ${BINDIR}/boot.lif ${BINDIR}/xxboot + +LDADD= ${LIBSA} ${LIBZ} ${LIBKERN} +DPADD= ${LIBSA} ${LIBZ} ${LIBKERN} + +.PATH: ${S}/stand/boot + +all: boot.lif + +realinstall: + ${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \ + boot ${DESTDIR}${BINDIR} + ${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \ + boot.lif ${DESTDIR}${BINDIR} + +.if exists(${.CURDIR}/../../compile/GENERIC/bsd) +bsd: ${.CURDIR}/../../compile/GENERIC/bsd + gzip -9 -c ${.CURDIR}/../../compile/GENERIC/bsd > bsd +ADDBOOT+=bsd +.endif + +# probably we should check for 256k limit for ISL +boot.lif: ${PROG} ${ADDBOOT} + -@cp ${PROG} ${PROG}.gdb + ${STRIP} ${PROG} + ${MKBOOT} -v ${PROG} ${ADDBOOT} boot.lif + +${PROG}: $(OBJS) $(DPADD) + $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LDADD) + @${SIZE} $(PROG) +.else +NOPROG= +.endif + +.include <bsd.prog.mk> + +CPPFLAGS+=${DEBUGFLAGS} -DRELOC=${LOADADDR} -DHEAP_LIMIT=${HEAP_LIMIT} +CFLAGS+=$(SACFLAGS) diff --git a/sys/arch/hppa64/stand/boot/boot.8 b/sys/arch/hppa64/stand/boot/boot.8 new file mode 100644 index 00000000000..4b52dabbe02 --- /dev/null +++ b/sys/arch/hppa64/stand/boot/boot.8 @@ -0,0 +1,342 @@ +.\" $OpenBSD: boot.8,v 1.1 2005/04/01 10:40:48 mickey Exp $ +.\" +.\" Copyright (c) 2002 Miodrag Vallat +.\" Copyright (c) 1997-2005 Michael Shalayeff +.\" 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 ``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 HIS RELATIVES 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 MIND, 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. +.\" +.\" +.Dd March 16, 2005 +.Dt BOOT 8 hppa +.Os +.Sh NAME +.Nm boot , +.Nm boot.conf +.Nd +hppa-specific bootstrap +.Sh DESCRIPTION +The main purpose of this program is to load the system kernel while dealing +with the various features of the PA-RISC hardware. +.Pp +As described in +.Xr boot_hppa 8 , +this program is loaded by the PDC firmware +and provides a convenient way to load the kernel. +.Pp +Basic operations include: +.Pp +.Bl -bullet -compact +.It +Loading kernels from any device supported by your system. +.It +Loading kernels compressed by +.Xr gzip 1 . +.It +Providing an interactive command line. +.It +Detecting and switching between multiple consoles. +.El +.Pp +The sequence of its operation is as follows: initialization, +parsing the configuration file, then an interactive command line. +While at the command line you have 5 seconds to type any commands, if needed. +If time expires, the kernel will be loaded according to +the current variable settings (see the +.Nm set +command). +Each time a kernel load fails, the timeout is increased by one second. +The sequence of +.Nm +operations is as follows: +.Bl -enum +.It +If the file +.Pa /etc/boot.conf +exists on the filesystem or LIF image +.Nm +was loaded from, open and parse it. +This file may contain any commands +.Nm +accepts at the interactive prompt. +Though default settings usually suffice, they can be changed here. +.It +The header line +.Pp +.Dl >> OpenBSD/hppa BOOT [x.xx] +.Pp +is displayed to the active console, where +.Ar x.xx +is the version number of the +.Nm +program, followed by the +.Pp +.Dl boot> +.Pp +prompt, which means you are in interactive mode and may enter commands. +If you do not, +.Nm +will proceed to load the kernel with the current parameters after the +timeout period has expired. +.El +.Pp +By default, +.Nm +attempts to load the kernel executable +.Pa /bsd . +If that fails, it will attempt to load +.Pa /obsd +and then +.Pa /bsd.old . +If it fails to find any of these files, +and no alternative kernel image has been specified, +the system will be unable to boot. +.Sh COMMANDS +The following commands are accepted at the +.Nm +prompt: +.Bl -tag -width shorten +.It boot Op Ar image Op Fl acds +Boots the kernel image specified by +.Ar image +with any options given. +Image specification consists of a pair +.Ar device : Ns Ar filename ; +either or both can be omitted (`:' is not needed if both are omitted), +in which case values from +.Nm +variables will be used. +.Bl -tag -width _a_ +.It Fl a +Causes the kernel to ask for the +.Nm root +device to use. +.It Fl c +Causes the kernel to go into +.Xr boot_config 8 +before performing +.Xr autoconf 4 +procedures. +.It Fl d +Causes the kernel to drop into +.Xr ddb 4 +at the earliest convenient point. +.It Fl s +Causes the kernel to boot single-user. +.El +.It echo Op Ar args +Displays +.Ar args +on the console device. +.It help +Prints a list of available commands and machine dependent +commands, if any. +.It machine Op Ar command +Issues machine-dependent commands. +These are defined for hppa architecture: +.Bl -tag -width keyboard +.It Nm console +Displays or sets the console path. +.Pp +When invoked with no argument, this command will display the configured +console path found in the stable storage area. +.Pp +Otherwise, the argument will be interpreted as a console path +definition string, and +.Nm +will attempt to switch the console configuration to the desired device. +The console definition attempts to follow the PDC syntax, +and would have a form of: +.Pp +.Bd -filled -compact +graphics +.Op _head +.Op .mode +.Ed +for graphics console, and +.Pp +.Bd -filled -compact +rs232 +.Op _2 +.Op .speed Op .bits Op .parity +.Ed +for serial console. +.Pp +The default head and mode for graphics console are 0, that is the default +videomode of the first graphics device. +The default serial settings are 9600 bps, 8 data bits, and no parity. +.It Nm keyboard +Displays or sets the keyboard path. +.Pp +When invoked with no argument, this command will display the configured +keyboard path found in the stable storage area. +.Pp +Otherwise, the argument will be interpreted as a keyboard path definition +string, and +.Nm +will attempt to switch the keyboard configuration to the desired port. +The keyboard definition attempts to follow the PDC syntax, +and would have a form of: +.Pp +.Bd -filled -compact +hil +.Ed +for hil keyboard, and +.Pp +.Bd -filled -compact +ps2 +.Ed +for PS/2 keyboard. +.El +.Pp +After changing any path settings, the machine usually has to be restarted for +the changes to have effect. +.It ls Op Ar directory +Prints contents of the specified +.Ar directory +in long format including: attributes and file type, owner, group, +size, filename. +.It reboot +Reboots the machine by initiating a warm boot procedure. +.It set Op Ar varname Op Ar value +If invoked without arguments, prints a list of variables and their values. +If only +.Ar varname +is specified, displays contents of that variable. +If +.Ar varname +and +.Ar value +are both specified, sets that variable to the given value. +Variables include: +.Pp +.Bl -tag -compact -width boothow +.It Nm addr +Address at which to load the kernel. +.It Nm debug +Debug flag if +.Nm +was compiled with DEBUG defined. +.It Nm device +Boot device name (i.e., +.Li lf0a , +.Li sd0a ) . +.It Nm howto +Options to pass to the loaded kernel. +.It Nm image +File name containing the kernel image. +.It Nm timeout +Number of seconds boot will wait for human intervention before +booting the default kernel image. +.\" .It Nm tty +.\" Active console device name (i.e., +.\" .Li ttya , +.\" .Li ttyb , +.\" .Li ite0) . +.El +.\" .It stty Op Ar device Op Ar speed +.\" Displays or sets the +.\" .Ar speed +.\" for a console +.\" .Ar device . +.\" If changing the baudrate for the currently active console, +.\" .Nm +.\" offers you five seconds of grace time before committing the change +.\" to allow you to change your terminal's speed to match. +.\" If changing speed +.\" .Em not +.\" for the active console, the baudrate is set for the +.\" .Em next +.\" time you switch to a serial console. +.\" The baudrate value is not used for the +.\" .Li ite0 +.\" console. +.\" .Pp +.\" The default baudrate is 9600bps. +.It time +Displays system time and date. +.El +.Sh FILES +.Bl -tag -width /etc/boot.conf -compact +.It Pa /boot +system bootstrap +.It Pa /etc/boot.conf +system bootstrap's startup file +.It Pa /bsd +kernel image +.El +.Sh EXAMPLES +Boot the default kernel: +.Pp +.Dl boot> boot +.Pp +Remove the 5 second pause at boot-time permanently, causing +.Nm +to load the kernel immediately without prompting: +.Pp +.Dl # echo \&"boot\&" > /etc/boot.conf +.Pp +Use serial console on the first serial port, with the usual 9600 8N1 settings. +A null modem cable should connect the specified serial port to a terminal. +Useful for debugging. +.Pp +.Dl boot> machine console rs232.9600.8.none +.Pp +Boot the kernel named +.Pa /bsd +from the second SCSI disk in +.Dq User Kernel Configuration +mode (see +.Xr boot_config 8 ) . +This mechanism allows for the explicit enabling and disabling of devices +during the current boot sequence, as well as the modification +of device parameters. +Once booted, such changes can be made permanent by using +.Xr config 8 Ns 's +.Fl e +option. +.Pp +.Dl boot> boot sd1a:/bsd -c +.Sh SEE ALSO +.Xr gzip 1 , +.Xr autoconf 4 , +.Xr ddb 4 , +.Xr boot_config 8 , +.Xr boot_hppa 8 , +.\" .Xr installboot 8 , +.Xr reboot 8 +.Pp +RFC 1950 describes the zlib library interface. +.Pp +The official home page for the version of zlib used in this +operating system see http://quest.jpl.nasa.gov/zlib/. +.Sh HISTORY +This program was written by Michael Shalayeff for +.Ox 2.1 . +The hppa specific parts were written by Michael Shalayeff and Miodrag Vallat +for +.Ox 3.1 . +.Sh CAVEATS +Making mistakes in console paths may cost you a toupee. +.Sh BUGS +Changing the display resolution (mode) on a graphics console does not work +correctly. diff --git a/sys/arch/hppa64/stand/boot/conf.c b/sys/arch/hppa64/stand/boot/conf.c new file mode 100644 index 00000000000..91ecd77b2b1 --- /dev/null +++ b/sys/arch/hppa64/stand/boot/conf.c @@ -0,0 +1,51 @@ +/* $OpenBSD: conf.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */ + +/* + * Copyright (c) 2005 Michael Shalayeff + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <libsa.h> +#include <lib/libsa/ufs.h> +#include <lib/libsa/cd9660.h> +#include <dev/cons.h> + +const char version[] = "0.8"; +int debug = 0; + +struct fs_ops file_system[] = { + { ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, + ufs_stat, ufs_readdir }, + { cd9660_open, cd9660_close, cd9660_read, cd9660_write, cd9660_seek, + cd9660_stat, cd9660_readdir }, + { lif_open, lif_close, lif_read, lif_write, lif_seek, + lif_stat, lif_readdir }, +}; +int nfsys = NENTS(file_system); + +struct devsw devsw[] = { + { "dk", iodcstrategy, dkopen, dkclose, noioctl }, + { "ct", iodcstrategy, ctopen, ctclose, noioctl }, + { "lf", iodcstrategy, lfopen, lfclose, noioctl } +}; +int ndevs = NENTS(devsw); + +struct consdev constab[] = { + { ite_probe, ite_init, ite_getc, ite_putc }, + { NULL } +}; +struct consdev *cn_tab; + diff --git a/sys/arch/hppa64/stand/boot/exec.c b/sys/arch/hppa64/stand/boot/exec.c new file mode 100644 index 00000000000..adc206b3a19 --- /dev/null +++ b/sys/arch/hppa64/stand/boot/exec.c @@ -0,0 +1,42 @@ +/* $OpenBSD: exec.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */ + +/* + * Copyright (c) 2005 Michael Shalayeff + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <machine/pdc.h> +#include "libsa.h" +#include <lib/libsa/loadfile.h> +#include <stand/boot/bootarg.h> +#include "dev_hppa64.h" + +typedef void (*startfuncp)(int, int, int, int, int, int, caddr_t) + __attribute__ ((noreturn)); + +void +run_loadfile(u_long *marks, int howto) +{ + fcacheall(); + + __asm("mtctl %r0, %cr17"); + __asm("mtctl %r0, %cr17"); + /* stack and the gung is ok at this point, so, no need for asm setup */ + (*(startfuncp)(marks[MARK_ENTRY]))((int)(long)(long)pdc, howto, bootdev, + marks[MARK_END], BOOTARG_APIVER, BOOTARG_LEN, (caddr_t)BOOTARG_OFF); + + /* not reached */ +} diff --git a/sys/arch/hppa64/stand/boot/ld.script b/sys/arch/hppa64/stand/boot/ld.script new file mode 100644 index 00000000000..51aed14df19 --- /dev/null +++ b/sys/arch/hppa64/stand/boot/ld.script @@ -0,0 +1,61 @@ +/* $OpenBSD: ld.script,v 1.1 2005/04/01 10:40:48 mickey Exp $ */ + +OUTPUT_FORMAT("elf64-hppa") +OUTPUT_ARCH(hppa2.0w) +ENTRY(begin) + +SECTIONS { + + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .text : { + *(.text) + *(.text.*) + *(.rodata) + *(.rodata1) + *($CODE$) + etext = .; + } = 0x08000240 + + /* Read-write sections, merged into data segment: */ + .data : { + $global$ = .; + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + edata = ABSOLUTE(.); + } = 0 + + .opd : { *(.opd) } + PROVIDE(__gp = .); + .plt : { *(.plt) } + .dlt : { *(.dlt) } + + .bss : { + __bss_start = .; + *(.dynbss) + *(.bss) + *(.sbss) + *(.scommon) + *(COMMON) + end = ABSOLUTE(.); + __bss_end = .; + } + + /* don't need an unwind in the boot, unless we'll have a boot-ddb (; */ + /DISCARD/ : + { + *(.PARISC.unwind) + *(.exitcall.exit) + *(.interp) + *(.dynsym) + *(.dynstr) + *(.dynamic) + *(.hash) + *(.stub) + } +} + diff --git a/sys/arch/hppa64/stand/boot/srt0.S b/sys/arch/hppa64/stand/boot/srt0.S new file mode 100644 index 00000000000..99498dbf970 --- /dev/null +++ b/sys/arch/hppa64/stand/boot/srt0.S @@ -0,0 +1,181 @@ +/* $OpenBSD: srt0.S,v 1.1 2005/04/01 10:40:48 mickey Exp $ */ + +/* + * Copyright (c) 2005 Michael Shalayeff + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* + * Copyright 1996 1995 by Open Software Foundation, Inc. + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appears in all copies and + * that both the copyright notice and this permission notice appear in + * supporting documentation. + * + * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, + * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ +; +; Copyright (c) 1990 mt Xinu, Inc. All rights reserved. +; Copyright (c) 1990 University of Utah. All rights reserved. +; +; This file may be freely distributed in any form as long as +; this copyright notice is included. +; THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +; IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +; WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +; +; Utah $Hdr: srt0.c 1.3 94/12/13$ +; + +#define _LOCORE +#include <machine/iomod.h> +#include <machine/asm.h> +#include <machine/frame.h> + +/* + * This is the ending of the begin + */ +ENTRY(begin,0) + + blr %r0,%r5 ; Get address of 'boff' into 'r5', + ldo begin-boff(%r5),%r5 ; and subtract to get 'begin'. +boff + ldil L%RELOC,%r4 + ldo R%RELOC(%r4),%r4 + ldo start-begin(%r4),%rp + ldil L%edata,%r3 + ldo R%edata(%r3),%r3 ; Get address of edata. + ldil L%begin,%r1 + ldo R%begin(%r1),%r1 ; Get address of begin + sub %r3,%r1,%r3 ; Subtract to get # of bytes to copy +copyloop ; do + ldwm 4(%r5),%r1 ; *r4++ = *r5++; + addib,>= -4,%r3,copyloop ; while (--r3 >= 0); + stwm %r1,4(%r4) + + ; here we zero the .bss + ldil L%__bss_start, %r4 + ldo R%__bss_start(%r4), %r4 + ldil L%__bss_end, %r3 + ldo R%__bss_end(%r3), %r3 +zeroloop + combf,<,n %r3,%r4, zeroloop ; while (r4 < r3); + stwm %r0,4(%r4) ; *r4++ = 0; + + ldil L%$global$,%dp + ldo R%$global$(%dp),%dp + ldil L%start,%r1 + ldo R%start(%r1),%r1 + sub %dp,%r1,%dp ; Subtract to get difference + add %rp,%dp,%dp ; and relocate it. + +; +; We have relocated ourself to RELOC. If we are running on a machine +; with separate instruction and data caches, we must flush our data +; cache before trying to execute the code starting at rp. +; + ldil L%RELOC,%r22 ; Set %t1 to start of relocated code. + ldo R%RELOC(%r22),%r22 + ldil L%edata,%r21 ; Set r21 to address of edata + ldo R%edata(%r21),%r21 + ldil L%begin,%r1 ; set %r1 to address of begin + ldo R%begin(%r1),%r1 + sub %r21,%r1,%r21 ; Subtract to get length + mtsp %r0,%sr0 ; Set sr0 to kernel space. + ldo -1(%r21),%r21 + fdc %r21(0,%r22) +loop addib,>,n -16,%r21,loop ; Decrement by cache line size (16). + fdc %r21(%sr0,%r22) + fdc 0(%sr0,%r22) ; Flush first word at addr to handle + sync ; arbitrary cache line boundary. + nop ; Prevent prefetching. + nop + nop + nop + nop + nop + nop + bv 0(%rp) + nop +EXIT(begin) /* jump to relocated code */ + +start + ldil L%HEAP_LIMIT, %sp + ldo R%HEAP_LIMIT(%sp), %sp + + .import bootprompt, data + ldil L%bootprompt, %r1 + stw %arg0, R%bootprompt(%r1) + b boot ; Call boot(), + copy %r0, %arg0 ; use default boot device + nop + +/* + * rtt - restart the box + */ +LEAF_ENTRY(_rtt) + ldil L%LBCAST_ADDR, %arg1 + ldi CMD_RESET, %arg0 + stw %arg0, R%iomod_command(%arg1) +forever ; Loop until bus reset takes effect. + b,n forever + + bv 0(%rp) + ldo -48(%sp),%sp +EXIT(_rtt) + +ENTRY(pdc_call,96) + copy %r3, %r1 + std %rp, HPPA_FRAME_RP(%sp) + copy %sp, %r3 + std,ma %r1, HPPA_FRAME_SIZE+8*4(%sp) + + copy %arg0, %r1 + copy %arg1, %arg0 + copy %arg2, %arg1 + copy %arg3, %arg2 + copy arg4, %arg3 + stw arg5, -(32 + 4*(4 + 1))(%sp) + stw arg6, -(32 + 4*(5 + 1))(%sp) + stw arg7, -(32 + 4*(6 + 1))(%sp) + ldw 0(ap), arg5 + ldw 8(ap), arg6 + ldw 16(ap), arg7 + stw arg5, -(32 + 4*(7 + 1))(%sp) + stw arg6, -(32 + 4*(8 + 1))(%sp) + stw arg7, -(32 + 4*(9 + 1))(%sp) + + .call + blr %r0, %rp + bv,n %r0(%r1) + nop + + ldd HPPA_FRAME_RP(%r3), %rp + bv %r0(%rp) + ldd,mb -(HPPA_FRAME_SIZE+8*4)(%sp), %r3 +EXIT(pdc_call) + + .end diff --git a/sys/arch/hppa64/stand/cdboot/Makefile b/sys/arch/hppa64/stand/cdboot/Makefile new file mode 100644 index 00000000000..6ff9c00821a --- /dev/null +++ b/sys/arch/hppa64/stand/cdboot/Makefile @@ -0,0 +1,55 @@ +# $OpenBSD: Makefile,v 1.1 2005/04/01 10:40:48 mickey Exp $ + +NOMAN= no man +S =${.CURDIR}/../../../.. +CLEANFILES+= cdboot.gdb cdboot.map + +.if ${MACHINE} == "hppa64" + +PROG= cdboot +SRCS= srt0.S cdboot.c pdc.c itecons.c dev_hppa64.c dk.c +LD?= ld +LDFLAGS+=-Bstatic -nostartfiles -nostdlib -N -Ttext $(LINKADDR) +LDFLAGS+=-T ${.CURDIR}/ld.script -Map cdboot.map +SIZE?= size +STRIP?= strip +STANDIR=${.CURDIR}/.. +CRTBEGIN= +CRTEND= + +SAREL= +USE_LOADFILE=yes +.include "${S}/lib/libsa/Makefile.inc" +DPADD+= $(SALIB) $(LIBKERN) +LDADD+= $(SALIB) $(LIBKERN) + +.PATH: ${S}/stand/boot +.PATH: ${.CURDIR}/../boot +.PATH: ${.CURDIR}/../libsa + +all: ${PROG} + +clean:: + rm -f a.out [Ee]rrs mklog core *.core \ + ${PROG} ${OBJS} ${LOBJS} ${CLEANFILES} + +realinstall: + ${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \ + ${PROG} ${DESTDIR}${BINDIR} + +# TODO check for <=32k +${PROG}: $(OBJS) $(DPADD) + $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LDADD) + @cp ${PROG} ${PROG}.gdb + ${STRIP} ${PROG} + @${SIZE} $(PROG) + @${MKBOOT} -v ${PROG} ${PROG}.lif + @mv ${PROG}.lif ${PROG} +.else +NOPROG= +.endif + +.include <bsd.prog.mk> + +CPPFLAGS+=-DRELOC=${LOADADDR} -DHEAP_LIMIT=${HEAP_LIMIT} +CFLAGS+=$(SACFLAGS) -I../.. -I${.CURDIR}/../libsa -I${S}/stand/boot diff --git a/sys/arch/hppa64/stand/cdboot/cdboot.c b/sys/arch/hppa64/stand/cdboot/cdboot.c new file mode 100644 index 00000000000..2ceb33315df --- /dev/null +++ b/sys/arch/hppa64/stand/cdboot/cdboot.c @@ -0,0 +1,82 @@ +/* $OpenBSD: cdboot.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */ + +/* + * Copyright (c) 2005 Michael Shalayeff + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/reboot.h> +#include <sys/stat.h> +#include <libsa.h> +#include <lib/libsa/cd9660.h> +#include <lib/libsa/loadfile.h> +#include <dev/cons.h> +#include <machine/pdc.h> +#include <stand/boot/bootarg.h> +#include "dev_hppa64.h" +#include "cmd.h" + +dev_t bootdev; +int debug = 1; +int bootprompt = 1; + +struct fs_ops file_system[] = { + { cd9660_open, cd9660_close, cd9660_read, cd9660_write, cd9660_seek, + cd9660_stat, cd9660_readdir }, +}; +int nfsys = NENTS(file_system); + +struct devsw devsw[] = { + { "dk", iodcstrategy, dkopen, dkclose, noioctl }, +}; +int ndevs = NENTS(devsw); + +struct consdev constab[] = { + { ite_probe, ite_init, ite_getc, ite_putc }, + { NULL } +}; +struct consdev *cn_tab; + +typedef void (*startfuncp)(int, int, int, int, int, int, caddr_t) + __attribute__ ((noreturn)); + +void +boot(dev_t dev) +{ + u_long marks[MARK_MAX]; + char path[128]; + + pdc_init(); + cninit(); + devboot(dev, path); + strncpy(path + strlen(path), ":/bsd.rd", 9); + printf(">> OpenBSD/" MACHINE " CDBOOT 0.1\n" + "booting %s: ", path); + + marks[MARK_START] = (u_long)DEFAULT_KERNEL_ADDRESS; + if (!loadfile(path, marks, LOAD_KERNEL)) { + marks[MARK_END] = ALIGN(marks[MARK_END] - + (u_long)DEFAULT_KERNEL_ADDRESS); + fcacheall(); + + __asm("mtctl %r0, %cr17"); + __asm("mtctl %r0, %cr17"); + (*(startfuncp)(marks[MARK_ENTRY]))((int)(long)pdc, 0, bootdev, + marks[MARK_END], BOOTARG_APIVER, BOOTARG_LEN, + (caddr_t)BOOTARG_OFF); + /* not reached */ + } +} diff --git a/sys/arch/hppa64/stand/cdboot/ld.script b/sys/arch/hppa64/stand/cdboot/ld.script new file mode 100644 index 00000000000..b36df9be9e4 --- /dev/null +++ b/sys/arch/hppa64/stand/cdboot/ld.script @@ -0,0 +1,49 @@ +/* $OpenBSD: ld.script,v 1.1 2005/04/01 10:40:48 mickey Exp $ */ + +OUTPUT_FORMAT("elf64-hppa") +OUTPUT_ARCH(hppa2.0w) +ENTRY(begin) + +SECTIONS { + + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .text : { + *(.text) + *(.text.*) + *(.rodata) + *(.rodata1) + *($CODE$) + etext = .; + } = 0x08000240 + + /* Read-write sections, merged into data segment: */ + .data : { + $global$ = .; + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + edata = ABSOLUTE(.); + } = 0 + + .bss : { + __bss_start = .; + *(.dynbss) + *(.bss) + *(.sbss) + *(.scommon) + *(COMMON) + end = ABSOLUTE(.); + __bss_end = .; + } + + /* don't need an unwind in the boot, unless we'll have a boot-ddb (; */ + /DISCARD/ : + { + *(.PARISC.unwind) + } +} + diff --git a/sys/arch/hppa64/stand/libkern/Makefile b/sys/arch/hppa64/stand/libkern/Makefile new file mode 100644 index 00000000000..6815b67c49b --- /dev/null +++ b/sys/arch/hppa64/stand/libkern/Makefile @@ -0,0 +1,29 @@ +# $OpenBSD: Makefile,v 1.1 2005/04/01 10:40:48 mickey Exp $ + +LIB= kern + +S= ${.CURDIR}/../../../.. +M= ${KERNDIR}/arch/${MACHINE_ARCH} +SADIR= ${.CURDIR}/.. +KERNDIR=$S/lib/libkern + +NOPIC= nopic +NOPROFILE= noprofile + +.PATH: ${KERNDIR} + +.include "arch/hppa64/Makefile.inc" + +# Quad support +SRCS+= adddi3.c anddi3.c ashldi3.c ashrdi3.c cmpdi2.c divdi3.c iordi3.c \ + lshldi3.c lshrdi3.c moddi3.c muldi3.c negdi2.c notdi2.c qdivrem.c \ + subdi3.c ucmpdi2.c udivdi3.c umoddi3.c xordi3.c + +# Other stuff +SRCS+= srandom.c bcd.c + +install: + +.include <bsd.lib.mk> +CPPFLAGS+= ${DEBUGFLAGS} +CFLAGS+= ${SACFLAGS} diff --git a/sys/arch/hppa64/stand/libsa/Makefile b/sys/arch/hppa64/stand/libsa/Makefile new file mode 100644 index 00000000000..eda10f3436e --- /dev/null +++ b/sys/arch/hppa64/stand/libsa/Makefile @@ -0,0 +1,43 @@ +# $OpenBSD: Makefile,v 1.1 2005/04/01 10:40:48 mickey Exp $ + +.include "${.CURDIR}/../Makefile.inc" + +LIB= sa + +S=${.CURDIR}/../../../.. +SADIR=${.CURDIR}/.. +DIR_SA= $S/lib/libsa + +NOPROFILE=noprofile +NOPIC=nopic + +#AS=cat ; +#AS+= -R +#AS+= -a + +# hppa64 stuff +SRCS= machdep.c pdc.c itecons.c dev_hppa64.c time.c \ + ct.c dk.c lf.c lif.c cmd_hppa64.c + +# stand routines +SRCS+= alloc.c exit.c getfile.c gets.c globals.c \ + printf.c strerror.c strtol.c strchr.c ctime.c loadfile.c snprintf.c + +# io routines +SRCS+= close.c closeall.c dev.c disklabel.c dkcksum.c fstat.c ioctl.c lseek.c \ + open.c read.c stat.c write.c cread.c readdir.c cons.c + +# boot filesystems +SRCS+= ufs.c cd9660.c + +.PATH: ${DIR_SA} + +all: ${SALIB} + +install: + +.include <bsd.lib.mk> + +CPPFLAGS+=-DHEAP_LIMIT=${HEAP_LIMIT} ${DEBUGFLAGS} -DNO_NET +CPPFLAGS+=-I${S}/stand/boot +CFLAGS+=${SACFLAGS} -D__INTERNAL_LIBSA_CREAD -DCOMPAT_UFS diff --git a/sys/arch/hppa64/stand/libsa/cmd_hppa64.c b/sys/arch/hppa64/stand/libsa/cmd_hppa64.c new file mode 100644 index 00000000000..1aa6117cb07 --- /dev/null +++ b/sys/arch/hppa64/stand/libsa/cmd_hppa64.c @@ -0,0 +1,819 @@ +/* $OpenBSD: cmd_hppa64.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */ + +/* + * Copyright (c) 2002 Miodrag Vallat + * 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 ``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 HIS RELATIVES 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 MIND, 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. + */ + +/*#define DEBUG*/ + +#include <sys/param.h> +/* would come from <sys/param.h> if -D_KERNEL */ +#define offsetof(s, e) ((size_t)&((s *)0)->e) + +#include <machine/iomod.h> +#include <machine/pdc.h> + +#include <arch/hppa/dev/cpudevs.h> + +#include <libsa.h> +#include "cmd.h" +#include "dev_hppa64.h" /* pdc */ + +extern struct stable_storage sstor; +extern int sstorsiz; + +/* storage sizes we're interested in */ +#define CONSOLEOFFSET \ + offsetof(struct stable_storage, ss_console) +#define CONSOLESIZE \ + (offsetof(struct stable_storage, ss_console) + \ + sizeof(struct device_path)) + +#define KEYBOARDOFFSET \ + offsetof(struct stable_storage, ss_keyboard) +#define KEYBOARDSIZE \ + (offsetof(struct stable_storage, ss_keyboard) + \ + sizeof(struct device_path)) + +/* + * Table for the possible console devices found during the device walk. + */ +struct consoledev { + struct device_path dp; + int type; + int iodc_type; + int iodc_model; +}; + +#define PS2 1 +#define HIL 2 +#define SERIAL 3 +#define GRAPHICS 4 + +/* max. serial ports */ +#define MAX_SERIALS 4 +/* max. HIL and PS2 */ +#define MAX_KEYBOARDS 2 +/* max. heads */ +#define MAX_GRAPHICS 4 + +struct consoledev serials[MAX_SERIALS]; +struct consoledev keyboards[MAX_KEYBOARDS]; +struct consoledev graphics[MAX_GRAPHICS]; + +/* Relaxed device comparison */ +#define MATCH(dev1, dev2) \ + (dev1).dp_mod == (dev2).dp_mod && \ + (dev1).dp_bc[0] == (dev2).dp_bc[0] && \ + (dev1).dp_bc[1] == (dev2).dp_bc[1] && \ + (dev1).dp_bc[2] == (dev2).dp_bc[2] && \ + (dev1).dp_bc[3] == (dev2).dp_bc[3] && \ + (dev1).dp_bc[4] == (dev2).dp_bc[4] && \ + (dev1).dp_bc[5] == (dev2).dp_bc[5] + +int walked; + +void bus_walk(struct device_path *); +void register_device(struct consoledev *, int, + struct device_path *, struct iodc_data *, int, int); + +int Xconsole(void); +void print_console(void); +int set_graphics(struct device_path *, int, char *); +int set_serial(struct device_path *, int, char *); +int set_console(struct device_path *); + +int Xkeyboard(void); +void print_keyboard(void); +int set_keyboard(struct device_path *); + +struct cmd_table cmd_machine[] = { + { "console", CMDT_CMD, Xconsole }, + { "keyboard", CMDT_CMD, Xkeyboard }, + { NULL, }, +}; + +/* value to console speed table */ +int i_speeds[] = { + 50, + 75, + 110, + 150, + 300, + 600, + 1200, + 2400, + 4800, + 7200, + 9600, + 19200, + 38400, + 57600, + 115200, + 230400, +}; + +char *c_speeds[] = { + "50", + "75", + "110", + "150", + "300", + "600", + "1200", + "2400", + "4800", + "7200", + "9600", + "19200", + "38400", + "57600", + "115200", + "230400", +}; + +/* values to console parity table */ +char *parities[] = { + "none", + "odd", + "<unknown parity>", + "even", +}; + +/* + * C O N S O L E S E T T I N G S + */ + +void +print_console() +{ + int port, mode, speed, parity, bits; + int i; + +#ifdef DEBUG + printf("console flags %x mod %x bc %d/%d/%d/%d/%d/%d\n", + sstor.ss_console.dp_flags, + sstor.ss_console.dp_mod, + sstor.ss_console.dp_bc[0], + sstor.ss_console.dp_bc[1], + sstor.ss_console.dp_bc[2], + sstor.ss_console.dp_bc[3], + sstor.ss_console.dp_bc[4], + sstor.ss_console.dp_bc[5]); + + printf("console path %x/%x/%x/%x/%x/%x\n", + sstor.ss_console.dp_layers[0], + sstor.ss_console.dp_layers[1], + sstor.ss_console.dp_layers[2], + sstor.ss_console.dp_layers[3], + sstor.ss_console.dp_layers[4], + sstor.ss_console.dp_layers[5]); +#endif + + printf("Console path: "); + + /* look for a serial console */ + for (port = i = 0; i < MAX_SERIALS; i++) + if (MATCH(serials[i].dp, sstor.ss_console)) { + port = i + 1; + break; + } + + if (port == 0) { + /* + * Graphics console + */ + + for (port = i = 0; i < MAX_GRAPHICS; i++) + if (MATCH(graphics[i].dp, sstor.ss_console)) { + port = i; + break; + } + + /* + * If the console could still not be identified, consider + * it is a simplified encoding for the default graphics + * console. Hence port == 0, no need to check. + */ + if (port == 0) + printf("graphics"); + else + printf("graphics_%d", port); + + mode = sstor.ss_console.dp_layers[0]; + if (mode != 0) + printf(".%d", mode); + } else { + /* + * Serial console + */ + + if (port == 1) + printf("rs232"); + else + printf("rs232_%d", port); + + speed = PZL_SPEED(sstor.ss_console.dp_layers[0]); + printf(".%d", i_speeds[speed]); + + bits = PZL_BITS(sstor.ss_console.dp_layers[0]); + printf(".%d", bits); + + parity = PZL_PARITY(sstor.ss_console.dp_layers[0]); + printf(".%s", parities[parity]); + } + + printf("\n"); +} + +int +set_graphics(console, port, arg) + struct device_path *console; + int port; + char *arg; +{ + int maxmode, mode = 0; + char *digit; + + /* head */ + if (graphics[port].type == 0) { + printf("no such device found\n"); + return 0; + } + + /* mode */ + if (arg != NULL) { + for (digit = arg; *digit != '\0'; digit++) { + if (*digit >= '0' && *digit <= '9') + mode = 10 * mode + (*digit - '0'); + else { + printf("invalid mode specification, %s\n", + arg); + return 0; + } + } + + if (mode <= 0) { + printf("invalid mode specification, %s\n", + arg); + return 0; + } + } + + /* + * If we are just changing the mode of the same graphics + * console, check that our mode is in the valid range. + */ + if (MATCH(graphics[port].dp, sstor.ss_console)) { + maxmode = sstor.ss_console.dp_layers[1]; + + /* pick back same mode if unspecified */ + if (mode == 0) + mode = sstor.ss_console.dp_layers[0]; + + if (mode > maxmode) { + printf("invalid mode value, available range is 1-%d\n", + maxmode); + return 0; + } + } else { + if (mode == 0) + mode = 1; + maxmode = mode; + } + + *console = graphics[port].dp; + console->dp_layers[0] = mode; + console->dp_layers[1] = maxmode; + console->dp_layers[2] = console->dp_layers[3] = + console->dp_layers[4] = console->dp_layers[5] = 0; + + return 1; +} + +int +set_serial(console, port, arg) + struct device_path *console; + int port; + char *arg; +{ + char *dot; + int i; + int speed, parity, bits; + + /* port */ + port--; + if (serials[port].type == 0) { + printf("no such device found\n"); + return 0; + } + + /* speed */ + dot = strchr(arg, '.'); + if (dot != NULL) + *dot++ = '\0'; + + speed = 0; + if (arg == NULL || *arg == '\0') { + for (i = 0; i < NENTS(i_speeds); i++) + if (i_speeds[i] == 9600) { + speed = i; + break; + } + } else { + for (i = 0; i < NENTS(c_speeds); i++) + if (strcmp(arg, c_speeds[i]) == 0) { + speed = i; + break; + } + if (speed == 0) { + printf("invalid speed specification, %s\n", arg); + return 0; + } + } + + /* data bits */ + arg = dot; + dot = strchr(arg, '.'); + + if (arg == NULL || *arg == '\0') + bits = 8; + else { + if (dot == arg + 1) + bits = *arg - '0'; + else + bits = 0; + + if (bits < 5 || bits > 8) { + printf("invalid bits specification, %s\n", arg); + return 0; + } + } + if (dot != NULL) + *dot++ = '\0'; + + /* parity */ + arg = dot; + if (arg == NULL || *arg == '\0') + parity = 0; /* none */ + else { + parity = -1; + for (i = 0; i <= 3; i++) + if (strcmp(arg, parities[i]) == 0) { + parity = i; + break; + } + if (parity == 2) + parity = -1; /* unknown parity */ + } + if (parity < 0) { + printf("invalid parity specification, %s\n", arg); + return 0; + } + + *console = serials[port].dp; + console->dp_layers[0] = PZL_ENCODE(bits, parity, speed); + + return 1; +} + +int +set_console(console) + struct device_path *console; +{ + char *arg = cmd.argv[1], *dot; + int port; + + /* extract first word */ + dot = strchr(arg, '.'); + if (dot != NULL) + *dot++ = '\0'; + + /* + * Graphics console + */ + if (strcmp(arg, "graphics") == 0) + return set_graphics(console, 0, dot); + if (strncmp(arg, "graphics_", 9) == 0) { + port = arg[9] - '0'; + if (port > 0 && port < MAX_GRAPHICS) + return set_graphics(console, port, dot); + } + + /* + * Serial console + */ + if (strcmp(arg, "rs232") == 0) + return set_serial(console, 1, dot); + if (strncmp(arg, "rs232_", 6) == 0) { + port = arg[6] - '0'; + if (port > 0 && port <= MAX_SERIALS) + return set_serial(console, port, dot); + } + + printf("invalid device specification, %s\n", arg); + return 0; +} + +int +Xconsole() +{ + struct device_path console; + int rc; + + /* walk the device list if not already done */ + if (walked == 0) { + bus_walk(NULL); + walked++; + } + + if (sstorsiz < CONSOLESIZE) { + printf("no console information in stable storage\n"); + return 0; + } + + if (cmd.argc == 1) { + print_console(); + } else { + console = sstor.ss_console; + if (set_console(&console)) { + if (memcmp(&sstor.ss_console, &console, + sizeof console) != 0) { + sstor.ss_console = console; + + /* alea jacta est */ + rc = (*pdc)(PDC_STABLE, PDC_STABLE_WRITE, + CONSOLEOFFSET, &sstor.ss_console, + sizeof(sstor.ss_console)); + if (rc != 0) { + printf("failed to save console settings, error %d\n", + rc); + /* read sstor again for safety */ + (*pdc)(PDC_STABLE, PDC_STABLE_READ, + CONSOLEOFFSET, &sstor.ss_console, + sizeof(sstor.ss_console)); + } else + printf("you will need to power-cycle " + "your machine for the changes " + "to take effect.\n"); + } + print_console(); + } + } + + return 0; +} + +/* + * K E Y B O A R D S E T T I N G S + */ + +void +print_keyboard() +{ + int type; + int i; + +#ifdef DEBUG + printf("keyboard flags %x mod %x bc %d/%d/%d/%d/%d/%d\n", + sstor.ss_keyboard.dp_flags, + sstor.ss_keyboard.dp_mod, + sstor.ss_keyboard.dp_bc[0], + sstor.ss_keyboard.dp_bc[1], + sstor.ss_keyboard.dp_bc[2], + sstor.ss_keyboard.dp_bc[3], + sstor.ss_keyboard.dp_bc[4], + sstor.ss_keyboard.dp_bc[5]); + + printf("keyboard path %x/%x/%x/%x/%x/%x\n", + sstor.ss_keyboard.dp_layers[0], + sstor.ss_keyboard.dp_layers[1], + sstor.ss_keyboard.dp_layers[2], + sstor.ss_keyboard.dp_layers[3], + sstor.ss_keyboard.dp_layers[4], + sstor.ss_keyboard.dp_layers[5]); +#endif + + printf("Keyboard path: "); + + for (type = i = 0; i < MAX_KEYBOARDS; i++) + if (MATCH(keyboards[i].dp, sstor.ss_keyboard)) { + type = keyboards[i].type; + break; + } + + switch (type) { + case HIL: + printf("hil"); + break; + case PS2: + printf("ps2"); + break; + default: + printf("unknown"); + break; + } + + printf("\n"); +} + +int +set_keyboard(keyboard) + struct device_path *keyboard; +{ + int i; + char *arg = cmd.argv[1]; + int type; + + if (strcmp(arg, "hil") == 0) + type = HIL; + else if (strcmp(arg, "ps2") == 0) + type = PS2; + else { + printf("invalid device specification, %s\n", arg); + return 0; + } + + for (i = 0; i < MAX_KEYBOARDS; i++) + if (keyboards[i].type == type) { + *keyboard = keyboards[i].dp; + return 1; + } + + printf("no such device found\n"); + return 0; +} + +int +Xkeyboard() +{ + struct device_path keyboard; + int rc; + + /* walk the device list if not already done */ + if (walked == 0) { + bus_walk(NULL); + walked++; + } + + if (sstorsiz < KEYBOARDSIZE) { + printf("no keyboard information in stable storage\n"); + return 0; + } + + if (cmd.argc == 1) { + print_keyboard(); + } else { + keyboard = sstor.ss_keyboard; + if (set_keyboard(&keyboard)) { + if (memcmp(&sstor.ss_keyboard, &keyboard, + sizeof keyboard) != 0) { + sstor.ss_keyboard = keyboard; + + /* alea jacta est */ + rc = (*pdc)(PDC_STABLE, PDC_STABLE_WRITE, + KEYBOARDOFFSET, &sstor.ss_keyboard, + sizeof(sstor.ss_keyboard)); + if (rc != 0) { + printf("failed to save keyboard settings, error %d\n", + rc); + /* read sstor again for safety */ + (*pdc)(PDC_STABLE, PDC_STABLE_READ, + KEYBOARDOFFSET, &sstor.ss_keyboard, + sizeof(sstor.ss_keyboard)); + } else + printf("you will need to power-cycle " + "your machine for the changes " + "to take effect.\n"); + } + print_keyboard(); + } + } + + return 0; +} + +/* + * U T I L I T I E S + */ + +/* + * Bus walker. + * This routine will walk all the modules on a given bus, registering + * serial ports, keyboard and graphics devices as they are found. + */ +void +bus_walk(struct device_path *idp) +{ + struct device_path dp; + struct pdc_memmap memmap; + struct iodc_data mptr; + int err, i, kluge_ps2 = 0; /* kluge, see below */ + + for (i = 0; i < MAXMODBUS; i++) { + + if (idp) { + dp.dp_bc[0] = idp->dp_bc[1]; + dp.dp_bc[1] = idp->dp_bc[2]; + dp.dp_bc[2] = idp->dp_bc[3]; + dp.dp_bc[3] = idp->dp_bc[4]; + dp.dp_bc[4] = idp->dp_bc[5]; + dp.dp_bc[5] = idp->dp_mod; + } else { + dp.dp_bc[0] = dp.dp_bc[1] = dp.dp_bc[2] = + dp.dp_bc[3] = dp.dp_bc[4] = dp.dp_bc[5] = -1; + } + + dp.dp_mod = i; + if ((pdc)(PDC_MEMMAP, PDC_MEMMAP_HPA, &memmap, &dp) < 0 && + (pdc)(PDC_SYSMAP, PDC_SYSMAP_HPA, &memmap, &dp) < 0) + continue; + + if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, &pdcbuf, memmap.hpa, + IODC_DATA, &mptr, sizeof(mptr))) < 0) + continue; + +#ifdef DEBUG + printf("device %d/%d/%d/%d/%d/%d " + "flags %d mod %x type %x model %x\n", + dp.dp_bc[0], dp.dp_bc[1], dp.dp_bc[2], dp.dp_bc[3], + dp.dp_bc[4], dp.dp_bc[5], dp.dp_flags, dp.dp_mod, + mptr.iodc_type, mptr.iodc_sv_model); +#endif + /* + * If the device can be considered as a valid rs232, + * graphics console or keyboard, register it. + * + * Unfortunately, devices which should be considered as + * ``main'' aren't necessarily seen first. + * The rules we try to enforce here are as follows: + * - GIO PS/2 ports wins over any other PS/2 port. + * - the first GIO serial found wins over any other + * serial port. + * The second rule is a bit tricky to achieve, since on + * some machines (for example, 715/100XC), the two serial + * ports are not seen as attached to the same busses... + */ + switch (mptr.iodc_type) { + case HPPA_TYPE_BCPORT: + bus_walk(&dp); + break; + case HPPA_TYPE_BHA: + case HPPA_TYPE_BRIDGE: + /* if there was no phantomas here */ + if (dp.dp_bc[5] == -1) { + dp.dp_bc[0] = dp.dp_bc[1]; + dp.dp_bc[1] = dp.dp_bc[2]; + dp.dp_bc[2] = dp.dp_bc[3]; + dp.dp_bc[3] = dp.dp_bc[4]; + dp.dp_bc[4] = dp.dp_bc[5]; + dp.dp_bc[5] = dp.dp_mod; + dp.dp_mod = 0; + } + bus_walk(&dp); + break; + case HPPA_TYPE_ADIRECT: + switch (mptr.iodc_sv_model) { + case HPPA_ADIRECT_RS232: + register_device(serials, MAX_SERIALS, + &dp, &mptr, SERIAL, 0); + break; + case HPPA_ADIRECT_HIL: + register_device(keyboards, MAX_KEYBOARDS, + &dp, &mptr, HIL, 0); + break; + case HPPA_ADIRECT_PEACOCK: + case HPPA_ADIRECT_LEONARDO: + register_device(graphics, MAX_GRAPHICS, + &dp, &mptr, GRAPHICS, 0); + break; + } + break; + case HPPA_TYPE_FIO: + switch (mptr.iodc_sv_model) { + case HPPA_FIO_HIL: + register_device(keyboards, MAX_KEYBOARDS, + &dp, &mptr, HIL, 0); + break; + case HPPA_FIO_RS232: + register_device(serials, MAX_SERIALS, + &dp, &mptr, SERIAL, 0); + break; + case HPPA_FIO_DINOPCK: + register_device(keyboards, MAX_KEYBOARDS, + &dp, &mptr, PS2, 0); + break; + case HPPA_FIO_GPCIO: + /* + * KLUGE! At this point, there is no way to + * know if this port is the keyboard port or + * the mouse port. + * Let's assume the first port found is the + * keyboard, and ignore the others. + */ + if (kluge_ps2 != 0) + break; + register_device(keyboards, MAX_KEYBOARDS, + &dp, &mptr, PS2, 1); + kluge_ps2++; + break; + case HPPA_FIO_GRS232: + { + int j, first; + + /* + * If a GIO serial port is already registered, + * register as extra port... + */ + first = 1; + for (j = 0; j < MAX_SERIALS; j++) + if (serials[j].type == SERIAL && + serials[j].iodc_type == + HPPA_TYPE_FIO && + serials[j].iodc_model == + HPPA_FIO_GRS232) { + first = 0; + break; + } + + register_device(serials, MAX_SERIALS, + &dp, &mptr, SERIAL, first); + } + break; + case HPPA_FIO_SGC: + register_device(graphics, MAX_GRAPHICS, + &dp, &mptr, GRAPHICS, 0); + break; + case HPPA_FIO_GSGC: + register_device(graphics, MAX_GRAPHICS, + &dp, &mptr, GRAPHICS, 1); + break; + } + break; + } + } +} + +void +register_device(devlist, cnt, dp, mptr, type, first) + struct consoledev *devlist; + int cnt; + struct device_path *dp; + struct iodc_data *mptr; + int type; + int first; +{ + int i; + struct consoledev *dev; + + for (i = 0, dev = devlist; i < cnt; i++, dev++) + if (dev->type == 0) + break; + + if (i == cnt) { +#ifdef DEBUG + printf("can't register device, need more room!\n"); +#endif + return; + } + + /* + * If this is supposedly the main device, insert on top + */ + if (first != 0) { + memcpy(devlist + 1, devlist, + (cnt - 1) * sizeof(struct consoledev)); + dev = devlist; + } + + dev->dp = *dp; + dev->type = type; + dev->iodc_type = mptr->iodc_type; + dev->iodc_model = mptr->iodc_sv_model; + +#ifdef DEBUG + printf("(registered as type %d)\n", type); +#endif +} diff --git a/sys/arch/hppa64/stand/libsa/ct.c b/sys/arch/hppa64/stand/libsa/ct.c new file mode 100644 index 00000000000..44316e10b12 --- /dev/null +++ b/sys/arch/hppa64/stand/libsa/ct.c @@ -0,0 +1,71 @@ +/* $OpenBSD: ct.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */ + +/* + * Copyright (c) 2005 Michael Shalayeff + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* + * Copyright 1996 1995 by Open Software Foundation, Inc. + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appears in all copies and + * that both the copyright notice and this permission notice appear in + * supporting documentation. + * + * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, + * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "libsa.h" + +#include <sys/param.h> +#include <sys/disklabel.h> +#include <sys/reboot.h> + +#include <machine/pdc.h> +#include <machine/iomod.h> + +#include "dev_hppa64.h" + +int +ctopen(struct open_file *f, ...) +{ + struct hppa_dev *dp = f->f_devdata; + + if (!(dp->pz_dev = pdc_findev(-1, PCL_SEQU))) + return (ENXIO); + + return (0); +} + +/*ARGSUSED*/ +int +ctclose(f) + struct open_file *f; +{ + free (f->f_devdata, sizeof(struct hppa_dev)); + f->f_devdata = NULL; + return 0; +} diff --git a/sys/arch/hppa64/stand/libsa/dev_hppa64.c b/sys/arch/hppa64/stand/libsa/dev_hppa64.c new file mode 100644 index 00000000000..75eb87528e4 --- /dev/null +++ b/sys/arch/hppa64/stand/libsa/dev_hppa64.c @@ -0,0 +1,228 @@ +/* $OpenBSD: dev_hppa64.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */ + +/* + * Copyright (c) 2005 Michael Shalayeff + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "libsa.h" +#include <sys/param.h> +#include <sys/disklabel.h> +#include <sys/reboot.h> +#include <dev/cons.h> + +#include <machine/iomod.h> + +#include "dev_hppa64.h" + +extern int debug; + +const char cdevs[][4] = { + "ite", "", "", "", "", "", "", "", + "", "", "", "", "" +}; +const int ncdevs = NENTS(cdevs); + +const struct pdc_devs { + char name[3]; + int dev_type; +} pdc_devs[] = { + { "dk", 0 }, + { "ct", 1 }, + { "lf", 2 }, + { "", -1 }, + { "rd", -1 }, + { "sw", -1 }, + { "fl", -1 }, +}; + +/* pass dev_t to the open routines */ +int +devopen(f, fname, file) + struct open_file *f; + const char *fname; + char **file; +{ + struct hppa_dev *hpd; + const struct pdc_devs *dp = pdc_devs; + int rc = 1; + + if (!(*file = strchr(fname, ':'))) + return ENODEV; + else + (*file)++; + +#ifdef DEBUGBUG + if (debug) + printf("devopen: "); +#endif + + for (dp = pdc_devs; dp < &pdc_devs[NENTS(pdc_devs)]; dp++) + if (!strncmp(fname, dp->name, sizeof(dp->name)-1)) + break; + + if (dp >= &pdc_devs[NENTS(pdc_devs)] || dp->dev_type < 0) + return ENODEV; +#ifdef DEBUGBUG + if (debug) + printf("%s\n", dp->name); +#endif + + if (!(hpd = alloc(sizeof *hpd))) { +#ifdef DEBUG + printf ("devopen: no mem\n"); +#endif + } else { + bzero(hpd, sizeof *hpd); + hpd->bootdev = bootdev; + hpd->buf = (char *)(((u_long)hpd->ua_buf + IODC_MINIOSIZ-1) & + ~(IODC_MINIOSIZ-1)); + f->f_devdata = hpd; + if ((rc = (*devsw[dp->dev_type].dv_open)(f, file)) == 0) { + f->f_dev = &devsw[dp->dev_type]; + return 0; + } + free (hpd, 0); + f->f_devdata = NULL; + } + + if (!(f->f_flags & F_NODEV)) + f->f_dev = &devsw[dp->dev_type]; + + if (!f->f_devdata) + *file = NULL; + + return rc; +} + +void +devboot(dev, p) + dev_t dev; + char *p; +{ + const char *q; + if (!dev) { + int type, unit; + + switch (PAGE0->mem_boot.pz_class) { + case PCL_RANDOM: + type = 0; + unit = PAGE0->mem_boot.pz_layers[0]; + break; + case PCL_SEQU: + type = 1; + unit = PAGE0->mem_boot.pz_layers[0]; + break; + case PCL_NET_MASK|PCL_SEQU: + type = 2; + unit = 0; + break; + default: + type = 0; + unit = 0; + break; + } + dev = bootdev = MAKEBOOTDEV(type, 0, 0, unit, B_PARTITION(dev)); + } +#ifdef _TEST + *p++ = '/'; + *p++ = 'd'; + *p++ = 'e'; + *p++ = 'v'; + *p++ = '/'; + *p++ = 'r'; +#endif + /* quick copy device name */ + for (q = pdc_devs[B_TYPE(dev)].name; (*p++ = *q++);); + p[-1] = '0' + B_UNIT(dev); + *p++ = 'a' + B_PARTITION(dev); + *p = '\0'; +} + +int pch_pos; + +void +putchar(c) + int c; +{ + switch(c) { + case '\177': /* DEL erases */ + cnputc('\b'); + cnputc(' '); + case '\b': + cnputc('\b'); + if (pch_pos) + pch_pos--; + break; + case '\t': + do + cnputc(' '); + while(++pch_pos % 8); + break; + case '\n': + case '\r': + cnputc(c); + pch_pos=0; + break; + default: + cnputc(c); + pch_pos++; + break; + } +} + +int +getchar() +{ + int c = cngetc(); + + if (c == '\r') + c = '\n'; + + if ((c < ' ' && c != '\n') || c == '\177') + return(c); + + putchar(c); + + return(c); +} + +char ttyname_buf[8]; +char * +ttyname(fd) + int fd; +{ + snprintf(ttyname_buf, sizeof ttyname_buf, "%s%d", + cdevs[major(cn_tab->cn_dev)], + minor(cn_tab->cn_dev)); + return (ttyname_buf); +} + +dev_t +ttydev(name) + char *name; +{ + int i, unit = -1; + char *no = name + strlen(name) - 1; + + while (no >= name && *no >= '0' && *no <= '9') + unit = (unit < 0 ? 0 : (unit * 10)) + *no-- - '0'; + if (no < name || unit < 0) + return (NODEV); + for (i = 0; i < ncdevs; i++) + if (strncmp(name, cdevs[i], no - name + 1) == 0) + return (makedev(i, unit)); + return (NODEV); +} diff --git a/sys/arch/hppa64/stand/libsa/dev_hppa64.h b/sys/arch/hppa64/stand/libsa/dev_hppa64.h new file mode 100644 index 00000000000..a47daa2173a --- /dev/null +++ b/sys/arch/hppa64/stand/libsa/dev_hppa64.h @@ -0,0 +1,43 @@ +/* $OpenBSD: dev_hppa64.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */ + + +#define IOPGSHIFT 11 +#define IONBPG (1 << IOPGSHIFT) +#define IOPGOFSET (IONBPG - 1) + +struct disklabel; +struct hppa_dev { + dev_t bootdev; + struct pz_device *pz_dev; /* device descriptor */ + daddr_t fsoff; /* offset to the file system */ + daddr_t last_blk; /* byte offset for last read blk */ + size_t last_read; /* amount read last time */ + struct disklabel *label; + /* buffer to cache data (aligned properly) */ + char *buf; + char ua_buf[IODC_IOSIZ + IODC_MINIOSIZ]; +}; + +#ifdef PDCDEBUG +#define DEVPATH_PRINT(dp) \ + printf("%x, %d.%d.%d.%d.%d.%d, 0x%x, %x.%x.%x.%x.%x.%x\n", \ + (dp)->dp_flags, (dp)->dp_bc[0], (dp)->dp_bc[1], (dp)->dp_bc[2], \ + (dp)->dp_bc[3], (dp)->dp_bc[4], (dp)->dp_bc[5], (dp)->dp_mod, \ + (dp)->dp_layers[0], (dp)->dp_layers[1], (dp)->dp_layers[2], \ + (dp)->dp_layers[3], (dp)->dp_layers[4], (dp)->dp_layers[5]); +#define PZDEV_PRINT(dp) \ + printf("devpath={%x, %d.%d.%d.%d.%d.%d, 0x%x, %x.%x.%x.%x.%x.%x}," \ + "\n\thpa=%p, spa=%p, io=%p, class=%u\n", \ + (dp)->pz_flags, (dp)->pz_bc[0], (dp)->pz_bc[1], (dp)->pz_bc[2], \ + (dp)->pz_bc[3], (dp)->pz_bc[4], (dp)->pz_bc[5], (dp)->pz_mod, \ + (dp)->pz_layers[0], (dp)->pz_layers[1], (dp)->pz_layers[2], \ + (dp)->pz_layers[3], (dp)->pz_layers[4], (dp)->pz_layers[5], \ + (dp)->pz_hpa, (dp)->pz_spa, (dp)->pz_iodc_io, (dp)->pz_class); +#endif + +extern pdcio_t pdc; +extern int pdcbuf[]; /* PDC returns, pdc.c */ + +int iodc_rw(char *, u_int, u_int, int func, struct pz_device *); +const char *dk_disklabel(struct hppa_dev *dp, struct disklabel *label); +int pdc_call(void *, ...); diff --git a/sys/arch/hppa64/stand/libsa/dk.c b/sys/arch/hppa64/stand/libsa/dk.c new file mode 100644 index 00000000000..d20d19d5b3f --- /dev/null +++ b/sys/arch/hppa64/stand/libsa/dk.c @@ -0,0 +1,101 @@ +/* $OpenBSD: dk.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */ + +/* + * Copyright 1996 1995 by Open Software Foundation, Inc. + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appears in all copies and + * that both the copyright notice and this permission notice appear in + * supporting documentation. + * + * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, + * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "libsa.h" + +#include <sys/param.h> +#include <sys/disklabel.h> +#include <sys/reboot.h> +#include <machine/pdc.h> +#include <machine/iomod.h> + +#include "dev_hppa64.h" + +const char * +dk_disklabel(struct hppa_dev *dp, struct disklabel *label) +{ + char buf[DEV_BSIZE]; + size_t ret; + + if (iodcstrategy(dp, F_READ, LABELSECTOR, DEV_BSIZE, buf, &ret)) + if (ret != DEV_BSIZE) + return "cannot read disklabel"; + + return (getdisklabel(buf, label)); +} + +int +dkopen(struct open_file *f, ...) +{ + struct disklabel *lp; + struct hppa_dev *dp = f->f_devdata; + const char *st; + +#ifdef DEBUG + if (debug) + printf("dkopen(%p)\n", f); +#endif + + if (!(dp->pz_dev = pdc_findev(-1, PCL_RANDOM))) + return ENXIO; + + lp = dp->label; + st = NULL; + +#ifdef DEBUG + if (debug) + printf ("disklabel\n"); +#endif + + if ((st = dk_disklabel(dp, lp)) != NULL) { +#ifdef DEBUG + if (debug) + printf ("dkopen: %s\n", st); +#endif + /* we do not know if it's a disk or net, but do not fail */ + } else { + u_int i; + + i = B_PARTITION(dp->bootdev); + if (i >= lp->d_npartitions || !lp->d_partitions[i].p_size) + return (EPART); + + dp->fsoff = lp->d_partitions[i].p_offset; + } + +#ifdef DEBUGBUG + if (debug) + printf ("dkopen() ret\n"); +#endif + return (0); +} + +int +dkclose(f) + struct open_file *f; +{ + free (f->f_devdata, sizeof(struct hppa_dev)); + f->f_devdata = NULL; + return 0; +} diff --git a/sys/arch/hppa64/stand/libsa/itecons.c b/sys/arch/hppa64/stand/libsa/itecons.c new file mode 100644 index 00000000000..49e4413e2d2 --- /dev/null +++ b/sys/arch/hppa64/stand/libsa/itecons.c @@ -0,0 +1,212 @@ +/* $OpenBSD: itecons.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */ + +/* + * Copyright (c) 2005 Michael Shalayeff + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* + * Copyright 1996 1995 by Open Software Foundation, Inc. + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appears in all copies and + * that both the copyright notice and this permission notice appear in + * supporting documentation. + * + * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, + * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "libsa.h" + +#include <sys/param.h> +#include <sys/disklabel.h> +#include <machine/pdc.h> +#include <machine/iomod.h> +#include <dev/cons.h> + +#include "dev_hppa64.h" + +iodcio_t cniodc; /* console IODC entry point */ +iodcio_t kyiodc; /* keyboard IODC entry point */ +pz_device_t *cons_pzdev, *kbd_pzdev; + +/* + * Console. + */ + +char cnbuf[IODC_MINIOSIZ] __attribute__ ((aligned (IODC_MINIOSIZ))); +int kycode[IODC_MAXSIZE/sizeof(int)]; + +int +cnspeed(dev, sp) + dev_t dev; + int sp; +{ + return 9600; +} + +void +ite_probe(cn) + struct consdev *cn; +{ + cniodc = (iodcio_t)(u_long)PAGE0->mem_free; + cons_pzdev = &PAGE0->mem_cons; + kbd_pzdev = &PAGE0->mem_kbd; + + if (pdc_call(pdc, PDC_IODC, PDC_IODC_READ, pdcbuf, cons_pzdev->pz_hpa, + IODC_INIT, cniodc, IODC_MAXSIZE) < 0 || + pdc_call(cniodc, cons_pzdev->pz_hpa, + (cons_pzdev->pz_hpa==PAGE0->mem_boot.pz_hpa)? + IODC_INIT_DEV: IODC_INIT_ALL, cons_pzdev->pz_spa, + cons_pzdev->pz_layers, pdcbuf, 0,0,0,0) < 0 || + pdc_call(pdc, PDC_IODC, PDC_IODC_READ, pdcbuf, cons_pzdev->pz_hpa, + IODC_IO, cniodc, IODC_MAXSIZE) < 0) { + /* morse code with the LED's?!! */ + cons_pzdev->pz_iodc_io = kbd_pzdev->pz_iodc_io = NULL; + } else { + cn->cn_pri = CN_INTERNAL; + cn->cn_dev = makedev(0, 0); + } +} + +void +ite_init(cn) + struct consdev *cn; +{ + /* + * If the keyboard is separate from the console output device, + * we load the keyboard code at `kycode'. + * + * N.B. In this case, since the keyboard code is part of the + * boot code, it will be overwritten when we load a kernel. + */ + if (cons_pzdev->pz_class != PCL_DUPLEX || + kbd_pzdev->pz_class == PCL_KEYBD) { + + kyiodc = (iodcio_t)kycode; + + if (pdc_call(pdc, PDC_IODC, PDC_IODC_READ, pdcbuf, kbd_pzdev->pz_hpa, + IODC_INIT, kyiodc, IODC_MAXSIZE) < 0 || + pdc_call(kyiodc, kbd_pzdev->pz_hpa, + (kbd_pzdev->pz_hpa == PAGE0->mem_boot.pz_hpa || + kbd_pzdev->pz_hpa == cons_pzdev->pz_hpa)? + IODC_INIT_DEV: IODC_INIT_ALL, kbd_pzdev->pz_spa, + kbd_pzdev->pz_layers, pdcbuf, 0, 0, 0, 0) < 0 || + pdc_call(pdc, PDC_IODC, PDC_IODC_READ, pdcbuf, kbd_pzdev->pz_hpa, + IODC_IO, kyiodc, IODC_MAXSIZE)) + kyiodc = NULL; + } else { + kyiodc = cniodc; + + bcopy((char *)&PAGE0->mem_cons, (char *)&PAGE0->mem_kbd, + sizeof(struct pz_device)); + } + + cons_pzdev->pz_iodc_io = (u_long)cniodc; + kbd_pzdev->pz_iodc_io = (u_long)kyiodc; +#ifdef DEBUG + if (!kyiodc) + printf("ite_init: no kbd\n"); +#endif +} + +void +ite_putc(dev, c) + dev_t dev; + int c; +{ + if (cniodc == NULL) + return; + + *cnbuf = c; + + pdc_call(cniodc, cons_pzdev->pz_hpa, IODC_IO_CONSOUT, + cons_pzdev->pz_spa, cons_pzdev->pz_layers, pdcbuf, 0, cnbuf, 1, 0); +} + +/* + * since i don't know how to 'just check the char available' + * i store the key into the stash removing on read op later; + */ +int +ite_getc(dev) + dev_t dev; +{ + static int stash = 0; + int err, c, l, i; + + if (kyiodc == NULL) + return(0x100); + + if (stash) { + c = stash; + if (!(dev & 0x80)) + stash = 0; + return c; + } + + i = 16; + do { + err = pdc_call(kyiodc, kbd_pzdev->pz_hpa, IODC_IO_CONSIN, + kbd_pzdev->pz_spa, kbd_pzdev->pz_layers, pdcbuf, + 0, cnbuf, 1, 0); + l = pdcbuf[0]; + c = cnbuf[0]; +#ifdef DEBUG + if (debug && err < 0) + printf("KBD input error: %d", err); +#endif + + /* if we are doing ischar() report immidiatelly */ + if (!i-- && (dev & 0x80) && l == 0) { +#ifdef DEBUG + if (debug > 2) + printf("ite_getc(0x%x): no char %d(%x)\n", + dev, l, c); +#endif + return (0); + } + } while(!l); + +#if DEBUG + if (debug && l > 1) + printf("KBD input got too much (%d)\n", l); + + if (debug > 3) + printf("kbd: \'%c\' (0x%x)\n", c, c); +#endif + if (dev & 0x80) + stash = c; + + return (c); +} + +void +ite_pollc(dev, on) + dev_t dev; + int on; +{ + +} diff --git a/sys/arch/hppa64/stand/libsa/lf.c b/sys/arch/hppa64/stand/libsa/lf.c new file mode 100644 index 00000000000..15b7a6c0957 --- /dev/null +++ b/sys/arch/hppa64/stand/libsa/lf.c @@ -0,0 +1,44 @@ +/* $OpenBSD: lf.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */ + +/* + * Copyright (c) 2005 Michael Shalayeff + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "libsa.h" +#include <machine/pdc.h> +#include <machine/iomod.h> +#include <machine/param.h> + +#include "dev_hppa64.h" + +int +lfopen(struct open_file *f, ...) +{ + struct hppa_dev *dp = f->f_devdata; + + if (!(dp->pz_dev = pdc_findev(-1, PCL_NET_MASK|PCL_SEQU))) + return ENXIO; + + return 0; +} + +int +lfclose(struct open_file *f) +{ + free(f->f_devdata, sizeof(struct hppa_dev)); + f->f_devdata = NULL; + return 0; +} diff --git a/sys/arch/hppa64/stand/libsa/libsa.h b/sys/arch/hppa64/stand/libsa/libsa.h new file mode 100644 index 00000000000..9952a35a383 --- /dev/null +++ b/sys/arch/hppa64/stand/libsa/libsa.h @@ -0,0 +1,72 @@ +/* $OpenBSD: libsa.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */ + +/* + * Copyright (c) 2005 Michael Shalayeff + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <lib/libsa/stand.h> + +#define EXEC_ELF +#define EXEC_SOM + +#define DEFAULT_KERNEL_ADDRESS 0 + +extern dev_t bootdev; + +void pdc_init(void); +struct pz_device; +struct pz_device *pdc_findev(int, int); + +int iodcstrategy(void *, int, daddr_t, size_t, void *, size_t *); + +int ctopen(struct open_file *, ...); +int ctclose(struct open_file *); + +int dkopen(struct open_file *, ...); +int dkclose(struct open_file *); + +int lfopen(struct open_file *, ...); +int lfstrategy(void *, int, daddr_t, size_t, void *, size_t *); +int lfclose(struct open_file *); + +void ite_probe(struct consdev *); +void ite_init(struct consdev *); +int ite_getc(dev_t); +void ite_putc(dev_t, int); +void ite_pollc(dev_t, int); + +void machdep(void); +void devboot(dev_t, char *); +void fcacheall(void); +void run_loadfile(u_long *marks, int howto); + +int lif_open(char *path, struct open_file *f); +int lif_close(struct open_file *f); +int lif_read(struct open_file *f, void *buf, size_t size, size_t *resid); +int lif_write(struct open_file *f, void *buf, size_t size, size_t *resid); +off_t lif_seek(struct open_file *f, off_t offset, int where); +int lif_stat(struct open_file *f, struct stat *sb); +int lif_readdir(struct open_file *f, char *name); + +union x_header; +struct x_param; +int som_probe(int, union x_header *); +int som_load(int, struct x_param *); +int som_ldsym(int, struct x_param *); + +extern int debug; + +#define MACHINE_CMD cmd_machine /* we have hppa specific commands */ diff --git a/sys/arch/hppa64/stand/libsa/lif.c b/sys/arch/hppa64/stand/libsa/lif.c new file mode 100644 index 00000000000..25c25471f14 --- /dev/null +++ b/sys/arch/hppa64/stand/libsa/lif.c @@ -0,0 +1,261 @@ +/* $OpenBSD: lif.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */ + +/* + * Copyright (c) 2005 Michael Shalayeff + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/disklabel.h> +#include "libsa.h" + +extern int debug; + +struct file { + char f_buf[LIF_FILESTART];/* buffer for lif volume header and dir */ + struct lifvol *f_lp; /* lif volume header pointer */ + struct lifdir *f_ld; /* lif dir pointer */ + int f_nfiles; /* gross number for lif dir entries */ + + off_t f_seek; /* seek pointer for file read */ + struct lifdir *f_rd; /* lif dir pointer for readdir */ + + int f_isdir; /* special hacky flag for '.' dir */ + int f_count; /* this file length */ + int f_off; /* this file offset */ +}; + +int +lif_open (path, f) + char *path; + struct open_file *f; +{ + struct file *fp; + struct lifdir *dp; + char *p, *q; + struct lif_load load; + size_t buf_size; + int err, l; + +#ifdef LIFDEBUG + if (debug) + printf("lif_open(%s, %p)\n", path, f); +#endif + + fp = alloc(sizeof(*fp)); + /* XXX we're assuming here that sizeof(fp->f_buf) >= LIF_FILESTART */ + if ((err = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, 0, + sizeof(fp->f_buf), &fp->f_buf, &buf_size)) || + buf_size != sizeof(fp->f_buf)) { +#ifdef LIFDEBUG + if (debug) + printf("lif_open: unable to read LIF header (%d)\n", err); +#endif + } else if ((fp->f_lp = (struct lifvol *)fp->f_buf)->vol_id == LIF_VOL_ID) { + f->f_fsdata = fp; + fp->f_ld = (struct lifdir *)(fp->f_buf + LIF_DIRSTART); + fp->f_seek = 0; + fp->f_rd = fp->f_ld; + fp->f_nfiles = lifstob(fp->f_lp->vol_dirsize) / + sizeof(struct lifdir); + + /* no dirs on the lif */ + for (p = path + (l = strlen(path)); p >= path; p--) + if (*p == '/') { + p++; + break; + } + if (p > path) + path = p; + } else + err = EINVAL; + + if (!err && *path != '.') { + fp->f_isdir = 0; + err = ENOENT; + for (dp = fp->f_ld; dp < &fp->f_ld[fp->f_nfiles]; dp++) { +#ifdef LIFDEBUG + if (debug) + printf("lif_open: " + "%s <--> '%c%c%c%c%c%c%c%c%c%c'\n", + path, dp->dir_name[0], dp->dir_name[1], + dp->dir_name[2], dp->dir_name[3], + dp->dir_name[4], dp->dir_name[5], + dp->dir_name[6], dp->dir_name[7], + dp->dir_name[8], dp->dir_name[9]); +#endif + for (p = path, q = dp->dir_name; + *q && *q != ' '; q++, p++) + if (tolower(*q) != tolower(*p)) + break; + if ((!*q || *q == ' ') && !*p) { + err = 0; + break; + } + } + if (!err) { + fp->f_off = lifstodb(dp->dir_addr); + if (!(err =(f->f_dev->dv_strategy)(f->f_devdata, F_READ, + fp->f_off, sizeof(load), &load, &buf_size)) && + buf_size == sizeof(load)) { + /* no checksum */ + fp->f_count = load.count - sizeof(int); + fp->f_off = dbtob(fp->f_off) + sizeof(load); +#ifdef LIFDEBUG + if (debug) + printf("lif_open: %u @ %u [%x]\n", + fp->f_count, fp->f_off, + load.address); +#endif + } else if (!err) + err = EIO; + } + } else + fp->f_isdir = 1; + + if (err) { + free (fp, sizeof(*fp)); + f->f_fsdata = NULL; + } +#ifdef LIFDEBUG + if (debug) + printf("ret(%d)\n", err); +#endif + return err; +} + +int +lif_close(f) + struct open_file *f; +{ + free (f->f_fsdata, sizeof(struct file)); + f->f_fsdata = NULL; + return 0; +} + +int +lif_read(f, buf, size, resid) + struct open_file *f; + void *buf; + size_t size; + size_t *resid; +{ + struct file *fp = (struct file *)f->f_fsdata; + char *p; + char bbuf[DEV_BSIZE]; + size_t bsize, count = sizeof(bbuf); + int err = 0; + int foff; + +#ifdef LIFDEBUG + if (debug) + printf("lif_read(%p, %p, %u, %p)\n", f, buf, size, resid); +#endif + + for (p = bbuf; size; fp->f_seek += bsize, p += bsize) { + twiddle(); + foff = fp->f_off + fp->f_seek; + if (fp->f_seek >= fp->f_count || + (err = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, + btodb(foff), count, p, &bsize))) + break; + if (p == bbuf) { + bsize = sizeof(bbuf) - (foff & (sizeof(bbuf) - 1)); + bsize = min(bsize, size); + bcopy(bbuf + (foff & (sizeof(bbuf) - 1)), buf, bsize); + p = buf; + } + count = size -= bsize; + } + if (resid) + *resid = size; + + return err; +} + +int +lif_write(f, buf, size, resid) + struct open_file *f; + void *buf; + size_t size; + size_t *resid; +{ + return EOPNOTSUPP; +} + +off_t +lif_seek(f, offset, where) + struct open_file *f; + off_t offset; + int where; +{ + struct file *fp = (struct file *)f->f_fsdata; + + switch (where) { + case SEEK_SET: + fp->f_seek = offset; + break; + case SEEK_CUR: + fp->f_seek += offset; + break; + case SEEK_END: + fp->f_seek = fp->f_count - offset; + break; + default: + return (-1); + } + return (fp->f_seek); +} + +int +lif_stat(f, sb) + struct open_file *f; + struct stat *sb; +{ + struct file *fp = (struct file *)f->f_fsdata; + + sb->st_mode = 0755 | (fp->f_isdir? S_IFDIR: 0); /* XXX */ + sb->st_uid = 0; + sb->st_gid = 0; + sb->st_size = fp->f_count; + return 0; +} + +int +lif_readdir(f, name) + struct open_file *f; + char *name; +{ + struct file *fp = (struct file *)f->f_fsdata; + char *p; + + if (name) { + while ((fp->f_rd->dir_name[0] == ' ' || + !fp->f_rd->dir_name[0]) && + (fp->f_rd - fp->f_ld) < fp->f_nfiles) + fp->f_rd++; + if ((fp->f_rd - fp->f_ld) >= fp->f_nfiles) { + *name = '\0'; + return -1; + } + strncpy(name, fp->f_rd->dir_name, sizeof(fp->f_rd->dir_name)); + if ((p = strchr(name, ' '))) + *p = '\0'; + fp->f_rd++; + } else + fp->f_rd = fp->f_ld; + + return 0; +} diff --git a/sys/arch/hppa64/stand/libsa/machdep.c b/sys/arch/hppa64/stand/libsa/machdep.c new file mode 100644 index 00000000000..521488e2257 --- /dev/null +++ b/sys/arch/hppa64/stand/libsa/machdep.c @@ -0,0 +1,75 @@ +/* $OpenBSD: machdep.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */ + +/* + * Copyright (c) 2005 Michael Shalayeff + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/disklabel.h> +#include <sys/reboot.h> +#include "libsa.h" +#include <machine/iomod.h> +#include <machine/pdc.h> + +#include "dev_hppa64.h" + +extern struct stable_storage sstor; /* contents of Stable Storage */ +int howto; +dev_t bootdev; + +void +machdep() +{ + pdc_init(); +#ifdef notyet + debug_init(); +#endif + cninit(); + +#ifdef PDCDEBUG + if (debug) { + int i; + + printf("SSTOR:\n"); + printf("pri_boot="); DEVPATH_PRINT(&sstor.ss_pri_boot); + printf("alt_boot="); DEVPATH_PRINT(&sstor.ss_alt_boot); + printf("console ="); DEVPATH_PRINT(&sstor.ss_console); + printf("keyboard="); DEVPATH_PRINT(&sstor.ss_keyboard); + printf("mem=%d, fn=%s, osver=%d\nos={", + sstor.ss_fast_size, sstor.ss_filenames, + sstor.ss_os_version); + for (i = 0; i < sizeof(sstor.ss_os); i++) + printf ("%x%c", sstor.ss_os[i], (i%8)? ',' : '\n'); + + printf("}\nPAGE0:\n"); + printf("ivec=%x, pf=%p[%u], toc=%p[%u], rndz=%p, clk/10ms=%u\n", + PAGE0->ivec_special, PAGE0->ivec_mempf, + PAGE0->ivec_mempflen, PAGE0->ivec_toc, + PAGE0->ivec_toclen, PAGE0->ivec_rendz, + PAGE0->mem_10msec); + printf ("mem: cont=%u, phys=%u, pdc_spa=%u, resv=%u, free=%x\n" + "cpu_hpa=%x, pdc=%p, imm_hpa=%p[%u,%u], soft=%u\n", + PAGE0->memc_cont, PAGE0->memc_phsize, PAGE0->memc_adsize, + PAGE0->memc_resv, PAGE0->mem_free, PAGE0->mem_hpa, + PAGE0->mem_pdc, PAGE0->imm_hpa, PAGE0->imm_spa_size, + PAGE0->imm_max_mem, PAGE0->imm_soft_boot); + + printf("console: "); PZDEV_PRINT(&PAGE0->mem_cons); + printf("boot: "); PZDEV_PRINT(&PAGE0->mem_boot); + printf("keyboard: "); PZDEV_PRINT(&PAGE0->mem_kbd); + } +#endif +} diff --git a/sys/arch/hppa64/stand/libsa/pdc.c b/sys/arch/hppa64/stand/libsa/pdc.c new file mode 100644 index 00000000000..1569c52a1dd --- /dev/null +++ b/sys/arch/hppa64/stand/libsa/pdc.c @@ -0,0 +1,448 @@ +/* $OpenBSD: pdc.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */ + +/* + * Copyright (c) 2005 Michael Shalayeff + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* + * Copyright 1996 1995 by Open Software Foundation, Inc. + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appears in all copies and + * that both the copyright notice and this permission notice appear in + * supporting documentation. + * + * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, + * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ +/* + * Copyright (c) 1990 mt Xinu, Inc. All rights reserved. + * Copyright (c) 1990 University of Utah. All rights reserved. + * + * This file may be freely distributed in any form as long as + * this copyright notice is included. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Utah $Hdr: pdc.c 1.8 92/03/14$ + */ + +#include <sys/time.h> +#include "libsa.h" +#include <sys/reboot.h> +#include <sys/disklabel.h> + +#include <machine/trap.h> +#include <machine/pdc.h> +#include <machine/iomod.h> +#include <machine/nvm.h> +#include <machine/param.h> +#include <machine/cpufunc.h> + +#include "dev_hppa64.h" + +/* + * Interface routines to initialize and access the PDC. + */ + +pdcio_t pdc; +int pdcbuf[64] PDC_ALIGNMENT;/* PDC return buffer */ +struct stable_storage sstor; /* contents of Stable Storage */ +int sstorsiz; /* size of Stable Storage */ +struct bootdata bd; +int bdsize = sizeof(struct bootdata); + +/* + * Initialize PDC and related variables. + */ +void +pdc_init() +{ + int err; + + /* + * Initialize important global variables (defined above). + */ + pdc = (pdcio_t)(u_long)PAGE0->mem_pdc; + + err = pdc_call(pdc, PDC_STABLE, PDC_STABLE_SIZE, pdcbuf, 0, 0); + if (err >= 0) { + sstorsiz = min(pdcbuf[0],sizeof(sstor)); + err = (*pdc)(PDC_STABLE, PDC_STABLE_READ, 0, &sstor, sstorsiz); + } + + /* + * Now that we (may) have an output device, if we encountered + * an error reading Stable Storage (above), let them know. + */ +#ifdef DEBUG + if (debug && err) + printf("Stable storage PDC_STABLE Read Ret'd %d\n", err); +#endif + + /* + * Clear the FAULT light (so we know when we get a real one) + */ + pdc_call(pdc, PDC_CHASSIS, PDC_CHASSIS_DISP, + PDC_OSTAT(PDC_OSTAT_BOOT) | 0xCEC0); +} + +/* + * Generic READ/WRITE through IODC. Takes pointer to PDC device + * information, returns (positive) number of bytes actually read or + * the (negative) error condition, or zero if at "EOF". + */ +int +iodcstrategy(devdata, rw, blk, size, buf, rsize) + void *devdata; + int rw; + daddr_t blk; + size_t size; + void *buf; + size_t *rsize; +{ + struct hppa_dev *dp = devdata; + struct pz_device *pzdev = dp->pz_dev; + iodcio_t iodc = (iodcio_t)(u_long)pzdev->pz_iodc_io; + int offset, xfer, ret; + +#ifdef PDCDEBUG + if (debug) + printf("iodcstrategy(%p, %s, %u, %u, %p, %p)\n", devdata, + rw==F_READ? "READ" : "WRITE", blk, size, buf, rsize); + + if (debug > 1) + PZDEV_PRINT(pzdev); +#endif + + blk += dp->fsoff; + blk <<= DEV_BSHIFT; + if ((pzdev->pz_class & PCL_CLASS_MASK) == PCL_SEQU) { + /* rewind and re-read to seek */ + if (blk < dp->last_blk) { +#ifdef PDCDEBUG + if (debug) + printf("iodc: rewind "); +#endif + if ((ret = ((iodcio_t)(long)pzdev->pz_iodc_io)( + pzdev->pz_hpa, IODC_IO_READ, pzdev->pz_spa, + pzdev->pz_layers, pdcbuf, 0, dp->buf, 0, 0)) < 0) { +#ifdef DEBUG + if (debug) + printf("IODC_IO: %d\n", ret); +#endif + return (EIO); + } else { + dp->last_blk = 0; + dp->last_read = 0; + } + } + +#ifdef PDCDEBUG + if (debug) + printf("seek %d ", dp->last_blk); +#endif + for (; (dp->last_blk + dp->last_read) <= blk; + dp->last_read = ret) { + twiddle(); + dp->last_blk += dp->last_read; + if ((ret = (iodc)(pzdev->pz_hpa, + IODC_IO_READ, pzdev->pz_spa, pzdev->pz_layers, + pdcbuf, dp->last_blk, dp->buf, IODC_IOSIZ, + IODC_IOSIZ)) < 0) { +#ifdef DEBUG + if (debug) + printf("IODC_IO: %d\n", ret); +#endif + return (EIO); + } + if ((ret = pdcbuf[0]) == 0) + break; +#ifdef PDCDEBUG + if (debug) + printf("-"); +#endif + } +#ifdef PDCDEBUG + if (debug) + printf("> %d[%d]\n", dp->last_blk, dp->last_read); +#endif + } + + xfer = 0; + /* see if we can scratch anything from buffer */ + if (dp->last_blk <= blk && (dp->last_blk + dp->last_read) > blk) { + twiddle(); + offset = blk - dp->last_blk; + xfer = min(dp->last_read - offset, size); + size -= xfer; + blk += xfer; +#ifdef PDCDEBUG + if (debug) + printf("off=%d,xfer=%d,size=%d,blk=%d\n", + offset, xfer, size, blk); +#endif + bcopy(dp->buf + offset, buf, xfer); + buf += xfer; + } + + /* + * double buffer it all the time, to cache + */ + for (; size; size -= ret, buf += ret, blk += ret, xfer += ret) { + offset = blk & IOPGOFSET; + if ((ret = (iodc)(pzdev->pz_hpa, + (rw == F_READ? IODC_IO_READ: IODC_IO_WRITE), + pzdev->pz_spa, pzdev->pz_layers, pdcbuf, + blk - offset, dp->buf, IODC_IOSIZ, IODC_IOSIZ)) < 0) { +#ifdef DEBUG + if (debug) + printf("iodc_read(%d,%d): %d\n", + blk - offset, IODC_IOSIZ, ret); +#endif + if (xfer) + break; + else + return (EIO); + } + if ((ret = pdcbuf[0]) <= 0) + break; + dp->last_blk = blk - offset; + dp->last_read = ret; + if ((ret -= offset) > size) + ret = size; + bcopy(dp->buf + offset, buf, ret); +#ifdef PDCDEBUG + if (debug) + printf("read %d(%d,%d)@%x ", ret, + dp->last_blk, dp->last_read, (u_int)buf); +#endif + } + +#ifdef PDCDEBUG + if (debug) + printf("\n"); +#endif + + if (rsize) + *rsize = xfer; + return (0); +} + +/* + * Find a device with specified unit number + * (any if unit == -1), and of specified class (PCL_*). + */ +struct pz_device * +pdc_findev(unit, class) + int unit, class; +{ + static struct pz_device pz; + int layers[sizeof(pz.pz_layers)/sizeof(pz.pz_layers[0])]; + iodcio_t iodc; + int err = 0; + u_int hpa, spa; + +#ifdef PDCDEBUG + if (debug) + printf("pdc_finddev(%d, %x)\n", unit, class); +#endif + iodc = (iodcio_t)((u_long)PAGE0->mem_free + IODC_MAXSIZE); + hpa = PAGE0->mem_boot.pz_hpa; + spa = ((struct iomod *)(u_long)hpa)->io_spa; + + /* quick hack for boot device */ + if (PAGE0->mem_boot.pz_class == class && + (unit == -1 || PAGE0->mem_boot.pz_layers[0] == unit)) { + + bcopy (&PAGE0->mem_boot.pz_dp, &pz.pz_dp, sizeof(pz.pz_dp)); + bcopy (pz.pz_layers, layers, sizeof(layers)); + if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, pdcbuf, hpa, + IODC_INIT, iodc, IODC_MAXSIZE)) < 0) { +#ifdef DEBUG + if (debug) + printf("IODC_READ: %d\n", err); +#endif + return NULL; + } + } else { + struct pdc_memmap memmap; + struct iodc_data mptr; + int i, stp; + + for (i = 0; i < 0xf; i++) { + pz.pz_bc[0] = pz.pz_bc[1] = + pz.pz_bc[2] = pz.pz_bc[3] = -1; + pz.pz_bc[4] = 2; + pz.pz_bc[5] = 0; /* core bus */ + pz.pz_mod = i; + if ((pdc)(PDC_MEMMAP, PDC_MEMMAP_HPA, &memmap, + &pz.pz_dp) < 0) + continue; +#ifdef PDCDEBUG + if (debug) + printf("memap: %d.%d.%d, hpa=%x, mpgs=%x\n", + pz.pz_bc[4], pz.pz_bc[5], pz.pz_mod, + memmap.hpa, memmap.morepages); +#endif + hpa = memmap.hpa; + + if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, &pdcbuf, hpa, + IODC_DATA, &mptr, sizeof(mptr))) < 0) { +#ifdef DEBUG + if (debug) + printf("IODC_DATA: %d\n", err); +#endif + continue; + } + + if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, pdcbuf, hpa, + IODC_INIT, iodc, IODC_MAXSIZE)) < 0) { +#ifdef DEBUG + if (debug) + printf("IODC_READ: %d\n", err); +#endif + continue; + } + + stp = IODC_INIT_FIRST; + do { + if ((err = (iodc)(hpa, stp, spa, layers, + pdcbuf, 0, 0, 0, 0)) < 0) { +#ifdef DEBUG + if (debug && err != PDC_ERR_EOD) + printf("IODC_INIT_%s: %d\n", + stp==IODC_INIT_FIRST? + "FIRST":"NEXT", err); +#endif + break; + } +#ifdef PDCDEBUG + if (debug) + printf("[%x,%x,%x,%x,%x,%x], " + "[%x,%x,%x,%x,%x,%x]\n", + pdcbuf[0], pdcbuf[1], pdcbuf[2], + pdcbuf[3], pdcbuf[4], pdcbuf[5], + layers[0], layers[1], layers[2], + layers[3], layers[4], layers[5]); +#endif + stp = IODC_INIT_NEXT; + + } while (pdcbuf[1] != class && + unit != -1 && unit != layers[0]); + + if (err >= 0) + break; + } + } + + if (err >= 0) { + /* init device */ + if (0 && (err = (iodc)(hpa, IODC_INIT_DEV, spa, + layers, pdcbuf, 0, 0, 0, 0)) < 0) { +#ifdef DEBUG + if (debug) + printf("INIT_DEV: %d\n", err); +#endif + return NULL; + } + + /* read i/o entry code */ + if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, pdcbuf, hpa, + IODC_IO, iodc, IODC_MAXSIZE)) < 0) { +#ifdef DEBUG + if (debug) + printf("IODC_READ: %d\n", err); +#endif + return NULL; + } + + pz.pz_flags = 0; + bcopy(layers, pz.pz_layers, sizeof(pz.pz_layers)); + pz.pz_hpa = hpa; +/* XXX pz.pz_spa = spa; */ + pz.pz_iodc_io = (u_long)iodc; + pz.pz_class = class; + + return &pz; + } + + return NULL; +} + +static __inline void +fall(int c_base, int c_count, int c_loop, int c_stride, int data) +{ + int loop; /* Internal vars */ + + for (; c_count--; c_base += c_stride) + for (loop = c_loop; loop--; ) + if (data) + fdce(0, c_base); + else + fice(0, c_base); +} + +/* + * fcacheall - Flush all caches. + * + * This routine is just a wrapper around the real cache flush routine. + */ +struct pdc_cache pdc_cacheinfo PDC_ALIGNMENT; + +void +fcacheall() +{ + int err; + + if ((err = (*pdc)(PDC_CACHE, PDC_CACHE_DFLT, &pdc_cacheinfo)) < 0) { +#ifdef DEBUG + if (debug) + printf("fcacheall: PDC_CACHE failed (%d).\n", err); +#endif + return; + } +#if PDCDEBUG + if (debug) + printf("pdc_cache:\nic={%u,%x,%x,%u,%u,%u}\n" + "dc={%u,%x,%x,%u,%u,%u}\n", + pdc_cacheinfo.ic_size, *(u_int *)&pdc_cacheinfo.ic_conf, + pdc_cacheinfo.ic_base, pdc_cacheinfo.ic_stride, + pdc_cacheinfo.ic_count, pdc_cacheinfo.ic_loop, + pdc_cacheinfo.dc_size, *(u_int *)&pdc_cacheinfo.ic_conf, + pdc_cacheinfo.dc_base, pdc_cacheinfo.dc_stride, + pdc_cacheinfo.dc_count, pdc_cacheinfo.dc_loop); +#endif + /* + * Flush the instruction, then data cache. + */ + fall(pdc_cacheinfo.ic_base, pdc_cacheinfo.ic_count, + pdc_cacheinfo.ic_loop, pdc_cacheinfo.ic_stride, 0); + sync_caches(); + fall(pdc_cacheinfo.dc_base, pdc_cacheinfo.dc_count, + pdc_cacheinfo.dc_loop, pdc_cacheinfo.dc_stride, 1); + sync_caches(); +} diff --git a/sys/arch/hppa64/stand/libsa/time.c b/sys/arch/hppa64/stand/libsa/time.c new file mode 100644 index 00000000000..fd1fa22f1e7 --- /dev/null +++ b/sys/arch/hppa64/stand/libsa/time.c @@ -0,0 +1,47 @@ +/* $OpenBSD: time.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */ + +/* + * Copyright (c) 2005 Michael Shalayeff + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/pdc.h> +#include <sys/disklabel.h> +#include "libsa.h" +#include "dev_hppa64.h" + +time_t +getsecs() +{ + time_t tt; + int err; + + if ((err = (*pdc)(PDC_TOD, PDC_TOD_READ, &pdcbuf)) < 0) { + tt = 0; +#ifdef DEBUG + if (debug) + printf("getsecs: TOD read failed (%d)\n", err); +#endif + } else { + tt = ((struct pdc_tod *)pdcbuf)->sec; +#ifdef DEBUG + if (debug && tt < 800000000) + printf("getsecs: got %u seconds\n", tt); +#endif + } + + return tt; +} diff --git a/sys/arch/hppa64/stand/libz/Makefile b/sys/arch/hppa64/stand/libz/Makefile new file mode 100644 index 00000000000..d6ed6c93837 --- /dev/null +++ b/sys/arch/hppa64/stand/libz/Makefile @@ -0,0 +1,10 @@ +# $OpenBSD: Makefile,v 1.1 2005/04/01 10:40:49 mickey Exp $ + +S=${.CURDIR}/../../../.. +ZDST=${.OBJDIR} +SADIR=${.CURDIR}/.. + +.PATH: ${S}/lib/libz + +.include "${S}/lib/libz/Makefile" +CFLAGS+=${SACFLAGS} -I${S}/lib/libsa diff --git a/sys/arch/hppa64/stand/mkboot/Makefile b/sys/arch/hppa64/stand/mkboot/Makefile new file mode 100644 index 00000000000..e83c1dd1f66 --- /dev/null +++ b/sys/arch/hppa64/stand/mkboot/Makefile @@ -0,0 +1,14 @@ +# $OpenBSD: Makefile,v 1.1 2005/04/01 10:40:49 mickey Exp $ + +MAN= mkboot.8 +MANSUBDIR=hppa64 + +.if ${MACHINE} == "hppa64" +PROG= mkboot +CC= ${HOSTCC} +LDSTATIC= -static +.else +NOPROG= +.endif + +.include <bsd.prog.mk> diff --git a/sys/arch/hppa64/stand/mkboot/mkboot.8 b/sys/arch/hppa64/stand/mkboot/mkboot.8 new file mode 100644 index 00000000000..536bc587019 --- /dev/null +++ b/sys/arch/hppa64/stand/mkboot/mkboot.8 @@ -0,0 +1,58 @@ +.\" $OpenBSD: mkboot.8,v 1.1 2005/04/01 10:40:49 mickey Exp $ +.\" +.\" Copyright (c) 1990, 1993 +.\" The Regents of the University of California. 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. +.\" 3. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. +.\" +.Dd November 11, 2002 +.Dt MKBOOT 8 +.Os +.Sh NAME +.Nm mkboot +.Nd create LIF files +.Sh SYNOPSIS +.Nm mkboot +.Op Fl v +.Op Fl l Ar loadpoint +.Ar program ... outfile +.Sh DESCRIPTION +Creates the LIF file containing the bootstrap +.Ar program +and possibly other programs to be used by the +.Tn HP 9000/700 +and +.Tn HP 9000/800 +systems. +.Pp +An argument to the +.Fl l +option specifies the load point for the boot program, +with the default value of zero. +.Sh HISTORY +An +.Nm +utility first appeared in +.Ox 2.4 . diff --git a/sys/arch/hppa64/stand/mkboot/mkboot.c b/sys/arch/hppa64/stand/mkboot/mkboot.c new file mode 100644 index 00000000000..ced89972b56 --- /dev/null +++ b/sys/arch/hppa64/stand/mkboot/mkboot.c @@ -0,0 +1,430 @@ +/* $OpenBSD: mkboot.c,v 1.1 2005/04/01 10:40:49 mickey Exp $ */ + +/* + * Copyright (c) 1990, 1993 + * The Regents of the University of California. 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. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * @(#)mkboot.c 8.1 (Berkeley) 7/15/93 + */ + +#if 0 +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1990, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char rcsid[] = "$OpenBSD: mkboot.c,v 1.1 2005/04/01 10:40:49 mickey Exp $"; +#endif /* not lint */ +#endif + +#include <sys/param.h> +#include <sys/file.h> +#include <sys/stat.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <time.h> +#ifdef __OpenBSD__ +#include <err.h> +#endif + +#include <sys/exec_aout.h> +#include <sys/exec_elf.h> + +#ifndef hppa +/* hack for cross compile XXX */ +#include "../../include/disklabel.h" +#else +#include <sys/disklabel.h> +#endif + +#include <stdio.h> +#include <ctype.h> + +int putfile(char *, int); +void __dead usage(void); +void bcddate(char *, char *); +char *lifname(char *); +int cksum(int, int *, int); + +char *to_file; +int loadpoint, verbose; +u_long entry; +#ifndef __OpenBSD__ +char *__progname = "mkboot"; +#endif + +/* + * Old Format: + * sector 0: LIF volume header (40 bytes) + * sector 1: <unused> + * sector 2: LIF directory (8 x 32 == 256 bytes) + * sector 3-: LIF file 0, LIF file 1, etc. + * where sectors are 256 bytes. + * + * New Format: + * sector 0: LIF volume header (40 bytes) + * sector 1: <unused> + * sector 2: LIF directory (8 x 32 == 256 bytes) + * sector 3: <unused> + * sector 4-31: disklabel (~300 bytes right now) + * sector 32-: LIF file 0, LIF file 1, etc. + */ +int +main(int argc, char **argv) +{ + int to; + register int n, pos, c; + char buf[LIF_FILESTART]; + struct lifvol *lifv = (struct lifvol *)buf; + struct lifdir *lifd = (struct lifdir *)(buf + LIF_DIRSTART); + + while ((c = getopt(argc, argv, "vl:")) != -1) { + switch (c) { + case 'v': + verbose++; + break; + case 'l': + sscanf(optarg, "0x%x", &loadpoint); + break; + default: + usage(); + } + } + if (argc - optind < 2) + usage(); + else if (argc - optind > 8) + errx(1, "too many boot programs (max 8 supported)"); + + to_file = argv[--argc]; + if ((to = open(to_file, O_RDWR | O_TRUNC | O_CREAT, 0644)) < 0) + err(1, "%s: open", to_file); + + bzero(buf, sizeof(buf)); + /* clear possibly unused directory entries */ + memset(lifd[1].dir_name, ' ', sizeof lifd[1].dir_name); + lifd[1].dir_type = -1; + lifd[1].dir_addr = 0; + lifd[1].dir_length = 0; + lifd[1].dir_flag = 0xFF; + lifd[1].dir_implement = 0; + lifd[7] = lifd[6] = lifd[5] = lifd[4] = lifd[3] = lifd[2] = lifd[1]; + + /* record volume info */ + lifv->vol_id = htobe16(LIF_VOL_ID); + strncpy(lifv->vol_label, "BOOT44", 6); + lifv->vol_addr = htobe32(btolifs(LIF_DIRSTART)); + lifv->vol_oct = htobe16(LIF_VOL_OCT); + lifv->vol_dirsize = htobe32(btolifs(LIF_DIRSIZE)); + lifv->vol_version = htobe16(1); + lifv->vol_lastvol = lifv->vol_number = htobe16(1); + lifv->vol_length = LIF_FILESTART; + bcddate(to_file, lifv->vol_toc); + lifv->ipl_addr = htobe32(LIF_FILESTART); + lifv->ipl_size = 0; + lifv->ipl_entry = 0; + + argv += optind; + argc -= optind; + optind = 0; + for (pos = LIF_FILESTART; optind < argc; optind++) { + + /* output bootfile */ + lseek(to, pos, 0); + lifd[optind].dir_addr = htobe32(btolifs(pos)); + n = btolifs(putfile(argv[optind], to)); + if (lifv->ipl_entry == 0) { + lifv->ipl_entry = htobe32(loadpoint + entry); + lifv->ipl_size = htobe32(lifstob(n)); + lifd[optind].dir_type = htobe16(LIF_DIR_ISL); + lifd[optind].dir_implement = 0; + } else { + lifd[optind].dir_type = htobe16(LIF_DIR_TYPE); + lifd[1].dir_implement = htobe32(loadpoint + entry); + } + + strlcpy(lifd[optind].dir_name, lifname(argv[optind]), + sizeof lifd[optind].dir_name); + lifd[optind].dir_length = htobe32(n); + bcddate(argv[optind], lifd[optind].dir_toc); + lifd[optind].dir_flag = htobe16(LIF_DIR_FLAG); + + lifv->vol_length += n; + pos += lifstob(n); + } + + lifv->vol_length = htobe32(lifv->vol_length); + + /* output volume/directory header info */ + lseek(to, LIF_VOLSTART, 0); + if (write(to, buf, sizeof(buf)) != sizeof(buf)) + err(1, "%s: write LIF volume", to_file); + lseek(to, 0, SEEK_END); + + if (close(to) < 0) + err(1, "%s", to_file); + + return(0); +} + +int +putfile(from_file, to) + char *from_file; + int to; +{ + struct exec ex; + register int n, total; + char buf[2048]; + int from, check_sum = 0; + struct lif_load load; + + if ((from = open(from_file, O_RDONLY)) < 0) + err(1, "%s", from_file); + + n = read(from, &ex, sizeof(ex)); + if (n != sizeof(ex)) + err(1, "%s: reading file header", from_file); + + entry = ex.a_entry; + if (N_GETMAGIC(ex) == OMAGIC || N_GETMAGIC(ex) == NMAGIC) + entry += sizeof(ex); + else if (IS_ELF(*(Elf64_Ehdr *)&ex)) { + Elf64_Ehdr elf_header; + Elf64_Phdr *elf_segments; + int i,header_count, memory_needed, elf_load_image_segment; + + (void) lseek(from, 0, SEEK_SET); + n = read(from, &elf_header, sizeof (elf_header)); + if (n != sizeof (elf_header)) + err(1, "%s: reading ELF header", from_file); + header_count = betoh32(elf_header.e_phnum); + memory_needed = header_count * sizeof (*elf_segments); + elf_segments = malloc(memory_needed); + if (elf_segments == NULL) + err(1, "malloc"); + (void) lseek(from, betoh32(elf_header.e_phoff), SEEK_SET); + n = read(from, elf_segments, memory_needed); + if (n != memory_needed) + err(1, "%s: reading ELF segments", from_file); + elf_load_image_segment = -1; + for (i = 0; i < header_count; i++) { + if (elf_segments[i].p_filesz && + elf_segments[i].p_type == htobe32(PT_LOAD) && + elf_segments[i].p_flags & htobe32(PF_X)) { + if (elf_load_image_segment != -1) + warnx("%s: more than one ELF program segment", from_file); + else + elf_load_image_segment = i; + } + } + if (elf_load_image_segment == -1) + errx(1, "%s: no suitable ELF program segment", from_file); + entry = betoh32(elf_header.e_entry) + + betoh32(elf_segments[elf_load_image_segment].p_offset) - + betoh32(elf_segments[elf_load_image_segment].p_vaddr); + } else if (*(u_char *)&ex == 0x1f && ((u_char *)&ex)[1] == 0x8b) { + entry = 0; + } else + errx(1, "%s: bad magic number", from_file); + + entry += sizeof(load); + lseek(to, sizeof(load), SEEK_CUR); + total = 0; + n = sizeof(buf) - sizeof(load); + /* copy the whole file */ + for (lseek(from, 0, 0); ; n = sizeof(buf)) { + bzero(buf, sizeof(buf)); + if ((n = read(from, buf, n)) < 0) + err(1, "%s", from_file); + else if (n == 0) + break; + + if (write(to, buf, n) != n) + err(1, "%s", to_file); + + total += n; + check_sum = cksum(check_sum, (int *)buf, n); + } + + /* load header */ + load.address = htobe32(loadpoint + sizeof(load)); + load.count = htobe32(4 + total); + check_sum = cksum(check_sum, (int *)&load, sizeof(load)); + + if (verbose) + warnx("wrote %d bytes of file \'%s\'", total, from_file); + + total += sizeof(load); + /* insert the header */ + lseek(to, -total, SEEK_CUR); + if (write(to, &load, sizeof(load)) != sizeof(load)) + err(1, "%s", to_file); + lseek(to, total - sizeof(load), SEEK_CUR); + + bzero(buf, sizeof(buf)); + /* pad to int */ + n = sizeof(int) - total % sizeof(int); + if (total % sizeof(int)) { + if (write(to, buf, n) != n) + err(1, "%s", to_file); + else + total += n; + } + + /* pad to the blocksize */ + n = sizeof(buf) - total % sizeof(buf); + + if (n < sizeof(int)) { + n += sizeof(buf); + total += sizeof(buf); + } else + total += n; + + /* TODO should pad here to the 65k boundary for tape boot */ + + if (verbose) + warnx("checksum is 0x%08x", -check_sum); + + check_sum = htobe32(-check_sum); + if (write(to, &check_sum, sizeof(int)) != sizeof(int)) + err(1, "%s", to_file); + + n -= sizeof(int); + + if (write(to, buf, n) != n) + err(1, "%s", to_file); + + if (close(from) < 0 ) + err(1, "%s", from_file); + + return total; +} + +int +cksum(ck, p, size) + int ck; + int *p; + int size; +{ + /* we assume size is int-aligned */ + for (size = (size + sizeof(int) - 1) / sizeof(int); size--; p++ ) + ck += betoh32(*p); + + return ck; +} + +void __dead +usage() +{ + extern char *__progname; + fprintf(stderr, + "usage: %s [-v] [-l loadpoint] prog1 {progN} outfile\n", + __progname); + exit(1); +} + +char * +lifname(str) + char *str; +{ + static char lname[10] = "XXXXXXXXXX"; + register int i; + + for (i = 0; i < 9; i++) { + if (islower(*str)) + lname[i] = toupper(*str); + else if (isalnum(*str) || *str == '_') + lname[i] = *str; + else + break; + str++; + } + for ( ; i < 10; i++) + lname[i] = ' '; + return(lname); +} + + +void +bcddate(file, toc) + char *file; + char *toc; +{ + struct stat statb; +#ifndef __OpenBSD__ + struct tm { + int tm_sec; /* second (0-61, allows for leap seconds) */ + int tm_min; /* minute (0-59) */ + int tm_hour; /* hour (0-23) */ + int tm_mday; /* day of the month (1-31) */ + int tm_mon; /* month (0-11) */ + int tm_year; /* years since 1900 */ + int tm_wday; /* day of the week (0-6) */ + int tm_yday; /* day of the year (0-365) */ + int tm_isdst; /* non-0 if daylight saving time is in effect */ + } *tm; +#else + struct tm *tm; +#endif + + stat(file, &statb); + tm = localtime(&statb.st_ctime); + *toc = (tm->tm_year / 10) << 4; + *toc++ |= tm->tm_year % 10; + *toc = ((tm->tm_mon+1) / 10) << 4; + *toc++ |= (tm->tm_mon+1) % 10; + *toc = (tm->tm_mday / 10) << 4; + *toc++ |= tm->tm_mday % 10; + *toc = (tm->tm_hour / 10) << 4; + *toc++ |= tm->tm_hour % 10; + *toc = (tm->tm_min / 10) << 4; + *toc++ |= tm->tm_min % 10; + *toc = (tm->tm_sec / 10) << 4; + *toc |= tm->tm_sec % 10; +} + +#ifndef __OpenBSD__ +int +err(ex, str) + int ex; + char *str; +{ + perror(str); + exit(ex); +} + +int +errx(ex, str) + int ex; + char *str; +{ + perror(str); + exit(ex); +} +#endif |