diff options
421 files changed, 13518 insertions, 5323 deletions
@@ -1,6 +1,6 @@ Slimline Open Firmware - SLOF -Copyright (C) 2005, 2007 IBM Corporation +Copyright (C) 2005, 2008 IBM Corporation BUILD @@ -1,4 +1,4 @@ -Copyright (c) 2004, 2007 IBM Corporation +Copyright (c) 2004, 2008 IBM Corporation All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License diff --git a/Makefile.gen b/Makefile.gen index 27237b5..4891944 100644 --- a/Makefile.gen +++ b/Makefile.gen @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -19,7 +19,7 @@ include ../make.rules ifdef DRIVER RELEASE=$(shell cat ../VERSION) -export DRIVER_NAME=$(shell cat ../VERSION | sed -e "s/-/./g" | awk -F . '{ printf("%s%02x%02x%1x%02x",$$1,$$2,$$3,$$4,$$5); }') +export DRIVER_NAME=$(shell cat ../VERSION | sed -e "s/-/./g" | awk -F . '{ printf("%s%02d%02d%1x%02x",$$1,$$2,$$3,$$4,$$5); }') else RELEASE="$(USER)@$(HOSTNAME)(private build)" export DRIVER_NAME=HEAD @@ -51,39 +51,41 @@ romfs_build: @$(CC) -v >> ../build_info.img 2>&1 @$(LD) -V >> ../build_info.img 2>&1 -boot_rom.bin: $(BUILDS) ../romfs/copyright.img ../build_info.img +../$(SUBBOARD).dtb: + @if [ -e dts/$(SUBBOARD).dts ]; then \ + dtc -q -I dts -O dtb dts/$(SUBBOARD).dts > $@; \ + fi + +boot_rom.bin boot_xdr.bin: $(BUILDS) ../romfs/copyright.img ../build_info.img ../$(SUBBOARD).dtb @echo " ====== Building $@ ======" @if [ -e $(ROMFSBRDDIR)/boot_rom.$(SUBBOARD).ffs ]; then \ cat $(ROMFSBRDDIR)/boot_rom.$(SUBBOARD).ffs > ../.boot_rom.ffs; \ else \ cat $(ROMFSBRDDIR)/boot_rom.ffs > ../.boot_rom.ffs; \ fi - cat $(PCDBRDDIR)/pcdfiles.ffs >> ../.boot_rom.ffs + @if [ -e $(PCDBRDDIR)/pcdfiles.ffs ]; then \ + cat $(PCDBRDDIR)/pcdfiles.ffs >> ../.boot_rom.ffs; \ + fi cat $(SLOFBRDDIR)/OF.ffs >> ../.boot_rom.ffs @echo build_info.img build_info.img 0 0 >> ../.boot_rom.ffs - cd .. && ./romfs/tools/build_romfs .boot_rom.ffs boot_rom.bin - cd .. && if [ -f boot_rom.bin.gz ]; then rm -f boot_rom.bin.gz; gzip -9 boot_rom.bin; fi - rm -f ../.boot_rom.ffs - -boot_xdr.bin: $(BUILDS) ../romfs/copyright.img ../build_info.img - @echo " ====== Building $@ ======" - @if [ -e $(ROMFSBRDDIR)/boot_rom.$(SUBBOARD).ffs ]; then \ - cat $(ROMFSBRDDIR)/boot_rom.$(SUBBOARD).ffs > ../.boot_xdr.ffs; \ - else \ - cat $(ROMFSBRDDIR)/boot_rom.ffs > ../.boot_xdr.ffs; \ + @if [ -e ../$(SUBBOARD).dtb ]; then \ + echo dtb $(SUBBOARD).dtb 0 0 >> ../.boot_rom.ffs; \ fi - cat $(PCDBRDDIR)/pcdfiles.ffs >> ../.boot_xdr.ffs - @echo build_info.img build_info.img 0 0 >> ../.boot_xdr.ffs - cat ./slof/OF.ffs >> ../.boot_xdr.ffs - cd .. && ./romfs/tools/build_romfs .boot_xdr.ffs boot_xdr.bin - rm -f ../.boot_xdr.ffs + cd .. && ./romfs/tools/build_romfs .boot_rom.ffs $@ + cd .. && if [ -f $@.gz ]; then rm -f $@.gz; gzip -9 $@ ; fi + rm -f ../.boot_rom.ffs + rm -f ../$(SUBBOARD).dtb -../boot_l2b.bin: $(BUILDS) ../romfs/copyright.img +../boot_l2b.bin: $(BUILDS) ../romfs/copyright.img ../$(SUBBOARD).dtb @if [ -e $(ROMFSBRDDIR)/boot_l2.$(SUBBOARD).ffs ]; then \ cd .. && ./romfs/tools/build_romfs $(ROMFSBRDDIR)/boot_l2.$(SUBBOARD).ffs boot_l2b.bin; \ else \ cd .. && ./romfs/tools/build_romfs $(ROMFSBRDDIR)/boot_l2.ffs boot_l2b.bin; \ fi + @if [ -e ../$(SUBBOARD).dtb ]; then \ + echo dtb $(SUBBOARD).dtb 0 0 >> ../.boot_rom.ffs; \ + fi + rm -f ../$(SUBBOARD).dtb boot_l2-dd2.ad: ../boot_l2b.bin @cd ../tools && ./elf2l2 dd2 ../boot_l2b.bin 0 ../boot_l2-dd2.ad @@ -137,6 +139,7 @@ tar_gz: copy_driver clean_top: @rm -f ../build_info.img @rm -f ../.crc_flash + @rm -f ../$(SUBBOARD).dtb clean_gen: clean_top make -C ../romfs/tools BOARD=$(BOARD) clean @@ -1,153 +1,153 @@ -Slimline Open Firmware - SLOF
-
-Copyright (C) 2004, 2007 IBM Corporation
-
-
-Index
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-1.0 Introduction to Open Firmware
-1.1 Build process
-2.0 Extension
-3.0 Limitations
-
-1.0 Introduction to Open Firmware
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-The IEEE Standard 1275-1994 [1], Standard for Boot (Initialization Configuration)
-Firmware, Core Requirements and Practices, is the first non-proprietary open
-standard for boot firmware that is usable on different processors and buses.
-Firmware which complies with this standard (also known as Open Firmware)
-includes a processor-independent device interface that allows add-in devices
-to identify itself and to supply a single boot driver that can be used,
-unchanged, on any CPU. In addition, Open Firmware includes a user interface
-with powerful scripting and debugging support and a client interface that
-allows an operating system and its loaders to use Open Firmware services
-during the configuration and initialization process. Open Firmware stores
-information about the hardware in a tree structure called the
-``device tree''. This device tree supports multiple interconnected system
-buses and offers a framework for ``plug and play''-type auto configuration
-across different buses. It was designed to support a variety of different
-processor Instruction Set Architectures (ISAs) and buses.
-
-The full documentation of this Standard can be found in [1].
-
-
-1.1 Build process
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-Open Firmware (OF) is based on the programming language Forth.
-SLOF use Paflof as the Forth engine, which was developed by
-Segher Boessenkool. Most parts of the Forth engine are implemented in
-C, by using GNU extensions of ANSI C, (e.g. assigned goto, often misnamed "computed goto"),
-resulting in a very efficient yet still quite portable engine.
-
-The basic Forth words, so-called primitives, are implemented with
-a set of C macros. A set of .in and .code files are provided, which
-define the semantic of the Forth primitives. A Perl script translates
-these files into valid C code, which will be compiled into the Forth engine.
-The complete Forth system composes of the basic Forth primitives and
-a set of Forth words, which are compiled during the start of the Forth
-system.
-
-Example:
-Forth primitive 'dup'
-
- dup ( a -- a a) \ Duplicate top of stack element
-
-
-prim.in:
- cod(DUP)
-
-prim.code:
- PRIM(DUP) cell x = TOS; PUSH; TOS = x; MIRP
-
-Generated code:
-
-static cell xt_DUP[] = { { .a = xt_DOTICK }, { .c = "\000\003DUP" },
- { .a = &&code_DUP }, };
-
-code_DUP: { asm("#### " "DUP"); void *w = (cfa = (++ip)->a)->a;
- cell x = (*dp); dp++; (*dp) = x; goto *w; }
-
-Without going into detail, it can be seen, that the data stack is
-implemented in C as an array of cells, where dp is the pointer to the top of
-stack.
-
-For the implementation of the Open Firmware, most of the
-code is added as Forth code and bound to the engine. Also
-the system vector for reset and all kinds of exceptions
-will be part of the image. Additionally a secondary boot-loader
-or any other client application can be bound to the code as payload,
-e.g. diagnostics and test programs.
-
-The Open Firmware image will be put together by the build
-process, with a loader at the start of the image. This loader
-is called by Low Level Firmware and loads at boot time the Open
-Firmware to it's location in memory (see 1.3 Load process). Additionally
-a secondary boot loader or any other client application can be bound
-to the code as payload.
-
-The Low Level Firmware (LLFW) is responsible for setting up the
-system in an initial state. This task includes the setup of the
-CPUs, the system memory and all the buses as well as the serial port
-itself.
-
-
-2.0 Extension
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-In the following paragraphs it will be shown how to add
-new primitive words (i.e., words implemented not by building
-pre-existing Forth words together, but instead implemented in
-C or assembler). With this, it is possible to adapt SLOF to
-the specific needs of different hardware and architectures.
-
-
-To add primitives:
-
- For a new primitive, following steps have to be done:
-
- + Definition of primitive name in <arch>.in
- - cod(ABC) defines primitive ABC
-
- You can also use the following in a .in file, see existing
- code for how to use these:
- - con(ABC) defines constant ABC
- - col(ABC) defines colon definition ABC
- - dfr(ABC) defines defer definition ABC
-
- + Definition of the primitives effects in <arch>.code
- - PRIM(ABC) ... MIRP
-
- The code for the primitive body is any C-code. With
- the macros of prim.code the data and return stack of
- the Forth engine can be appropriately manipulated.
-
-
-3.0 Limitations of this package
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
- On a JS20 the memory setup is very static and therefore there are
- only very few combinations of memory DIMM placement actually work.
-
- Known booting configurations:
-
- * 4x 256 MB (filling all slots) -- only "0.5 GB" reported.
- * 2x 1 GB, slots 3/4 -- only "0.5 GB" reported.
-
- Known failing configurations
-
- * 2x 256 MB, slots 3/4
- * 2x 256 MB, slots 1/2
-
- On a JS20 SLOF wil always report 0.5 GB even if there is much more memory
- available.
-
- On a JS21 all memory configurations should work.
-
-Documentation
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-[1] IEEE 1275-1994 Standard, Standard for Boot (Initialization Configuration)
- Firmware: Core Requierements and Practices
-
+Slimline Open Firmware - SLOF + +Copyright (C) 2004, 2008 IBM Corporation + + +Index +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +1.0 Introduction to Open Firmware +1.1 Build process +2.0 Extension +3.0 Limitations + +1.0 Introduction to Open Firmware +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +The IEEE Standard 1275-1994 [1], Standard for Boot (Initialization Configuration) +Firmware, Core Requirements and Practices, is the first non-proprietary open +standard for boot firmware that is usable on different processors and buses. +Firmware which complies with this standard (also known as Open Firmware) +includes a processor-independent device interface that allows add-in devices +to identify itself and to supply a single boot driver that can be used, +unchanged, on any CPU. In addition, Open Firmware includes a user interface +with powerful scripting and debugging support and a client interface that +allows an operating system and its loaders to use Open Firmware services +during the configuration and initialization process. Open Firmware stores +information about the hardware in a tree structure called the +``device tree''. This device tree supports multiple interconnected system +buses and offers a framework for ``plug and play''-type auto configuration +across different buses. It was designed to support a variety of different +processor Instruction Set Architectures (ISAs) and buses. + +The full documentation of this Standard can be found in [1]. + + +1.1 Build process +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Open Firmware (OF) is based on the programming language Forth. +SLOF use Paflof as the Forth engine, which was developed by +Segher Boessenkool. Most parts of the Forth engine are implemented in +C, by using GNU extensions of ANSI C, (e.g. assigned goto, often misnamed "computed goto"), +resulting in a very efficient yet still quite portable engine. + +The basic Forth words, so-called primitives, are implemented with +a set of C macros. A set of .in and .code files are provided, which +define the semantic of the Forth primitives. A Perl script translates +these files into valid C code, which will be compiled into the Forth engine. +The complete Forth system composes of the basic Forth primitives and +a set of Forth words, which are compiled during the start of the Forth +system. + +Example: +Forth primitive 'dup' + + dup ( a -- a a) \ Duplicate top of stack element + + +prim.in: + cod(DUP) + +prim.code: + PRIM(DUP) cell x = TOS; PUSH; TOS = x; MIRP + +Generated code: + +static cell xt_DUP[] = { { .a = xt_DOTICK }, { .c = "\000\003DUP" }, + { .a = &&code_DUP }, }; + +code_DUP: { asm("#### " "DUP"); void *w = (cfa = (++ip)->a)->a; + cell x = (*dp); dp++; (*dp) = x; goto *w; } + +Without going into detail, it can be seen, that the data stack is +implemented in C as an array of cells, where dp is the pointer to the top of +stack. + +For the implementation of the Open Firmware, most of the +code is added as Forth code and bound to the engine. Also +the system vector for reset and all kinds of exceptions +will be part of the image. Additionally a secondary boot-loader +or any other client application can be bound to the code as payload, +e.g. diagnostics and test programs. + +The Open Firmware image will be put together by the build +process, with a loader at the start of the image. This loader +is called by Low Level Firmware and loads at boot time the Open +Firmware to it's location in memory (see 1.3 Load process). Additionally +a secondary boot loader or any other client application can be bound +to the code as payload. + +The Low Level Firmware (LLFW) is responsible for setting up the +system in an initial state. This task includes the setup of the +CPUs, the system memory and all the buses as well as the serial port +itself. + + +2.0 Extension +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +In the following paragraphs it will be shown how to add +new primitive words (i.e., words implemented not by building +pre-existing Forth words together, but instead implemented in +C or assembler). With this, it is possible to adapt SLOF to +the specific needs of different hardware and architectures. + + +To add primitives: + + For a new primitive, following steps have to be done: + + + Definition of primitive name in <arch>.in + - cod(ABC) defines primitive ABC + + You can also use the following in a .in file, see existing + code for how to use these: + - con(ABC) defines constant ABC + - col(ABC) defines colon definition ABC + - dfr(ABC) defines defer definition ABC + + + Definition of the primitives effects in <arch>.code + - PRIM(ABC) ... MIRP + + The code for the primitive body is any C-code. With + the macros of prim.code the data and return stack of + the Forth engine can be appropriately manipulated. + + +3.0 Limitations of this package +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + On a JS20 the memory setup is very static and therefore there are + only very few combinations of memory DIMM placement actually work. + + Known booting configurations: + + * 4x 256 MB (filling all slots) -- only "0.5 GB" reported. + * 2x 1 GB, slots 3/4 -- only "0.5 GB" reported. + + Known failing configurations + + * 2x 256 MB, slots 3/4 + * 2x 256 MB, slots 1/2 + + On a JS20 SLOF wil always report 0.5 GB even if there is much more memory + available. + + On a JS21 all memory configurations should work. + +Documentation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +[1] IEEE 1275-1994 Standard, Standard for Boot (Initialization Configuration) + Firmware: Core Requierements and Practices + diff --git a/board-js2x/Makefile b/board-js2x/Makefile index 1ccaf59..7021497 100644 --- a/board-js2x/Makefile +++ b/board-js2x/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -13,9 +13,9 @@ JS2X_TARGETS = tools_build romfs_build stage1 SUBDIRS = slof rtas -COMMON_LIBS = libc libipmi libbootmsg libbases libelf +COMMON_LIBS = libc libipmi libbootmsg libbases libelf libnvram -all: $(JS2X_TARGETS) subdirs clients_build bcm57xx boot_rom_js2x.bin boot_rom_bimini.bin +all: $(JS2X_TARGETS) subdirs clients_build bcm57xx boot_rom_js2x.bin .PHONY : subdirs $(SUBDIRS) clean distclean @@ -46,25 +46,13 @@ boot_rom_js2x.bin: $(JS2X_TARGETS) subdirs clients_build bcm57xx ../build_info. cd .. && if [ -f boot_rom.bin.gz ]; then rm -f boot_rom.bin.gz; gzip -9 boot_rom.bin; fi rm -f ../.boot_rom.ffs -boot_rom_bimini.bin: $(JS2X_TARGETS) subdirs clients_build bcm57xx ../build_info.img - @echo " ====== Building $@ ======" - cat $(ROMFSBRDDIR)/boot_rom_bimini.ffs > ../.boot_rom.ffs - cat $(SLOFBRDDIR)/OF.ffs >> ../.boot_rom.ffs - @echo build_info.img build_info.img 0 0 >> ../.boot_rom.ffs - cd .. && ./romfs/tools/build_romfs .boot_rom.ffs boot_rom_bimini.bin - cd .. && if [ -f boot_rom_bimini.bin.gz ]; then rm -f boot_romi_bimini.bin.gz; gzip -9 boot_rom_bimini.bin; fi - rm -f ../.boot_rom.ffs - bcm57xx: make -C ../other-licence/bcm clean_here: - rm -f package-firmware rm -f ../slof/OF.ffs - rm -f ../boot_rom.bin ../js2*.img ../ram.bin - rm -f ../bimini.img ../bimini.ram.bin - rm -rf ../boot_rom_bimini.bin + rm -f ../boot_rom.bin clean: clean_here clean_gen make -C ../other-licence/bcm clean @@ -91,11 +79,11 @@ takeover: all @rm -rf ../driver-$(RELEASE) @mkdir -p ../driver-$(RELEASE) -.tar_gz: .driver_dirs takeover +.tar_gz: .driver_dirs takeover external_flasher @mv ../boot_rom.bin \ ../driver-$(RELEASE)/$(RELEASE)-js2x.bin - @mv ../boot_rom_bimini.bin \ - ../driver-$(RELEASE)/$(RELEASE)-bimini.bin + @mv ../boot_rom-$(FLASH_SIZE_MB)MB-BigEndian.bin \ + ../driver-$(RELEASE)/$(RELEASE)-$(FLASH_SIZE_MB)MB-BigEndian.bin @mv $(TOPCMNDIR)/clients/takeover/takeover.elf \ ../driver-$(RELEASE)/$(RELEASE)-takeover.bin @cp ../VERSION ../driver-$(RELEASE) diff --git a/board-js2x/Makefile.dirs b/board-js2x/Makefile.dirs index 7d776af..1493d3b 100644 --- a/board-js2x/Makefile.dirs +++ b/board-js2x/Makefile.dirs @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License diff --git a/board-js2x/config b/board-js2x/config index 28cc3c6..9d4ce99 100644 --- a/board-js2x/config +++ b/board-js2x/config @@ -3,3 +3,4 @@ TARG=ppc64 export CPUARCH=ppc970 export CPUARCHDEF=-DCPU_PPC970 export SNK_BIOSEMU_APPS=1 +FLASH_SIZE=8388608 diff --git a/board-js2x/include/bmc.h b/board-js2x/include/bmc.h index bc9a14c..39dff80 100644 --- a/board-js2x/include/bmc.h +++ b/board-js2x/include/bmc.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/board-js2x/include/hw.h b/board-js2x/include/hw.h index 2b8342c..27117c3 100644 --- a/board-js2x/include/hw.h +++ b/board-js2x/include/hw.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/board-js2x/include/nvramlog.h b/board-js2x/include/nvramlog.h index c086e61..5d6c5d1 100644 --- a/board-js2x/include/nvramlog.h +++ b/board-js2x/include/nvramlog.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/board-js2x/include/product.h b/board-js2x/include/product.h index 4a95c70..55e9132 100644 --- a/board-js2x/include/product.h +++ b/board-js2x/include/product.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/board-js2x/include/southbridge.h b/board-js2x/include/southbridge.h index d10107b..1edeb6d 100644 --- a/board-js2x/include/southbridge.h +++ b/board-js2x/include/southbridge.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/board-js2x/llfw/Cboot.S b/board-js2x/llfw/Cboot.S index 3e37984..d22f3c9 100644 --- a/board-js2x/llfw/Cboot.S +++ b/board-js2x/llfw/Cboot.S @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/board-js2x/llfw/Makefile b/board-js2x/llfw/Makefile index f8aa8eb..e5c687a 100644 --- a/board-js2x/llfw/Makefile +++ b/board-js2x/llfw/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -14,35 +14,26 @@ include ../../make.rules CPPFLAGS = -I$(INCLBRDDIR) -I$(INCLCMNDIR) -I$(INCLCMNDIR)/$(CPUARCH) \ -I$(LIBCMNDIR)/libc/include -CFLAGS += -fno-builtin $(CPPFLAGS) -O2 -msoft-float $(MAMBO) $(PLATFORM) +CFLAGS += -fno-builtin $(CPPFLAGS) -O2 -msoft-float $(MAMBO) CFLAGS += $(BOOT) $(IOCONF) -Wa,-mregnames $(RELEASE) $(CPUARCHDEF) -Wall -ASFLAGS = $(PLATFORM) $(BOOT) $(IOCONF) $(RELEASE)$(CPUARCHDEF) -Wa,-mregnames +ASFLAGS = $(BOOT) $(IOCONF) $(RELEASE)$(CPUARCHDEF) -Wa,-mregnames LDFLAGS1 = -nostdlib -e__start -Tstage2.lds -N -Ttext=0x100 STG1OBJ = startup.o boot_abort.o romfs.o hw.o io_generic.o board_io.o STG1OBJ += stage2_head.o stage2.o comlib.o romfs_wrap.o nvramlog.o +STG1OBJ += u4mem.o -all: stage1.js2x stage1.bimini stageS.bin Cboot.o +all: stage1.bin stageS.bin Cboot.o -stage1.js2x: $(STG1OBJ) u4maui.o $(LIBCMNDIR)/libelf.a $(LIBCMNDIR)/libc.a +stage1.bin: $(STG1OBJ) $(LIBCMNDIR)/libelf.a $(LIBCMNDIR)/libc.a $(LD) $(LDFLAGS1) -o stage1.elf $^ - $(OBJCOPY) -O binary stage1.elf stage1.js2x - -stage1.bimini: $(STG1OBJ) u4bimini.o $(LIBCMNDIR)/libelf.a $(LIBCMNDIR)/libc.a - $(LD) $(LDFLAGS1) -o stage1.elf $? - $(OBJCOPY) -O binary stage1.elf stage1.bimini + $(OBJCOPY) -O binary stage1.elf $@ stageS.bin: stage_s.o $(LD) -nostdlib -N -Tstage_s.lds -o stage_s.elf stage_s.o $(OBJCOPY) -O binary stage_s.elf stageS.bin -u4bimini.o: u4mem.c - $(CC) $(CFLAGS) -DBOARD_BIMINI -o u4bimini.o -c u4mem.c - -u4maui.o: u4mem.c - $(CC) $(CFLAGS) -DBOARD_MAUI -o u4maui.o -c u4mem.c - romfs.o: ../../llfw/romfs.S $(CC) $(CFLAGS) -c ../../llfw/romfs.S @@ -76,4 +67,4 @@ $(LIBCMNDIR)/libelf.a: $(CC) $(CFLAGS) -c $^ clean: - rm -f *.o *.bin *.elf *.js2x *.bimini + rm -f *.o *.bin *.elf diff --git a/board-js2x/llfw/board_io.S b/board-js2x/llfw/board_io.S index 6e39dfc..2f36588 100644 --- a/board-js2x/llfw/board_io.S +++ b/board-js2x/llfw/board_io.S @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/board-js2x/llfw/hw.c b/board-js2x/llfw/hw.c index a656f18..e01b583 100644 --- a/board-js2x/llfw/hw.c +++ b/board-js2x/llfw/hw.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/board-js2x/llfw/stage2.c b/board-js2x/llfw/stage2.c index 6485d32..245d92e 100644 --- a/board-js2x/llfw/stage2.c +++ b/board-js2x/llfw/stage2.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -261,7 +261,7 @@ early_c_entry(uint64_t start_addr) c_romfs_lookup("bootinfo", romfs_base, &fileInfo); boot_info = (uint64_t *) fileInfo.addr_data; boot_info[1] = start_addr; - load_file(0x100, "xvect", 0x100, romfs_base); + load_file(0x100, "xvect", 0, romfs_base); load_file(SLAVELOOP_LOADBASE, "stageS", 0, romfs_base); c_romfs_lookup("ofw_main", romfs_base, &fileInfo); load_elf_file((void *) fileInfo.addr_data, &ofw_addr); diff --git a/board-js2x/llfw/stage2.h b/board-js2x/llfw/stage2.h index 1c5205a..9ce3c82 100644 --- a/board-js2x/llfw/stage2.h +++ b/board-js2x/llfw/stage2.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/board-js2x/llfw/stage2.lds b/board-js2x/llfw/stage2.lds index 703ef9d..f91f065 100644 --- a/board-js2x/llfw/stage2.lds +++ b/board-js2x/llfw/stage2.lds @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/board-js2x/llfw/stage2_head.S b/board-js2x/llfw/stage2_head.S index ea1cf59..5460bfe 100644 --- a/board-js2x/llfw/stage2_head.S +++ b/board-js2x/llfw/stage2_head.S @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/board-js2x/llfw/stage_s.S b/board-js2x/llfw/stage_s.S index 15eed93..202350f 100644 --- a/board-js2x/llfw/stage_s.S +++ b/board-js2x/llfw/stage_s.S @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/board-js2x/llfw/stage_s.lds b/board-js2x/llfw/stage_s.lds index 989ca3d..200c1b3 100644 --- a/board-js2x/llfw/stage_s.lds +++ b/board-js2x/llfw/stage_s.lds @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/board-js2x/llfw/startup.S b/board-js2x/llfw/startup.S index 59e1c3f..1357d3f 100644 --- a/board-js2x/llfw/startup.S +++ b/board-js2x/llfw/startup.S @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/board-js2x/llfw/u4mem.c b/board-js2x/llfw/u4mem.c index e7a159a..b7eba4d 100644 --- a/board-js2x/llfw/u4mem.c +++ b/board-js2x/llfw/u4mem.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -43,17 +43,9 @@ static const uint32_t SUBVER = 1; /* * macros to detect the current board layout */ -#ifdef BOARD_BIMINI -#define IS_MAUI 0 //( ( load8_ci( 0xf4000682 ) >> 4 ) == 0 ) -#define IS_BIMINI 1 //( ( load8_ci( 0xf4000682 ) >> 4 ) == 1 ) -#define IS_KAUAI 0 //( ( load8_ci( 0xf4000682 ) >> 4 ) == 2 ) -#endif - -#ifdef BOARD_MAUI -#define IS_MAUI 1 //( ( load8_ci( 0xf4000682 ) >> 4 ) == 0 ) -#define IS_BIMINI 0 //( ( load8_ci( 0xf4000682 ) >> 4 ) == 1 ) -#define IS_KAUAI 0 //( ( load8_ci( 0xf4000682 ) >> 4 ) == 2 ) -#endif +#define IS_MAUI ( ( load8_ci( 0xf4000682 ) >> 4 ) == 0 ) +#define IS_BIMINI ( ( load8_ci( 0xf4000682 ) >> 4 ) == 1 ) +#define IS_KAUAI ( ( load8_ci( 0xf4000682 ) >> 4 ) == 2 ) /* * local constants @@ -320,7 +312,7 @@ typedef struct /* * the following timing values are all in 1/100ns - */ + */ uint32_t m_tCK_pu32[NUM_CL]; uint32_t m_tRAS_u32; uint32_t m_tRTP_u32; @@ -436,7 +428,7 @@ static uint64_t m_memsize_u64; // memsize in bytes static void progbar( void ) { - static uint8_t bar[] = + static uint8_t bar[] = { '|', '/', '-', '\\', 0 }; static uint32_t idx = 0; @@ -448,7 +440,7 @@ progbar( void ) } -static void +static void or32_ci( uint64_t r, uint32_t m ) { uint32_t v; @@ -470,7 +462,7 @@ and32_ci( uint64_t r, uint32_t m ) static void dly( uint64_t volatile f_wait_u64 ) \ -{ +{ while( f_wait_u64 ) { f_wait_u64--; } @@ -539,7 +531,7 @@ i2c_read( uint32_t f_addr_u32, uint32_t f_suba_u32, uint8_t *f_buf_pu08, uint32_ if( ( load32_ci( I2C_STAT_R ) & IBIT(30) ) == 0 ) { i2c_term(); return RET_ERR; - } else { + } else { // send ack store32_ci( I2C_CTRL_R, IBIT(31) ); // clear int @@ -617,10 +609,10 @@ static uint32_t ddr2_get_dimm_size( uint8_t *f_spd_pu08 ) { static const int SIZE_IDX = (int) 31; - uint8_t l_smsk_u08; + uint8_t l_smsk_u08; uint32_t i; - l_smsk_u08 = ( f_spd_pu08[SIZE_IDX] << 3 ) | + l_smsk_u08 = ( f_spd_pu08[SIZE_IDX] << 3 ) | ( f_spd_pu08[SIZE_IDX] >> 5 ); for( i = 0; ( ( l_smsk_u08 & ( (uint8_t) 0x1 << i ) ) == 0 ) ; i++ ); @@ -692,7 +684,7 @@ ddr2_get_dimm_speed( dimm_t *f_dimm, uint8_t *f_spd_pu08 ) uint32_t idx = 0; uint32_t i; - for( i = NUM_CL - f_dimm->m_clcnt_u32; i < NUM_CL; i++ ) { + for( i = NUM_CL - f_dimm->m_clcnt_u32; i < NUM_CL; i++ ) { l_tmp_u08 = f_spd_pu08[SPEED_IDX[i]]; l_dspeed_u32 = (uint32_t) ( l_tmp_u08 >> 4 ) * 100; l_tmp_u08 &= (uint8_t) 0xf; @@ -752,7 +744,7 @@ ddr2_get_dimm_timings( dimm_t *f_dimm, uint8_t *f_spd_pu08 ) f_dimm->m_tRFC_u32 += NS[l_tmp_u32]; l_tmp_u32 = (uint32_t) f_spd_pu08[tREF_IDX]; - l_tmp_u32 &= (uint32_t) 0x7f; + l_tmp_u32 &= (uint32_t) 0x7f; if( l_tmp_u32 == 0 ) { l_tmp_u32 = (uint32_t) 2; @@ -1027,7 +1019,7 @@ ddr2_setupDIMMcfg( void ) #endif return RET_ERR; } - + /* * check valid DIMM organisation (must be x4) */ @@ -1105,7 +1097,7 @@ ddr2_setupDIMMcfg( void ) } } - + /* * return on error */ @@ -1130,7 +1122,7 @@ ddr2_setupDIMMcfg( void ) /* * setup timing parameters - */ + */ /* * find smallest common CL value @@ -1150,8 +1142,8 @@ ddr2_setupDIMMcfg( void ) m_gendimm.m_speed_pu32[i] = (uint32_t) ~0; for( j = 0; j < m_dcnt_u32; j++ ) { - l_tmp0_u32 = - ddr2_cl2speed( m_dptr[j], + l_tmp0_u32 = + ddr2_cl2speed( m_dptr[j], m_gendimm.m_clval_pu32[i], &l_tmp1_u32 ); @@ -1204,7 +1196,7 @@ ddr2_setupDIMMcfg( void ) m_gendimm.m_bankcnt_u32 = 0; for( i = 0; i < m_dcnt_u32; i++ ) { - + if( m_gendimm.m_bankcnt_u32 < m_dptr[i]->m_bankcnt_u32 ) { m_gendimm.m_bankcnt_u32 = m_dptr[i]->m_bankcnt_u32; } @@ -1494,7 +1486,7 @@ u4_group2banks( uint32_t *bidx ) * known conditions at this point: * -4 slots are populated */ - + /* * check wether DIMM banks may be grouped */ @@ -1644,7 +1636,7 @@ u4_calcDIMMcnfg( void ) m_dgrptr[i]->m_end_u32 = ( l_end_u32 >> 7 ); m_dgrptr[i]->m_add2g_u32 = l_add2g_u32; m_dgrptr[i]->m_sub2g_u32 = l_sub2g_u32; - + /* * continue with next group */ @@ -1680,7 +1672,7 @@ u4_calcDIMMmemmode( void ) l_modeoffs_u32 = MAX_ORG / l_dptr->m_orgval_u32; l_modeoffs_u32 /= (uint32_t) 2; l_sizebase_u32 = ( MIN_BASE << l_modeoffs_u32 ); - + j = 0; while( ( l_sizebase_u32 != l_dptr->m_size_u32 ) && ( j < MAX_MODE ) ) { @@ -1784,7 +1776,7 @@ u4_setup_core_clock( void ) s = m_gendimm.m_speed_pu32[m_dclidx_u32]; s -= MCLK; s /= CDIV; - + /* * insert new core clock value */ @@ -1838,7 +1830,7 @@ u4_setup_core_clock( void ) #endif return RET_ERR; } - + #ifdef U4_INFO printf( "\b\b\bOK\r\n" ); #endif @@ -1850,10 +1842,10 @@ static void u4_auto_calib_init( void ) { static const uint32_t SEQ[] = { - 0xb1000000, 0xd1000000, 0xd1000000, 0xd1000000, - 0xd1000000, 0xd1000000, 0xd1000000, 0xd1000000, - 0xd1000000, 0xd1000000, 0xd1000000, 0xd1000000, - 0xd1000000, 0xd1000000, 0xd1000400, 0x00000000, + 0xb1000000, 0xd1000000, 0xd1000000, 0xd1000000, + 0xd1000000, 0xd1000000, 0xd1000000, 0xd1000000, + 0xd1000000, 0xd1000000, 0xd1000000, 0xd1000000, + 0xd1000000, 0xd1000000, 0xd1000400, 0x00000000, }; uint64_t i; @@ -1869,7 +1861,7 @@ u4_auto_calib_init( void ) static uint32_t u4_RSL_BLane( uint32_t f_Rank_u32, uint32_t f_BLane_u32 ) { - static const uint32_t MemProgCntl_V = (uint32_t) 0x80000500; + static const uint32_t MemProgCntl_V = (uint32_t) 0x80000500; static const uint32_t CalConf0_V = (uint32_t) 0x0000aa10; uint32_t l_MemProgCntl_u32; uint32_t l_CalConf0_u32; @@ -1888,32 +1880,32 @@ u4_RSL_BLane( uint32_t f_Rank_u32, uint32_t f_BLane_u32 ) } else if( f_BLane_u32 < 8 ) { f_BLane_u32 -= 4; MeasStat_R = MeasStatusC1_R; - CalC_R = CalC1_R; + CalC_R = CalC1_R; VerC_R = RstLdEnVerniersC1_R; } else if( f_BLane_u32 < 12 ) { f_BLane_u32 -= 8; MeasStat_R = MeasStatusC2_R; - CalC_R = CalC2_R; + CalC_R = CalC2_R; VerC_R = RstLdEnVerniersC2_R; } else if( f_BLane_u32 == 16 ) { f_BLane_u32 = 4; MeasStat_R = MeasStatusC1_R; - CalC_R = CalC1_R; + CalC_R = CalC1_R; VerC_R = RstLdEnVerniersC1_R; } else if( f_BLane_u32 == 17 ) { f_BLane_u32 = 4; MeasStat_R = MeasStatusC3_R; - CalC_R = CalC3_R; + CalC_R = CalC3_R; VerC_R = RstLdEnVerniersC3_R; } else { f_BLane_u32 -= 12; MeasStat_R = MeasStatusC3_R; - CalC_R = CalC3_R; + CalC_R = CalC3_R; VerC_R = RstLdEnVerniersC3_R; } - + shft = (uint32_t) 28 - ( f_BLane_u32 * 4 ); - + /* * start auto calibration logic & wait for completion */ @@ -1930,7 +1922,7 @@ u4_RSL_BLane( uint32_t f_Rank_u32, uint32_t f_BLane_u32 ) store32_ci( VerC_R, ( v << 24 ) | ( v << 16 ) ); l_MemProgCntl_u32 = MemProgCntl_V; - l_MemProgCntl_u32 |= + l_MemProgCntl_u32 |= ( (uint32_t) 0x00800000 >> f_Rank_u32 ); store32_ci( MemProgCntl_R, l_MemProgCntl_u32 ); @@ -1938,7 +1930,7 @@ u4_RSL_BLane( uint32_t f_Rank_u32, uint32_t f_BLane_u32 ) l_MemProgCntl_u32 = load32_ci( MemProgCntl_R ); } while( ( l_MemProgCntl_u32 & IBIT(1) ) == 0 ); - l_CalC_u32 = ( ( load32_ci( CalC_R ) >> shft ) & + l_CalC_u32 = ( ( load32_ci( CalC_R ) >> shft ) & (uint32_t) 0xf ); if( l_CalC_u32 != (uint32_t) 0xa ) { @@ -1959,7 +1951,7 @@ u4_RSL_BLane( uint32_t f_Rank_u32, uint32_t f_BLane_u32 ) static uint32_t u4_RMDF_BLane( uint32_t f_Rank_u32, uint32_t f_BLane_u32 ) { - static const uint32_t MemProgCntl_V = (uint32_t) 0x80000f00; + static const uint32_t MemProgCntl_V = (uint32_t) 0x80000f00; static const uint32_t CalConf0_V = (uint32_t) 0x0000ac10; uint32_t l_MemProgCntl_u32; uint32_t l_CalConf0_u32; @@ -1978,32 +1970,32 @@ u4_RMDF_BLane( uint32_t f_Rank_u32, uint32_t f_BLane_u32 ) } else if( f_BLane_u32 < 8 ) { f_BLane_u32 -= 4; MeasStat_R = MeasStatusC1_R; - CalC_R = CalC1_R; + CalC_R = CalC1_R; VerC_R = RstLdEnVerniersC1_R; } else if( f_BLane_u32 < 12 ) { f_BLane_u32 -= 8; MeasStat_R = MeasStatusC2_R; - CalC_R = CalC2_R; + CalC_R = CalC2_R; VerC_R = RstLdEnVerniersC2_R; } else if( f_BLane_u32 == 16 ) { f_BLane_u32 = 4; MeasStat_R = MeasStatusC1_R; - CalC_R = CalC1_R; + CalC_R = CalC1_R; VerC_R = RstLdEnVerniersC1_R; } else if( f_BLane_u32 == 17 ) { f_BLane_u32 = 4; MeasStat_R = MeasStatusC3_R; - CalC_R = CalC3_R; + CalC_R = CalC3_R; VerC_R = RstLdEnVerniersC3_R; } else { f_BLane_u32 -= 12; MeasStat_R = MeasStatusC3_R; - CalC_R = CalC3_R; + CalC_R = CalC3_R; VerC_R = RstLdEnVerniersC3_R; } - + shft = (uint32_t) 28 - ( f_BLane_u32 * 4 ); - + /* * start auto calibration logic & wait for completion */ @@ -2021,7 +2013,7 @@ u4_RMDF_BLane( uint32_t f_Rank_u32, uint32_t f_BLane_u32 ) store32_ci( VerC_R, ( v << 24 ) | ( v << 16 ) ); l_MemProgCntl_u32 = MemProgCntl_V; - l_MemProgCntl_u32 |= + l_MemProgCntl_u32 |= ( (uint32_t) 0x00800000 >> f_Rank_u32 ); store32_ci( MemProgCntl_R, l_MemProgCntl_u32 ); @@ -2029,7 +2021,7 @@ u4_RMDF_BLane( uint32_t f_Rank_u32, uint32_t f_BLane_u32 ) l_MemProgCntl_u32 = load32_ci( MemProgCntl_R ); } while( ( l_MemProgCntl_u32 & IBIT(1) ) == 0 ); - l_CalC_u32 = ( ( load32_ci( CalC_R ) >> shft ) & + l_CalC_u32 = ( ( load32_ci( CalC_R ) >> shft ) & (uint32_t) 0xf ); if( l_CalC_u32 != (uint32_t) 0xa ) { @@ -2047,7 +2039,7 @@ u4_RMDF_BLane( uint32_t f_Rank_u32, uint32_t f_BLane_u32 ) } static int32_t -u4_RMDF_Rank( uint32_t f_Rank_u32, +u4_RMDF_Rank( uint32_t f_Rank_u32, uint32_t *f_Buf_pu32 ) { int32_t l_Err_pi32 = 0; @@ -2180,7 +2172,7 @@ u4_auto_calib_MemBus( auto_calib_t *f_ac_pt ) f_ac_pt->m_MemBusCnfg_u32 = load32_ci( MemBusCnfg_R ); f_ac_pt->m_MemBusCnfg2_u32 = load32_ci( MemBusCnfg2_R ); - + /* * calculate the average vernier setting for the * bytelanes which share one vernier @@ -2212,7 +2204,7 @@ u4_auto_calib_MemBus( auto_calib_t *f_ac_pt ) } } - + /* * average the values */ @@ -2256,7 +2248,7 @@ u4_auto_calib( auto_calib_t *f_ac_pt ) u4_auto_calib_init(); l_Ret_i32 = u4_auto_calib_MemBus( f_ac_pt ); - + /* * restore manipulated registers */ @@ -2337,7 +2329,7 @@ u4_Scrub( uint32_t f_scrub_u32, uint32_t f_pattern_u32, eccerror_t *f_eccerr_pt * setup scrub parameters */ store32_ci( MSCR_R, 0 ); // stop scrub - store32_ci( MSRSR_R, 0x0 ); // set start + store32_ci( MSRSR_R, 0x0 ); // set start store32_ci( MSRER_R, u4_CalcScrubEnd() ); // set end store32_ci( MSPR_R, f_pattern_u32 ); // set pattern @@ -2381,7 +2373,7 @@ u4_InitialScrub( void ) if( l_err_i32[0] >= -1 /*CE*/ ) { l_err_i32[1] = u4_Scrub( IMMEDIATE_SCRUB, 0x0, &l_eccerr_st[1] ); - } + } if( l_err_i32[0] < l_err_i32[1] ) { return l_eccerr_st[0]; @@ -2420,7 +2412,7 @@ u4_MemInitSequence( uint32_t tRP, uint32_t tWR, uint32_t tRFC, uint32_t CL, l_MemInit_u32 = INI_SEQ[i]; switch( i ) { - case 0: + case 0: case 5: { l_MemInit_u32 |= ( ( RND( tRP ) - TD ) << 20 ); break; @@ -2436,7 +2428,7 @@ u4_MemInitSequence( uint32_t tRP, uint32_t tWR, uint32_t tRFC, uint32_t CL, case 8: { l_MemInit_u32 |= ( ( RND( tWR ) - 1 ) << 9 ); l_MemInit_u32 |= ( CL << 4 ); - + store32_ci( MRSRegCntl_R, l_MemInit_u32 & (uint32_t) 0xffff ); break; @@ -2462,7 +2454,7 @@ u4_MemInitSequence( uint32_t tRP, uint32_t tWR, uint32_t tRFC, uint32_t CL, * Kick off memory init sequence & wait for completion */ store32_ci( MemProgCntl_R, IBIT(0) ); - + do { i = load32_ci( MemProgCntl_R ); } while( ( i & IBIT(1) ) == 0 ); @@ -2902,7 +2894,7 @@ u4_start( eccerror_t *f_ecc_pt ) uint32_t tRFC = m_gendimm.m_tRFC_u32; uint32_t tREF = m_gendimm.m_tREF_u32; - reg_statics_t *rst; + reg_statics_t *rst = 0; uint32_t l_RAS0_u32; uint32_t l_RAS1_u32; @@ -2942,7 +2934,7 @@ u4_start( eccerror_t *f_ecc_pt ) #endif return RET_ERR; } - + } /* @@ -2957,7 +2949,7 @@ u4_start( eccerror_t *f_ecc_pt ) } /* - * Switch off Fast Path by default for all DIMMs + * Switch off Fast Path by default for all DIMMs * running with more than 400Mhz */ if( SPEED == 400 ) { @@ -2994,7 +2986,7 @@ u4_start( eccerror_t *f_ecc_pt ) l_RAS0_u32 |= ( ( WL + BL/2 + RND( tWR ) - TD ) << 17 ); // TiPtA = RND(tRP) -> RAS0[15:19] l_RAS0_u32 |= ( ( RND( tRP ) - TD ) << 12 ); - // TiPAtA = RND(tRP) or + // TiPAtA = RND(tRP) or // RND(tRP) + 1 for 8 bank devices -> RAS0[20:24] if( m_gendimm.m_bankcnt_u32 <= 4 ) { l_RAS0_u32 |= ( ( RND( tRP ) - TD ) << 7 ); @@ -3011,7 +3003,7 @@ u4_start( eccerror_t *f_ecc_pt ) l_RAS1_u32 |= ( ( CL + AL + BL/2 - 1 + RND( tWR + tRP ) - TD ) << 22 ); // TiAtARk = tRRD -> RAS1[10:14] l_RAS1_u32 |= ( ( RND( tRRD ) - TD ) << 17 ); - // TiAtABk = tRC -> RAS1[15:19] + // TiAtABk = tRC -> RAS1[15:19] l_RAS1_u32 |= ( ( RND( tRC ) - TD ) << 12 ); // TiAtRW = tRCD -> RAS1[20:24] l_RAS1_u32 |= ( ( RND( tRCD ) - TD ) << 7 ); @@ -3094,7 +3086,7 @@ u4_start( eccerror_t *f_ecc_pt ) l_UsrCnfg_u32 |= ( m_dgrptr[i]->m_csmode_u32 << ( 30 - 2 * t0 ) ); } - + } } @@ -3229,7 +3221,7 @@ u4_start( eccerror_t *f_ecc_pt ) store32_ci( MemModeCntl_R, IBIT(0) | IBIT(8) ); dly( 50000000 ); - + #ifdef U4_INFO printf( "\b\b\bOK\r\n" ); @@ -3337,14 +3329,14 @@ u4_start( eccerror_t *f_ecc_pt ) #endif return RET_ACERR_UE; } - + } /* * start continuous background scrub */ #ifdef U4_INFO - printf( " [background scrub: ]" ); + printf( " [background scrub: ]" ); #endif u4_Scrub( BACKGROUND_SCRUB, 0, NULL ); @@ -3379,7 +3371,7 @@ u4_memtest(uint8_t argCnt, char *pArgs[], uint64_t flags) static const uint64_t PATTERN[] = { 0x9090909090909090, 0x0020002000200020, 0x0c0c0c0c0c0c0c0c, 0x8080808080808080, - 0x1004010004001041, 0x0000000000000000 + 0x1004010004001041, 0x0000000000000000 }; uint64_t mend = (uint64_t) 0x200000000;//m_memsize_u64; @@ -3425,8 +3417,8 @@ u4_memtest(uint8_t argCnt, char *pArgs[], uint64_t flags) for( block = 0; block < numblocks; block++ ) { for( i = 0; i < _line; i += 8 ) { - addr = _start + - ( block * _bsize ) + + addr = _start + + ( block * _bsize ) + ( line * _line ) + i; @@ -3449,13 +3441,13 @@ u4_memtest(uint8_t argCnt, char *pArgs[], uint64_t flags) } } - + } } } - + check = PATTERN[pidx]; tlast = 0; tstate = TCHK; @@ -3485,8 +3477,8 @@ u4_memtest(uint8_t argCnt, char *pArgs[], uint64_t flags) for( block = 0; block < numblocks; block++ ) { for( i = 0; i < _line; i += 8 ) { - addr = _start + - ( block * _bsize ) + + addr = _start + + ( block * _bsize ) + ( line * _line ) + i; @@ -3497,7 +3489,7 @@ u4_memtest(uint8_t argCnt, char *pArgs[], uint64_t flags) *( (uint64_t *) addr ) >>= 1; if( one ) { - *( (uint64_t *) addr ) |= + *( (uint64_t *) addr ) |= (uint64_t) 0x8000000000000000; } @@ -3514,19 +3506,19 @@ u4_memtest(uint8_t argCnt, char *pArgs[], uint64_t flags) } } - + } } } - + tlast = 1; tstate = TCHK; } break; case 2: { - + if( rotr < 6 ) { rotr++; tstate = 1; @@ -3554,8 +3546,8 @@ u4_memtest(uint8_t argCnt, char *pArgs[], uint64_t flags) for( block = 0; block < numblocks; block++ ) { for( i = 0; i < _line; i += 8 ) { - addr = _start + - ( block * _bsize ) + + addr = _start + + ( block * _bsize ) + ( line * _line ) + i; @@ -3578,13 +3570,13 @@ u4_memtest(uint8_t argCnt, char *pArgs[], uint64_t flags) } } - + } } } - + tlast = 3; tstate = TCHK; } break; @@ -3612,8 +3604,8 @@ u4_memtest(uint8_t argCnt, char *pArgs[], uint64_t flags) for( block = 0; block < numblocks; block++ ) { for( i = 0; i < _line; i += 8 ) { - addr = _start + - ( block * _bsize ) + + addr = _start + + ( block * _bsize ) + ( line * _line ) + i; @@ -3624,7 +3616,7 @@ u4_memtest(uint8_t argCnt, char *pArgs[], uint64_t flags) *( (uint64_t *) addr ) <<= 1; if( one ) { - *( (uint64_t *) addr ) |= + *( (uint64_t *) addr ) |= (uint64_t) 0x1; } @@ -3641,19 +3633,19 @@ u4_memtest(uint8_t argCnt, char *pArgs[], uint64_t flags) } } - + } } } - + tlast = 4; tstate = TCHK; } break; case 5: { - + if( rotl < 6 ) { rotl++; tstate = 4; @@ -3680,8 +3672,8 @@ u4_memtest(uint8_t argCnt, char *pArgs[], uint64_t flags) for( block = 0; block < numblocks; block++ ) { for( i = 0; i < _line; i += 8 ) { - addr = _start + - ( block * _bsize ) + + addr = _start + + ( block * _bsize ) + ( line * _line ) + i; @@ -3704,13 +3696,13 @@ u4_memtest(uint8_t argCnt, char *pArgs[], uint64_t flags) } } - + } } } - + tlast = TEND - 1; tstate = TCHK; } break; @@ -3732,8 +3724,8 @@ u4_memtest(uint8_t argCnt, char *pArgs[], uint64_t flags) for( block = 0; block < numblocks; block++ ) { for( i = 0; i < _line; i += 8 ) { - addr = _start + - ( block * _bsize ) + + addr = _start + + ( block * _bsize ) + ( line * _line ) + i; @@ -3765,7 +3757,7 @@ u4_memtest(uint8_t argCnt, char *pArgs[], uint64_t flags) } } - + } } @@ -3982,7 +3974,7 @@ u4_scrubStart(uint8_t argCnt, char *pArgs[], uint64_t flags ) * setup scrub parameters */ store32_ci( MSCR_R, 0 ); // stop scrub - store32_ci( MSRSR_R, 0x0 ); // set start + store32_ci( MSRSR_R, 0x0 ); // set start store32_ci( MSRER_R, 0x1c ); // set end store32_ci( MSPR_R, 0x0 ); // set pattern @@ -4019,7 +4011,7 @@ u4_memwr(uint8_t argCnt, char *pArgs[], uint64_t flags ) if( ( i & 0xf ) == 0 ) { v = ~v; } - + store32_ci( i, v ); } diff --git a/board-js2x/romfs/boot_rom.ffs b/board-js2x/romfs/boot_rom.ffs index 32ddefa..fc86bbf 100644 --- a/board-js2x/romfs/boot_rom.ffs +++ b/board-js2x/romfs/boot_rom.ffs @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -13,7 +13,7 @@ # FFile-Name Real Filename Flags ROM-Offset i/a #--------------|-----------------------|-----------------------|-------------- header romfs/header.img 0 0 -stage1 board-js2x/llfw/stage1.js2x 1 0x100 +stage1 board-js2x/llfw/stage1.bin 1 0x100 xvect slof/xvect.bin 0 0 ofw_main board-js2x/slof/paflof 0 0 stageS board-js2x/llfw/stageS.bin 0 0 diff --git a/board-js2x/rtas/Makefile b/board-js2x/rtas/Makefile index 02fa2c7..70e506f 100644 --- a/board-js2x/rtas/Makefile +++ b/board-js2x/rtas/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -19,8 +19,8 @@ include $(TOPCMNDIR)/make.rules LDFLAGS = -nostdlib CPPFLAGS = -I. -I$(LIBCMNDIR)/libc/include -I$(LIBCMNDIR)/libipmi -I$(INCLBRDDIR) \ -I$(INCLCMNDIR) -I$(RTASCMNDIR) -I$(INCLCMNDIR)/$(CPUARCH) -ASFLAGS = $(PLATFORM) -Wa,-mregnames $(FLAG) -CFLAGS += -Wall -Wextra -O2 -msoft-float -ffreestanding $(PLATFORM) $(FLAG) +ASFLAGS = -Wa,-mregnames $(FLAG) +CFLAGS += -Wall -Wextra -O2 -msoft-float -ffreestanding $(FLAG) # Board specific RTAS files: BOARD_SRC_ASM = @@ -56,7 +56,7 @@ rtas: $(RTASCMNDIR)/rtas.lds $(OBJS) reloc_table.o $(LD) $(LDFLAGS) -o $@ -T $(RTASCMNDIR)/rtas.lds $(OBJS) reloc_table.o reloc_table.o: $(TOOLSDIR)/gen_reloc_table $(OBJS) - $(TOOLSDIR)/create_reloc_table.sh --ld "$(LD)" --ldflags "$(LDFLAGS)" \ + $(TOOLSDIR)/create_reloc_table.sh --ld "$(ONLY_LD)" --ldflags "$(LDFLAGS)" \ --lds "$(RTASCMNDIR)/rtas.lds" --objcopy "$(OBJCOPY)" $(OBJS) $(TOOLSDIR)/gen_reloc_table: $(TOOLSDIR)/gen_reloc_table.c diff --git a/board-js2x/rtas/rtas_board.c b/board-js2x/rtas/rtas_board.c index 1a3c9e2..f8b7cca 100644 --- a/board-js2x/rtas/rtas_board.c +++ b/board-js2x/rtas/rtas_board.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/board-js2x/rtas/rtas_board.h b/board-js2x/rtas/rtas_board.h index 107da45..06766e1 100644 --- a/board-js2x/rtas/rtas_board.h +++ b/board-js2x/rtas/rtas_board.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/board-js2x/rtas/rtas_flash.c b/board-js2x/rtas/rtas_flash.c index 0673e5b..90b9c70 100644 --- a/board-js2x/rtas/rtas_flash.c +++ b/board-js2x/rtas/rtas_flash.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -228,6 +228,7 @@ copy_flash(short mode) { unsigned char *flash = (unsigned char *) FLASH; uint64_t blockCnt; + uint64_t hash = 0; short notmode = mode ^ 0x1; if (bmc_set_flashside(notmode) != notmode) { return -1; @@ -261,12 +262,19 @@ copy_flash(short mode) } write_flash_page(blockCnt, (unsigned short *) manage_flash_buffer); + + //progress output... + print_progress(); + if (blockCnt > hash * progress) { + print_hash(); + hash++; + } } enter_data_mode(); if (bmc_set_flashside(mode) != mode) { return -1; } - printf("\b# "); + printf("\b#\n"); return 0; } @@ -498,9 +506,16 @@ rtas_update_flash(rtas_args_t * rtas_args) dump_blocklist(bl, version); #endif + // from SLOF we pass a second (unofficial) parameter, if this parameter is 1, we do not + // check wether we are on permanent side. Needed for update-flash -c to work! + uint8_t perm_check = 1; + if ((rtas_args->nargs > 1) && (rtas_args->args[1] == 1)) { + perm_check = 0; + } + //first check if we are running on P //we do not flash on the permanent side - if (bmc_get_flashside() == 0) { + if (perm_check && (bmc_get_flashside() == 0)) { rtas_args->args[rtas_args->nargs] = -9002; //not authorized return; } diff --git a/board-js2x/rtas/rtas_flash.h b/board-js2x/rtas/rtas_flash.h index 7efd925..2f79435 100644 --- a/board-js2x/rtas/rtas_flash.h +++ b/board-js2x/rtas/rtas_flash.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/board-js2x/rtas/rtas_i2c_bmc.h b/board-js2x/rtas/rtas_i2c_bmc.h index 301e32c..e46de88 100644 --- a/board-js2x/rtas/rtas_i2c_bmc.h +++ b/board-js2x/rtas/rtas_i2c_bmc.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/board-js2x/rtas/rtas_ipmi_bmc.h b/board-js2x/rtas/rtas_ipmi_bmc.h index 92cded6..00532d4 100644 --- a/board-js2x/rtas/rtas_ipmi_bmc.h +++ b/board-js2x/rtas/rtas_ipmi_bmc.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/board-js2x/rtas/rtas_out.c b/board-js2x/rtas/rtas_out.c index 46dad96..ac2b25d 100644 --- a/board-js2x/rtas/rtas_out.c +++ b/board-js2x/rtas/rtas_out.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/board-js2x/rtas/rtas_pci.c b/board-js2x/rtas/rtas_pci.c index cac384c..610c326 100644 --- a/board-js2x/rtas/rtas_pci.c +++ b/board-js2x/rtas/rtas_pci.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/board-js2x/rtas/rtas_table.c b/board-js2x/rtas/rtas_table.c index 53f813e..fed4032 100644 --- a/board-js2x/rtas/rtas_table.c +++ b/board-js2x/rtas/rtas_table.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -39,8 +39,6 @@ const rtas_funcdescr_t rtas_func_tab[] = { {"rtas-fetch-slaves", rtas_fetch_slaves, RTAS_TBLFLG_INTERNAL}, {"rtas-stop-bootwatchdog", rtas_stop_bootwatchdog, RTAS_TBLFLG_INTERNAL}, {"rtas-set-bootwatchdog", rtas_set_bootwatchdog, RTAS_TBLFLG_INTERNAL}, - {"freeze-time-base", NULL, RTAS_TBLFLG_INTERNAL}, - {"thaw-time-base", NULL, RTAS_TBLFLG_INTERNAL}, {"rtas-get-blade-descr", rtas_get_blade_descr, RTAS_TBLFLG_INTERNAL}, }; diff --git a/board-js2x/slof/Makefile b/board-js2x/slof/Makefile index 621539b..3d7882a 100644 --- a/board-js2x/slof/Makefile +++ b/board-js2x/slof/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -19,11 +19,12 @@ include $(TOPCMNDIR)/make.rules all: Makefile.dep OF.ffs paflof $(SLOFCMNDIR)/xvect.bin -CPPFLAGS = -I$(LIBCMNDIR)/libbootmsg -SLOF_LIBS = $(LIBCMNDIR)/libbootmsg.a +CPPFLAGS = -I$(LIBCMNDIR)/libbootmsg -I$(LIBCMNDIR)/libnvram +SLOF_LIBS = $(LIBCMNDIR)/libbootmsg.a $(LIBCMNDIR)/libnvram.a BOARD_SLOF_IN = \ $(LIBCMNDIR)/libbootmsg/bootmsg.in \ - $(LIBCMNDIR)/libbases/libbases.in + $(LIBCMNDIR)/libbases/libbases.in \ + $(LIBCMNDIR)/libnvram/libnvram.in BOARD_SLOF_CODE = $(BOARD_SLOF_IN:%.in=%.code) include $(SLOFCMNDIR)/Makefile.inc @@ -50,7 +51,9 @@ USB_FFS_FILES = \ $(SLOFCMNDIR)/fs/usb/usb-storage-wrapper.fs \ $(SLOFCMNDIR)/fs/usb/usb-keyboard.fs \ $(SLOFCMNDIR)/fs/usb/usb-kbd-device-support.fs \ - $(SLOFCMNDIR)/fs/usb/usb-mouse.fs + $(SLOFCMNDIR)/fs/usb/usb-mouse.fs \ + $(SLOFCMNDIR)/fs/scsi-support.fs + # Files that should go into the ROM fs (and so have to be listed in OF.ffs): @@ -82,6 +85,7 @@ OF_FFS_FILES = \ $(SLOFCMNDIR)/fs/pci-properties.fs \ $(SLOFCMNDIR)/fs/pci-config-bridge.fs \ $(SLOFCMNDIR)/fs/update_flash.fs \ + $(SLOFCMNDIR)/fs/xmodem.fs \ $(SLOFCMNDIR)/fs/devices/pci-device_10de_0141.fs \ $(SLOFCMNDIR)/fs/devices/pci-class_02.fs \ $(SLOFBRDDIR)/default-font.bin \ diff --git a/board-js2x/slof/OF.fs b/board-js2x/slof/OF.fs index f70581f..0b8a31f 100644 --- a/board-js2x/slof/OF.fs +++ b/board-js2x/slof/OF.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -14,15 +14,6 @@ hex -: .slof-logo - cr ." ..`. .. ....... .. ...... ......." - cr ." ..`...`''.`'. .''``````..''. .`''```''`. `''``````" - cr ." .`` .:' ': `''..... .''. ''` .''..''......." - cr ." ``.':.';. ``````''`.''. .''. ''``''`````'`" - cr ." ``.':':` .....`''.`'`...... `'`.....`''.`'` " - cr ." .`.`'`` .'`'`````. ``'''''' ``''`'''`. `'` " -; - \ as early as possible we want to know if it is js20, js21 or bimini \ u3 = js20; u4 = js21/bimini \ the difference if bimini or js21 will be done later depending if @@ -30,7 +21,8 @@ hex \ f8000000 is probably the place of the u3/u4 version f8000000 rl@ CONSTANT uni-n-version uni-n-version 4 rshift dup 3 = CONSTANT u3? 4 = CONSTANT u4? -false value bimini? +\ if (f4000682 >> 4) == 1... it is a bimini... +f4000682 rb@ 4 rshift 1 = CONSTANT bimini? \ to decide wether vga initialisation using bios emulation should be attempted, \ we need to know wether a vga-device was found during pci-scan. @@ -61,8 +53,6 @@ defer planar-id ( -- planar-id ) cr -eregs 11 8 * + @ CONSTANT hsprg1 - #include "base.fs" \ Little-endian accesses. Also known as `wrong-endian'. @@ -178,6 +168,7 @@ THEN 200 cp +#include <slof-logo.fs> #include <banner.fs> : .banner .slof-logo .banner ; @@ -220,6 +211,10 @@ d# 14318378 VALUE tb-frequency \ default value - needed for "ms" to work : us 999 + 1000 / ms ; 280 cp + +\ rtas-config is not used +0 CONSTANT rtas-config + #include "rtas.fs" 290 cp s" update_flash.fs" included @@ -256,6 +251,7 @@ create vpd-bootlist 4 allot 300 cp #include <usb/usb-static.fs> 320 cp +#include <scsi-loader.fs> #include <root.fs> 360 cp #include "tree.fs" @@ -309,7 +305,7 @@ takeover? not u4? and IF \ the partition with the type 51 should have been added \ by LLFW... if it does not exist then something went \ wrong and we just destroy the whole thing - 51 get-header IF 0 0 nvram-base rb! ELSE 2drop THEN + 51 get-nvram-partition IF 0 0 nvram-c! ELSE 2drop THEN THEN 880 cp @@ -336,12 +332,13 @@ check-for-nvramrc \ check wether a VGA device was found during pci scan, if it was \ try to initialize it and create the needed device-nodes 0 value biosemu-vmem +100000 value biosemu-vmem-size 0 value screen-info vga-device-node? 0<> IF s" VGA Device found: " type vga-device-node? node>path type s" initializing..." type cr \ claim virtual memory for biosemu of 1MB - 100000 4 claim to biosemu-vmem + biosemu-vmem-size 4 claim to biosemu-vmem \ claim memory for screen-info struct (140 bytes) d# 140 4 claim to screen-info \ remember current-node (it might be node 0 so we cannot use get-node) @@ -352,8 +349,10 @@ vga-device-node? 0<> IF \ s" Time before biosemu:" type .date cr vga-device-node? node>path ( pathstr len ) s" biosemu " biosemu-vmem $cathex ( pathstr len paramstr len ) - 20 char-cat \ add a space - 2swap $cat ( paramstr len ) bios-exec + 20 char-cat \ add a space ( pathstr len paramstr len ) + biosemu-vmem-size $cathex \ add VMEM Size ( pathstr len paramstr len ) + 20 char-cat \ add a space ( pathstr len paramstr len ) + 2swap $cat ( paramstr+path len ) bios-exec \ s" Time after biosemu:" type .date cr s" VGA initialization: detecting displays..." type cr \ try to get info for two monitors @@ -374,8 +373,10 @@ vga-device-node? 0<> IF \ we need to call it before assembling the parameter string vga-device-node? node>path ( pathstr len ) s" get_vbe_info " biosemu-vmem $cathex ( pathstr len paramstr len ) - 20 char-cat \ add a space - 2swap $cat ( paramstr len ) + 20 char-cat \ add a space ( pathstr len paramstr len ) + biosemu-vmem-size $cathex \ add VMEM Size ( pathstr len paramstr len ) + 20 char-cat \ add a space ( pathstr len paramstr len ) + 2swap $cat ( paramstr+path len ) 20 char-cat screen-info $cathex bios-exec \ s" Time after client exec:" type .date cr @@ -395,7 +396,7 @@ vga-device-node? 0<> IF set-node \ release the claimed memory screen-info d# 140 release - biosemu-vmem 100000 release + biosemu-vmem biosemu-vmem-size release s" VGA initialization done." type cr THEN \ vga-device-node? @@ -410,7 +411,6 @@ THEN \ do not let the usb scan overwrite the atapi cdrom alias pci-cdrom-num TO cdrom-alias-num - usb-scan s" net" s" net1" find-alias ?dup IF set-alias ELSE 2drop THEN @@ -429,17 +429,29 @@ THEN ; directserial - -\ enable USB keyboard -s" keyboard" find-alias IF drop - \ s" keyboard" input - \ at this point serial input is disabled -THEN - -\ this enables the framebuffer as primary output device -s" screen" find-alias IF drop - \ s" screen" output - \ at this point serial output is theoretically disabled + +\ on bimini we want to automatically enable screen and keyboard, if they are detected... +bimini? IF + key? IF + cr ." input available on current console input device, not switching input / output." cr + ELSE + \ this enables the framebuffer as primary output device + s" screen" find-alias IF drop + s" screen" output + \ at this point serial output is theoretically disabled + ." screen detected and set as default output device" cr + THEN + \ enable USB keyboard + s" keyboard" find-alias IF drop + s" keyboard" input + \ at this point serial input is disabled + \ if key-available? method is found, defer it to key? + + ." keyboard detected and set as default output device" cr + ." Press and hold 's' to enter Open Firmware." cr + 1000 ms \ wait, in case user wants to press 's' + THEN + THEN THEN : .flashside @@ -469,6 +481,24 @@ bmc? IF disable-watchdog THEN \ for the blades we read the bootlist from the VPD bimini? takeover? or 0= IF ['] vpd-boot-import to read-bootlist THEN +\ for the bimini, we try to boot from disk, if it exists, +\ only if "boot-device" is not set in the nvram +: bimini-bootlist + \ check nvram + s" boot-device" evaluate swap drop ( boot-device-strlen ) + 0= IF + \ no boot-device set in NVRAM, check if disk is available and set it... + \ clear boot-device list + 0 0 set-boot-device + s" disk" find-alias ?dup IF + \ alias found, use it as default + add-boot-device + THEN + THEN +; + +bimini? IF ['] bimini-bootlist to read-bootlist THEN + #include <start-up.fs> #include <boot.fs> @@ -480,3 +510,11 @@ cr \ this CATCH is to ensure the code bellow always executes: boot may ABORT! ' start-it CATCH drop + +#include <history.fs> +nvram-history? [IF] +." loading shell history .. " +history-load +." done" cr +[THEN] + diff --git a/board-js2x/slof/attu.fs b/board-js2x/slof/attu.fs index 91004a4..cc12252 100644 --- a/board-js2x/slof/attu.fs +++ b/board-js2x/slof/attu.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -62,48 +62,26 @@ c0000000 encode-64+ 30000000 encode-64+ s" ranges" property \ Host bridge, so full bus range. f0 encode-int ff encode-int+ s" bus-range" property -\ cr .( Scanning Attu PCIe...) -\ INCLUDE hw/pci-scan.fs - -\ INCLUDE pci-scan.fs - - : open true ; : close ; -\ c0000000 next-pci-mem ! -\ e8000000 max-pci-mem ! -\ e8000000 next-pci-mmio ! -\ f0000000 max-pci-mmio ! -\ for x86emu io access must have 16 bit addresses, so start I/O space at 0xf000 -\ f000 next-pci-io ! -\ 100000000 max-pci-io ! -\ 0 next-pci-bus ! - -\ 0 probe-pci \ : probe-pci-host-bridge ( bus-max bus-min mmio-max mmio-base mem-max mem-base io-max io-base my-puid -- ) -0 my-puid pci-irq-init drop +s" /mpic" find-node my-puid pci-irq-init drop 00fff1f0 18 config-l! ff F0 f0000000 e8000000 e8000000 c0000000 100000000 f000 my-puid probe-pci-host-bridge - \ \ PCIe debug / fixup - : find-pcie-cap ( devfn -- offset | 0 ) - >r 34 BEGIN r@ + config-b@ dup ff <> over and WHILE - dup r@ + config-b@ 10 = IF r> drop EXIT THEN 1+ REPEAT r> 2drop 0 ; - : .pcie ( devfn -- ) - dup find-pcie-cap ?dup IF cr over . ." cap @ " dup . + - dup 8 + config-w@ 5 rshift 7 and 80 swap lshift cr ." max payload size: " .d - dup 8 + config-w@ c rshift 7 and 80 swap lshift cr ." max read req: " .d - dup 12 + config-w@ 4 rshift 3f and cr ." link width: " .d - THEN drop ; - : .pcies ( -- ) - cr cr ." PCIe:" - 10000 0 DO i 8 lshift .pcie LOOP ; - +: find-pcie-cap ( devfn -- offset | 0 ) + >r 34 BEGIN r@ + config-b@ dup ff <> over and WHILE + dup r@ + config-b@ 10 = IF + r> drop EXIT + THEN 1+ + REPEAT r> 2drop 0 +; + : (set-ps) ( ps addr -- ) 8 + >r 5 lshift r@ config-w@ ff1f and or r> config-w! ; : set-ps ( ps -- ) @@ -119,8 +97,5 @@ my-puid probe-pci-host-bridge + 2dup (set-rr) THEN drop LOOP drop ; 80 set-ps 80 set-rr -\ .pcies - finish-device - diff --git a/board-js2x/slof/citrine-disk.fs b/board-js2x/slof/citrine-disk.fs index bfe43f5..146e7ec 100644 --- a/board-js2x/slof/citrine-disk.fs +++ b/board-js2x/slof/citrine-disk.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/citrine-flash.fs b/board-js2x/slof/citrine-flash.fs index f9b9b05..5842b07 100644 --- a/board-js2x/slof/citrine-flash.fs +++ b/board-js2x/slof/citrine-flash.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/citrine.fs b/board-js2x/slof/citrine.fs index d25c909..ee26c9a 100644 --- a/board-js2x/slof/citrine.fs +++ b/board-js2x/slof/citrine.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/copyright-oss.fs b/board-js2x/slof/copyright-oss.fs index 813d997..06f9a3a 100644 --- a/board-js2x/slof/copyright-oss.fs +++ b/board-js2x/slof/copyright-oss.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -10,7 +10,7 @@ \ * IBM Corporation - initial implementation \ ****************************************************************************/ -cr .( Copyright (c) char ) emit .( 2004, 2007 IBM Corporation All rights reserved.) +cr .( Copyright (c) char ) emit .( 2004, 2008 IBM Corporation All rights reserved.) cr .( This program and the accompanying materials are made available) cr .( under the terms of the BSD License available at) cr .( http://www.opensource.org/licenses/bsd-license.php) diff --git a/board-js2x/slof/cpu.fs b/board-js2x/slof/cpu.fs index 3f5977e..bee07d1 100644 --- a/board-js2x/slof/cpu.fs +++ b/board-js2x/slof/cpu.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/dart.fs b/board-js2x/slof/dart.fs index be65421..8fdac83 100644 --- a/board-js2x/slof/dart.fs +++ b/board-js2x/slof/dart.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/flash.fs b/board-js2x/slof/flash.fs index 19b59bf..9c72182 100644 --- a/board-js2x/slof/flash.fs +++ b/board-js2x/slof/flash.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/freq.fs b/board-js2x/slof/freq.fs index c226c85..9f1d36d 100644 --- a/board-js2x/slof/freq.fs +++ b/board-js2x/slof/freq.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/header.fs b/board-js2x/slof/header.fs index 9c17ffb..7248a7e 100644 --- a/board-js2x/slof/header.fs +++ b/board-js2x/slof/header.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/helper.fs b/board-js2x/slof/helper.fs index 4c36a45..9da396c 100644 --- a/board-js2x/slof/helper.fs +++ b/board-js2x/slof/helper.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/ht.fs b/board-js2x/slof/ht.fs index 31a8de3..e122a03 100644 --- a/board-js2x/slof/ht.fs +++ b/board-js2x/slof/ht.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -10,14 +10,12 @@ \ * IBM Corporation - initial implementation \ ****************************************************************************/ - \ Hypertransport. \ See the PCI OF binding document. new-device - s" ht" 2dup device-name device-type s" u3-ht" compatible s" U3" encode-string s" model" property @@ -26,8 +24,14 @@ s" U3" encode-string s" model" property 2 encode-int s" #size-cells" property s" /mpic" find-node encode-int s" interrupt-parent" property -\ XXX should have interrupt map, etc. this works for now though. -\ linux gets the PCI irqs right; only need to tell it the lpc irqs are edge. + +4000 encode-int 0 encode-int+ 0 encode-int+ +1 encode-int+ s" /mpic" find-node encode-int+ +10 encode-int+ 0 encode-int+ +s" interrupt-map" property + +f800 encode-int 0 encode-int+ 0 encode-int+ +7 encode-int+ s" interrupt-map-mask" property : decode-unit 2 hex-decode-unit 3 lshift or 8 lshift 0 0 rot ; @@ -64,10 +68,10 @@ f2000000 CONSTANT my-puid 00000000 encode-int+ f4000000 encode-int+ 00000000 encode-int+ 00400000 encode-int+ -\ 1.75GB of memory space @ 80000000. +\ 1 GB of memory space @ 80000000 02000000 encode-int+ 00000000 encode-int+ 80000000 encode-int+ 00000000 encode-int+ 80000000 encode-int+ -00000000 encode-int+ 4000000 encode-int+ s" ranges" property +00000000 encode-int+ 40000000 encode-int+ s" ranges" property \ Host bridge, so full bus range. 0 encode-int ff encode-int+ s" bus-range" property @@ -137,148 +141,33 @@ clearht f8070111 rb@ setwidth f8070120 rw@ 2log dup .( Switching top HT bus to ) ht>freq 0 d# .r .( MHz...) cr setfreq u3? IF ldtstop THEN u4? IF ldtstop1 THEN - -\ #include <pci-scan.fs> - - : open true ; : close ; - -\ 80000000 next-pci-mem ! -\ b8000000 max-pci-mem ! -\ b8000000 next-pci-mmio ! -\ c0000000 max-pci-mmio ! -\ 10000 next-pci-io ! -\ 100000000 max-pci-io ! -\ 0 next-pci-bus ! - -\ 0 probe-pci \ : probe-pci-host-bridge ( bus-max bus-min mmio-max mmio-base mem-max mem-base io-max io-base my-puid -- ) s" /mpic" find-node my-puid pci-irq-init drop 1f 0 c0000000 b8000000 b8000000 80000000 100000000 10000 my-puid probe-pci-host-bridge - - - : msi -\ \ on citrine (pass2) -\ f8005000 101054 config-l! 0 101058 config-l! -\ f 10105c config-w! 81 101052 config-b! - -\ \ on citrine (pass4) -\ f8005000 010854 config-l! 0 010858 config-l! -\ f 01085c config-w! 81 010852 config-b! - - \ on citrine (pass4), using old vector f80040f0 010854 config-l! 0 010858 config-l! ffff 01085c config-w! 81 010852 config-b! - - \ on pxb1 -\ f8000000 08a4 config-l! 0 08a8 config-l! 1 08a2 config-b! ; -\ f8000000 08a4 config-l! fd 08a8 config-l! 1 08a2 config-b! ; - ; - - \ This works. Needs cleaning up though; and we need to communicate the \ MSI address range to the client program. (We keep the default range \ at fee00000 for now). : msi-on 7 1 DO 10000 i 800 * a0 + config-l! LOOP ; msi-on - - -\ \ \ -\ \ \ IRQ DEBUG CODE -\ \ \ - -: >mpic0 f8041000 + ; -: mpic0@ >mpic0 rl@ ; -: mpic0! >mpic0 rl! ; - -: >mpic f8050000 + ; -: mpic@ >mpic rl@ ; -: mpic! >mpic rl! ; - -: mpic-on dup 20 * 00880000 rot + over mpic! 1 swap 10 + mpic! ; -: mpic-all-on 7c 0 DO i mpic-on LOOP ; - -: mpic-cpu-on 0 f8060080 rl! ; -: mpic-cur cr ." pending: " 4 0 DO f80600a0 i c lshift + rl@ . LOOP ; -: mpic-eoi 0 f80600b0 rl! ; - -: one-by-one 7c 0 DO cr i . i mpic-on mpic-cur mpic-eoi LOOP ; - -CREATE pcie-cnfg-space 24 allot - -: .pci-express-capabilites-reg ( val -- ) - cr ." Cap ID :" dup ff and u. - cr ." Next Cap :" dup 8 rshift ff and u. - cr ." Type :" dup 14 rshift f and - CASE - 0 OF ." PCI Express Endpoint" ENDOF - 1 OF ." Legacy PCI Express Endpoint" ENDOF - 4 OF ." Root Port" ENDOF - 5 OF ." Switch upstream port" ENDOF - 6 OF ." Switch downstream port" ENDOF - 7 OF ." Express-to-PCI/PCI-X bridge" ENDOF - 8 OF ." PCI/PCI-X to Express bridge" ENDOF - dup OF 0 ENDOF ." Reserved" ENDCASE - drop -; - -: .pci-device-capabilites-reg ( val -- ) - cr ." MaxPS :" dup 7 and u. - drop -; - -: .pci-device-control-reg ( val -- ) - cr ." MaxPS act:" dup 5 rshift 7 and u. - cr ." MaxRS act:" dup c rshift 7 and u. - cr ." ERROR :" dup 10 rshift 3f and u. - drop -; - -: .pci-link-capabilites-reg ( val -- ) - cr ." Max linkW:" dup 4 rshift 3f and u. - drop -; - -: .pci-link-control-reg ( val -- ) - cr ." Neg linkW:" dup 4 10 + rshift 3f and u. - cr ." Train ERR:" dup a 10 + rshift 1 and u. - cr ." Train act:" dup b 10 + rshift 1 and u. - drop -; - -: .pcie-ext - 8 0 DO dup i 4 * dup >r + config-l@ r> pcie-cnfg-space + l! LOOP -\ pcie-cnfg-space 24 dump - pcie-cnfg-space l@ .pci-express-capabilites-reg - pcie-cnfg-space 4 + l@ .pci-device-capabilites-reg - pcie-cnfg-space 8 + l@ .pci-device-control-reg - pcie-cnfg-space c + l@ .pci-link-capabilites-reg - pcie-cnfg-space 10 + l@ .pci-link-control-reg -; - - \ PCIe debug / fixup -: find-pcie-cap ( devfn -- offset | 0 ) - >r 34 BEGIN r@ + config-b@ dup ff <> over and WHILE - dup r@ + config-b@ 10 = IF r> drop EXIT THEN 1+ REPEAT r> 2drop 0 ; -: .pcie ( devfn -- ) - dup find-pcie-cap ?dup IF cr over . ." cap @ " dup . + -\ .pcie-ext - dup 8 + config-w@ 5 rshift 7 and 80 swap lshift cr ." max payload size: " .d - dup 8 + config-w@ c rshift 7 and 80 swap lshift cr ." max read req: " .d - dup 12 + config-w@ 4 rshift 3f and cr ." link width: " .d - THEN drop ; -: .pcies ( -- ) - cr cr ." PCIe:" - 10000 0 DO i 8 lshift .pcie LOOP ; +: find-pcie-cap ( devfn -- offset | 0 ) + >r 34 BEGIN r@ + config-b@ dup ff <> over and WHILE + dup r@ + config-b@ 10 = IF + r> drop EXIT + THEN 1+ + REPEAT r> 2drop 0 +; : (set-ps) ( ps addr -- ) 8 + >r 5 lshift r@ config-w@ ff1f and or r> config-w! ; @@ -294,16 +183,7 @@ CREATE pcie-cnfg-space 24 allot 10000 0 DO i 8 lshift dup find-pcie-cap ?dup IF + 2dup (set-rr) THEN drop LOOP drop ; -bimini? IF - 100 set-ps 200 set-rr -\ .pcies -ELSE - 100 set-ps 200 set-rr -\ .pcies -THEN - -: set-ps set-ps .pcies ; -: set-rr set-rr .pcies ; - +100 set-ps 200 set-rr +100 set-ps 200 set-rr finish-device diff --git a/board-js2x/slof/i2c.fs b/board-js2x/slof/i2c.fs index 16a2145..044bde9 100644 --- a/board-js2x/slof/i2c.fs +++ b/board-js2x/slof/i2c.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/io.fs b/board-js2x/slof/io.fs index a607767..f388984 100644 --- a/board-js2x/slof/io.fs +++ b/board-js2x/slof/io.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/ioapic.fs b/board-js2x/slof/ioapic.fs index 8519413..685d6df 100644 --- a/board-js2x/slof/ioapic.fs +++ b/board-js2x/slof/ioapic.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/ipmi-kcs.fs b/board-js2x/slof/ipmi-kcs.fs index edf939e..cf9d5af 100644 --- a/board-js2x/slof/ipmi-kcs.fs +++ b/board-js2x/slof/ipmi-kcs.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/ipmi-vpd.fs b/board-js2x/slof/ipmi-vpd.fs index 9b1f564..a69722d 100644 --- a/board-js2x/slof/ipmi-vpd.fs +++ b/board-js2x/slof/ipmi-vpd.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/memory.fs b/board-js2x/slof/memory.fs index ae3002e..b1b7aaa 100644 --- a/board-js2x/slof/memory.fs +++ b/board-js2x/slof/memory.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/mpic.fs b/board-js2x/slof/mpic.fs index abba585..a952344 100644 --- a/board-js2x/slof/mpic.fs +++ b/board-js2x/slof/mpic.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/pci-aliases.fs b/board-js2x/slof/pci-aliases.fs index f685487..f017e4a 100644 --- a/board-js2x/slof/pci-aliases.fs +++ b/board-js2x/slof/pci-aliases.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/pci-bridge_1022_7460.fs b/board-js2x/slof/pci-bridge_1022_7460.fs index 3e4a9d1..d8f0c0e 100644 --- a/board-js2x/slof/pci-bridge_1022_7460.fs +++ b/board-js2x/slof/pci-bridge_1022_7460.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -21,7 +21,9 @@ \ run first. So do it now. 00 842 config-b! \ Disable 8237 & 8254 & 8259's. We're not a PC. -80 847 config-b! \ Disable EHCI, as it is terminally broken. +u3? IF + 80 847 config-b! \ Disable EHCI, as it is terminally broken. +THEN 03 848 config-b! \ Enable LPC, IDE; disable I2C, SMM, AC'97 functions. 01 849 config-b! \ Enable USB, disable 100Mb enet. 01 84b config-b! \ Enable IO-APIC. @@ -72,6 +74,115 @@ INCLUDE freq.fs \ 8111 has only 16 bits of PCI I/O space. Get the address in range. 8000 next-pci-io ! +\ before disabling EHCI it needs to be reset + +\ first we are setting up the BAR0, so that we can talk to the +\ memory mapped controller; not using the PCI scan because we just +\ want a temporary setup + +: really-disable-broken-amd8111-ehci ( -- ) + \ this word only works on U4 systems (JS21/Bimini) + \ yeah, hardcoded! + f2000000 to puid + + \ the PCI scan would assign b8302000 to that device + \ let's just take that address + b8302000 70210 rtas-config-l! + + \ enable memory space + 70204 dup rtas-config-l@ 2 or swap rtas-config-l! + + b8302000 ( base ) + + \ Sequence prescribed for resetting the EHCI contoller + + \ If Run/Stop bit (ECAP30 bit 0) is 1 + \ Set Run/Stop bit to 0 + \ wait 2ms + + dup 30 + rl@ 1 and 1 = IF + dup 30 + rl@ 1 or + dup 30 + rl! + 2 ms + THEN + + \ While HCHalted bit (ECAP34 bit 12) is 0 (still running, wait forever) + \ wait 2ms + + BEGIN dup 34 + rl@ 1000 and 0= 2 ms UNTIL + + \ Set HCReset bit (ECAP30 bit 1) + + dup 30 + 2 swap rl! + + \ While HCReset bit is 1 (wait forever for reset to complete) + \ wait 2ms + + BEGIN dup 30 + rl@ 2 and 0= 2 ms UNTIL drop + + \ now it is really disabled + + \ disable memory space access again + 2100000 70204 rtas-config-l! + + 80 847 config-b! \ Disable EHCI, as it is terminally broken. +; + my-space pci-class-name type cr -my-space pci-bridge-generic-setup -s" pci" device-name + +\ copied from pci-properties.fs and pci-scan.fs +\ changed to disable the EHCI completely just before the scan +\ and after mem/IO transactions have been enabled + +\ Setup the Base and Limits in the Bridge +\ and scan the bus(es) beyond that Bridge +: pci-bridge-probe-amd8111 ( addr -- ) + dup pci-bridge-set-bases \ SetUp all Base Registers + pci-bus-number 1+ TO pci-bus-number \ increase number of busses found + pci-device-vec-len 1+ TO pci-device-vec-len \ increase the device-slot vector depth + dup \ stack config-addr for pci-bus! + FF swap \ Subordinate Bus Number ( for now to max to open all subbusses ) + pci-bus-number swap \ Secondary Bus Number ( the new busnumber ) + dup pci-addr2bus swap \ Primary Bus Number ( the current bus ) + pci-bus! \ and set them into the bridge + pci-enable \ enable mem/IO transactions + + \ at this point we can talk to the broken EHCI controller + really-disable-broken-amd8111-ehci + + dup pci-bus-scnd@ func-pci-probe-bus \ and probe the secondary bus + dup pci-bus-number swap pci-bus-subo! \ set SubOrdinate Bus Number to current number of busses + pci-device-vec-len 1- TO pci-device-vec-len \ decrease the device-slot vector depth + dup pci-bridge-set-limits \ SetUp all Limit Registers + drop \ forget the config-addr +; + +\ used to set up all unknown Bridges. +\ If a Bridge has no special handling for setup +\ the device file (pci-bridge_VENDOR_DEVICE.fs) can call +\ this word to setup busses and scan beyond. +: pci-bridge-generic-setup-amd8111 ( addr -- ) + pci-device-slots >r \ save the slot array on return stack + dup pci-common-props \ set the common properties before scanning the bus + s" pci" device-type \ the type is allways "pci" + dup pci-bridge-probe-amd8111 \ find all device connected to it + dup assign-all-bridge-bars \ set up all memory access BARs + dup pci-set-irq-line \ set the interrupt pin + dup pci-set-capabilities \ set up the capabilities + pci-bridge-props \ and generate all properties + r> TO pci-device-slots \ and reset the slot array +; + +: amd8111-bridge-setup + my-space + u3? takeover? or IF + \ if it is js20 or we are coming from takeover + \ we just do the normal setup + pci-bridge-generic-setup + ELSE + pci-bridge-generic-setup-amd8111 + THEN + s" pci" device-name +; + +amd8111-bridge-setup diff --git a/board-js2x/slof/pci-capabilities.fs b/board-js2x/slof/pci-capabilities.fs index 8f9998e..a50714a 100644 --- a/board-js2x/slof/pci-capabilities.fs +++ b/board-js2x/slof/pci-capabilities.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/pci-class_03.fs b/board-js2x/slof/pci-class_03.fs index 833c8eb..f95e502 100644 --- a/board-js2x/slof/pci-class_03.fs +++ b/board-js2x/slof/pci-class_03.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/pci-device_1002_515e.fs b/board-js2x/slof/pci-device_1002_515e.fs index ebbd9a2..5cd692b 100644 --- a/board-js2x/slof/pci-device_1002_515e.fs +++ b/board-js2x/slof/pci-device_1002_515e.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -413,7 +413,14 @@ pllwriteoff h# 50 reg-rl@ H# F8FFFFFF AND h# 03000000 or h# 50 reg-rl! h# 50 h# 22C reg-rl! set-palette - mem-addr h# F0000 0 fill + + \ at this point for some reason mem-addr does not point + \ to the right address and therefore the following command + \ which should probably clean the frame buffer just + \ overwrites everything starting from 0 including the + \ exception vectors + + \ mem-addr h# F0000 0 fill ; : DO-INIT diff --git a/board-js2x/slof/pci-device_1014_028c.fs b/board-js2x/slof/pci-device_1014_028c.fs index 1a3eca5..e83a4e0 100644 --- a/board-js2x/slof/pci-device_1014_028c.fs +++ b/board-js2x/slof/pci-device_1014_028c.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/pci-device_1014_02bd.fs b/board-js2x/slof/pci-device_1014_02bd.fs index a305931..1db6bda 100644 --- a/board-js2x/slof/pci-device_1014_02bd.fs +++ b/board-js2x/slof/pci-device_1014_02bd.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -17,7 +17,6 @@ my-space pci-set-irq-line \ set Memory Write and Invalidate Enable, SERR# Enable (see PCI 3.0 Spec Chapter 6.2.2 device control) 7 4 config-w! -true to bimini? \ Citrine storage controller. s" obsidian" diff --git a/board-js2x/slof/pci-device_1022_7451.fs b/board-js2x/slof/pci-device_1022_7451.fs index cd9b46a..8c2c30b 100644 --- a/board-js2x/slof/pci-device_1022_7451.fs +++ b/board-js2x/slof/pci-device_1022_7451.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/pci-device_1022_7468.fs b/board-js2x/slof/pci-device_1022_7468.fs index ac7a719..4126ca2 100644 --- a/board-js2x/slof/pci-device_1022_7468.fs +++ b/board-js2x/slof/pci-device_1022_7468.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/pci-device_1022_7469.fs b/board-js2x/slof/pci-device_1022_7469.fs index 999bdfe..fdae920 100644 --- a/board-js2x/slof/pci-device_1022_7469.fs +++ b/board-js2x/slof/pci-device_1022_7469.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/pci-interrupts.fs b/board-js2x/slof/pci-interrupts.fs index 6380332..92851cd 100644 --- a/board-js2x/slof/pci-interrupts.fs +++ b/board-js2x/slof/pci-interrupts.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/rtas.fs b/board-js2x/slof/rtas.fs index 6331795..6a0672c 100644 --- a/board-js2x/slof/rtas.fs +++ b/board-js2x/slof/rtas.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -23,7 +23,7 @@ \ for update-flash : (set-flashside) ( flashside -- status ) - dup rtas-set-flashside = IF -1 ELSE 0 THEN + dup rtas-set-flashside = IF 0 ELSE -1 THEN ; ' (set-flashside) to set-flashside @@ -198,11 +198,14 @@ blist 50 erase : rtas-ibm-update-flash-64 ( block-list -- status ) [ s" ibm,update-flash-64" rtas-get-token ] LITERAL rtas-cb rtas>token l! - 1 rtas-cb rtas>nargs l! + 2 rtas-cb rtas>nargs l! 1 rtas-cb rtas>nret l! rtas-cb rtas>args0 l! + \ special unofficial parameter: if this is set to 1, the rtas function will not check, wether + \ we are on the perm side... this is needed for "update-flash -c" to work... + 1 rtas-cb rtas>args1 l! enter-rtas - rtas-cb rtas>args1 l@ + rtas-cb rtas>args2 l@ ; \ for update-flash @@ -228,8 +231,8 @@ blist 50 erase [ s" rtas-get-blade-descr" rtas-get-token ] LITERAL rtas-cb rtas>token l! 2 rtas-cb rtas>nargs l! 2 rtas-cb rtas>nret l! - rtas-cb rtas>args0 l! rtas-cb rtas>args1 l! + rtas-cb rtas>args0 l! enter-rtas rtas-cb rtas>args2 l@ rtas-cb rtas>args3 l@ diff --git a/board-js2x/slof/rtc.fs b/board-js2x/slof/rtc.fs index db497e9..861b3f9 100644 --- a/board-js2x/slof/rtc.fs +++ b/board-js2x/slof/rtc.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/serial.fs b/board-js2x/slof/serial.fs index eb9506e..98b2f29 100644 --- a/board-js2x/slof/serial.fs +++ b/board-js2x/slof/serial.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/sio.fs b/board-js2x/slof/sio.fs index 4c967e0..554cf83 100644 --- a/board-js2x/slof/sio.fs +++ b/board-js2x/slof/sio.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/tpm.fs b/board-js2x/slof/tpm.fs index 5a45c0b..69b9bc4 100644 --- a/board-js2x/slof/tpm.fs +++ b/board-js2x/slof/tpm.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/tree.fs b/board-js2x/slof/tree.fs index 6f8c1b1..6b3150c 100644 --- a/board-js2x/slof/tree.fs +++ b/board-js2x/slof/tree.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -33,7 +33,22 @@ \ The root of the device tree and some of its kids. s" /" find-device -vpd-read-model encode-string s" model" property +\ read model string from VPD +vpd-read-model ( straddr strlen ) +\ if it is a bimini, we replace the "IBM," in the model string with "TSS," +bimini? IF + 2dup drop 4 ( straddr strlen str 4 ) \ for string comparison: only first 4 bytes ("IBM,") + \ string comparison + s" IBM," str= IF + \ model starts with "IBM,", we replace it with "TSS," + 2dup drop s" TSS," ( straddr strlen straddr replacestr len ) + rot swap ( straddr strlen replacestr straddr len ) \ correct order for move: src dest len + move ( straddr strlen ) \ now we have TSS, at beginning of str... + THEN +THEN +\ store the model string +encode-string s" model" property + 2 encode-int s" #address-cells" property 2 encode-int s" #size-cells" property @@ -44,8 +59,19 @@ vpd-read-model encode-string s" model" property \ Yaboot is stupid. Without this, it can't/won't find /etc/yaboot.conf. s" chrp SLOF based 970 blade" device-type +\ add more information to the compatible property +js21? IF + bimini? IF + s" IBM,Bimini" + ELSE + s" IBM,JS21" + THEN +ELSE + s" IBM,JS20" +THEN encode-string \ To get linux-2.6.10 and later to work out-of-the-box. -s" Momentum,Maple" compatible +s" Momentum,Maple" encode-string encode+ s" compatible" property + \ See 3.6.5, and the PowerPC OF binding document. new-device diff --git a/board-js2x/slof/u4-mem.fs b/board-js2x/slof/u4-mem.fs index a2f1473..0f8b1ee 100644 --- a/board-js2x/slof/u4-mem.fs +++ b/board-js2x/slof/u4-mem.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/board-js2x/slof/vga-display.fs b/board-js2x/slof/vga-display.fs index e9decfd..0cc9bba 100644 --- a/board-js2x/slof/vga-display.fs +++ b/board-js2x/slof/vga-display.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/clients/Makefile b/clients/Makefile index 3198176..d656f08 100644 --- a/clients/Makefile +++ b/clients/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License diff --git a/clients/clients.mk b/clients/clients.mk index 45a8534..ca741e4 100644 --- a/clients/clients.mk +++ b/clients/clients.mk @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License diff --git a/clients/net-snk/Makefile b/clients/net-snk/Makefile index 4636cec..f89ef28 100644 --- a/clients/net-snk/Makefile +++ b/clients/net-snk/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -17,7 +17,7 @@ include $(TOP)/make.rules OBJS = kernel/kernel.o oflib/oflib.o libc/libc-glue.o app/app.o .PHONY : subdirs clean depend mrproper -client : subdirs $(OBJS) $(LIBCMNDIR)/libc.a +client : .depend subdirs $(OBJS) $(LIBCMNDIR)/libc.a $(LD) $(LDFLAGS) -o $@ -Tclient.lds $(OBJS) $(LIBCMNDIR)/libc.a $(OBJDUMP) -DSsx $@ > $@.dis cp $@ $@.unstripped @@ -26,6 +26,13 @@ client : subdirs $(OBJS) $(LIBCMNDIR)/libc.a sec-client : subdirs $(OBJS) $(LIBCMNDIR)/libc.a $(LD) $(LDFLAGS) -o $@ -Tsec-client.lds $(OBJS) $(LIBCMNDIR)/libc.a +fpga-client : + $(MAKE) -C . fpga-client-int SNK_LJTAG_PROCESS=1 + +fpga-client-int : subdirs $(OBJS) $(LIBCMNDIR)/libc.a + $(LD) $(LDFLAGS) -o fpga-client -Tsec-client.lds $(OBJS) $(LIBCMNDIR)/libc.a + $(STRIP) fpga-client + subdirs : @for dir in $(dir $(OBJS)); do \ $(MAKE) -C $$dir || exit 1; \ @@ -39,7 +46,7 @@ clean: $(MAKE) -C $$dir clean; \ done rm -f $(OBJS) client diag netboot sec-client net-diag \ - *.dis client.unstripped + *.dis client.unstripped fpga-client mrproper : clean $(MAKE) -C app mrproper @@ -47,11 +54,13 @@ mrproper : clean $(MAKE) -C kernel mrproper $(MAKE) -C oflib mrproper find -name .*.bak | xargs rm -rf + $(RM) .depend distclean: mrproper -depend : +depend .depend: $(MAKE) -C app depend $(MAKE) -C libc depend $(MAKE) -C kernel depend $(MAKE) -C oflib depend + touch .depend diff --git a/clients/net-snk/app/Makefile b/clients/net-snk/app/Makefile index d65216c..294ec15 100644 --- a/clients/net-snk/app/Makefile +++ b/clients/net-snk/app/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -19,6 +19,10 @@ include $(TOP)/make.rules CFLAGS +=$(ADDCFLAGS) OBJS = main.o +ifeq ($(SNK_LJTAG_PROCESS), 1) +OBJDIRS = ljtag/ljtag.o +CFLAGS += -DSNK_LJTAG_PROCESS +else OBJDIRS = netlib/netlib.o netapps/netboot.o OBJDIRS += netapps/netflash.o OBJDIRS += netapps/ping.o @@ -27,11 +31,18 @@ ifeq ($(SNK_BIOSEMU_APPS), 1) OBJDIRS += biosemu/biosemu_app.o CFLAGS += -DSNK_BIOSEMU_APPS endif +ifeq ($(SNK_GENMODULE_APPS), 1) +OBJDIRS += forth/forth.o snkshell/snkshell.o +CFLAGS += -DSNK_GENMODULE_APPS +endif +endif + +SUBDIRS = $(dir $(OBJDIRS)) all: app.o subdirs: - for dir in $(dir $(OBJDIRS)); do \ + for dir in $(SUBDIRS); do \ $(MAKE) -C $$dir DIRECTORY=$(DIRECTORY)$$dir || exit 1; \ done @@ -40,7 +51,7 @@ app.o: subdirs $(OBJS) clean : $(RM) -f *.o *.a *.i - for dir in $(dir $(OBJDIRS)); do \ + for dir in $(SUBDIRS); do \ $(CLEAN) ; \ $(MAKE) -C $$dir DIRECTORY=$(DIRECTORY)$$dir clean; \ done diff --git a/clients/net-snk/app/biosemu/Makefile b/clients/net-snk/app/biosemu/Makefile index 8fe149d..3a07ada 100644 --- a/clients/net-snk/app/biosemu/Makefile +++ b/clients/net-snk/app/biosemu/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -16,7 +16,7 @@ ifndef TOP endif include $(TOP)/make.rules -CFLAGS += -I$(ROOTDIR)/other-licence/x86emu -I$(ROOTDIR)/other-licence/x86emu/include -save-temps +CFLAGS += -I$(ROOTDIR)/other-licence/x86emu -I$(ROOTDIR)/other-licence/x86emu/include OBJS = biosemu.o debug.o device.o mem.o io.o interrupt.o vbe.o LIBX86EMU = $(ROOTDIR)/other-licence/x86emu/libx86emu.a diff --git a/clients/net-snk/app/biosemu/biosemu.c b/clients/net-snk/app/biosemu/biosemu.c index 1d9b3da..428f8d4 100644 --- a/clients/net-snk/app/biosemu/biosemu.c +++ b/clients/net-snk/app/biosemu/biosemu.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -15,7 +15,7 @@ #include <stdlib.h> #include <string.h> -#include <types.h> +#include <stdint.h> #include <cpu.h> #include "debug.h" @@ -24,13 +24,14 @@ #include <x86emu/regs.h> #include <x86emu/prim_ops.h> // for push_word +#include "biosemu.h" #include "io.h" #include "mem.h" #include "interrupt.h" +#include "device.h" #include <rtas.h> -#include "device.h" static X86EMU_memFuncs my_mem_funcs = { my_rdb, my_rdw, my_rdl, @@ -49,9 +50,11 @@ biosemu(char argc, char **argv) { uint8_t *rom_image; int i = 0; - int32_t len; uint8_t *biosmem; uint32_t biosmem_size; +#ifdef DEBUG + debug_flags = DEBUG_PRINT_INT10 | DEBUG_PNP;// | DEBUG_PMM;// | DEBUG_INTR | DEBUG_CHECK_VMEM_ACCESS | DEBUG_MEM | DEBUG_IO;// | DEBUG_TRACE_X86EMU | DEBUG_JMP; +#endif if (argc < 3) { printf("Usage %s <vmem_base> <device_path>\n", argv[0]); for (i = 0; i < argc; i++) { @@ -59,82 +62,71 @@ biosemu(char argc, char **argv) } return -1; } - // argv[1] is address of virtual BIOS mem... it should be 1MB large... + // argv[1] is address of virtual BIOS mem... + // argv[2] is the size biosmem = (uint8_t *) strtoul(argv[1], 0, 16); - biosmem_size = 0x100000; - // argv[2] is the device to open and use... - if (dev_init(argv[2]) != 0) { + biosmem_size = strtoul(argv[2], 0, 16); + if (biosmem_size < MIN_REQUIRED_VMEM_SIZE) { + printf("Error: Not enough virtual memory: %x, required: %x!\n", + biosmem_size, MIN_REQUIRED_VMEM_SIZE); + return -1; + } + // argv[3] is the device to open and use... + if (dev_init(argv[3]) != 0) { printf("Error initializing device!\n"); return -1; } - // get expROM address using rtas_pci_config_read - uint64_t rom_base_addr = - rtas_pci_config_read(bios_device.puid, 4, bios_device.bus, - bios_device.devfn, 0x30); - if ((rom_base_addr & 0x1) != 1) { - printf("Error: invalid Expansion ROM address: 0x%llx!\n", - rom_base_addr); + if (dev_check_exprom() != 0) { + printf("Error: Device Expansion ROM invalid!\n"); return -1; } - // unset lowest bit... - rom_base_addr = rom_base_addr & 0xFFFFFFFE; - DEBUG_PRINTF("rom_base: %llx\n", rom_base_addr); - - dev_translate_address(&rom_base_addr); - DEBUG_PRINTF("translated rom_base: %llx\n", rom_base_addr); - - rom_image = (uint8_t *) rom_base_addr; + rom_image = (uint8_t *) bios_device.img_addr; DEBUG_PRINTF("executing rom_image from %p\n", rom_image); DEBUG_PRINTF("biosmem at %p\n", biosmem); - // first of all, we need the size (3rd byte) - set_ci(); - len = *(rom_image + 2); - clr_ci(); - // size is in 512 byte blocks - len = len * 512; - DEBUG_PRINTF("Length: %d\n", len); + DEBUG_PRINTF("Image Size: %d\n", bios_device.img_size); // in case we jump somewhere unexpected, or execution is finished, // fill the biosmem with hlt instructions (0xf4) - memset(biosmem, 0xf4, sizeof(biosmem)); + memset(biosmem, 0xf4, biosmem_size); M.mem_base = (long) biosmem; M.mem_size = biosmem_size; DEBUG_PRINTF("membase set: %08x, size: %08x\n", (int) M.mem_base, (int) M.mem_size); - // copy expansion ROM image to segment C000 + // copy expansion ROM image to segment OPTION_ROM_CODE_SEGMENT // NOTE: this sometimes fails, some bytes are 0x00... so we compare // after copying and do some retries... - uint8_t *vga_img = biosmem + 0xc0000; + uint8_t *mem_img = biosmem + (OPTION_ROM_CODE_SEGMENT << 4); uint8_t copy_count = 0; uint8_t cmp_result = 0; do { #if 0 set_ci(); - memcpy(vga_img, rom_image, len); + memcpy(mem_img, rom_image, len); clr_ci(); #else // memcpy fails... try copy byte-by-byte with set/clr_ci uint8_t c; - for (i = 0; i < len; i++) { + for (i = 0; i < bios_device.img_size; i++) { set_ci(); c = *(rom_image + i); if (c != *(rom_image + i)) { clr_ci(); - printf("Copy failed at: %x/%x\n", i, len); - printf("rom_image(%x): %x, vga_img(%x): %x\n", - i, *(rom_image + i), i, *(vga_img + i)); + printf("Copy failed at: %x/%x\n", i, + bios_device.img_size); + printf("rom_image(%x): %x, mem_img(%x): %x\n", + i, *(rom_image + i), i, *(mem_img + i)); break; } clr_ci(); - *(vga_img + i) = c; + *(mem_img + i) = c; } #endif copy_count++; set_ci(); - cmp_result = memcmp(vga_img, rom_image, len); + cmp_result = memcmp(mem_img, rom_image, bios_device.img_size); clr_ci(); } while ((copy_count < 5) && (cmp_result != 0)); @@ -143,18 +135,80 @@ biosemu(char argc, char **argv) ("\nCopying Expansion ROM Image to Memory failed after %d retries! (%x)\n", copy_count, cmp_result); dump(rom_image, 0x20); - dump(vga_img, 0x20); + dump(mem_img, 0x20); return 0; } - // setup BIOS area + // setup default Interrupt Vectors + // some expansion ROMs seem to check for these addresses.. + // each handler is only an IRET (0xCF) instruction + // ROM BIOS Int 10 Handler F000:F065 + my_wrl(0x10 * 4, 0xf000f065); + my_wrb(0x000ff065, 0xcf); + // ROM BIOS Int 11 Handler F000:F84D + my_wrl(0x11 * 4, 0xf000f84d); + my_wrb(0x000ff84d, 0xcf); + // ROM BIOS Int 12 Handler F000:F841 + my_wrl(0x12 * 4, 0xf000f841); + my_wrb(0x000ff841, 0xcf); + // ROM BIOS Int 13 Handler F000:EC59 + my_wrl(0x13 * 4, 0xf000ec59); + my_wrb(0x000fec59, 0xcf); + // ROM BIOS Int 14 Handler F000:E739 + my_wrl(0x14 * 4, 0xf000e739); + my_wrb(0x000fe739, 0xcf); + // ROM BIOS Int 15 Handler F000:F859 + my_wrl(0x15 * 4, 0xf000f859); + my_wrb(0x000ff859, 0xcf); + // ROM BIOS Int 16 Handler F000:E82E + my_wrl(0x16 * 4, 0xf000e82e); + my_wrb(0x000fe82e, 0xcf); + // ROM BIOS Int 17 Handler F000:EFD2 + my_wrl(0x17 * 4, 0xf000efd2); + my_wrb(0x000fefd2, 0xcf); + // ROM BIOS Int 1A Handler F000:FE6E + my_wrl(0x1a * 4, 0xf000fe6e); + my_wrb(0x000ffe6e, 0xcf); + + // setup BIOS Data Area (0000:04xx, or 0040:00xx) + // we currently 0 this area, meaning "we dont have + // any hardware" :-) no serial/parallel ports, floppys, ... + memset(biosmem + 0x400, 0x0, 0x100); + + // at offset 13h in BDA is the memory size in kbytes + my_wrw(0x413, biosmem_size / 1024); + // at offset 0eh in BDA is the segment of the Extended BIOS Data Area + // see setup further down + my_wrw(0x40e, INITIAL_EBDA_SEGMENT); + // TODO: setup BDA Video Data ( offset 49h-66h) + // e.g. to store video mode, cursor position, ... + // in int10 (done) handler and VBE Functions + + // TODO: setup BDA Fixed Disk Data + // 74h: Fixed Disk Last Operation Status + // 75h: Fixed Disk Number of Disk Drives + + // TODO: check BDA for further needed data... + + //setup Extended BIOS Data Area + //we currently 0 this area + memset(biosmem + (INITIAL_EBDA_SEGMENT << 4), 0, INITIAL_EBDA_SIZE); + // at offset 0h in EBDA is the size of the EBDA in KB + my_wrw((INITIAL_EBDA_SEGMENT << 4) + 0x0, INITIAL_EBDA_SIZE / 1024); + //TODO: check for further needed EBDA data... + + // setup original ROM BIOS Area (F000:xxxx) char *date = "06/11/99"; for (i = 0; date[i]; i++) my_wrb(0xffff5 + i, date[i]); - /* set up eisa ident string */ - strcpy((char *) (biosmem + 0x0FFD9), "PCI_ISA"); + // set up eisa ident string + char *ident = "PCI_ISA"; + for (i = 0; ident[i]; i++) + my_wrb(0xfffd9 + i, ident[i]); - /* write system model id for IBM-AT */ - *((unsigned char *) (biosmem + 0x0FFFE)) = 0xfc; + // write system model id for IBM-AT + // according to "Ralf Browns Interrupt List" Int15 AH=C0 Table 515, + // model FC is the original AT and also used in all DOSEMU Versions. + my_wrb(0xFFFFE, 0xfc); //setup interrupt handler X86EMU_intrFuncs intrFuncs[256]; @@ -169,12 +223,12 @@ biosemu(char argc, char **argv) M.x86.R_AL = bios_device.devfn; M.x86.R_DX = 0x80; M.x86.R_EIP = 3; - M.x86.R_CS = 0xc000; + M.x86.R_CS = OPTION_ROM_CODE_SEGMENT; // Initialize stack and data segment - M.x86.R_SS = 0x0030; - M.x86.R_DS = 0x0040; - M.x86.R_SP = 0xfffe; + M.x86.R_SS = STACK_SEGMENT; + M.x86.R_SP = STACK_START_OFFSET; + M.x86.R_DS = DATA_SEGMENT; // push a HLT instruction and a pointer to it onto the stack // any return will pop the pointer and jump to the HLT, thus @@ -183,29 +237,104 @@ biosemu(char argc, char **argv) push_word(M.x86.R_SS); push_word(M.x86.R_SP + 2); - M.x86.R_ES = 0x0000; -#ifdef DEBUG_TRACE_X86EMU - X86EMU_trace_on(); - //since we have our own mem and io functions and dont use the x86emu functions, - // we dont need to enabled the debug... - //M.x86.debug |= DEBUG_MEM_TRACE_F; - //M.x86.debug |= DEBUG_IO_TRACE_F; -#endif -#ifdef DEBUG_JMP - M.x86.debug |= DEBUG_TRACEJMP_F; - M.x86.debug |= DEBUG_TRACEJMP_REGS_F; - M.x86.debug |= DEBUG_TRACECALL_F; - M.x86.debug |= DEBUG_TRACECALL_REGS_F; -#endif + CHECK_DBG(DEBUG_TRACE_X86EMU) { + X86EMU_trace_on(); + } else { #ifdef DEBUG - M.x86.debug |= DEBUG_SAVE_IP_CS_F; - M.x86.debug |= DEBUG_DECODE_F; - M.x86.debug |= DEBUG_DECODE_NOPRINT_F; + M.x86.debug |= DEBUG_SAVE_IP_CS_F; + M.x86.debug |= DEBUG_DECODE_F; + M.x86.debug |= DEBUG_DECODE_NOPRINT_F; #endif + } + CHECK_DBG(DEBUG_JMP) { + M.x86.debug |= DEBUG_TRACEJMP_F; + M.x86.debug |= DEBUG_TRACEJMP_REGS_F; + M.x86.debug |= DEBUG_TRACECALL_F; + M.x86.debug |= DEBUG_TRACECALL_REGS_F; + } - DEBUG_PRINTF("Los gehts...\n"); + DEBUG_PRINTF("Executing Initialization Vector...\n"); X86EMU_exec(); - DEBUG_PRINTF("Fertig\n"); + DEBUG_PRINTF("done\n"); + + // according to PNP BIOS Spec, Option ROMs should upon exit, return some boot device status in + // AX (see PNP BIOS Spec Section 3.3 + DEBUG_PRINTF_CS_IP("Option ROM Exit Status: %04x\n", M.x86.R_AX); +#ifdef DEBUG + DEBUG_PRINTF("Exit Status Decode:\n"); + if (M.x86.R_AX & 0x100) { // bit 8 + DEBUG_PRINTF + (" IPL Device supporting INT 13h Block Device Format:\n"); + switch (((M.x86.R_AX >> 4) & 0x3)) { // bits 5:4 + case 0: + DEBUG_PRINTF(" No IPL Device attached\n"); + break; + case 1: + DEBUG_PRINTF(" IPL Device status unknown\n"); + break; + case 2: + DEBUG_PRINTF(" IPL Device attached\n"); + break; + case 3: + DEBUG_PRINTF(" IPL Device status RESERVED!!\n"); + break; + } + } + if (M.x86.R_AX & 0x80) { // bit 7 + DEBUG_PRINTF + (" Output Device supporting INT 10h Character Output:\n"); + switch (((M.x86.R_AX >> 4) & 0x3)) { // bits 5:4 + case 0: + DEBUG_PRINTF(" No Display Device attached\n"); + break; + case 1: + DEBUG_PRINTF(" Display Device status unknown\n"); + break; + case 2: + DEBUG_PRINTF(" Display Device attached\n"); + break; + case 3: + DEBUG_PRINTF(" Display Device status RESERVED!!\n"); + break; + } + } + if (M.x86.R_AX & 0x40) { // bit 6 + DEBUG_PRINTF + (" Input Device supporting INT 9h Character Input:\n"); + switch (((M.x86.R_AX >> 4) & 0x3)) { // bits 5:4 + case 0: + DEBUG_PRINTF(" No Input Device attached\n"); + break; + case 1: + DEBUG_PRINTF(" Input Device status unknown\n"); + break; + case 2: + DEBUG_PRINTF(" Input Device attached\n"); + break; + case 3: + DEBUG_PRINTF(" Input Device status RESERVED!!\n"); + break; + } + } +#endif + // check wether the stack is "clean" i.e. containing the HLT instruction + // we pushed before executing, and pointing to the original stack address... + // indicating that the initialization probably was successful + if ((pop_word() == 0xf4f4) && (M.x86.R_SS == STACK_SEGMENT) + && (M.x86.R_SP == STACK_START_OFFSET)) { + DEBUG_PRINTF("Stack is clean, initialization successfull!\n"); + } else { + DEBUG_PRINTF + ("Stack unclean, initialization probably NOT COMPLETE!!!\n"); + DEBUG_PRINTF("SS:SP = %04x:%04x, expected: %04x:%04x\n", + M.x86.R_SS, M.x86.R_SP, STACK_SEGMENT, + STACK_START_OFFSET); + } + + // TODO: according to the BIOS Boot Spec initializations may be ended using INT18h and setting + // the status. + // We need to implement INT18 accordingly, pseudo code is in specsbbs101.pdf page 30 + // (also for Int19) return 0; } diff --git a/clients/net-snk/app/biosemu/biosemu.h b/clients/net-snk/app/biosemu/biosemu.h new file mode 100644 index 0000000..7ffd5bc --- /dev/null +++ b/clients/net-snk/app/biosemu/biosemu.h @@ -0,0 +1,40 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#ifndef _BIOSEMU_BIOSEMU_H_ +#define _BIOSEMU_BIOSEMU_H_ + +#define MIN_REQUIRED_VMEM_SIZE 0x100000 // 1MB + +//define default segments for different components +#define STACK_SEGMENT 0x1000 //1000:xxxx +#define STACK_START_OFFSET 0xfffe + +#define DATA_SEGMENT 0x2000 +#define VBE_SEGMENT 0x3000 + +#define PMM_CONV_SEGMENT 0x4000 // 4000:xxxx is PMM conventional memory area, extended memory area + // will be anything beyound MIN_REQUIRED_MEMORY_SIZE +#define PNP_DATA_SEGMENT 0x5000 + +#define OPTION_ROM_CODE_SEGMENT 0xc000 + +#define BIOS_DATA_SEGMENT 0xF000 +// both EBDA values are _initial_ values, they may (and will be) changed at runtime by option ROMs!! +#define INITIAL_EBDA_SEGMENT 0xF600 // segment of the Extended BIOS Data Area +#define INITIAL_EBDA_SIZE 0x400 // size of the EBDA (at least 1KB!! since size is stored in KB!) + +#define PMM_INT_NUM 0xFC // we misuse INT FC for PMM functionality, at the PMM Entry Point + // Address, there will only be a call to this INT and a RETF +#define PNP_INT_NUM 0xFD + +#endif diff --git a/clients/net-snk/app/biosemu/debug.c b/clients/net-snk/app/biosemu/debug.c index 4346dda..2fce244 100644 --- a/clients/net-snk/app/biosemu/debug.c +++ b/clients/net-snk/app/biosemu/debug.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -14,6 +14,8 @@ #include "debug.h" +uint32_t debug_flags = 0; + void dump(uint8_t * addr, uint32_t len) { diff --git a/clients/net-snk/app/biosemu/debug.h b/clients/net-snk/app/biosemu/debug.h index 71e69fe..c056190 100644 --- a/clients/net-snk/app/biosemu/debug.h +++ b/clients/net-snk/app/biosemu/debug.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -13,50 +13,61 @@ #define _BIOSEMU_DEBUG_H_ #include <stdio.h> -#include <types.h> +#include <stdint.h> -//#define DEBUG_TRACE_X86EMU -//#undef DEBUG_TRACE_X86EMU +extern uint32_t debug_flags; +// from x86emu...needed for debugging +extern void x86emu_dump_xregs(); + +#define DEBUG_IO 0x1 +#define DEBUG_MEM 0x2 +// set this to print messages for certain virtual memory accesses (Interrupt Vectors, ...) +#define DEBUG_CHECK_VMEM_ACCESS 0x4 +#define DEBUG_INTR 0x8 +#define DEBUG_PRINT_INT10 0x10 // set to have the INT10 routine print characters +#define DEBUG_VBE 0x20 +#define DEBUG_PMM 0x40 +#define DEBUG_DISK 0x80 +#define DEBUG_PNP 0x100 + +#define DEBUG_TRACE_X86EMU 0x1000 +// set to enable tracing of JMPs in x86emu +#define DEBUG_JMP 0x2000 //#define DEBUG #ifdef DEBUG -//#define DEBUG_IO -//#define DEBUG_MEM -//#define DEBUG_INTR -//#define DEBUG_VBE -// define to enable tracing of JMPs in x86emu -//#define DEBUG_JMP +#define CHECK_DBG(_flag) if (debug_flags & _flag) -#define DEBUG_PRINTF(_x...) printf(_x) -#else -#define DEBUG_PRINTF(_x...) +#define DEBUG_PRINTF(_x...) printf(_x); +// prints the CS:IP before the printout, NOTE: actually its CS:IP of the _next_ instruction +// to be executed, since the x86emu advances CS:IP _before_ actually executing an instruction +#define DEBUG_PRINTF_CS_IP(_x...) DEBUG_PRINTF("%x:%x ", M.x86.R_CS, M.x86.R_IP); DEBUG_PRINTF(_x); -#endif //DEBUG +#define DEBUG_PRINTF_IO(_x...) CHECK_DBG(DEBUG_IO) { DEBUG_PRINTF_CS_IP(_x) } +#define DEBUG_PRINTF_MEM(_x...) CHECK_DBG(DEBUG_MEM) { DEBUG_PRINTF_CS_IP(_x) } +#define DEBUG_PRINTF_INTR(_x...) CHECK_DBG(DEBUG_INTR) { DEBUG_PRINTF_CS_IP(_x) } +#define DEBUG_PRINTF_VBE(_x...) CHECK_DBG(DEBUG_VBE) { DEBUG_PRINTF_CS_IP(_x) } +#define DEBUG_PRINTF_PMM(_x...) CHECK_DBG(DEBUG_PMM) { DEBUG_PRINTF_CS_IP(_x) } +#define DEBUG_PRINTF_DISK(_x...) CHECK_DBG(DEBUG_DISK) { DEBUG_PRINTF_CS_IP(_x) } +#define DEBUG_PRINTF_PNP(_x...) CHECK_DBG(DEBUG_PNP) { DEBUG_PRINTF_CS_IP(_x) } -#ifdef DEBUG_IO -#define DEBUG_PRINTF_IO(_x...) DEBUG_PRINTF("%x:%x ", M.x86.R_CS, M.x86.R_IP); DEBUG_PRINTF(_x) #else -#define DEBUG_PRINTF_IO(_x...) -#endif -#ifdef DEBUG_MEM -#define DEBUG_PRINTF_MEM(_x...) DEBUG_PRINTF("%x:%x ", M.x86.R_CS, M.x86.R_IP); DEBUG_PRINTF(_x) -#else -#define DEBUG_PRINTF_MEM(_x...) -#endif +#define CHECK_DBG(_flag) if (0) -#ifdef DEBUG_INTR -#define DEBUG_PRINTF_INTR(_x...) DEBUG_PRINTF("%x:%x ", M.x86.R_CS, M.x86.R_IP); DEBUG_PRINTF(_x) -#else -#define DEBUG_PRINTF_INTR(_x...) -#endif +#define DEBUG_PRINTF(_x...) +#define DEBUG_PRINTF_CS_IP(_x...) -#ifdef DEBUG_VBE -#define DEBUG_PRINTF_VBE(_x...) DEBUG_PRINTF("%x:%x ", M.x86.R_CS, M.x86.R_IP); DEBUG_PRINTF(_x) -#else +#define DEBUG_PRINTF_IO(_x...) +#define DEBUG_PRINTF_MEM(_x...) +#define DEBUG_PRINTF_INTR(_x...) #define DEBUG_PRINTF_VBE(_x...) -#endif +#define DEBUG_PRINTF_PMM(_x...) +#define DEBUG_PRINTF_DISK(_x...) +#define DEBUG_PRINTF_PNP(_x...) + +#endif //DEBUG void dump(uint8_t * addr, uint32_t len); diff --git a/clients/net-snk/app/biosemu/device.c b/clients/net-snk/app/biosemu/device.c index 3a60818..71402d5 100644 --- a/clients/net-snk/app/biosemu/device.c +++ b/clients/net-snk/app/biosemu/device.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -177,10 +177,107 @@ dev_get_device_vendor_id() bios_device.pci_device_id, bios_device.pci_vendor_id); } +/* check, wether the device has a valid Expansion ROM, also search the PCI Data Structure and + * any Expansion ROM Header (using dev_scan_exp_header()) for needed information */ +uint8_t +dev_check_exprom() +{ + int i = 0; + translate_address_t ta; + uint64_t rom_base_addr = 0; + uint16_t pci_ds_offset; + pci_data_struct_t pci_ds; + // check for ExpROM Address (Offset 30) in taa + for (i = 0; i <= taa_last_entry; i++) { + ta = translate_address_array[i]; + if (ta.cfg_space_offset == 0x30) { + rom_base_addr = ta.address + ta.address_offset; //translated address + break; + } + } + // in the ROM there could be multiple Expansion ROM Images... start searching + // them for a x86 image + do { + if (rom_base_addr == 0) { + printf("Error: no Expansion ROM address found!\n"); + return -1; + } + set_ci(); + uint16_t rom_signature = *((uint16_t *) rom_base_addr); + clr_ci(); + if (rom_signature != 0x55aa) { + printf + ("Error: invalid Expansion ROM signature: %02x!\n", + *((uint16_t *) rom_base_addr)); + return -1; + } + set_ci(); + // at offset 0x18 is the (16bit little-endian) pointer to the PCI Data Structure + pci_ds_offset = in16le((void *) (rom_base_addr + 0x18)); + //copy the PCI Data Structure + memcpy(&pci_ds, (void *) (rom_base_addr + pci_ds_offset), + sizeof(pci_ds)); + clr_ci(); +#ifdef DEBUG + DEBUG_PRINTF("PCI Data Structure @%llx:\n", + rom_base_addr + pci_ds_offset); + dump((void *) &pci_ds, sizeof(pci_ds)); +#endif + if (strncmp((const char *) pci_ds.signature, "PCIR", 4) != 0) { + printf("Invalid PCI Data Structure found!\n"); + break; + } + //little-endian conversion + pci_ds.vendor_id = in16le(&pci_ds.vendor_id); + pci_ds.device_id = in16le(&pci_ds.device_id); + pci_ds.img_length = in16le(&pci_ds.img_length); + pci_ds.pci_ds_length = in16le(&pci_ds.pci_ds_length); + if (pci_ds.vendor_id != bios_device.pci_vendor_id) { + printf + ("Image has invalid Vendor ID: %04x, expected: %04x\n", + pci_ds.vendor_id, bios_device.pci_vendor_id); + break; + } + if (pci_ds.device_id != bios_device.pci_device_id) { + printf + ("Image has invalid Device ID: %04x, expected: %04x\n", + pci_ds.device_id, bios_device.pci_device_id); + break; + } + //DEBUG_PRINTF("Image Length: %d\n", pci_ds.img_length * 512); + //DEBUG_PRINTF("Image Code Type: %d\n", pci_ds.code_type); + if (pci_ds.code_type == 0) { + //x86 image + //store image address and image length in bios_device struct + bios_device.img_addr = rom_base_addr; + bios_device.img_size = pci_ds.img_length * 512; + // we found the image, exit the loop + break; + } else { + // no x86 image, check next image (if any) + rom_base_addr += pci_ds.img_length * 512; + } + if ((pci_ds.indicator & 0x80) == 0x80) { + //last image found, exit the loop + DEBUG_PRINTF("Last PCI Expansion ROM Image found.\n"); + break; + } + } + while (bios_device.img_addr == 0); + // in case we did not find a valid x86 Expansion ROM Image + if (bios_device.img_addr == 0) { + printf("Error: no valid x86 Expansion ROM Image found!\n"); + return -1; + } + return 0; +} + uint8_t dev_init(char *device_name) { + uint8_t rval = 0; //init bios_device struct + DEBUG_PRINTF("%s(%s)\n", __FUNCTION__, device_name); memset(&bios_device, 0, sizeof(bios_device)); bios_device.ihandle = of_open(device_name); if (bios_device.ihandle == 0) { @@ -192,7 +289,7 @@ dev_init(char *device_name) dev_find_vmem_addr(); dev_get_puid(); dev_get_device_vendor_id(); - return 0; + return rval; } // translate address function using translate_address_array assembled diff --git a/clients/net-snk/app/biosemu/device.h b/clients/net-snk/app/biosemu/device.h index 04bd34e..074bd69 100644 --- a/clients/net-snk/app/biosemu/device.h +++ b/clients/net-snk/app/biosemu/device.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -13,11 +13,50 @@ #ifndef DEVICE_LIB_H #define DEVICE_LIB_H -#include "types.h" +#include <stdint.h> #include <cpu.h> #include "of.h" #include <stdio.h> +// a Expansion Header Struct as defined in Plug and Play BIOS Spec 1.0a Chapter 3.2 +typedef struct { + char signature[4]; // signature + uint8_t structure_revision; + uint8_t length; // in 16 byte blocks + uint16_t next_header_offset; // offset to next Expansion Header as 16bit little-endian value, as offset from the start of the Expansion ROM + uint8_t reserved; + uint8_t checksum; // the sum of all bytes of the Expansion Header must be 0 + uint32_t device_id; // PnP Device ID as 32bit little-endian value + uint16_t p_manufacturer_string; //16bit little-endian offset from start of Expansion ROM + uint16_t p_product_string; //16bit little-endian offset from start of Expansion ROM + uint8_t device_base_type; + uint8_t device_sub_type; + uint8_t device_if_type; + uint8_t device_indicators; + // the following vectors are all 16bit little-endian offsets from start of Expansion ROM + uint16_t bcv; // Boot Connection Vector + uint16_t dv; // Disconnect Vector + uint16_t bev; // Bootstrap Entry Vector + uint16_t reserved_2; + uint16_t sriv; // Static Resource Information Vector +} __attribute__ ((__packed__)) exp_header_struct_t; + +// a PCI Data Struct as defined in PCI 2.3 Spec Chapter 6.3.1.2 +typedef struct { + uint8_t signature[4]; // signature, the String "PCIR" + uint16_t vendor_id; + uint16_t device_id; + uint16_t reserved; + uint16_t pci_ds_length; // PCI Data Structure Length, 16bit little-endian value + uint8_t pci_ds_revision; + uint8_t class_code[3]; + uint16_t img_length; // length of the Exp.ROM Image, 16bit little-endian value in 512 bytes + uint16_t img_revision; + uint8_t code_type; + uint8_t indicator; + uint16_t reserved_2; +} __attribute__ ((__packed__)) pci_data_struct_t; + typedef struct { uint8_t bus; uint8_t devfn; @@ -25,7 +64,7 @@ typedef struct { phandle_t phandle; ihandle_t ihandle; // store the address of the BAR that is used to simulate - // legacy memory accesses + // legacy VGA memory accesses uint64_t vmem_addr; uint64_t vmem_size; // used to buffer I/O Accesses, that do not access the I/O Range of the device... @@ -33,6 +72,9 @@ typedef struct { uint8_t io_buffer[64 * 1024]; uint16_t pci_vendor_id; uint16_t pci_device_id; + // translated address of the "PC-Compatible" Expansion ROM Image for this device + uint64_t img_addr; + uint32_t img_size; // size of the Expansion ROM Image (read from the PCI Data Structure) } device_t; typedef struct { @@ -61,6 +103,8 @@ uint8_t taa_last_entry; device_t bios_device; uint8_t dev_init(char *device_name); +// NOTE: for dev_check_exprom to work, dev_init MUST be called first! +uint8_t dev_check_exprom(); uint8_t dev_translate_address(uint64_t * addr); diff --git a/clients/net-snk/app/biosemu/interrupt.c b/clients/net-snk/app/biosemu/interrupt.c index b0ad12f..f1137fe 100644 --- a/clients/net-snk/app/biosemu/interrupt.c +++ b/clients/net-snk/app/biosemu/interrupt.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -14,6 +14,7 @@ #include <rtas.h> +#include "biosemu.h" #include "mem.h" #include "device.h" #include "debug.h" @@ -42,6 +43,273 @@ setupInt(int intNum) M.x86.R_IP = my_rdw(intNum * 4); } +// handle int10 (VGA BIOS Interrupt) +void +handleInt10() +{ + // the data for INT10 is stored in BDA (0000:0400h) offset 49h-66h + // function number in AH + //DEBUG_PRINTF_CS_IP("%s:\n", __FUNCTION__); + //x86emu_dump_xregs(); + //if ((M.x86.R_IP == 0x32c2) && (M.x86.R_SI == 0x1ce2)){ + //X86EMU_trace_on(); + //M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F; + //} + switch (M.x86.R_AH) { + case 0x00: + // set video mode + // BDA offset 49h is current video mode + my_wrb(0x449, M.x86.R_AL); + if (M.x86.R_AL > 7) + M.x86.R_AL = 0x20; + else if (M.x86.R_AL == 6) + M.x86.R_AL = 0x3f; + else + M.x86.R_AL = 0x30; + break; + case 0x01: + // set cursor shape + // ignore + break; + case 0x02: + // set cursor position + // BH: pagenumber, DX: cursor_pos (DH:row, DL:col) + // BDA offset 50h-60h are 8 cursor position words for + // eight possible video pages + my_wrw(0x450 + (M.x86.R_BH * 2), M.x86.R_DX); + break; + case 0x03: + //get cursor position + // BH: pagenumber + // BDA offset 50h-60h are 8 cursor position words for + // eight possible video pages + M.x86.R_AX = 0; + M.x86.R_CH = 0; // start scan line ??? + M.x86.R_CL = 0; // end scan line ??? + M.x86.R_DX = my_rdw(0x450 + (M.x86.R_BH * 2)); + break; + case 0x05: + // set active page + // BDA offset 62h is current page number + my_wrb(0x462, M.x86.R_AL); + break; + case 0x06: + //scroll up windows + break; + case 0x07: + //scroll down windows + break; + case 0x08: + //read character and attribute at position + M.x86.R_AH = 0x07; // white-on-black + M.x86.R_AL = 0x20; // a space... + break; + case 0x09: + // write character and attribute + //AL: char, BH: page number, BL: attribute, CX: number of times to write + //BDA offset 62h is current page number + CHECK_DBG(DEBUG_PRINT_INT10) { + uint32_t i = 0; + if (M.x86.R_BH == my_rdb(0x462)) { + for (i = 0; i < M.x86.R_CX; i++) + printf("%c", M.x86.R_AL); + } + } + break; + case 0x0a: + // write character + //AL: char, BH: page number, BL: attribute, CX: number of times to write + //BDA offset 62h is current page number + CHECK_DBG(DEBUG_PRINT_INT10) { + uint32_t i = 0; + if (M.x86.R_BH == my_rdb(0x462)) { + for (i = 0; i < M.x86.R_CX; i++) + printf("%c", M.x86.R_AL); + } + } + break; + case 0x0e: + // teletype output: write character and advance cursor... + //AL: char, BH: page number, BL: attribute + //BDA offset 62h is current page number + CHECK_DBG(DEBUG_PRINT_INT10) { + // we ignore the pagenumber on this call... + //if (M.x86.R_BH == my_rdb(0x462)) + { + printf("%c", M.x86.R_AL); + // for debugging, to read all lines + //if (M.x86.R_AL == 0xd) // carriage return + // printf("\n"); + } + } + break; + case 0x0f: + // get video mode + // BDA offset 49h is current video mode + // BDA offset 62h is current page number + // BDA offset 4ah is columns on screen + M.x86.R_AH = 80; //number of character columns... we hardcode it to 80 + M.x86.R_AL = my_rdb(0x449); + M.x86.R_BH = my_rdb(0x462); + break; + default: + printf("%s(): unknown function (%x) for int10 handler.\n", + __FUNCTION__, M.x86.R_AH); + DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", + M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, + M.x86.R_DX); + HALT_SYS(); + break; + } +} + +// this table translates ASCII chars into their XT scan codes: +static uint8_t keycode_table[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 - 7 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8 - 15 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 16 - 23 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 24 - 31 + 0x39, 0x02, 0x28, 0x04, 0x05, 0x06, 0x08, 0x28, // 32 - 39 + 0x0a, 0x0b, 0x09, 0x2b, 0x33, 0x0d, 0x34, 0x35, // 40 - 47 + 0x0b, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // 48 - 55 + 0x09, 0x0a, 0x27, 0x27, 0x33, 0x2b, 0x34, 0x35, // 56 - 63 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 64 - 71 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 72 - 79 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 80 - 87 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 88 - 95 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 96 - 103 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 104 - 111 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 112 - 119 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 120 - 127 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +} + +; + +void +translate_keycode(uint64_t * keycode) +{ + uint8_t scan_code = 0; + uint8_t char_code = 0; + if (*keycode < 256) { + scan_code = keycode_table[*keycode]; + char_code = (uint8_t) * keycode & 0xff; + } else { + switch (*keycode) { + case 0x1b50: + // F1 + scan_code = 0x3b; + char_code = 0x0; + break; + default: + printf("%s(): unknown multibyte keycode: %llx\n", + __FUNCTION__, *keycode); + break; + } + } + //assemble scan/char code in keycode + *keycode = (uint64_t) ((((uint16_t) scan_code) << 8) | char_code); +} + +// handle int16 (Keyboard BIOS Interrupt) +void +handleInt16() +{ + // keyboard buffer is in BIOS Memory Area: + // offset 0x1a (WORD) pointer to next char in keybuffer + // offset 0x1c (WORD) pointer to next insert slot in keybuffer + // offset 0x1e-0x3e: 16 WORD Ring Buffer + // since we currently always read the char from the FW buffer, + // we misuse the ring buffer, we use it as pointer to a uint64_t that stores + // multi-byte keys (e.g. special keys in VT100 terminal) + // and as long as a key is available (not 0) we dont read further keys + uint64_t *keycode = (uint64_t *) (M.mem_base + 0x41e); + int8_t c; + // function number in AH + DEBUG_PRINTF_INTR("%s(): Keyboard Interrupt: function: %x.\n", + __FUNCTION__, M.x86.R_AH); + DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", M.x86.R_AX, + M.x86.R_BX, M.x86.R_CX, M.x86.R_DX); + switch (M.x86.R_AH) { + case 0x00: + // get keystroke + if (*keycode) { + M.x86.R_AX = (uint16_t) * keycode; + // clear keycode + *keycode = 0; + } else { + M.x86.R_AH = 0x61; // scancode for space key + M.x86.R_AL = 0x20; // a space + } + break; + case 0x01: + // check keystroke + // ZF set = no keystroke + // read first byte of key code + if (*keycode) { + // already read, but not yet taken + CLEAR_FLAG(F_ZF); + M.x86.R_AX = (uint16_t) * keycode; + } else { + c = getchar(); + if (c == -1) { + // no key available + SET_FLAG(F_ZF); + } else { + *keycode = c; + + // since after an ESC it may take a while to receive the next char, + // we send something that is not shown on the screen, and then try to get + // the next char + // TODO: only after ESC?? what about other multibyte keys + printf("tt%c%c", 0x08, 0x08); // 0x08 == Backspace + + while ((c = getchar()) != -1) { + *keycode = (*keycode << 8) | c; + DEBUG_PRINTF(" key read: %0llx\n", + *keycode); + } + translate_keycode(keycode); + DEBUG_PRINTF(" translated key: %0llx\n", + *keycode); + if (*keycode == 0) { + //not found + SET_FLAG(F_ZF); + } else { + CLEAR_FLAG(F_ZF); + M.x86.R_AX = (uint16_t) * keycode; + //X86EMU_trace_on(); + //M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F; + } + } + } + break; + default: + printf("%s(): unknown function (%x) for int16 handler.\n", + __FUNCTION__, M.x86.R_AH); + DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", + M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, + M.x86.R_DX); + HALT_SYS(); + break; + } +} + // handle int1a (PCI BIOS Interrupt) void handleInt1a() @@ -62,10 +330,14 @@ handleInt1a() // NOTE: we currently only allow the device to find itself... // it SHOULD be all we ever need... // device_id in CX, vendor_id in DX + // device index in SI (i.e. if multiple devices with same vendor/device id + // are connected). We currently only support device index 0 DEBUG_PRINTF_INTR("%s(): function: %x: PCI Find Device\n", __FUNCTION__, M.x86.R_AX); if ((M.x86.R_CX == bios_device.pci_device_id) - && (M.x86.R_DX == bios_device.pci_vendor_id)) { + && (M.x86.R_DX == bios_device.pci_vendor_id) + // device index must be 0 + && (M.x86.R_SI == 0)) { CLEAR_FLAG(F_CF); M.x86.R_AH = 0x00; // return code: success M.x86.R_BH = bios_device.bus; @@ -75,9 +347,9 @@ handleInt1a() __FUNCTION__, M.x86.R_AX, M.x86.R_BX); } else { DEBUG_PRINTF_INTR - ("%s(): function %x: invalid device/vendor! (%04x/%04x expected: %04x/%04x) \n", + ("%s(): function %x: invalid device/vendor/device index! (%04x/%04x/%02x expected: %04x/%04x/0) \n", __FUNCTION__, M.x86.R_AX, M.x86.R_CX, M.x86.R_DX, - bios_device.pci_device_id, + M.x86.R_SI, bios_device.pci_device_id, bios_device.pci_vendor_id); SET_FLAG(F_CF); M.x86.R_AH = 0x86; // return code: device not found @@ -189,16 +461,14 @@ handleInt1a() } break; default: - DEBUG_PRINTF_INTR - ("%s(): unknown function (%x) for int1a handler.\n", - __FUNCTION__, M.x86.R_AX); + printf("%s(): unknown function (%x) for int1a handler.\n", + __FUNCTION__, M.x86.R_AX); DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, M.x86.R_DX); HALT_SYS(); break; } - } // main Interrupt Handler routine, should be registered as x86emu interrupt handler @@ -206,32 +476,49 @@ void handleInterrupt(int intNum) { uint8_t int_handled = 0; +#ifndef DEBUG_PRINT_INT10 + // this printf makes output by int 10 unreadable... + // so we only enable it, if int10 print is disabled DEBUG_PRINTF_INTR("%s(%x)\n", __FUNCTION__, intNum); +#endif switch (intNum) { case 0x10: //BIOS video interrupt case 0x42: // INT 10h relocated by EGA/VGA BIOS case 0x6d: // INT 10h relocated by VGA BIOS // get interrupt vector from IDT (4 bytes per Interrupt starting at address 0 - if (my_rdl(intNum * 4) == 0xF000F065) //F000:F065 is default BIOS interrupt handler address + if ((my_rdl(intNum * 4) == 0xF000F065) || //F000:F065 is default BIOS interrupt handler address + (my_rdl(intNum * 4) == 0xF4F4F4F4)) //invalid { - // default handler called, ignore interrupt... +#if 0 + // ignore interrupt... DEBUG_PRINTF_INTR - ("%s(%x): default interrupt Vector (%08x) found, interrupt ignored...\n", + ("%s(%x): invalid interrupt Vector (%08x) found, interrupt ignored...\n", __FUNCTION__, intNum, my_rdl(intNum * 4)); DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, M.x86.R_DX); //HALT_SYS(); +#endif + handleInt10(); int_handled = 1; } break; + case 0x16: + // Keyboard BIOS Interrupt + handleInt16(); + int_handled = 1; + break; case 0x1a: // PCI BIOS Interrupt handleInt1a(); int_handled = 1; break; default: - DEBUG_PRINTF_INTR("Interrupt %#x (Vector: %x) not implemented\n", intNum, my_rdl(intNum * 4)); // 4bytes per interrupt vector... + printf("Interrupt %#x (Vector: %x) not implemented\n", intNum, + my_rdl(intNum * 4)); + DEBUG_PRINTF_INTR("AX=%04x BX=%04x CX=%04x DX=%04x\n", + M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, + M.x86.R_DX); int_handled = 1; HALT_SYS(); break; @@ -247,9 +534,9 @@ void runInt10() { // Initialize stack and data segment - M.x86.R_SS = 0x0030; - M.x86.R_DS = 0x0040; - M.x86.R_SP = 0xfffe; + M.x86.R_SS = STACK_SEGMENT; + M.x86.R_DS = DATA_SEGMENT; + M.x86.R_SP = STACK_START_OFFSET; // push a HLT instruction and a pointer to it onto the stack // any return will pop the pointer and jump to the HLT, thus @@ -264,19 +551,57 @@ runInt10() M.x86.R_CS = M.x86.R_SS; M.x86.R_IP = M.x86.R_SP; // + 4; -#ifdef DEBUG_TRACE_X86EMU - X86EMU_trace_on(); -#endif -#ifdef DEBUG_JMP - M.x86.debug |= DEBUG_TRACEJMP_REGS_F; - M.x86.debug |= DEBUG_TRACEJMP_REGS_F; - M.x86.debug |= DEBUG_TRACECALL_F; - M.x86.debug |= DEBUG_TRACECALL_REGS_F; -#endif - + CHECK_DBG(DEBUG_TRACE_X86EMU) { + X86EMU_trace_on(); + } + CHECK_DBG(DEBUG_JMP) { + M.x86.debug |= DEBUG_TRACEJMP_REGS_F; + M.x86.debug |= DEBUG_TRACEJMP_REGS_F; + M.x86.debug |= DEBUG_TRACECALL_F; + M.x86.debug |= DEBUG_TRACECALL_REGS_F; + } setupInt(0x10); DEBUG_PRINTF_INTR("%s(): starting execution of INT10...\n", __FUNCTION__); X86EMU_exec(); DEBUG_PRINTF_INTR("%s(): execution finished\n", __FUNCTION__); } + +// prepare and execute Interrupt 13 (Disk Interrupt) +void +runInt13() +{ + // Initialize stack and data segment + M.x86.R_SS = STACK_SEGMENT; + M.x86.R_DS = DATA_SEGMENT; + M.x86.R_SP = STACK_START_OFFSET; + + // push a HLT instruction and a pointer to it onto the stack + // any return will pop the pointer and jump to the HLT, thus + // exiting (more or less) cleanly + push_word(0xf4f4); //F4=HLT + //push_word(M.x86.R_SS); + //push_word(M.x86.R_SP + 2); + + // setupInt will push the current CS and IP to the stack to return to it, + // but we want to halt, so set CS:IP to the HLT instruction we just pushed + // to the stack + M.x86.R_CS = M.x86.R_SS; + M.x86.R_IP = M.x86.R_SP; + + CHECK_DBG(DEBUG_TRACE_X86EMU) { + X86EMU_trace_on(); + } + CHECK_DBG(DEBUG_JMP) { + M.x86.debug |= DEBUG_TRACEJMP_REGS_F; + M.x86.debug |= DEBUG_TRACEJMP_REGS_F; + M.x86.debug |= DEBUG_TRACECALL_F; + M.x86.debug |= DEBUG_TRACECALL_REGS_F; + } + + setupInt(0x13); + DEBUG_PRINTF_INTR("%s(): starting execution of INT13...\n", + __FUNCTION__); + X86EMU_exec(); + DEBUG_PRINTF_INTR("%s(): execution finished\n", __FUNCTION__); +} diff --git a/clients/net-snk/app/biosemu/interrupt.h b/clients/net-snk/app/biosemu/interrupt.h index 2d3f979..9c09086 100644 --- a/clients/net-snk/app/biosemu/interrupt.h +++ b/clients/net-snk/app/biosemu/interrupt.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -16,4 +16,6 @@ void handleInterrupt(int intNum); void runInt10(); +void runInt13(); + #endif diff --git a/clients/net-snk/app/biosemu/io.c b/clients/net-snk/app/biosemu/io.c index 9329eca..53653d3 100644 --- a/clients/net-snk/app/biosemu/io.c +++ b/clients/net-snk/app/biosemu/io.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -16,13 +16,16 @@ #include "rtas.h" #include "debug.h" #include "device.h" -#include <types.h> +#include <stdint.h> #include <x86emu/x86emu.h> +#include <time.h> // those are defined in net-snk/oflib/pci.c -// currently not used... -//extern unsigned int read_io(void *, size_t); -//extern int write_io(void *, unsigned int, size_t); +extern unsigned int read_io(void *, size_t); +extern int write_io(void *, unsigned int, size_t); + +//defined in net-snk/kernel/timer.c +extern uint64_t get_time(void); // these are not used, only needed for linking, must be overridden using X86emu_setupPioFuncs // with the functions and struct below @@ -71,29 +74,57 @@ inl(uint16_t port) return 0; } +uint32_t pci_cfg_read(X86EMU_pioAddr addr, uint8_t size); +void pci_cfg_write(X86EMU_pioAddr addr, uint32_t val, uint8_t size); +uint8_t handle_port_61h(); + uint8_t my_inb(X86EMU_pioAddr addr) { + uint8_t rval = 0xFF; uint64_t translated_addr = addr; uint8_t translated = dev_translate_address(&translated_addr); if (translated != 0) { - //translation successfull, access VGA I/O (BAR or Legacy...) - DEBUG_PRINTF_IO("%s(%x): access to VGA I/O\n", __FUNCTION__, + //translation successfull, access Device I/O (BAR or Legacy...) + DEBUG_PRINTF_IO("%s(%x): access to Device I/O\n", __FUNCTION__, addr); //DEBUG_PRINTF_IO("%s(%04x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr); - set_ci(); - uint8_t rval = *((uint8_t *) translated_addr); - DEBUG_PRINTF_IO("%s(%04x) VGA I/O --> %02x\n", __FUNCTION__, + rval = read_io((void *)translated_addr, 1); + DEBUG_PRINTF_IO("%s(%04x) Device I/O --> %02x\n", __FUNCTION__, addr, rval); - clr_ci(); return rval; } else { - DEBUG_PRINTF_IO("%s(%04x) reading from bios_device.io_buffer\n", - __FUNCTION__, addr); - uint8_t rval = *((uint8_t *) (bios_device.io_buffer + addr)); - DEBUG_PRINTF_IO("%s(%04x) I/O Buffer --> %02x\n", __FUNCTION__, - addr, rval); - return rval; + switch (addr) { + case 0x61: + //8254 KB Controller / Timer Port + rval = handle_port_61h(); + //DEBUG_PRINTF_IO("%s(%04x) KB / Timer Port B --> %02x\n", __FUNCTION__, addr, rval); + return rval; + break; + case 0xCFC: + case 0xCFD: + case 0xCFE: + case 0xCFF: + // PCI Config Mechanism 1 Ports + return (uint8_t) pci_cfg_read(addr, 1); + break; + case 0x0a: + CHECK_DBG(DEBUG_INTR) { + X86EMU_trace_on(); + } + M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F; + //HALT_SYS(); + // no break, intentional fall-through to default!! + default: + DEBUG_PRINTF_IO + ("%s(%04x) reading from bios_device.io_buffer\n", + __FUNCTION__, addr); + rval = *((uint8_t *) (bios_device.io_buffer + addr)); + DEBUG_PRINTF_IO("%s(%04x) I/O Buffer --> %02x\n", + __FUNCTION__, addr, rval); + return rval; + break; + } } } @@ -103,33 +134,42 @@ my_inw(X86EMU_pioAddr addr) uint64_t translated_addr = addr; uint8_t translated = dev_translate_address(&translated_addr); if (translated != 0) { - //translation successfull, access VGA I/O (BAR or Legacy...) - DEBUG_PRINTF_IO("%s(%x): access to VGA I/O\n", __FUNCTION__, + //translation successfull, access Device I/O (BAR or Legacy...) + DEBUG_PRINTF_IO("%s(%x): access to Device I/O\n", __FUNCTION__, addr); //DEBUG_PRINTF_IO("%s(%04x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr); uint16_t rval; if ((translated_addr & (uint64_t) 0x1) == 0) { // 16 bit aligned access... - set_ci(); - rval = in16le((void *) translated_addr); - clr_ci(); + uint16_t tempval = read_io((void *)translated_addr, 2); + //little endian conversion + rval = in16le((void *) &tempval); } else { - // unaligned access, read single bytes - set_ci(); - rval = (*((uint8_t *) translated_addr)) | - (*((uint8_t *) translated_addr + 1) << 8); - clr_ci(); + // unaligned access, read single bytes, little-endian + rval = (read_io((void *)translated_addr, 1) << 8) + | (read_io((void *)(translated_addr + 1), 1)); } - DEBUG_PRINTF_IO("%s(%04x) VGA I/O --> %04x\n", __FUNCTION__, + DEBUG_PRINTF_IO("%s(%04x) Device I/O --> %04x\n", __FUNCTION__, addr, rval); return rval; } else { - DEBUG_PRINTF_IO("%s(%04x) reading from bios_device.io_buffer\n", - __FUNCTION__, addr); - uint16_t rval = in16le((void *) bios_device.io_buffer + addr); - DEBUG_PRINTF_IO("%s(%04x) I/O Buffer --> %04x\n", __FUNCTION__, - addr, rval); - return rval; + switch (addr) { + case 0xCFC: + case 0xCFE: + //PCI Config Mechanism 1 + return (uint16_t) pci_cfg_read(addr, 2); + break; + default: + DEBUG_PRINTF_IO + ("%s(%04x) reading from bios_device.io_buffer\n", + __FUNCTION__, addr); + uint16_t rval = + in16le((void *) bios_device.io_buffer + addr); + DEBUG_PRINTF_IO("%s(%04x) I/O Buffer --> %04x\n", + __FUNCTION__, addr, rval); + return rval; + break; + } } } @@ -139,70 +179,43 @@ my_inl(X86EMU_pioAddr addr) uint64_t translated_addr = addr; uint8_t translated = dev_translate_address(&translated_addr); if (translated != 0) { - //translation successfull, access VGA I/O (BAR or Legacy...) - DEBUG_PRINTF_IO("%s(%x): access to VGA I/O\n", __FUNCTION__, + //translation successfull, access Device I/O (BAR or Legacy...) + DEBUG_PRINTF_IO("%s(%x): access to Device I/O\n", __FUNCTION__, addr); //DEBUG_PRINTF_IO("%s(%04x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr); uint32_t rval; if ((translated_addr & (uint64_t) 0x2) == 0) { // 32 bit aligned access... - set_ci(); - rval = in32le((void *) translated_addr); - clr_ci(); + uint32_t tempval = read_io((void *) translated_addr, 4); + //little endian conversion + rval = in32le((void *) &tempval); } else { - // unaligned access, read single bytes - set_ci(); - rval = (*((uint8_t *) translated_addr)) | - (*((uint8_t *) translated_addr + 1) << 8) | - (*((uint8_t *) translated_addr + 2) << 16) | - (*((uint8_t *) translated_addr + 3) << 24); - clr_ci(); + // unaligned access, read single bytes, little-endian + rval = (read_io((void *)(translated_addr), 1) << 24) + | (read_io((void *)(translated_addr + 1), 1) << 16) + | (read_io((void *)(translated_addr + 2), 1) << 8) + | (read_io((void *)(translated_addr + 3), 1)); } - DEBUG_PRINTF_IO("%s(%04x) VGA I/O --> %08x\n", __FUNCTION__, + DEBUG_PRINTF_IO("%s(%04x) Device I/O --> %08x\n", __FUNCTION__, addr, rval); return rval; - } else if (addr == 0xcfc) { - // PCI Configuration Mechanism 1 step 1 - // write to 0xCF8, sets bus, device, function and Config Space offset - // later read from 0xCFC returns the value... - uint8_t bus, devfn, offs; - uint32_t port_cf8_val = my_inl(0xcf8); - if ((port_cf8_val & 0x80000000) != 0) { - //highest bit enables config space mapping - bus = (port_cf8_val & 0x00FF0000) >> 16; - devfn = (port_cf8_val & 0x0000FF00) >> 8; - offs = (port_cf8_val & 0x000000FF); - if ((bus != bios_device.bus) - || (devfn != bios_device.devfn)) { - // fail accesses to any device but ours... - printf - ("Config access invalid! bus: %x, devfn: %x, offs: %x\n", - bus, devfn, offs); - HALT_SYS(); - return 0xFFFFFFFF; - } else { - DEBUG_PRINTF_IO("%s(%04x) PCI Config Access\n", - __FUNCTION__, addr); - uint32_t rval = - (uint32_t) rtas_pci_config_read(bios_device. - puid, 4, - bus, devfn, - offs); - DEBUG_PRINTF_IO - ("%s(%04x) PCI Config Access --> 0x%08x\n", - __FUNCTION__, addr, rval); - return rval; - } - } else { - return 0xFFFFFFFF; - } } else { - DEBUG_PRINTF_IO("%s(%04x) reading from bios_device.io_buffer\n", - __FUNCTION__, addr); - uint32_t rval = in32le((void *) bios_device.io_buffer + addr); - DEBUG_PRINTF_IO("%s(%04x) I/O Buffer --> %08x\n", __FUNCTION__, - addr, rval); - return rval; + switch (addr) { + case 0xCFC: + //PCI Config Mechanism 1 + return pci_cfg_read(addr, 4); + break; + default: + DEBUG_PRINTF_IO + ("%s(%04x) reading from bios_device.io_buffer\n", + __FUNCTION__, addr); + uint32_t rval = + in32le((void *) bios_device.io_buffer + addr); + DEBUG_PRINTF_IO("%s(%04x) I/O Buffer --> %08x\n", + __FUNCTION__, addr, rval); + return rval; + break; + } } } @@ -212,18 +225,29 @@ my_outb(X86EMU_pioAddr addr, uint8_t val) uint64_t translated_addr = addr; uint8_t translated = dev_translate_address(&translated_addr); if (translated != 0) { - //translation successfull, access VGA I/O (BAR or Legacy...) - DEBUG_PRINTF_IO("%s(%x, %x): access to VGA I/O\n", + //translation successfull, access Device I/O (BAR or Legacy...) + DEBUG_PRINTF_IO("%s(%x, %x): access to Device I/O\n", __FUNCTION__, addr, val); //DEBUG_PRINTF_IO("%s(%04x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr); - set_ci(); - *((uint8_t *) translated_addr) = val; - clr_ci(); + write_io((void *) translated_addr, val, 1); + DEBUG_PRINTF_IO("%s(%04x) Device I/O <-- %02x\n", __FUNCTION__, + addr, val); } else { - DEBUG_PRINTF_IO - ("%s(%04x,%02x) writing to bios_device.io_buffer\n", - __FUNCTION__, addr, val); - *((uint8_t *) (bios_device.io_buffer + addr)) = val; + switch (addr) { + case 0xCFC: + case 0xCFD: + case 0xCFE: + case 0xCFF: + // PCI Config Mechanism 1 Ports + pci_cfg_write(addr, val, 1); + break; + default: + DEBUG_PRINTF_IO + ("%s(%04x,%02x) writing to bios_device.io_buffer\n", + __FUNCTION__, addr, val); + *((uint8_t *) (bios_device.io_buffer + addr)) = val; + break; + } } } @@ -233,27 +257,38 @@ my_outw(X86EMU_pioAddr addr, uint16_t val) uint64_t translated_addr = addr; uint8_t translated = dev_translate_address(&translated_addr); if (translated != 0) { - //translation successfull, access VGA I/O (BAR or Legacy...) + //translation successfull, access Device I/O (BAR or Legacy...) + DEBUG_PRINTF_IO("%s(%x, %x): access to Device I/O\n", + __FUNCTION__, addr, val); //DEBUG_PRINTF_IO("%s(%04x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr); if ((translated_addr & (uint64_t) 0x1) == 0) { + // little-endian conversion + uint16_t tempval = in16le((void *) &val); // 16 bit aligned access... - set_ci(); - out16le((void *) translated_addr, val); - clr_ci(); + write_io((void *) translated_addr, tempval, 2); } else { - // unaligned access, write single bytes - set_ci(); - *((uint8_t *) translated_addr) = - (uint8_t) (val & 0x00FF); - *((uint8_t *) translated_addr + 1) = - (uint8_t) ((val & 0xFF00) >> 8); - clr_ci(); + // unaligned access, write single bytes, little-endian + write_io(((void *) (translated_addr + 1)), + (uint8_t) ((val & 0xFF00) >> 8), 1); + write_io(((void *) translated_addr), + (uint8_t) (val & 0x00FF), 1); } + DEBUG_PRINTF_IO("%s(%04x) Device I/O <-- %04x\n", __FUNCTION__, + addr, val); } else { - DEBUG_PRINTF_IO - ("%s(%04x,%04x) writing to bios_device.io_buffer\n", - __FUNCTION__, addr, val); - out16le((void *) bios_device.io_buffer + addr, val); + switch (addr) { + case 0xCFC: + case 0xCFE: + // PCI Config Mechanism 1 Ports + pci_cfg_write(addr, val, 2); + break; + default: + DEBUG_PRINTF_IO + ("%s(%04x,%04x) writing to bios_device.io_buffer\n", + __FUNCTION__, addr, val); + out16le((void *) bios_device.io_buffer + addr, val); + break; + } } } @@ -263,30 +298,134 @@ my_outl(X86EMU_pioAddr addr, uint32_t val) uint64_t translated_addr = addr; uint8_t translated = dev_translate_address(&translated_addr); if (translated != 0) { - //translation successfull, access VGA I/O (BAR or Legacy...) + //translation successfull, access Device I/O (BAR or Legacy...) + DEBUG_PRINTF_IO("%s(%x, %x): access to Device I/O\n", + __FUNCTION__, addr, val); //DEBUG_PRINTF_IO("%s(%04x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr); if ((translated_addr & (uint64_t) 0x3) == 0) { + // little-endian conversion + uint32_t tempval = in32le((void *) &val); // 32 bit aligned access... - set_ci(); - out32le((void *) translated_addr, val); - clr_ci(); + write_io((void *) translated_addr, tempval, 4); } else { - // unaligned access, write single bytes - set_ci(); - *((uint8_t *) translated_addr) = - (uint8_t) (val & 0x000000FF); - *((uint8_t *) translated_addr + 1) = - (uint8_t) ((val & 0x0000FF00) >> 8); - *((uint8_t *) translated_addr + 2) = - (uint8_t) ((val & 0x00FF0000) >> 16); - *((uint8_t *) translated_addr + 3) = - (uint8_t) ((val & 0xFF000000) >> 24); - clr_ci(); + // unaligned access, write single bytes, little-endian + write_io(((void *) translated_addr + 3), + (uint8_t) ((val & 0xFF000000) >> 24), 1); + write_io(((void *) translated_addr + 2), + (uint8_t) ((val & 0x00FF0000) >> 16), 1); + write_io(((void *) translated_addr + 1), + (uint8_t) ((val & 0x0000FF00) >> 8), 1); + write_io(((void *) translated_addr), + (uint8_t) (val & 0x000000FF), 1); } + DEBUG_PRINTF_IO("%s(%04x) Device I/O <-- %08x\n", __FUNCTION__, + addr, val); } else { - DEBUG_PRINTF_IO - ("%s(%04x,%08x) writing to bios_device.io_buffer\n", - __FUNCTION__, addr, val); - out32le((void *) bios_device.io_buffer + addr, val); + switch (addr) { + case 0xCFC: + // PCI Config Mechanism 1 Ports + pci_cfg_write(addr, val, 4); + break; + default: + DEBUG_PRINTF_IO + ("%s(%04x,%08x) writing to bios_device.io_buffer\n", + __FUNCTION__, addr, val); + out32le((void *) bios_device.io_buffer + addr, val); + break; + } + } +} + +uint32_t +pci_cfg_read(X86EMU_pioAddr addr, uint8_t size) +{ + uint32_t rval = 0xFFFFFFFF; + if ((addr >= 0xCFC) && ((addr + size) <= 0xCFF)) { + // PCI Configuration Mechanism 1 step 1 + // write to 0xCF8, sets bus, device, function and Config Space offset + // later read from 0xCFC-0xCFF returns the value... + uint8_t bus, devfn, offs; + uint32_t port_cf8_val = my_inl(0xCF8); + if ((port_cf8_val & 0x80000000) != 0) { + //highest bit enables config space mapping + bus = (port_cf8_val & 0x00FF0000) >> 16; + devfn = (port_cf8_val & 0x0000FF00) >> 8; + offs = (port_cf8_val & 0x000000FF); + offs += (addr - 0xCFC); // if addr is not 0xcfc, the offset is moved accordingly + if ((bus != bios_device.bus) + || (devfn != bios_device.devfn)) { + // fail accesses to any device but ours... + printf + ("Config access invalid! bus: %x, devfn: %x, offs: %x\n", + bus, devfn, offs); + HALT_SYS(); + } else { + rval = + (uint32_t) rtas_pci_config_read(bios_device. + puid, size, + bus, devfn, + offs); + DEBUG_PRINTF_IO + ("%s(%04x) PCI Config Read @%02x, size: %d --> 0x%08x\n", + __FUNCTION__, addr, offs, size, rval); + } + } + } + return rval; +} + +void +pci_cfg_write(X86EMU_pioAddr addr, uint32_t val, uint8_t size) +{ + if ((addr >= 0xCFC) && ((addr + size) <= 0xCFF)) { + // PCI Configuration Mechanism 1 step 1 + // write to 0xCF8, sets bus, device, function and Config Space offset + // later write to 0xCFC-0xCFF sets the value... + uint8_t bus, devfn, offs; + uint32_t port_cf8_val = my_inl(0xCF8); + if ((port_cf8_val & 0x80000000) != 0) { + //highest bit enables config space mapping + bus = (port_cf8_val & 0x00FF0000) >> 16; + devfn = (port_cf8_val & 0x0000FF00) >> 8; + offs = (port_cf8_val & 0x000000FF); + offs += (addr - 0xCFC); // if addr is not 0xcfc, the offset is moved accordingly + if ((bus != bios_device.bus) + || (devfn != bios_device.devfn)) { + // fail accesses to any device but ours... + printf + ("Config access invalid! bus: %x, devfn: %x, offs: %x\n", + bus, devfn, offs); + HALT_SYS(); + } else { + rtas_pci_config_write(bios_device.puid, + size, bus, devfn, offs, + val); + DEBUG_PRINTF_IO + ("%s(%04x) PCI Config Write @%02x, size: %d <-- 0x%08x\n", + __FUNCTION__, addr, offs, size, val); + } + } + } +} + +uint8_t +handle_port_61h() +{ + static uint64_t last_time = 0; + uint64_t curr_time = get_time(); + uint64_t time_diff; // time since last call + uint32_t period_ticks; // length of a period in ticks + uint32_t nr_periods; //number of periods passed since last call + // bit 4 should toggle with every (DRAM) refresh cycle... (66kHz??) + time_diff = curr_time - last_time; + // at 66kHz a period is ~ 15 ns long, converted to ticks: (tb_freq is ticks/second) + // TODO: as long as the frequency does not change, we should not calculate this every time + period_ticks = (15 * tb_freq) / 1000000; + nr_periods = time_diff / period_ticks; + // if the number if ticks passed since last call is odd, we toggle bit 4 + if ((nr_periods % 2) != 0) { + *((uint8_t *) (bios_device.io_buffer + 0x61)) ^= 0x10; } + //finally read the value from the io_buffer + return *((uint8_t *) (bios_device.io_buffer + 0x61)); } diff --git a/clients/net-snk/app/biosemu/io.h b/clients/net-snk/app/biosemu/io.h index d01f82b..5a0bb4b 100644 --- a/clients/net-snk/app/biosemu/io.h +++ b/clients/net-snk/app/biosemu/io.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -13,7 +13,7 @@ #ifndef _BIOSEMU_IO_H_ #define _BIOSEMU_IO_H_ #include <x86emu/x86emu.h> -#include <types.h> +#include <stdint.h> uint8_t my_inb(X86EMU_pioAddr addr); diff --git a/clients/net-snk/app/biosemu/mem.c b/clients/net-snk/app/biosemu/mem.c index 3e29b38..d9ad46d 100644 --- a/clients/net-snk/app/biosemu/mem.c +++ b/clients/net-snk/app/biosemu/mem.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -11,11 +11,163 @@ *****************************************************************************/ #include <stdio.h> -#include <types.h> +#include <stdint.h> #include <cpu.h> #include "debug.h" #include "device.h" #include "x86emu/x86emu.h" +#include "biosemu.h" +#include <time.h> + +// define a check for access to certain (virtual) memory regions (interrupt handlers, BIOS Data Area, ...) +#ifdef DEBUG +static uint8_t in_check = 0; // to avoid recursion... +uint16_t ebda_segment; +uint32_t ebda_size; + +//TODO: these macros have grown so large, that they should be changed to an inline function, +//just for the sake of readability... + +//declare prototypes of the functions to follow, for use in DEBUG_CHECK_VMEM_ACCESS +uint8_t my_rdb(uint32_t); +uint16_t my_rdw(uint32_t); +uint32_t my_rdl(uint32_t); + +#define DEBUG_CHECK_VMEM_READ(_addr, _rval) \ + if ((debug_flags & DEBUG_CHECK_VMEM_ACCESS) && (in_check == 0)) { \ + in_check = 1; \ + /* determine ebda_segment and size \ + * since we are using my_rdx calls, make sure, this is after setting in_check! */ \ + /* offset 03 in BDA is EBDA segment */ \ + ebda_segment = my_rdw(0x40e); \ + /* first value in ebda is size in KB */ \ + ebda_size = my_rdb(ebda_segment << 4) * 1024; \ + /* check Interrupt Vector Access (0000:0000h - 0000:0400h) */ \ + if (_addr < 0x400) { \ + DEBUG_PRINTF_CS_IP("%s: read from Interrupt Vector %x --> %x\n", \ + __FUNCTION__, _addr / 4, _rval); \ + } \ + /* access to BIOS Data Area (0000:0400h - 0000:0500h)*/ \ + else if ((_addr >= 0x400) && (addr < 0x500)) { \ + DEBUG_PRINTF_CS_IP("%s: read from BIOS Data Area: addr: %x --> %x\n", \ + __FUNCTION__, _addr, _rval); \ + /* dump registers */ \ + /* x86emu_dump_xregs(); */ \ + } \ + /* access to first 64k of memory... */ \ + else if (_addr < 0x10000) { \ + DEBUG_PRINTF_CS_IP("%s: read from segment 0000h: addr: %x --> %x\n", \ + __FUNCTION__, _addr, _rval); \ + /* dump registers */ \ + /* x86emu_dump_xregs(); */ \ + } \ + /* read from PMM_CONV_SEGMENT */ \ + else if ((_addr <= ((PMM_CONV_SEGMENT << 4) | 0xffff)) && (_addr >= (PMM_CONV_SEGMENT << 4))) { \ + DEBUG_PRINTF_CS_IP("%s: read from PMM Segment %04xh: addr: %x --> %x\n", \ + __FUNCTION__, PMM_CONV_SEGMENT, _addr, _rval); \ + /* HALT_SYS(); */ \ + /* dump registers */ \ + /* x86emu_dump_xregs(); */ \ + } \ + /* read from PNP_DATA_SEGMENT */ \ + else if ((_addr <= ((PNP_DATA_SEGMENT << 4) | 0xffff)) && (_addr >= (PNP_DATA_SEGMENT << 4))) { \ + DEBUG_PRINTF_CS_IP("%s: read from PnP Data Segment %04xh: addr: %x --> %x\n", \ + __FUNCTION__, PNP_DATA_SEGMENT, _addr, _rval); \ + /* HALT_SYS(); */ \ + /* dump registers */ \ + /* x86emu_dump_xregs(); */ \ + } \ + /* read from EBDA Segment */ \ + else if ((_addr <= ((ebda_segment << 4) | (ebda_size - 1))) && (_addr >= (ebda_segment << 4))) { \ + DEBUG_PRINTF_CS_IP("%s: read from Extended BIOS Data Area %04xh, size: %04x: addr: %x --> %x\n", \ + __FUNCTION__, ebda_segment, ebda_size, _addr, _rval); \ + } \ + /* read from BIOS_DATA_SEGMENT */ \ + else if ((_addr <= ((BIOS_DATA_SEGMENT << 4) | 0xffff)) && (_addr >= (BIOS_DATA_SEGMENT << 4))) { \ + DEBUG_PRINTF_CS_IP("%s: read from BIOS Data Segment %04xh: addr: %x --> %x\n", \ + __FUNCTION__, BIOS_DATA_SEGMENT, _addr, _rval); \ + /* for PMM debugging */ \ + /*if (_addr == BIOS_DATA_SEGMENT << 4) { \ + X86EMU_trace_on(); \ + M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F; \ + }*/ \ + /* dump registers */ \ + /* x86emu_dump_xregs(); */ \ + } \ + in_check = 0; \ + } +#define DEBUG_CHECK_VMEM_WRITE(_addr, _val) \ + if ((debug_flags & DEBUG_CHECK_VMEM_ACCESS) && (in_check == 0)) { \ + in_check = 1; \ + /* determine ebda_segment and size \ + * since we are using my_rdx calls, make sure, this is after setting in_check! */ \ + /* offset 03 in BDA is EBDA segment */ \ + ebda_segment = my_rdw(0x40e); \ + /* first value in ebda is size in KB */ \ + ebda_size = my_rdb(ebda_segment << 4) * 1024; \ + /* check Interrupt Vector Access (0000:0000h - 0000:0400h) */ \ + if (_addr < 0x400) { \ + DEBUG_PRINTF_CS_IP("%s: write to Interrupt Vector %x <-- %x\n", \ + __FUNCTION__, _addr / 4, _val); \ + } \ + /* access to BIOS Data Area (0000:0400h - 0000:0500h)*/ \ + else if ((_addr >= 0x400) && (addr < 0x500)) { \ + DEBUG_PRINTF_CS_IP("%s: write to BIOS Data Area: addr: %x <-- %x\n", \ + __FUNCTION__, _addr, _val); \ + /* dump registers */ \ + /* x86emu_dump_xregs(); */ \ + } \ + /* access to first 64k of memory...*/ \ + else if (_addr < 0x10000) { \ + DEBUG_PRINTF_CS_IP("%s: write to segment 0000h: addr: %x <-- %x\n", \ + __FUNCTION__, _addr, _val); \ + /* dump registers */ \ + /* x86emu_dump_xregs(); */ \ + } \ + /* write to PMM_CONV_SEGMENT... */ \ + else if ((_addr <= ((PMM_CONV_SEGMENT << 4) | 0xffff)) && (_addr >= (PMM_CONV_SEGMENT << 4))) { \ + DEBUG_PRINTF_CS_IP("%s: write to PMM Segment %04xh: addr: %x <-- %x\n", \ + __FUNCTION__, PMM_CONV_SEGMENT, _addr, _val); \ + /* dump registers */ \ + /* x86emu_dump_xregs(); */ \ + } \ + /* write to PNP_DATA_SEGMENT... */ \ + else if ((_addr <= ((PNP_DATA_SEGMENT << 4) | 0xffff)) && (_addr >= (PNP_DATA_SEGMENT << 4))) { \ + DEBUG_PRINTF_CS_IP("%s: write to PnP Data Segment %04xh: addr: %x <-- %x\n", \ + __FUNCTION__, PNP_DATA_SEGMENT, _addr, _val); \ + /* dump registers */ \ + /* x86emu_dump_xregs(); */ \ + } \ + /* write to EBDA Segment... */ \ + else if ((_addr <= ((ebda_segment << 4) | (ebda_size - 1))) && (_addr >= (ebda_segment << 4))) { \ + DEBUG_PRINTF_CS_IP("%s: write to Extended BIOS Data Area %04xh, size: %04x: addr: %x <-- %x\n", \ + __FUNCTION__, ebda_segment, ebda_size, _addr, _val); \ + } \ + /* write to BIOS_DATA_SEGMENT... */ \ + else if ((_addr <= ((BIOS_DATA_SEGMENT << 4) | 0xffff)) && (_addr >= (BIOS_DATA_SEGMENT << 4))) { \ + DEBUG_PRINTF_CS_IP("%s: write to BIOS Data Segment %04xh: addr: %x <-- %x\n", \ + __FUNCTION__, BIOS_DATA_SEGMENT, _addr, _val); \ + /* dump registers */ \ + /* x86emu_dump_xregs(); */ \ + } \ + /* write to current CS segment... */ \ + else if ((_addr < ((M.x86.R_CS << 4) | 0xffff)) && (_addr > (M.x86.R_CS << 4))) { \ + DEBUG_PRINTF_CS_IP("%s: write to CS segment %04xh: addr: %x <-- %x\n", \ + __FUNCTION__, M.x86.R_CS, _addr, _val); \ + /* dump registers */ \ + /* x86emu_dump_xregs(); */ \ + } \ + in_check = 0; \ + } +#else +#define DEBUG_CHECK_VMEM_READ(_addr, _rval) +#define DEBUG_CHECK_VMEM_WRITE(_addr, _val) +#endif + +//defined in net-snk/kernel/timer.c +extern uint64_t get_time(void); + +void update_time(uint32_t); // read byte from memory uint8_t @@ -23,13 +175,14 @@ my_rdb(uint32_t addr) { uint64_t translated_addr = addr; uint8_t translated = dev_translate_address(&translated_addr); + uint8_t rval; if (translated != 0) { //translation successfull, access VGA Memory (BAR or Legacy...) DEBUG_PRINTF_MEM("%s(%08x): access to VGA Memory\n", __FUNCTION__, addr); //DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr); set_ci(); - uint8_t rval = *((uint8_t *) translated_addr); + rval = *((uint8_t *) translated_addr); clr_ci(); DEBUG_PRINTF_MEM("%s(%08x) VGA --> %02x\n", __FUNCTION__, addr, rval); @@ -41,9 +194,10 @@ my_rdb(uint32_t addr) HALT_SYS(); } else { /* read from virtual memory */ - return *((uint8_t *) (M.mem_base + addr)); + rval = *((uint8_t *) (M.mem_base + addr)); + DEBUG_CHECK_VMEM_READ(addr, rval); + return rval; } - // never reached return -1; } @@ -53,12 +207,12 @@ my_rdw(uint32_t addr) { uint64_t translated_addr = addr; uint8_t translated = dev_translate_address(&translated_addr); + uint16_t rval; if (translated != 0) { //translation successfull, access VGA Memory (BAR or Legacy...) DEBUG_PRINTF_MEM("%s(%08x): access to VGA Memory\n", __FUNCTION__, addr); //DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr); - uint16_t rval; // check for legacy memory, because of the remapping to BARs, the reads must // be byte reads... if ((addr >= 0xa0000) && (addr < 0xc0000)) { @@ -91,9 +245,10 @@ my_rdw(uint32_t addr) HALT_SYS(); } else { /* read from virtual memory */ - return in16le((void *) (M.mem_base + addr)); + rval = in16le((void *) (M.mem_base + addr)); + DEBUG_CHECK_VMEM_READ(addr, rval); + return rval; } - // never reached return -1; } @@ -103,12 +258,12 @@ my_rdl(uint32_t addr) { uint64_t translated_addr = addr; uint8_t translated = dev_translate_address(&translated_addr); + uint32_t rval; if (translated != 0) { //translation successfull, access VGA Memory (BAR or Legacy...) DEBUG_PRINTF_MEM("%s(%x): access to VGA Memory\n", __FUNCTION__, addr); //DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr); - uint32_t rval; // check for legacy memory, because of the remapping to BARs, the reads must // be byte reads... if ((addr >= 0xa0000) && (addr < 0xc0000)) { @@ -146,9 +301,17 @@ my_rdl(uint32_t addr) HALT_SYS(); } else { /* read from virtual memory */ - return in32le((void *) (M.mem_base + addr)); + rval = in32le((void *) (M.mem_base + addr)); + switch (addr) { + case 0x46c: + //BDA Time Data, update it, before reading + update_time(rval); + rval = in32le((void *) (M.mem_base + addr)); + break; + } + DEBUG_CHECK_VMEM_READ(addr, rval); + return rval; } - // never reached return -1; } @@ -173,6 +336,7 @@ my_wrb(uint32_t addr, uint8_t val) HALT_SYS(); } else { /* write to virtual memory */ + DEBUG_CHECK_VMEM_WRITE(addr, val); *((uint8_t *) (M.mem_base + addr)) = val; } } @@ -218,6 +382,7 @@ my_wrw(uint32_t addr, uint16_t val) HALT_SYS(); } else { /* write to virtual memory */ + DEBUG_CHECK_VMEM_WRITE(addr, val); out16le((void *) (M.mem_base + addr), val); } } @@ -268,6 +433,31 @@ my_wrl(uint32_t addr, uint32_t val) HALT_SYS(); } else { /* write to virtual memory */ + DEBUG_CHECK_VMEM_WRITE(addr, val); out32le((void *) (M.mem_base + addr), val); } } + +//update time in BIOS Data Area +//DWord at offset 0x6c is the timer ticks since midnight, timer is running at 18Hz +//byte at 0x70 is timer overflow (set if midnight passed since last call to interrupt 1a function 00 +//cur_val is the current value, of offset 6c... +void +update_time(uint32_t cur_val) +{ + //for convenience, we let the start of timebase be at midnight, we currently dont support + //real daytime anyway... + uint64_t ticks_per_day = tb_freq * 60 * 24; + // at 18Hz a period is ~55ms, converted to ticks (tb_freq is ticks/second) + uint32_t period_ticks = (55 * tb_freq) / 1000; + uint64_t curr_time = get_time(); + uint64_t ticks_since_midnight = curr_time % ticks_per_day; + uint32_t periods_since_midnight = ticks_since_midnight / period_ticks; + // if periods since midnight is smaller than last value, set overflow + // at BDA Offset 0x70 + if (periods_since_midnight < cur_val) { + my_wrb(0x470, 1); + } + // store periods since midnight at BDA offset 0x6c + my_wrl(0x46c, periods_since_midnight); +} diff --git a/clients/net-snk/app/biosemu/mem.h b/clients/net-snk/app/biosemu/mem.h index efce891..f0fbad9 100644 --- a/clients/net-snk/app/biosemu/mem.h +++ b/clients/net-snk/app/biosemu/mem.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -13,7 +13,7 @@ #ifndef _BIOSEMU_MEM_H_ #define _BIOSEMU_MEM_H_ #include <x86emu/x86emu.h> -#include <types.h> +#include <stdint.h> // read byte from memory uint8_t my_rdb(uint32_t addr); diff --git a/clients/net-snk/app/biosemu/vbe.c b/clients/net-snk/app/biosemu/vbe.c index 7f9ebe7..06b1b18 100644 --- a/clients/net-snk/app/biosemu/vbe.c +++ b/clients/net-snk/app/biosemu/vbe.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -14,7 +14,7 @@ #include <stdlib.h> #include <string.h> -#include <types.h> +#include <stdint.h> #include <cpu.h> #include "debug.h" @@ -23,10 +23,10 @@ #include <x86emu/regs.h> #include <x86emu/prim_ops.h> // for push_word +#include "biosemu.h" #include "io.h" #include "mem.h" #include "interrupt.h" - #include "device.h" static X86EMU_memFuncs my_mem_funcs = { @@ -99,7 +99,7 @@ typedef struct { static inline uint8_t vbe_prepare() { - vbe_info_buffer = biosmem + 0x10000; // segment:offset 1000:0000 + vbe_info_buffer = biosmem + (VBE_SEGMENT << 4); // segment:offset off VBE Data Area //clear buffer memset(vbe_info_buffer, 0, 512); //set VbeSignature to "VBE2" to indicate VBE 2.0+ request @@ -107,9 +107,9 @@ vbe_prepare() vbe_info_buffer[0] = 'B'; vbe_info_buffer[0] = 'E'; vbe_info_buffer[0] = '2'; - // ES:DI store pointer to buffer in virtual mem (@ 0x10000) see vbe_info_buffer above... + // ES:DI store pointer to buffer in virtual mem see vbe_info_buffer above... M.x86.R_EDI = 0x0; - M.x86.R_ES = 0x1000; + M.x86.R_ES = VBE_SEGMENT; return 0; // successfull init } @@ -123,10 +123,9 @@ vbe_info(vbe_info_t * info) M.x86.R_EAX = 0x4f00; // enable trace -#ifdef DEBUG_TRACE_X86EMU - X86EMU_trace_on(); -#endif - + CHECK_DBG(DEBUG_TRACE_X86EMU) { + X86EMU_trace_on(); + } // run VESA Interrupt runInt10(); @@ -194,10 +193,9 @@ vbe_get_mode_info(vbe_mode_info_t * mode_info) M.x86.R_CX = mode_info->video_mode; // enable trace -#ifdef DEBUG_TRACE_X86EMU - X86EMU_trace_on(); -#endif - + CHECK_DBG(DEBUG_TRACE_X86EMU) { + X86EMU_trace_on(); + } // run VESA Interrupt runInt10(); @@ -268,10 +266,9 @@ vbe_set_mode(vbe_mode_info_t * mode_info) M.x86.R_BX); // enable trace -#ifdef DEBUG_TRACE_X86EMU - X86EMU_trace_on(); -#endif - + CHECK_DBG(DEBUG_TRACE_X86EMU) { + X86EMU_trace_on(); + } // run VESA Interrupt runInt10(); @@ -305,10 +302,9 @@ vbe_set_palette_format(uint8_t format) format); // enable trace -#ifdef DEBUG_TRACE_X86EMU - X86EMU_trace_on(); -#endif - + CHECK_DBG(DEBUG_TRACE_X86EMU) { + X86EMU_trace_on(); + } // run VESA Interrupt runInt10(); @@ -349,10 +345,9 @@ vbe_set_color(uint16_t color_number, uint32_t color_value) color_number, color_value); // enable trace -#ifdef DEBUG_TRACE_X86EMU - X86EMU_trace_on(); -#endif - + CHECK_DBG(DEBUG_TRACE_X86EMU) { + X86EMU_trace_on(); + } // run VESA Interrupt runInt10(); @@ -386,10 +381,9 @@ vbe_get_color(uint16_t color_number, uint32_t * color_value) M.x86.R_DI = 0x0; // enable trace -#ifdef DEBUG_TRACE_X86EMU - X86EMU_trace_on(); -#endif - + CHECK_DBG(DEBUG_TRACE_X86EMU) { + X86EMU_trace_on(); + } // run VESA Interrupt runInt10(); @@ -428,10 +422,9 @@ vbe_get_ddc_info(vbe_ddc_info_t * ddc_info) M.x86.R_DI = 0x0; // enable trace -#ifdef DEBUG_TRACE_X86EMU - X86EMU_trace_on(); -#endif - + CHECK_DBG(DEBUG_TRACE_X86EMU) { + X86EMU_trace_on(); + } // run VESA Interrupt runInt10(); @@ -464,10 +457,9 @@ vbe_get_ddc_info(vbe_ddc_info_t * ddc_info) M.x86.R_DI = 0x0; // enable trace -#ifdef DEBUG_TRACE_X86EMU - X86EMU_trace_on(); -#endif - + CHECK_DBG(DEBUG_TRACE_X86EMU) { + X86EMU_trace_on(); + } // run VESA Interrupt runInt10(); @@ -493,11 +485,11 @@ vbe_get_ddc_info(vbe_ddc_info_t * ddc_info) } uint32_t -vbe_get_info(uint8_t argc, uint8_t ** argv) +vbe_get_info(uint8_t argc, char ** argv) { uint8_t rval; uint32_t i; - if (argc < 3) { + if (argc < 4) { printf ("Usage %s <vmem_base> <device_path> <address of screen_info_t>\n", argv[0]); @@ -507,23 +499,29 @@ vbe_get_info(uint8_t argc, uint8_t ** argv) } return -1; } - // argv[1] is address of virtual BIOS mem... it should be 1MB large... - biosmem = (uint8_t *) strtoul((char *) argv[1], 0, 16); - biosmem_size = 0x100000; - // argv[2] is the device to open and use... - if (dev_init((char *) argv[2]) != 0) { - printf("Error initializing device!\n"); - return -1; - } // get a copy of input struct... screen_info_input_t input = - *((screen_info_input_t *) strtoul((char *) argv[3], 0, 16)); - // output is pointer to the address passed as argv[3] + *((screen_info_input_t *) strtoul((char *) argv[4], 0, 16)); + // output is pointer to the address passed as argv[4] screen_info_t *output = - (screen_info_t *) strtoul((char *) argv[3], 0, 16); + (screen_info_t *) strtoul((char *) argv[4], 0, 16); // zero output memset(output, 0, sizeof(screen_info_t)); + // argv[1] is address of virtual BIOS mem... + // argv[2] is the size + biosmem = (uint8_t *) strtoul(argv[1], 0, 16); + biosmem_size = strtoul(argv[2], 0, 16);; + if (biosmem_size < MIN_REQUIRED_VMEM_SIZE) { + printf("Error: Not enough virtual memory: %x, required: %x!\n", + biosmem_size, MIN_REQUIRED_VMEM_SIZE); + return -1; + } + // argv[3] is the device to open and use... + if (dev_init((char *) argv[3]) != 0) { + printf("Error initializing device!\n"); + return -1; + } //setup interrupt handler X86EMU_intrFuncs intrFuncs[256]; for (i = 0; i < 256; i++) @@ -557,7 +555,7 @@ vbe_get_info(uint8_t argc, uint8_t ** argv) (info.capabilities & 0x4) == 0 ? "normal" : "use blank bit in Function 09h"); - // argv[3] may be a pointer with enough space to return screen_info_t + // argv[4] may be a pointer with enough space to return screen_info_t // as input, it must contain a screen_info_input_t with the following content: // byte[0:3] = "DDC\0" (zero-terminated signature header) // byte[4:5] = reserved space for the return struct... just in case we ever change @@ -566,224 +564,212 @@ vbe_get_info(uint8_t argc, uint8_t ** argv) // byte[6] = monitor port number for DDC requests ("only" one byte... so lets hope we never have more than 255 monitors... // byte[7:8] = max. screen width (OF may want to limit this) // byte[9] = required color depth in bpp - if (argc >= 4) { - if (strncmp((char *) input.signature, "DDC", 4) != 0) { - printf - ("%s: Invalid input signature! expected: %s, is: %s\n", - __FUNCTION__, "DDC", input.signature); - return -1; - } - if (input.size_reserved != sizeof(screen_info_t)) { - printf - ("%s: Size of return struct is wrong, required: %d, available: %d\n", - __FUNCTION__, (int) sizeof(screen_info_t), - input.size_reserved); - return -1; - } + if (strncmp((char *) input.signature, "DDC", 4) != 0) { + printf + ("%s: Invalid input signature! expected: %s, is: %s\n", + __FUNCTION__, "DDC", input.signature); + return -1; + } + if (input.size_reserved != sizeof(screen_info_t)) { + printf + ("%s: Size of return struct is wrong, required: %d, available: %d\n", + __FUNCTION__, (int) sizeof(screen_info_t), + input.size_reserved); + return -1; + } - vbe_ddc_info_t ddc_info; - ddc_info.port_number = input.monitor_number; - vbe_get_ddc_info(&ddc_info); + vbe_ddc_info_t ddc_info; + ddc_info.port_number = input.monitor_number; + vbe_get_ddc_info(&ddc_info); #if 0 - DEBUG_PRINTF_VBE("DDC: edid_tranfer_time: %d\n", - ddc_info.edid_transfer_time); - DEBUG_PRINTF_VBE("DDC: ddc_level: %x\n", ddc_info.ddc_level); - DEBUG_PRINTF_VBE("DDC: EDID: \n"); -#ifdef DEBUG_VBE + DEBUG_PRINTF_VBE("DDC: edid_tranfer_time: %d\n", + ddc_info.edid_transfer_time); + DEBUG_PRINTF_VBE("DDC: ddc_level: %x\n", ddc_info.ddc_level); + DEBUG_PRINTF_VBE("DDC: EDID: \n"); + CHECK_DBG(DEBUG_VBE) { dump(ddc_info.edid_block_zero, sizeof(ddc_info.edid_block_zero)); + } #endif -#endif - if (*((uint64_t *) ddc_info.edid_block_zero) != - (uint64_t) 0x00FFFFFFFFFFFF00) { - // invalid EDID signature... probably no monitor - - output->display_type = 0x0; - return 0; - } else if ((ddc_info.edid_block_zero[20] & 0x80) != 0) { - // digital display - output->display_type = 2; - } else { - // analog - output->display_type = 1; - } - DEBUG_PRINTF_VBE("DDC: found display type %d\n", - output->display_type); - memcpy(output->edid_block_zero, ddc_info.edid_block_zero, - sizeof(ddc_info.edid_block_zero)); - i = 0; - vbe_mode_info_t mode_info; - vbe_mode_info_t best_mode_info; - // initialize best_mode to 0 - memset(&best_mode_info, 0, sizeof(best_mode_info)); - while ((mode_info.video_mode = - info.video_mode_list[i]) != 0xFFFF) { - //DEBUG_PRINTF_VBE("%x: Mode: %04x\n", i, mode_info.video_mode); - vbe_get_mode_info(&mode_info); + if (*((uint64_t *) ddc_info.edid_block_zero) != + (uint64_t) 0x00FFFFFFFFFFFF00) { + // invalid EDID signature... probably no monitor + + output->display_type = 0x0; + return 0; + } else if ((ddc_info.edid_block_zero[20] & 0x80) != 0) { + // digital display + output->display_type = 2; + } else { + // analog + output->display_type = 1; + } + DEBUG_PRINTF_VBE("DDC: found display type %d\n", output->display_type); + memcpy(output->edid_block_zero, ddc_info.edid_block_zero, + sizeof(ddc_info.edid_block_zero)); + i = 0; + vbe_mode_info_t mode_info; + vbe_mode_info_t best_mode_info; + // initialize best_mode to 0 + memset(&best_mode_info, 0, sizeof(best_mode_info)); + while ((mode_info.video_mode = info.video_mode_list[i]) != 0xFFFF) { + //DEBUG_PRINTF_VBE("%x: Mode: %04x\n", i, mode_info.video_mode); + vbe_get_mode_info(&mode_info); #if 0 - DEBUG_PRINTF_VBE("Video Mode 0x%04x available, %s\n", - mode_info.video_mode, - (mode_info.attributes & 0x1) == - 0 ? "not supported" : "supported"); - DEBUG_PRINTF_VBE("\tTTY: %s\n", - (mode_info.attributes & 0x4) == - 0 ? "no" : "yes"); - DEBUG_PRINTF_VBE("\tMode: %s %s\n", - (mode_info.attributes & 0x8) == - 0 ? "monochrome" : "color", - (mode_info.attributes & 0x10) == - 0 ? "text" : "graphics"); - DEBUG_PRINTF_VBE("\tVGA: %s\n", - (mode_info.attributes & 0x20) == - 0 ? "compatible" : "not compatible"); - DEBUG_PRINTF_VBE("\tWindowed Mode: %s\n", - (mode_info.attributes & 0x40) == - 0 ? "yes" : "no"); - DEBUG_PRINTF_VBE("\tFramebuffer: %s\n", - (mode_info.attributes & 0x80) == - 0 ? "no" : "yes"); - DEBUG_PRINTF_VBE("\tResolution: %dx%d\n", - mode_info.x_resolution, - mode_info.y_resolution); - DEBUG_PRINTF_VBE("\tChar Size: %dx%d\n", - mode_info.x_charsize, - mode_info.y_charsize); - DEBUG_PRINTF_VBE("\tColor Depth: %dbpp\n", - mode_info.bits_per_pixel); - DEBUG_PRINTF_VBE("\tMemory Model: 0x%x\n", - mode_info.memory_model); - DEBUG_PRINTF_VBE("\tFramebuffer Offset: %08x\n", - mode_info.framebuffer_address); + DEBUG_PRINTF_VBE("Video Mode 0x%04x available, %s\n", + mode_info.video_mode, + (mode_info.attributes & 0x1) == + 0 ? "not supported" : "supported"); + DEBUG_PRINTF_VBE("\tTTY: %s\n", + (mode_info.attributes & 0x4) == + 0 ? "no" : "yes"); + DEBUG_PRINTF_VBE("\tMode: %s %s\n", + (mode_info.attributes & 0x8) == + 0 ? "monochrome" : "color", + (mode_info.attributes & 0x10) == + 0 ? "text" : "graphics"); + DEBUG_PRINTF_VBE("\tVGA: %s\n", + (mode_info.attributes & 0x20) == + 0 ? "compatible" : "not compatible"); + DEBUG_PRINTF_VBE("\tWindowed Mode: %s\n", + (mode_info.attributes & 0x40) == + 0 ? "yes" : "no"); + DEBUG_PRINTF_VBE("\tFramebuffer: %s\n", + (mode_info.attributes & 0x80) == + 0 ? "no" : "yes"); + DEBUG_PRINTF_VBE("\tResolution: %dx%d\n", + mode_info.x_resolution, + mode_info.y_resolution); + DEBUG_PRINTF_VBE("\tChar Size: %dx%d\n", + mode_info.x_charsize, mode_info.y_charsize); + DEBUG_PRINTF_VBE("\tColor Depth: %dbpp\n", + mode_info.bits_per_pixel); + DEBUG_PRINTF_VBE("\tMemory Model: 0x%x\n", + mode_info.memory_model); + DEBUG_PRINTF_VBE("\tFramebuffer Offset: %08x\n", + mode_info.framebuffer_address); #endif - if ((mode_info.bits_per_pixel == input.color_depth) - && (mode_info.x_resolution <= - input.max_screen_width) - && ((mode_info.attributes & 0x80) != 0) // framebuffer mode - && ((mode_info.attributes & 0x10) != 0) // graphics - && ((mode_info.attributes & 0x8) != 0) // color - && (mode_info.x_resolution > best_mode_info.x_resolution)) // better than previous best_mode - { - // yiiiihaah... we found a new best mode - memcpy(&best_mode_info, &mode_info, - sizeof(mode_info)); - } - i++; + if ((mode_info.bits_per_pixel == input.color_depth) + && (mode_info.x_resolution <= input.max_screen_width) + && ((mode_info.attributes & 0x80) != 0) // framebuffer mode + && ((mode_info.attributes & 0x10) != 0) // graphics + && ((mode_info.attributes & 0x8) != 0) // color + && (mode_info.x_resolution > best_mode_info.x_resolution)) // better than previous best_mode + { + // yiiiihaah... we found a new best mode + memcpy(&best_mode_info, &mode_info, sizeof(mode_info)); } + i++; + } - if (best_mode_info.video_mode != 0) { - DEBUG_PRINTF_VBE - ("Best Video Mode found: 0x%x, %dx%d, %dbpp, framebuffer_address: 0x%x\n", - best_mode_info.video_mode, - best_mode_info.x_resolution, - best_mode_info.y_resolution, - best_mode_info.bits_per_pixel, - best_mode_info.framebuffer_address); - - //printf("Mode Info Dump:"); - //dump(best_mode_info.mode_info_block, 64); - - // set the video mode - vbe_set_mode(&best_mode_info); - - if ((info.capabilities & 0x1) != 0) { - // switch to 8 bit palette format - vbe_set_palette_format(8); - } - // setup a palette: - // - first 216 colors are mixed colors for each component in 6 steps - // (6*6*6=216) - // - then 10 shades of the three primary colors - // - then 10 shades of grey - // ------- - // = 256 colors - // - // - finally black is color 0 and white color FF (because SLOF expects it - // this way...) - // this resembles the palette that the kernel/X Server seems to expect... - - uint8_t mixed_color_values[6] = - { 0xFF, 0xDA, 0xB3, 0x87, 0x54, 0x00 }; - uint8_t primary_color_values[10] = - { 0xF3, 0xE7, 0xCD, 0xC0, 0xA5, 0x96, 0x77, 0x66, - 0x3F, 0x27 }; - uint8_t mc_size = sizeof(mixed_color_values); - uint8_t prim_size = sizeof(primary_color_values); - - uint8_t curr_color_index; - uint32_t curr_color; - - uint8_t r, g, b; - // 216 mixed colors - for (r = 0; r < mc_size; r++) { - for (g = 0; g < mc_size; g++) { - for (b = 0; b < mc_size; b++) { - curr_color_index = - (r * mc_size * mc_size) + - (g * mc_size) + b; - curr_color = 0; - curr_color |= ((uint32_t) mixed_color_values[r]) << 16; //red value - curr_color |= ((uint32_t) mixed_color_values[g]) << 8; //green value - curr_color |= (uint32_t) mixed_color_values[b]; //blue value - vbe_set_color(curr_color_index, - curr_color); - } + if (best_mode_info.video_mode != 0) { + DEBUG_PRINTF_VBE + ("Best Video Mode found: 0x%x, %dx%d, %dbpp, framebuffer_address: 0x%x\n", + best_mode_info.video_mode, + best_mode_info.x_resolution, + best_mode_info.y_resolution, + best_mode_info.bits_per_pixel, + best_mode_info.framebuffer_address); + + //printf("Mode Info Dump:"); + //dump(best_mode_info.mode_info_block, 64); + + // set the video mode + vbe_set_mode(&best_mode_info); + + if ((info.capabilities & 0x1) != 0) { + // switch to 8 bit palette format + vbe_set_palette_format(8); + } + // setup a palette: + // - first 216 colors are mixed colors for each component in 6 steps + // (6*6*6=216) + // - then 10 shades of the three primary colors + // - then 10 shades of grey + // ------- + // = 256 colors + // + // - finally black is color 0 and white color FF (because SLOF expects it + // this way...) + // this resembles the palette that the kernel/X Server seems to expect... + + uint8_t mixed_color_values[6] = + { 0xFF, 0xDA, 0xB3, 0x87, 0x54, 0x00 }; + uint8_t primary_color_values[10] = + { 0xF3, 0xE7, 0xCD, 0xC0, 0xA5, 0x96, 0x77, 0x66, 0x3F, + 0x27 + }; + uint8_t mc_size = sizeof(mixed_color_values); + uint8_t prim_size = sizeof(primary_color_values); + + uint8_t curr_color_index; + uint32_t curr_color; + + uint8_t r, g, b; + // 216 mixed colors + for (r = 0; r < mc_size; r++) { + for (g = 0; g < mc_size; g++) { + for (b = 0; b < mc_size; b++) { + curr_color_index = + (r * mc_size * mc_size) + + (g * mc_size) + b; + curr_color = 0; + curr_color |= ((uint32_t) mixed_color_values[r]) << 16; //red value + curr_color |= ((uint32_t) mixed_color_values[g]) << 8; //green value + curr_color |= (uint32_t) mixed_color_values[b]; //blue value + vbe_set_color(curr_color_index, + curr_color); } } + } - // 10 shades of each primary color - // red - for (r = 0; r < prim_size; r++) { - curr_color_index = - mc_size * mc_size * mc_size + r; - curr_color = - ((uint32_t) primary_color_values[r]) << 16; - vbe_set_color(curr_color_index, curr_color); - } - //green - for (g = 0; g < prim_size; g++) { - curr_color_index = - mc_size * mc_size * mc_size + prim_size + g; - curr_color = - ((uint32_t) primary_color_values[g]) << 8; - vbe_set_color(curr_color_index, curr_color); - } - //blue - for (b = 0; b < prim_size; b++) { - curr_color_index = - mc_size * mc_size * mc_size + - prim_size * 2 + b; - curr_color = (uint32_t) primary_color_values[b]; - vbe_set_color(curr_color_index, curr_color); - } - // 10 shades of grey - for (i = 0; i < prim_size; i++) { - curr_color_index = - mc_size * mc_size * mc_size + - prim_size * 3 + i; - curr_color = 0; - curr_color |= ((uint32_t) primary_color_values[i]) << 16; //red - curr_color |= ((uint32_t) primary_color_values[i]) << 8; //green - curr_color |= ((uint32_t) primary_color_values[i]); //blue - vbe_set_color(curr_color_index, curr_color); - } - - // SLOF is using color 0x0 (black) and 0xFF (white) to draw to the screen... - vbe_set_color(0x00, 0x00000000); - vbe_set_color(0xFF, 0x00FFFFFF); - - output->screen_width = best_mode_info.x_resolution; - output->screen_height = best_mode_info.y_resolution; - output->screen_linebytes = best_mode_info.linebytes; - output->color_depth = best_mode_info.bits_per_pixel; - output->framebuffer_address = - best_mode_info.framebuffer_address; - } else { - printf("%s: No suitable video mode found!\n", - __FUNCTION__); - //unset display_type... - output->display_type = 0; + // 10 shades of each primary color + // red + for (r = 0; r < prim_size; r++) { + curr_color_index = mc_size * mc_size * mc_size + r; + curr_color = ((uint32_t) primary_color_values[r]) << 16; + vbe_set_color(curr_color_index, curr_color); } + //green + for (g = 0; g < prim_size; g++) { + curr_color_index = + mc_size * mc_size * mc_size + prim_size + g; + curr_color = ((uint32_t) primary_color_values[g]) << 8; + vbe_set_color(curr_color_index, curr_color); + } + //blue + for (b = 0; b < prim_size; b++) { + curr_color_index = + mc_size * mc_size * mc_size + prim_size * 2 + b; + curr_color = (uint32_t) primary_color_values[b]; + vbe_set_color(curr_color_index, curr_color); + } + // 10 shades of grey + for (i = 0; i < prim_size; i++) { + curr_color_index = + mc_size * mc_size * mc_size + prim_size * 3 + i; + curr_color = 0; + curr_color |= ((uint32_t) primary_color_values[i]) << 16; //red + curr_color |= ((uint32_t) primary_color_values[i]) << 8; //green + curr_color |= ((uint32_t) primary_color_values[i]); //blue + vbe_set_color(curr_color_index, curr_color); + } + + // SLOF is using color 0x0 (black) and 0xFF (white) to draw to the screen... + vbe_set_color(0x00, 0x00000000); + vbe_set_color(0xFF, 0x00FFFFFF); + + output->screen_width = best_mode_info.x_resolution; + output->screen_height = best_mode_info.y_resolution; + output->screen_linebytes = best_mode_info.linebytes; + output->color_depth = best_mode_info.bits_per_pixel; + output->framebuffer_address = + best_mode_info.framebuffer_address; + } else { + printf("%s: No suitable video mode found!\n", __FUNCTION__); + //unset display_type... + output->display_type = 0; } return 0; } diff --git a/clients/net-snk/app/biosemu/vbe.h b/clients/net-snk/app/biosemu/vbe.h index 3fe3c8a..07daedb 100644 --- a/clients/net-snk/app/biosemu/vbe.h +++ b/clients/net-snk/app/biosemu/vbe.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/app/main.c b/clients/net-snk/app/main.c index 2910901..ed0a291 100644 --- a/clients/net-snk/app/main.c +++ b/clients/net-snk/app/main.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -21,6 +21,15 @@ extern int biosemu(char argc, char**argv); extern int vbe_get_info(char argc, char**argv); #endif +#ifdef SNK_GENMODULE_APPS +extern int forth(int, char*[]); +extern int snkshell(void); +#endif + +#ifdef SNK_LJTAG_PROCESS +extern int ljtag(char argc, char**argv); +#endif + extern void _callback_entry(void); int @@ -29,7 +38,10 @@ main(int argc, char *argv[]) int i; of_set_callback((void *) &_callback_entry); - if (strcmp(argv[0], "netboot") == 0 && argc >= 4) +#ifdef SNK_LJTAG_PROCESS + return ljtag(argc, argv); +#else + if (strcmp(argv[0], "netboot") == 0 && argc >= 5) return netboot(argc, argv); if (strcmp(argv[0], "netflash") == 0) return netflash(argc, argv); @@ -42,6 +54,13 @@ main(int argc, char *argv[]) if (strcmp(argv[0], "get_vbe_info") == 0) return vbe_get_info(argc, argv); #endif +#ifdef SNK_GENMODULE_APPS + if (strcmp(argv[0], "forth") == 0) + return forth(argc, argv); + if (strcmp(argv[0], "snkshell") == 0) + return snkshell(); +#endif +#endif printf("Unknown client application called\n"); for (i = 0; i < argc; i++) diff --git a/clients/net-snk/app/netapps/Makefile b/clients/net-snk/app/netapps/Makefile index 9882a18..a40cb95 100644 --- a/clients/net-snk/app/netapps/Makefile +++ b/clients/net-snk/app/netapps/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License diff --git a/clients/net-snk/app/netapps/args.c b/clients/net-snk/app/netapps/args.c index ac71342..2f4a615 100644 --- a/clients/net-snk/app/netapps/args.c +++ b/clients/net-snk/app/netapps/args.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/app/netapps/args.h b/clients/net-snk/app/netapps/args.h index 99c1c78..b80982a 100644 --- a/clients/net-snk/app/netapps/args.h +++ b/clients/net-snk/app/netapps/args.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/app/netapps/netapps.h b/clients/net-snk/app/netapps/netapps.h index 836edd4..8b0a5e7 100644 --- a/clients/net-snk/app/netapps/netapps.h +++ b/clients/net-snk/app/netapps/netapps.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/app/netapps/netboot.c b/clients/net-snk/app/netapps/netboot.c index b0f8c87..13202a7 100644 --- a/clients/net-snk/app/netapps/netboot.c +++ b/clients/net-snk/app/netapps/netboot.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -10,78 +10,155 @@ * IBM Corporation - initial implementation *****************************************************************************/ -#include <netlib/netlib.h> -#include <netlib/netbase.h> -#include <netlib/icmp.h> -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> +#include <netlib/tftp.h> +#include <netlib/ethernet.h> +#include <netlib/dhcp.h> +//#include <netlib/dhcpv6.h> +#include <netlib/ipv4.h> +//#include <netlib/ipv6.h> #include <string.h> +#include <stdio.h> #include <time.h> +#include <stdlib.h> +#include <sys/socket.h> #include <netapps/args.h> #include <libbootmsg/libbootmsg.h> -#include <sys/socket.h> #include <of.h> #define IP_INIT_DEFAULT 2 #define IP_INIT_NONE 0 #define IP_INIT_BOOTP 1 #define IP_INIT_DHCP 2 +#define IP_INIT_DHCPV6_STATELESS 3 +#define IP_INIT_IPV6_MANUAL 4 #define DEFAULT_BOOT_RETRIES 600 #define DEFAULT_TFTP_RETRIES 20 +static int ip_version = 4; typedef struct { + char filename[100]; int ip_init; char siaddr[4]; - char filename[100]; + //ip6_addr_t si6addr; char ciaddr[4]; + //ip6_addr_t ci6addr; char giaddr[4]; + //ip6_addr_t gi6addr; int bootp_retries; int tftp_retries; } obp_tftp_args_t; + /** - * Parses a argument string which is given by netload, extracts all - * parameters and fills a structure according to this - * - * Netload-Parameters: - * [bootp,]siaddr,filename,ciaddr,giaddr,bootp-retries,tftp-retries + * Parses a argument string for IPv6 booting, extracts all + * parameters and fills a structure accordingly * * @param arg_str string with arguments, seperated with ',' + * @param argc number of arguments * @param obp_tftp_args structure which contains the result - * @return none + * @return updated arg_str */ -static void parse_args(const char *arg_str, obp_tftp_args_t *obp_tftp_args) { - unsigned int argc; +/* +static const char * +parse_ipv6args (const char *arg_str, unsigned int argc, + obp_tftp_args_t *obp_tftp_args) +{ + char *ptr = NULL; char arg_buf[100]; - char *ptr; - argc = get_args_count(arg_str); + // find out siaddr + if (argc == 0) + memset(&obp_tftp_args->si6addr.addr, 0, 16); + else { + argncpy(arg_str, 0, arg_buf, 100); + if(parseip6(arg_buf, (uint8_t *) &(obp_tftp_args->si6addr.addr[0]))) { + arg_str = get_arg_ptr(arg_str, 1); + --argc; + } + else if(arg_buf[0] == 0) { + memset(&obp_tftp_args->si6addr.addr, 0, 16); + arg_str = get_arg_ptr(arg_str, 1); + --argc; + } + else + memset(&obp_tftp_args->si6addr.addr, 0, 16); + } - // find out if we should use BOOTP or DHCP - if(argc==0) - obp_tftp_args->ip_init = IP_INIT_DEFAULT; + // find out filename + if (argc == 0) + obp_tftp_args->filename[0] = 0; + else { + argncpy(arg_str, 0, obp_tftp_args->filename, 100); + for(ptr = obp_tftp_args->filename; *ptr != 0; ++ptr) + if(*ptr == '\\') { + *ptr = '/'; + } + arg_str = get_arg_ptr(arg_str, 1); + --argc; + } + + // find out ciaddr + if (argc == 0) + memset(&obp_tftp_args->ci6addr, 0, 16); else { argncpy(arg_str, 0, arg_buf, 100); - if(strcasecmp(arg_buf, "bootp") == 0) { - obp_tftp_args->ip_init = IP_INIT_BOOTP; + if (parseip6(arg_buf, (uint8_t *) &(obp_tftp_args->ci6addr.addr)) ) { arg_str = get_arg_ptr(arg_str, 1); --argc; } - else if(strcasecmp(arg_buf, "dhcp") == 0) { - obp_tftp_args->ip_init = IP_INIT_DHCP; + else if(arg_buf[0] == 0) { + memset(&obp_tftp_args->ci6addr.addr, 0, 16); arg_str = get_arg_ptr(arg_str, 1); --argc; } else - obp_tftp_args->ip_init = IP_INIT_DEFAULT; + memset(&obp_tftp_args->ci6addr.addr, 0, 16); } + // find out giaddr + if (argc == 0) + memset(&obp_tftp_args->gi6addr, 0, 16); + else { + argncpy(arg_str, 0, arg_buf, 100); + if (parseip6(arg_buf, (uint8_t *) &(obp_tftp_args->gi6addr.addr)) ) { + arg_str = get_arg_ptr(arg_str, 1); + --argc; + } + else if(arg_buf[0] == 0) { + memset(&obp_tftp_args->gi6addr, 0, 16); + arg_str = get_arg_ptr(arg_str, 1); + --argc; + } + else + memset(&obp_tftp_args->gi6addr.addr, 0, 16); + } + + return arg_str; +} +*/ + + +/** + * Parses a argument string for IPv4 booting, extracts all + * parameters and fills a structure accordingly + * + * @param arg_str string with arguments, seperated with ',' + * @param argc number of arguments + * @param obp_tftp_args structure which contains the result + * @return updated arg_str + */ +static const char * +parse_ipv4args (const char *arg_str, unsigned int argc, + obp_tftp_args_t *obp_tftp_args) +{ + char *ptr = NULL; + char arg_buf[100]; + // find out siaddr - if(argc==0) + if(argc==0) { memset(obp_tftp_args->siaddr, 0, 4); - else { + } else { argncpy(arg_str, 0, arg_buf, 100); if(strtoip(arg_buf, obp_tftp_args->siaddr)) { arg_str = get_arg_ptr(arg_str, 1); @@ -144,8 +221,64 @@ static void parse_args(const char *arg_str, obp_tftp_args_t *obp_tftp_args) { memset(obp_tftp_args->giaddr, 0, 4); } - // find out bootp-retries + return arg_str; +} + +/** + * Parses a argument string which is given by netload, extracts all + * parameters and fills a structure according to this + * + * Netload-Parameters: + * [bootp,]siaddr,filename,ciaddr,giaddr,bootp-retries,tftp-retries + * + * @param arg_str string with arguments, seperated with ',' + * @param obp_tftp_args structure which contains the result + * @return none + */ +static void +parse_args(const char *arg_str, obp_tftp_args_t *obp_tftp_args) +{ + unsigned int argc; + char arg_buf[100]; + + argc = get_args_count(arg_str); + + // find out if we should use BOOTP or DHCP if(argc==0) + obp_tftp_args->ip_init = IP_INIT_DEFAULT; + else { + argncpy(arg_str, 0, arg_buf, 100); + if (strcasecmp(arg_buf, "bootp") == 0) { + obp_tftp_args->ip_init = IP_INIT_BOOTP; + arg_str = get_arg_ptr(arg_str, 1); + --argc; + } + else if(strcasecmp(arg_buf, "dhcp") == 0) { + obp_tftp_args->ip_init = IP_INIT_DHCP; + arg_str = get_arg_ptr(arg_str, 1); + --argc; + } + else if(strcasecmp(arg_buf, "ipv6") == 0) { + obp_tftp_args->ip_init = IP_INIT_DHCPV6_STATELESS; + arg_str = get_arg_ptr(arg_str, 1); + --argc; + ip_version = 6; + } + else + obp_tftp_args->ip_init = IP_INIT_DEFAULT; + } + + if (ip_version == 4) { + arg_str = parse_ipv4args (arg_str, argc, obp_tftp_args); + } +/* + else if (ip_version == 6) { + arg_str = parse_ipv6args (arg_str, argc, obp_tftp_args); + } +*/ + + // find out bootp-retries + if (argc == 0) obp_tftp_args->bootp_retries = DEFAULT_BOOT_RETRIES; else { argncpy(arg_str, 0, arg_buf, 100); @@ -161,7 +294,7 @@ static void parse_args(const char *arg_str, obp_tftp_args_t *obp_tftp_args) { } // find out tftp-retries - if(argc==0) + if (argc == 0) obp_tftp_args->tftp_retries = DEFAULT_TFTP_RETRIES; else { argncpy(arg_str, 0, arg_buf, 100); @@ -190,10 +323,18 @@ netboot(int argc, char *argv[]) tftp_err_t tftp_err; obp_tftp_args_t obp_tftp_args; char null_ip[4] = { 0x00, 0x00, 0x00, 0x00 }; +/* + char null_ip6[16] = { 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; +*/ int huge_load = strtol(argv[4], 0, 10); + int32_t block_size = strtol(argv[5], 0, 10); + uint8_t own_mac[6]; printf("\n"); - printf(" Bootloader 1.5 \n"); + printf(" Bootloader 1.6 \n"); memset(&fn_ip, 0, sizeof(filename_ip_t)); /*********************************************************** @@ -208,7 +349,7 @@ netboot(int argc, char *argv[]) set_timer(TICKS_SEC); while (get_timer() > 0); } - fd_device = socket(0, 0, 0, (char *) fn_ip.own_mac); + fd_device = socket(0, 0, 0, (char*) own_mac); if(fd_device != -2) break; if(getchar() == 27) { @@ -234,11 +375,14 @@ netboot(int argc, char *argv[]) printf(" Reading MAC address from device: " "%02x:%02x:%02x:%02x:%02x:%02x\n", - fn_ip.own_mac[0], fn_ip.own_mac[1], fn_ip.own_mac[2], - fn_ip.own_mac[3], fn_ip.own_mac[4], fn_ip.own_mac[5]); + own_mac[0], own_mac[1], own_mac[2], + own_mac[3], own_mac[4], own_mac[5]); - if (argc >= 5) { - parse_args(argv[5], &obp_tftp_args); + // init ethernet layer + set_mac_address(own_mac); + + if (argc > 6) { + parse_args(argv[6], &obp_tftp_args); if(obp_tftp_args.bootp_retries - rc < DEFAULT_BOOT_RETRIES) obp_tftp_args.bootp_retries = DEFAULT_BOOT_RETRIES; else @@ -252,40 +396,35 @@ netboot(int argc, char *argv[]) } memcpy(&fn_ip.own_ip, obp_tftp_args.ciaddr, 4); - // init network stack - netbase_init(fd_device, fn_ip.own_mac, fn_ip.own_ip); - // reset of error code rc = 0; /* if we still have got all necessary parameters, then we don't need to perform an BOOTP/DHCP-Request */ - if(memcmp(obp_tftp_args.ciaddr, null_ip, 4) != 0 - && memcmp(obp_tftp_args.siaddr, null_ip, 4) != 0 - && obp_tftp_args.filename[0] != 0) { - memcpy(&fn_ip.server_ip, obp_tftp_args.siaddr, 4); - - // try to get the MAC address of the TFTP server - if (net_iptomac(fn_ip.server_ip, fn_ip.server_mac)) { - // we got it + if (ip_version == 4) { + if (memcmp(obp_tftp_args.ciaddr, null_ip, 4) != 0 + && memcmp(obp_tftp_args.siaddr, null_ip, 4) != 0 + && obp_tftp_args.filename[0] != 0) { + + memcpy(&fn_ip.server_ip, &obp_tftp_args.siaddr, 4); obp_tftp_args.ip_init = IP_INIT_NONE; } + } +/* + else if (ip_version == 6) { + if (memcmp(&obp_tftp_args.ci6addr, null_ip6, 16) != 0 + && memcmp(&obp_tftp_args.si6addr, null_ip6, 16) != 0 + && obp_tftp_args.filename[0] != 0) { + + memcpy(&fn_ip.server_ip6.addr[0], + &obp_tftp_args.si6addr.addr, 16); + obp_tftp_args.ip_init = IP_INIT_IPV6_MANUAL; + } else { - // figure out if there is a change to get it somehow else - switch(obp_tftp_args.ip_init) { - case IP_INIT_NONE: - case IP_INIT_BOOTP: // BOOTP doesn't help - obp_tftp_args.ip_init = IP_INIT_NONE; - rc = -2; - break; - case IP_INIT_DHCP: // the DHCP server might tell us an - // appropriate router and netmask - default: - break; - } + obp_tftp_args.ip_init = IP_INIT_DHCPV6_STATELESS; } } - +*/ // construction of fn_ip from parameter switch(obp_tftp_args.ip_init) { case IP_INIT_BOOTP: @@ -295,26 +434,33 @@ netboot(int argc, char *argv[]) if(memcmp(obp_tftp_args.giaddr, null_ip, 4) == 0) { // don't do this, when using DHCP !!! fn_ip.server_ip = 0xFFFFFFFF; - memset(fn_ip.server_mac, 0xff, 6); } // if giaddr is specified, then we have to use this // IP address as proxy to identify the BOOTP server else { memcpy(&fn_ip.server_ip, obp_tftp_args.giaddr, 4); - memset(fn_ip.server_mac, 0xff, 6); } - rc = bootp(fd_device, ret_buffer, &fn_ip, obp_tftp_args.bootp_retries); + rc = bootp(ret_buffer, &fn_ip, obp_tftp_args.bootp_retries); break; case IP_INIT_DHCP: printf(" Requesting IP address via DHCP: "); - rc = dhcp(fd_device, ret_buffer, &fn_ip, obp_tftp_args.bootp_retries); + rc = dhcp(ret_buffer, &fn_ip, obp_tftp_args.bootp_retries); + break; +/* + case IP_INIT_DHCPV6_STATELESS: + set_ipv6_address(0); + rc = do_dhcpv6 (ret_buffer, &fn_ip, 10, DHCPV6_STATELESS); + break; + case IP_INIT_IPV6_MANUAL: + set_ipv6_address(&obp_tftp_args.ci6addr); break; +*/ case IP_INIT_NONE: default: break; } - if(rc >= 0) { + if(rc >= 0 && ip_version == 4) { if(memcmp(obp_tftp_args.ciaddr, null_ip, 4) != 0 && memcmp(obp_tftp_args.ciaddr, &fn_ip.own_ip, 4) != 0) memcpy(&fn_ip.own_ip, obp_tftp_args.ciaddr, 4); @@ -323,15 +469,20 @@ netboot(int argc, char *argv[]) && memcmp(obp_tftp_args.siaddr, &fn_ip.server_ip, 4) != 0) memcpy(&fn_ip.server_ip, obp_tftp_args.siaddr, 4); - // reinit network stack - netbase_init(fd_device, fn_ip.own_mac, fn_ip.own_ip); - - if (!net_iptomac(fn_ip.server_ip, fn_ip.server_mac)) { - // printf("\nERROR:\t\t\tCan't obtain TFTP server MAC!\n"); - rc = -2; - } + // init IPv4 layer + set_ipv4_address(fn_ip.own_ip); } - +/* + else if (rc >= 0 && ip_version == 6) { + if(memcmp(&obp_tftp_args.ci6addr.addr, null_ip6, 16) != 0 + && memcmp(&obp_tftp_args.ci6addr.addr, &fn_ip.own_ip6, 16) != 0) + memcpy(&fn_ip.own_ip6, &obp_tftp_args.ci6addr.addr, 16); + + if(memcmp(&obp_tftp_args.si6addr.addr, null_ip6, 16) != 0 + && memcmp(&obp_tftp_args.si6addr.addr, &fn_ip.server_ip6.addr, 16) != 0) + memcpy(&fn_ip.server_ip6.addr, &obp_tftp_args.si6addr.addr, 16); + } +*/ if (rc == -1) { strcpy(buf,"E3001: (net) Could not get IP address"); bootmsg_error(0x3001, &buf[7]); @@ -386,7 +537,9 @@ netboot(int argc, char *argv[]) // accept at most 20 bad packets // wait at most for 40 packets - rc = tftp(fd_device, &fn_ip, (unsigned char *) buffer, len, obp_tftp_args.tftp_retries, &tftp_err, huge_load); + rc = tftp(&fn_ip, (unsigned char *) buffer, + len, obp_tftp_args.tftp_retries, + &tftp_err, huge_load, block_size, ip_version); if(obp_tftp_args.ip_init == IP_INIT_DHCP) dhcp_send_release(); diff --git a/clients/net-snk/app/netapps/netflash.c b/clients/net-snk/app/netapps/netflash.c index 8cdcdad..6865ecb 100644 --- a/clients/net-snk/app/netapps/netflash.c +++ b/clients/net-snk/app/netapps/netflash.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -10,15 +10,15 @@ * IBM Corporation - initial implementation *****************************************************************************/ -#include <netlib/netlib.h> -#include <netlib/netbase.h> -#include <netlib/icmp.h> +#include <netlib/tftp.h> +#include <netlib/dhcp.h> +#include <netlib/ethernet.h> +#include <netlib/ipv4.h> +#include <rtas.h> #include <stdio.h> +#include <string.h> #include <stdlib.h> #include <sys/socket.h> -#include <string.h> - -#include <rtas.h> int netflash(int argc, char * argv[]) { @@ -32,6 +32,7 @@ int netflash(int argc, char * argv[]) int fd_device; tftp_err_t tftp_err; char * ptr; + uint8_t own_mac[6]; printf("\n Flasher 1.4 \n"); memset(&fn_ip, 0, sizeof(filename_ip_t)); @@ -71,7 +72,7 @@ int netflash(int argc, char * argv[]) /* Get mac_addr from device */ printf(" Reading MAC address from device: "); - fd_device = socket(0, 0, 0, (char *) fn_ip.own_mac); + fd_device = socket(0, 0, 0, (char *) own_mac); if (fd_device == -1) { printf("\nE3000: Could not read MAC address\n"); return -100; @@ -82,11 +83,12 @@ int netflash(int argc, char * argv[]) } printf("%02x:%02x:%02x:%02x:%02x:%02x\n", - fn_ip.own_mac[0], fn_ip.own_mac[1], fn_ip.own_mac[2], - fn_ip.own_mac[3], fn_ip.own_mac[4], fn_ip.own_mac[5]); + own_mac[0], own_mac[1], own_mac[2], + own_mac[3], own_mac[4], own_mac[5]); + + // init ethernet layer + set_mac_address(own_mac); - // init network stack - netbase_init(fd_device, fn_ip.own_mac, fn_ip.own_ip); // identify the BOOTP/DHCP server via broadcasts // don't do this, when using DHCP !!! // fn_ip.server_ip = 0xFFFFFFFF; @@ -94,16 +96,11 @@ int netflash(int argc, char * argv[]) /* Get ip address for our mac address */ printf(" Requesting IP address via DHCP: "); - arp_failed = dhcp(fd_device, 0, &fn_ip, 30); + arp_failed = dhcp(0, &fn_ip, 30); if(arp_failed >= 0) { // reinit network stack - netbase_init(fd_device, fn_ip.own_mac, fn_ip.own_ip); - - if (!net_iptomac(fn_ip.server_ip, fn_ip.server_mac)) { - // printf("\nERROR:\t\t\tCan't obtain TFTP server MAC!\n"); - arp_failed = -2; - } + set_ipv4_address(fn_ip.own_ip); } if (arp_failed == -1) { @@ -133,7 +130,7 @@ int netflash(int argc, char * argv[]) strcpy((char *) fn_ip.filename,argv[3]); - rc = tftp (fd_device, &fn_ip, (unsigned char *) buffer, len, 20, &tftp_err, 0); + rc = tftp(&fn_ip, (unsigned char*) buffer, len, 20, &tftp_err, 0, 512, 4); dhcp_send_release(); diff --git a/clients/net-snk/app/netapps/ping.c b/clients/net-snk/app/netapps/ping.c index 9d98b24..5557baf 100644 --- a/clients/net-snk/app/netapps/ping.c +++ b/clients/net-snk/app/netapps/ping.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -10,14 +10,14 @@ * IBM Corporation - initial implementation *****************************************************************************/ -#include <netlib/icmp.h> -#include <netlib/arp.h> -#include <netlib/netlib.h> +#include <netlib/ipv4.h> +#include <netlib/dhcp.h> +#include <netlib/ethernet.h> #include <sys/socket.h> -#include <netlib/netbase.h> #include <string.h> #include <stdio.h> #include <stdlib.h> +#include <time.h> #include <netapps/args.h> struct ping_args { @@ -110,6 +110,7 @@ ping(int argc, char *argv[]) filename_ip_t fn_ip; int fd_device; struct ping_args ping_args; + uint8_t own_mac[6]; memset(&ping_args, 0, sizeof(struct ping_args)); @@ -127,7 +128,7 @@ ping(int argc, char *argv[]) /* Get mac_addr from device */ printf("\n Reading MAC address from device: "); - fd_device = socket(0, 0, 0, (char *) fn_ip.own_mac); + fd_device = socket(0, 0, 0, (char *) own_mac); if (fd_device == -1) { printf("\nE3000: Could not read MAC address\n"); return -100; @@ -137,11 +138,11 @@ ping(int argc, char *argv[]) } printf("%02x:%02x:%02x:%02x:%02x:%02x\n", - fn_ip.own_mac[0], fn_ip.own_mac[1], fn_ip.own_mac[2], - fn_ip.own_mac[3], fn_ip.own_mac[4], fn_ip.own_mac[5]); + own_mac[0], own_mac[1], own_mac[2], + own_mac[3], own_mac[4], own_mac[5]); - // init network stack - netbase_init(fd_device, fn_ip.own_mac, fn_ip.own_ip); + // init ethernet layer + set_mac_address(own_mac); // identify the BOOTP/DHCP server via broadcasts // don't do this, when using DHCP !!! // fn_ip.server_ip = 0xFFFFFFFF; @@ -150,7 +151,7 @@ ping(int argc, char *argv[]) if (!ping_args.client_ip.integer) { /* Get ip address for our mac address */ printf(" Requesting IP address via DHCP: "); - arp_failed = dhcp(fd_device, 0, &fn_ip, 30); + arp_failed = dhcp(0, &fn_ip, 30); if (arp_failed == -1) { printf("\n DHCP: Could not get ip address\n"); @@ -164,7 +165,7 @@ ping(int argc, char *argv[]) } // reinit network stack - netbase_init(fd_device, fn_ip.own_mac, fn_ip.own_ip); + set_ipv4_address(fn_ip.own_ip); printf("%d.%d.%d.%d\n", ((fn_ip.own_ip >> 24) & 0xFF), ((fn_ip.own_ip >> 16) & 0xFF), @@ -176,23 +177,17 @@ ping(int argc, char *argv[]) ((fn_ip.server_ip >> 8) & 0xFF), (fn_ip.server_ip & 0xFF)); - if (ping_args.gateway_ip.integer) { - if (!arp_getmac(ping_args.gateway_ip.integer, fn_ip.server_mac)) { - printf("failed\n"); - return -1; - } - } else { - if (!arp_getmac(fn_ip.server_ip, fn_ip.server_mac)) { - printf("failed\n"); - return -1; + ping_ipv4(fn_ip.server_ip); + + set_timer(TICKS_SEC / 10 * ping_args.timeout); + while(get_timer() > 0) { + receive_ether(); + if(pong_ipv4() == 0) { + printf("success\n"); + return 0; } } - if (!echo_request(fd_device, &fn_ip, ping_args.timeout)) { - printf("success\n"); - return 0; - } else { - printf("failed\n"); - return -1; - } + printf("failed\n"); + return -1; } diff --git a/clients/net-snk/app/netlib/Makefile b/clients/net-snk/app/netlib/Makefile index b88d06c..5b91470 100644 --- a/clients/net-snk/app/netlib/Makefile +++ b/clients/net-snk/app/netlib/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -18,7 +18,18 @@ include $(TOP)/make.rules CFLAGS += -I../ -OBJS = tftp.o netbase.o arp.o dns.o bootp.o dhcp.o icmp.o +ifeq ($(SNK_USE_MTFTP), 1) +CFLAGS += -DUSE_MTFTP +endif + +OBJS = ethernet.o ipv4.o udp.o tcp.o dns.o bootp.o \ + dhcp.o + +ifeq ($(SNK_USE_MTFTP), 1) +OBJS += mtftp.o +else +OBJS += tftp.o +endif all: netlib.o diff --git a/clients/net-snk/app/netlib/bootp.c b/clients/net-snk/app/netlib/bootp.c index b89f0bf..b1e97ed 100644 --- a/clients/net-snk/app/netlib/bootp.c +++ b/clients/net-snk/app/netlib/bootp.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -10,14 +10,17 @@ * IBM Corporation - initial implementation *****************************************************************************/ -#include <types.h> -#include <stdlib.h> + #include <stdio.h> #include <string.h> #include <sys/socket.h> -#include <netlib/netlib.h> #include <time.h> +#include <ethernet.h> +#include <ipv4.h> +#include <udp.h> +#include <dhcp.h> + #define DEBUG 0 static char * response_buffer; @@ -43,50 +46,35 @@ checksum(unsigned short *packet, int words) static int -send_bootp(int boot_device, filename_ip_t * fn_ip) +send_bootp(filename_ip_t * fn_ip) { +#if DEBUG int i; +#endif unsigned int packetsize = sizeof(struct iphdr) + sizeof(struct ethhdr) + sizeof(struct udphdr) + sizeof(struct btphdr); unsigned char packet[packetsize]; - struct ethhdr *ethh; struct iphdr *iph; struct udphdr *udph; struct btphdr *btph; - ethh = (struct ethhdr *) packet; - iph = (struct iphdr *) ((void *) ethh + sizeof(struct ethhdr)); - udph = (struct udphdr *) ((void *) iph + sizeof(struct iphdr)); - btph = (struct btphdr *) ((void *) udph + sizeof(struct udphdr)); + iph = (struct iphdr *) packet; + udph = (struct udphdr *) (iph + 1); + btph = (struct btphdr *) (udph + 1); memset(packet, 0, packetsize); - memcpy(ethh->src_mac, fn_ip->own_mac, 6); - memcpy(ethh->dest_mac, fn_ip->server_mac, 6); - - ethh->type = htons(ETHERTYPE_IP); - iph->ip_hlv = 0x45; - iph->ip_tos = 0; - iph->ip_len = htons(packetsize - sizeof(struct ethhdr)); - iph->ip_id = htons(54321); - iph->ip_off = 0; - iph->ip_ttl = 255; - iph->ip_p = IPTYPE_UDP; - iph->ip_src = fn_ip->own_ip; - iph->ip_dst = fn_ip->server_ip; - iph->ip_sum = - checksum((unsigned short *) iph, sizeof(struct iphdr) >> 1); - - udph->uh_sport = htons(UDPPORT_BOOTPC); - udph->uh_dport = htons(UDPPORT_BOOTPS); - udph->uh_ulen = htons(sizeof(struct udphdr) + sizeof(struct btphdr)); - udph->uh_sum = 0; + fill_iphdr((uint8_t *) iph, htons(packetsize - sizeof(struct ethhdr)), + IPTYPE_UDP, 0, fn_ip->server_ip); + fill_udphdr((uint8_t *) udph, + htons(sizeof(struct udphdr) + sizeof(struct btphdr)), + htons(UDPPORT_BOOTPC), htons(UDPPORT_BOOTPS)); btph->op = 1; btph->htype = 1; btph->hlen = 6; strcpy((char *) btph->file, "bla"); - memcpy(btph->chaddr, ethh->src_mac, 6); + memcpy(btph->chaddr, get_mac_address(), 6); #if DEBUG printf("Sending packet\n"); @@ -96,7 +84,7 @@ send_bootp(int boot_device, filename_ip_t * fn_ip) printf(".\n"); #endif - i = send(boot_device, packet, packetsize, 0); + send_ipv4(packet, iph->ip_len); #if DEBUG printf("%d bytes transmitted over socket.\n", i); #endif @@ -106,7 +94,7 @@ send_bootp(int boot_device, filename_ip_t * fn_ip) static int -receive_bootp(int boot_device, filename_ip_t * fn_ip) +receive_bootp(filename_ip_t * fn_ip) { int len, old_sum; unsigned int packetsize = 2000; @@ -118,8 +106,8 @@ receive_bootp(int boot_device, filename_ip_t * fn_ip) ethh = (struct ethhdr *) packet; iph = (struct iphdr *) (packet + sizeof(struct ethhdr)); - udph = (struct udphdr *) ((void *) iph + sizeof(struct iphdr)); - btph = (struct btphdr *) ((void *) udph + sizeof(struct udphdr)); + udph = (struct udphdr *) (iph + 1); + btph = (struct btphdr *) (udph + 1); memset(packet, 0, packetsize); @@ -129,7 +117,7 @@ receive_bootp(int boot_device, filename_ip_t * fn_ip) do { /* let's receive a packet */ - len = recv(boot_device, packet, packetsize, 0); + len = recv(0, packet, packetsize, 0); #if DEBUG int j; @@ -163,7 +151,7 @@ receive_bootp(int boot_device, filename_ip_t * fn_ip) if (btph->op != 2) continue; /* Comparing our mac address with the one in the bootp reply */ - if (memcmp(fn_ip->own_mac, btph->chaddr, ETH_ALEN)) + if (memcmp(get_mac_address(), btph->chaddr, ETH_ALEN)) continue; if(response_buffer) @@ -171,15 +159,14 @@ receive_bootp(int boot_device, filename_ip_t * fn_ip) fn_ip->own_ip = btph->yiaddr; fn_ip->server_ip = btph->siaddr; - memcpy(fn_ip->server_mac, ðh->src_mac, 6); strcpy((char *) fn_ip->filename, (char *) btph->file); #if DEBUG printf("\nThese are the details of the bootp reply:\n"); printf("Our IP address: "); - print_ip(&fn_ip->own_ip); + print_ip((char*) &fn_ip->own_ip); printf("Next server IP address: "); - print_ip(&fn_ip->server_ip); + print_ip((char*) &fn_ip->server_ip); printf("Boot file name: %s\n", btph->file); printf("Packet is: %s\n", btph->file); for (j = 0; j < len; j++) { @@ -189,14 +176,15 @@ receive_bootp(int boot_device, filename_ip_t * fn_ip) } printf(".\n"); printf("fn_ip->own_mac: %02x:%02x:%02x:%02x:%02x:%02x\n", - fn_ip->own_mac[0], fn_ip->own_mac[1], fn_ip->own_mac[2], - fn_ip->own_mac[3], fn_ip->own_mac[4], fn_ip->own_mac[5]); + get_mac_address()[0], get_mac_address()[1], + get_mac_address()[2], get_mac_address()[3], + get_mac_address()[4], get_mac_address()[5]); printf("Header ethh->dest_mac: %02x:%02x:%02x:%02x:%02x:%02x\n", - ethh->dest_mac[0], ethh->dest_mac[1], ethh->dest_mac[2], - ethh->dest_mac[3], ethh->dest_mac[4], ethh->dest_mac[5]); + ethh->dest_mac[0], ethh->dest_mac[1], ethh->dest_mac[2], + ethh->dest_mac[3], ethh->dest_mac[4], ethh->dest_mac[5]); printf("Header ethh->src_mac: %02x:%02x:%02x:%02x:%02x:%02x\n", - ethh->src_mac[0], ethh->src_mac[1], ethh->src_mac[2], - ethh->src_mac[3], ethh->src_mac[4], ethh->src_mac[5]); + ethh->src_mac[0], ethh->src_mac[1], ethh->src_mac[2], + ethh->src_mac[3], ethh->src_mac[4], ethh->src_mac[5]); printf("Header ethh->typ: %x\n",ethh->type); printf("Header iph->ip_hlv: %x\n",iph->ip_hlv); printf("Header iph->ip_len: %x\n",iph->ip_len); @@ -219,10 +207,9 @@ receive_bootp(int boot_device, filename_ip_t * fn_ip) printf("Header btph->siaddr: %x\n",btph->siaddr); printf("Header btph->giaddr: %x\n",btph->giaddr); - printf("Header btph->chaddr: %02x:%02x:%02x:%02x:%02x:%02x:\n", - btph->chaddr[0], btph->chaddr[1], btph->chaddr[2], - btph->chaddr[3], btph->chaddr[4], btph->chaddr[5]); - + printf("Header btph->chaddr: %02x:%02x:%02x:%02x:%02x:%02x:\n", + btph->chaddr[0], btph->chaddr[1], btph->chaddr[2], + btph->chaddr[3], btph->chaddr[4], btph->chaddr[5]); #endif return 0; @@ -234,7 +221,7 @@ receive_bootp(int boot_device, filename_ip_t * fn_ip) int -bootp(int boot_device, char *ret_buffer, filename_ip_t * fn_ip, unsigned int retries) +bootp(char *ret_buffer, filename_ip_t * fn_ip, unsigned int retries) { int i = (int) retries+1; fn_ip->own_ip = 0; @@ -250,12 +237,12 @@ bootp(int boot_device, char *ret_buffer, filename_ip_t * fn_ip, unsigned int ret retries+1); return -1; } - send_bootp(boot_device, fn_ip); + send_bootp(fn_ip); /* if the timer in receive_bootp expired it will return * -1 and we will just send another bootp request just * in case the previous one was lost. And because we don't * trust the network cable we keep on doing this 30 times */ - } while (receive_bootp(boot_device, fn_ip) != 0); + } while (receive_bootp(fn_ip) != 0); printf("\b\b\b"); return 0; } diff --git a/clients/net-snk/app/netlib/dhcp.c b/clients/net-snk/app/netlib/dhcp.c index 8f27cf6..8f81bf3 100644 --- a/clients/net-snk/app/netlib/dhcp.c +++ b/clients/net-snk/app/netlib/dhcp.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -43,17 +43,18 @@ /*>>>>>>>>>>>>>>>>>>>>> DEFINITIONS & DECLARATIONS <<<<<<<<<<<<<<<<<<<<<<*/ -#include <types.h> -#include <ctype.h> -#include <stdlib.h> +#include <dhcp.h> +#include <ethernet.h> +#include <ipv4.h> +#include <udp.h> +#include <dns.h> + #include <stdio.h> #include <string.h> -#include <sys/socket.h> -#include <netlib/netlib.h> -#include <netlib/netbase.h> -#include <netlib/arp.h> -#include <netlib/dns.h> #include <time.h> +#include <sys/socket.h> +#include <ctype.h> +#include <stdlib.h> /* DHCP Message Types */ #define DHCPDISCOVER 1 @@ -162,10 +163,7 @@ strtoip(int8_t * str, uint32_t * ip); /*>>>>>>>>>>>>>>>>>>>>>>>>>>>> LOCAL VARIABLES <<<<<<<<<<<<<<<<<<<<<<<<<<*/ static uint8_t ether_packet[ETH_MTU_SIZE]; -static int32_t dhcp_device_socket = 0; -static uint8_t dhcp_own_mac[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; static uint32_t dhcp_own_ip = 0; -static uint8_t dhcp_server_mac[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; static uint32_t dhcp_server_ip = 0; static uint32_t dhcp_siaddr_ip = 0; static int8_t dhcp_filename[256]; @@ -187,17 +185,14 @@ static char * response_buffer; * NON ZERO - error condition occurs. */ int32_t -dhcp(int32_t boot_device, char *ret_buffer, filename_ip_t * fn_ip, unsigned int retries) { +dhcp(char *ret_buffer, filename_ip_t * fn_ip, unsigned int retries) { int i = (int) retries+1; - uint8_t dhcp_tftp_mac[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint32_t dhcp_tftp_ip = 0; strcpy((char *) dhcp_filename, ""); strcpy((char *) dhcp_tftp_name, ""); response_buffer = ret_buffer; - dhcp_device_socket = boot_device; - memcpy(dhcp_own_mac, fn_ip -> own_mac, 6); printf(" "); @@ -224,15 +219,6 @@ dhcp(int32_t boot_device, char *ret_buffer, filename_ip_t * fn_ip, unsigned int strcpy((char *) dhcp_filename, (char *) fn_ip->filename); } - // Information from DHCP server were obtained - PRINT_MSGIP("\n\nClient IP:\t\t", dhcp_own_ip); - PRINT_MSGMAC("Client MAC:\t\t", dhcp_own_mac); - PRINT_MSGIP("\nDHCP Server IP:\t\t", dhcp_server_ip); - - // Obtain DHCP-server MAC to be able to send dhcp_release - net_iptomac(dhcp_server_ip, dhcp_server_mac); - PRINT_MSGMAC("DHCP Server MAC:\t", dhcp_server_mac); - // TFTP SERVER if (!strlen((char *) dhcp_tftp_name)) { if (!dhcp_siaddr_ip) { @@ -245,7 +231,6 @@ dhcp(int32_t boot_device, char *ret_buffer, filename_ip_t * fn_ip, unsigned int } else { // TFTP server defined by its name - NET_DEBUG_PRINTF("\nTFTP server name:\t%s\n", dhcp_tftp_name); if (!strtoip(dhcp_tftp_name, &(dhcp_tftp_ip))) { if (!dns_get_ip(dhcp_tftp_name, &(dhcp_tftp_ip))) { // DNS error - can't obtain TFTP-server name @@ -261,26 +246,9 @@ dhcp(int32_t boot_device, char *ret_buffer, filename_ip_t * fn_ip, unsigned int } } - PRINT_MSGIP("\nTFTP server IP:\t\t", dhcp_tftp_ip); - if (!net_iptomac(dhcp_tftp_ip, dhcp_tftp_mac)) { - // printf("\nERROR:\t\t\tCan't obtain TFTP server MAC!\n"); - return -2; - } - - PRINT_MSGMAC("TFTP server MAC:\t", dhcp_tftp_mac); - -// // Bootfile name -// if (!strlen(dhcp_filename)) { -// // ERROR: Bootfile name is not presented -// return -5; -// } - - NET_DEBUG_PRINTF("\nBootfile name:\t\t%s\n\n", dhcp_filename); - // Store configuration info into filename_ip strucutre fn_ip -> own_ip = dhcp_own_ip; fn_ip -> server_ip = dhcp_tftp_ip; - memcpy(fn_ip -> server_mac, dhcp_tftp_mac, 6); strcpy((char *) fn_ip -> filename, (char *) dhcp_filename); return 0; @@ -645,21 +613,20 @@ dhcp_combine_option(uint8_t dst_options[], uint32_t * dst_len, */ static void dhcp_send_discover(void) { - uint32_t packetsize = sizeof(struct ethhdr) + sizeof(struct iphdr) + + uint32_t packetsize = sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct btphdr); struct btphdr *btph; - uint8_t dest_mac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; dhcp_options_t opt; memset(ether_packet, 0, packetsize); - btph = (struct btphdr *) (ðer_packet[sizeof(struct ethhdr) + + btph = (struct btphdr *) (ðer_packet[ sizeof(struct iphdr) + sizeof(struct udphdr)]); btph -> op = 1; btph -> htype = 1; btph -> hlen = 6; - memcpy(btph -> chaddr, dhcp_own_mac, 6); + memcpy(btph -> chaddr, get_mac_address(), 6); memset(&opt, 0, sizeof(dhcp_options_t)); @@ -673,17 +640,14 @@ dhcp_send_discover(void) { dhcp_encode_options(btph -> vend, &opt); - fill_udphdr(ðer_packet[sizeof(struct ethhdr) + sizeof(struct iphdr)], + fill_udphdr(ðer_packet[sizeof(struct iphdr)], sizeof(struct btphdr) + sizeof(struct udphdr), UDPPORT_BOOTPC, UDPPORT_BOOTPS); - fill_iphdr(ðer_packet[sizeof(struct ethhdr)], sizeof(struct btphdr) + + fill_iphdr(ether_packet, sizeof(struct btphdr) + sizeof(struct udphdr) + sizeof(struct iphdr), IPTYPE_UDP, dhcp_own_ip, 0xFFFFFFFF); - fill_ethhdr(ðer_packet[0], ETHERTYPE_IP, dhcp_own_mac, dest_mac); - - PRINT_SENDING(ether_packet, packetsize); - send(dhcp_device_socket, ether_packet, packetsize, 0); + send_ipv4(ether_packet, packetsize); } /** @@ -691,21 +655,20 @@ dhcp_send_discover(void) { */ static void dhcp_send_request(void) { - uint32_t packetsize = sizeof(struct ethhdr) + sizeof(struct iphdr) + + uint32_t packetsize = sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct btphdr); struct btphdr *btph; - uint8_t dest_mac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; dhcp_options_t opt; memset(ether_packet, 0, packetsize); - btph = (struct btphdr *) (ðer_packet[sizeof(struct ethhdr) + + btph = (struct btphdr *) (ðer_packet[ sizeof(struct iphdr) + sizeof(struct udphdr)]); btph -> op = 1; btph -> htype = 1; btph -> hlen = 6; - memcpy(btph -> chaddr, dhcp_own_mac, 6); + memcpy(btph -> chaddr, get_mac_address(), 6); memset(&opt, 0, sizeof(dhcp_options_t)); @@ -723,17 +686,14 @@ dhcp_send_request(void) { dhcp_encode_options(btph -> vend, &opt); - fill_udphdr(ðer_packet[sizeof(struct ethhdr) + sizeof(struct iphdr)], + fill_udphdr(ðer_packet[sizeof(struct iphdr)], sizeof(struct btphdr) + sizeof(struct udphdr), UDPPORT_BOOTPC, UDPPORT_BOOTPS); - fill_iphdr(ðer_packet[sizeof(struct ethhdr)], sizeof(struct btphdr) + + fill_iphdr(ether_packet, sizeof(struct btphdr) + sizeof(struct udphdr) + sizeof(struct iphdr), IPTYPE_UDP, 0, 0xFFFFFFFF); - fill_ethhdr(ðer_packet[0], ETHERTYPE_IP, dhcp_own_mac, dest_mac); - PRINT_SENDING(ether_packet, packetsize); - - send(dhcp_device_socket, ether_packet, packetsize, 0); + send_ipv4(ether_packet, packetsize); } @@ -741,12 +701,12 @@ dhcp_send_request(void) { * DHCP: Sends DHCP-Release message. Releases occupied IP. */ void dhcp_send_release(void) { - uint32_t packetsize = sizeof(struct ethhdr) + sizeof(struct iphdr) + + uint32_t packetsize = sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct btphdr); struct btphdr *btph; dhcp_options_t opt; - btph = (struct btphdr *) (ðer_packet[sizeof(struct ethhdr) + + btph = (struct btphdr *) (ðer_packet[ sizeof(struct iphdr) + sizeof(struct udphdr)]); memset(ether_packet, 0, packetsize); @@ -755,7 +715,7 @@ void dhcp_send_release(void) { btph -> htype = 1; btph -> hlen = 6; strcpy((char *) btph -> file, ""); - memcpy(btph -> chaddr, dhcp_own_mac, 6); + memcpy(btph -> chaddr, get_mac_address(), 6); btph -> ciaddr = htonl(dhcp_own_ip); memset(&opt, 0, sizeof(dhcp_options_t)); @@ -766,17 +726,14 @@ void dhcp_send_release(void) { dhcp_encode_options(btph -> vend, &opt); - fill_udphdr(ðer_packet[sizeof(struct ethhdr) + sizeof(struct iphdr)], + fill_udphdr(ðer_packet[sizeof(struct iphdr)], sizeof(struct btphdr) + sizeof(struct udphdr), UDPPORT_BOOTPC, UDPPORT_BOOTPS); - fill_iphdr(ðer_packet[sizeof(struct ethhdr)], sizeof(struct btphdr) + + fill_iphdr(ether_packet, sizeof(struct btphdr) + sizeof(struct udphdr) + sizeof(struct iphdr), IPTYPE_UDP, dhcp_own_ip, dhcp_server_ip); - fill_ethhdr(ðer_packet[0], ETHERTYPE_IP, dhcp_own_mac, dhcp_server_mac); - - PRINT_SENDING(ether_packet, packetsize); - send(dhcp_device_socket, ether_packet, packetsize, 0); + send_ipv4(ether_packet, packetsize); } /** @@ -813,8 +770,6 @@ handle_dhcp(uint8_t * packet, int32_t packetsize) { if (memcmp(btph -> vend, dhcp_magic, 4)) { // It is BootP - RFC 951 - NET_DEBUG_PRINTF("WARNING:\t\tBooting via BootP 951\n"); - dhcp_own_ip = htonl(btph -> yiaddr); dhcp_siaddr_ip = htonl(btph -> siaddr); dhcp_server_ip = htonl(iph -> ip_src); @@ -887,8 +842,6 @@ handle_dhcp(uint8_t * packet, int32_t packetsize) { if (!opt.msg_type) { // It is BootP with Extensions - RFC 1497 - NET_DEBUG_PRINTF("WARNING:\t\tBooting via BootP 1497\n"); - // retrieve conf. settings from BootP - reply dhcp_own_ip = htonl(btph -> yiaddr); dhcp_siaddr_ip = htonl(btph -> siaddr); @@ -975,38 +928,20 @@ handle_dhcp(uint8_t * packet, int32_t packetsize) { // initialize network entity with real own_ip // to be able to answer for foreign requests - netbase_init(dhcp_device_socket, dhcp_own_mac, dhcp_own_ip); + set_ipv4_address(dhcp_own_ip); /* Subnet mask */ if (opt.flag[DHCP_MASK]) { /* Router */ if (opt.flag[DHCP_ROUTER]) { - if(net_setrouter(opt.router_IP, opt.subnet_mask) - == 0) { - // don't abort if ARP faild - // dhcp_state = DHCP_STATE_FAULT; - // return -1; - - // pretend like no router was specified - opt.flag[DHCP_ROUTER] = 0; - net_setrouter(0, opt.subnet_mask); - } + set_ipv4_router(opt.router_IP); + set_ipv4_netmask(opt.subnet_mask); } - - if (! opt.flag[DHCP_ROUTER]) { - NET_DEBUG_PRINTF("WARNING:\t\tRouter IP is not presented!\n"); - } - } - else { - NET_DEBUG_PRINTF("\nWARNING:\t\tSubnet mask is not presented!\n"); } /* DNS-server */ if (opt.flag[DHCP_DNS]) { - dns_init(dhcp_device_socket, dhcp_own_mac, dhcp_own_ip, opt.dns_IP); - } - else { - NET_DEBUG_PRINTF("WARNING:\t\tDomain Name Server IP is not presented!\n"); + dns_init(opt.dns_IP); } } diff --git a/clients/net-snk/app/netlib/dhcp.h b/clients/net-snk/app/netlib/dhcp.h index 5d0d636..853200c 100644 --- a/clients/net-snk/app/netlib/dhcp.h +++ b/clients/net-snk/app/netlib/dhcp.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -10,5 +10,44 @@ * IBM Corporation - initial implementation *****************************************************************************/ +#ifndef _DHCP_H_ +#define _DHCP_H_ + +#include <types.h> + +#ifdef USE_MTFTP +#include <netlib/mtftp.h> +#else +#include <netlib/tftp.h> +#endif + +/** \struct btphdr + * A header for BootP/DHCP-messages. + * For more information see RFC 951 / RFC 2131. + */ +struct btphdr { + uint8_t op; /**< Identifies is it request (1) or reply (2) */ + uint8_t htype; /**< HW address type (ethernet usually) */ + uint8_t hlen; /**< HW address length */ + uint8_t hops; /**< This info used by relay agents (not used) */ + uint32_t xid; /**< This ID is used to match queries and replies */ + uint16_t secs; /**< Unused */ + uint16_t unused; /**< Unused */ + uint32_t ciaddr; /**< Client IP address (if client knows it) */ + uint32_t yiaddr; /**< "Your" (client) IP address */ + uint32_t siaddr; /**< Next server IP address (TFTP server IP) */ + uint32_t giaddr; /**< Gateway IP address (used by relay agents) */ + uint8_t chaddr[16]; /**< Client HW address */ + uint8_t sname[64]; /**< Server host name (TFTP server name) */ + uint8_t file[128]; /**< Boot file name */ + uint8_t vend[64]; /**< Optional parameters field (DHCP-options) */ +}; + +int bootp(char *ret_buffer, filename_ip_t *, unsigned int); +int dhcp(char *ret_buffer, filename_ip_t *, unsigned int); +void dhcp_send_release(void); + /* Handles DHCP-packets, which are detected by receive_ether. */ extern int8_t handle_dhcp(uint8_t * packet, int32_t packetsize); + +#endif diff --git a/clients/net-snk/app/netlib/dns.c b/clients/net-snk/app/netlib/dns.c index d0eb7b0..5a931d5 100644 --- a/clients/net-snk/app/netlib/dns.c +++ b/clients/net-snk/app/netlib/dns.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -12,17 +12,15 @@ /*>>>>>>>>>>>>>>>>>>>>> DEFINITIONS & DECLARATIONS <<<<<<<<<<<<<<<<<<<<<<*/ -#include <types.h> -#include <ctype.h> -#include <stdlib.h> +#include <dns.h> #include <stdio.h> #include <string.h> -#include <sys/socket.h> -#include <netlib/netlib.h> -#include <netlib/netbase.h> -#include <netlib/arp.h> -#include <netlib/dns.h> #include <time.h> +#include <sys/socket.h> + +#include <ethernet.h> +#include <ipv4.h> +#include <udp.h> #define DNS_FLAG_MSGTYPE 0xF800 /**< Message type mask (opcode) */ #define DNS_FLAG_SQUERY 0x0000 /**< Standard query type */ @@ -83,10 +81,6 @@ hosttodomain(char * host_name, char * domain_name); /*>>>>>>>>>>>>>>>>>>>>>>>>>>> LOCAL VARIABLES <<<<<<<<<<<<<<<<<<<<<<<<<<<*/ static uint8_t ether_packet[ETH_MTU_SIZE]; -static int32_t dns_device_socket = 0; -static uint8_t dns_own_mac[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -static int32_t dns_own_ip = 0; -static uint8_t dns_server_mac[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; static int32_t dns_server_ip = 0; static int32_t dns_result_ip = 0; static int8_t dns_error = 0; /**< Stores error code or 0 */ @@ -100,32 +94,14 @@ static int8_t dns_domain_cname[0x100]; /**< Canonical domain name */ * To perfrom DNS-queries use the function dns_get_ip. * * @param device_socket a socket number used to send and recieve packets - * @param own_mac client hardware-address (MAC) - * @param own_ip client IPv4 address (e.g. 127.0.0.1) * @param server_ip DNS-server IPv4 address (e.g. 127.0.0.1) * @return TRUE in case of successful initialization; * FALSE in case of fault (e.g. can't obtain MAC). * @see dns_get_ip */ int8_t -dns_init(int32_t device_socket, uint8_t own_mac[], uint32_t own_ip, - uint32_t server_ip) { - dns_device_socket = device_socket; - memcpy(dns_own_mac, own_mac, 6); - dns_own_ip = own_ip; - dns_server_ip = server_ip; - - PRINT_MSGIP("\nDomain Name Server IP:\t", dns_server_ip); - if (net_iptomac(dns_server_ip, dns_server_mac)) { - PRINT_MSGMAC("DNS Server MAC:\t\t", dns_server_mac); - return 1; - } - - dns_server_ip = 0; - dns_own_ip = 0; - memset(dns_server_mac, 0, 6); - - NET_DEBUG_PRINTF("\nWARNING:\t\tCan't obtain DNS server MAC!\n"); +dns_init(uint32_t _dns_server_ip) { + dns_server_ip = _dns_server_ip; return 0; } @@ -174,15 +150,6 @@ dns_get_ip(int8_t * url, uint32_t * domain_ip) { "(DNS server is not presented)!\n"); return 0; } - if (dns_server_mac[0] == 0 && dns_server_mac[1] == 0 && - dns_server_mac[2] == 0 && dns_server_mac[3] == 0 && - dns_server_mac[4] == 0 && dns_server_mac[5] == 0) { - if(!net_iptomac(dns_server_ip, dns_server_mac)) { - printf("\nERROR:\t\t\tCan't resolve domain name " - "(DNS server is not presented)!\n"); - return 0; - } - } // Use DNS-server to obtain IP dns_result_ip = 0; @@ -245,7 +212,6 @@ handle_dns(uint8_t * packet, int32_t packetsize) { // Is error condition occurs? (check error field in incoming packet) if ((dnsh -> flags & htons(DNS_FLAG_RCODE)) != DNS_RCODE_NERROR) { - NET_DEBUG_PRINTF("\nERROR:\t\t\tDNS error - can't obtain IP!\n"); dns_error = 1; return 0; } @@ -317,27 +283,24 @@ static void dns_send_query(int8_t * domain_name) { int qry_len = strlen((char *) domain_name) + 5; - uint32_t packetsize = sizeof(struct iphdr) + sizeof(struct ethhdr) + + uint32_t packetsize = sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct dnshdr) + qry_len; memset(ether_packet, 0, packetsize); - fill_dnshdr(ðer_packet[sizeof(struct ethhdr) + + fill_dnshdr(ðer_packet[ sizeof(struct iphdr) + sizeof(struct udphdr)], domain_name); - fill_udphdr(ðer_packet[sizeof(struct ethhdr) + + fill_udphdr(ðer_packet[ sizeof(struct iphdr)], sizeof(struct dnshdr) + sizeof(struct udphdr) + qry_len, UDPPORT_DNSC, UDPPORT_DNSS); - fill_iphdr(ether_packet + sizeof(struct ethhdr), + fill_iphdr(ether_packet, sizeof(struct dnshdr) + sizeof(struct udphdr) + sizeof(struct iphdr) + qry_len, - IPTYPE_UDP, dns_own_ip, dns_server_ip); - fill_ethhdr(ether_packet, ETHERTYPE_IP, dns_own_mac, dns_server_mac); - - PRINT_SENDING(ether_packet, packetsize); + IPTYPE_UDP, 0, dns_server_ip); - send(dns_device_socket, ether_packet, packetsize, 0); + send_ipv4(ether_packet, packetsize); } /** diff --git a/clients/net-snk/app/netlib/dns.h b/clients/net-snk/app/netlib/dns.h index 5bf0f84..ef9f48e 100644 --- a/clients/net-snk/app/netlib/dns.h +++ b/clients/net-snk/app/netlib/dns.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -11,11 +11,18 @@ *****************************************************************************/ +#ifndef _DNS_H_ +#define _DNS_H_ + +#include <types.h> + /* Initialize the environment for DNS client. */ -extern int8_t dns_init(int32_t device_socket, uint8_t own_mac[], uint32_t own_ip, uint32_t server_ip); +extern int8_t dns_init(uint32_t dns_server_ip); /* For given URL retrieves IPv4 from DNS-server. */ extern int8_t dns_get_ip(int8_t * domain_name, uint32_t * domain_ip); /* Handles DNS-packets, which are detected by receive_ether. */ extern int32_t handle_dns(uint8_t * packet, int32_t packetsize); + +#endif diff --git a/clients/net-snk/app/netlib/ethernet.c b/clients/net-snk/app/netlib/ethernet.c new file mode 100644 index 0000000..cc77457 --- /dev/null +++ b/clients/net-snk/app/netlib/ethernet.c @@ -0,0 +1,186 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + + +/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ALGORITHMS <<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ + +/** \file netbase.c <pre> + * *********************** Receive-handle diagram ************************* + * + * Note: Every layer calls out required upper layer + * + * lower + * | MAC/LLC Receive packet (receive_ether) + * | | + * | NETWORK +-----------+---------+ + * | | | + * | IPv4 (handle_ipv4) IPv6 (handle_ipv4) + * | ARP (handle_arp) ICMP & NDP + * | ICMP | + * | | | + * | +---------+---------+ + * | | + * | TRANSPORT +---------+---------+ + * | | | + * | TCP (handle_tcp) UDP (handle_udp) + * | | + * | APPLICATION +----------------+-----------+ + * V | | + * upper DNS (handle_dns) BootP / DHCP (handle_bootp_client) + * + * ************************************************************************ + * </pre> */ + + +/*>>>>>>>>>>>>>>>>>>>>>>> DEFINITIONS & DECLARATIONS <<<<<<<<<<<<<<<<<<<<*/ + +#include <ethernet.h> +#include <string.h> +#include <sys/socket.h> +#include <ipv4.h> +//#include <ipv6.h> + + +/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>> LOCAL VARIABLES <<<<<<<<<<<<<<<<<<<<<<<<<*/ + +static uint8_t ether_packet[ETH_MTU_SIZE]; +static uint8_t own_mac[6] = {0, 0, 0, 0, 0, 0}; +static uint8_t multicast_mac[] = {0x01, 0x00, 0x5E}; +static const uint8_t broadcast_mac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + +/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IMPLEMENTATION <<<<<<<<<<<<<<<<<<<<<<<<<<*/ + +/** + * Ethernet: Set the own MAC address to initializes ethernet layer. + * + * @param own_mac own hardware-address (MAC) + */ +void +set_mac_address(const uint8_t * _own_mac) { + if (_own_mac) + memcpy(own_mac, _own_mac, 6); + else + memset(own_mac, 0, 6); +} + +/** + * Ethernet: Set the own MAC address to initializes ethernet layer. + * + * @return own hardware-address (MAC) + */ +const uint8_t * +get_mac_address(void) { + return own_mac; +} + +/** + * Ethernet: Check if given multicast address is a multicast MAC address + * starting with 0x3333 + * + * @return true or false + */ +static uint8_t +is_multicast_mac(uint8_t * mac) { + + uint16_t mc = 0x3333; + if (memcmp(mac, &mc, 2) == 0) + return 1; + + return 0; +} + + +/** + * Ethernet: Receives an ethernet-packet and handles it according to + * Receive-handle diagram. + * + * @return ZERO - packet was handled or no packets received; + * NON ZERO - error condition occurs. + */ +int32_t +receive_ether(void) { + int32_t bytes_received; + struct ethhdr * ethh; + + memset(ether_packet, 0, ETH_MTU_SIZE); + bytes_received = recv(0, ether_packet, ETH_MTU_SIZE, 0); + + if (!bytes_received) // No messages + return 0; + + if (bytes_received < sizeof(struct ethhdr)) + return -1; // packet is too small + + ethh = (struct ethhdr *) ether_packet; + + if(memcmp(ethh->dest_mac, broadcast_mac, 6) != 0 + && memcmp(ethh->dest_mac, multicast_mac, 3) != 0 + && memcmp(ethh->dest_mac, own_mac, 6 ) != 0 + && !is_multicast_mac(ethh->dest_mac)) + return -1; // packet is too small + + switch (htons(ethh -> type)) { + case ETHERTYPE_IP: + return handle_ipv4((uint8_t*) (ethh + 1), + bytes_received - sizeof(struct ethhdr)); +/* + case ETHERTYPE_IPv6: + return handle_ipv6(ether_packet + sizeof(struct ethhdr), + bytes_received - sizeof(struct ethhdr)); +*/ + case ETHERTYPE_ARP: + return handle_arp((uint8_t*) (ethh + 1), + bytes_received - sizeof(struct ethhdr)); + default: + break; + } + return -1; // unknown protocol +} + +/** + * Ethernet: Sends an ethernet frame via the initialized file descriptor. + * + * @return number of transmitted bytes + */ +int +send_ether(void* buffer, int len) +{ + return send(0, buffer, len, 0); +} + +/** + * Ethernet: Creates Ethernet-packet. Places Ethernet-header in a packet and + * fills it with corresponding information. + * <p> + * Use this function with similar functions for other network layers + * (fill_arphdr, fill_iphdr, fill_udphdr, fill_dnshdr, fill_btphdr). + * + * @param packet Points to the place where eth-header must be placed. + * @param eth_type Type of the next level protocol (e.g. IP or ARP). + * @param src_mac Sender MAC address + * @param dest_mac Receiver MAC address + * @see ethhdr + * @see fill_arphdr + * @see fill_iphdr + * @see fill_udphdr + * @see fill_dnshdr + * @see fill_btphdr + */ +void +fill_ethhdr(uint8_t * packet, uint16_t eth_type, + const uint8_t * src_mac, const uint8_t * dest_mac) { + struct ethhdr * ethh = (struct ethhdr *) packet; + + ethh -> type = htons(eth_type); + memcpy(ethh -> src_mac, src_mac, 6); + memcpy(ethh -> dest_mac, dest_mac, 6); +} diff --git a/clients/net-snk/app/netlib/ethernet.h b/clients/net-snk/app/netlib/ethernet.h new file mode 100644 index 0000000..e305a66 --- /dev/null +++ b/clients/net-snk/app/netlib/ethernet.h @@ -0,0 +1,47 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#ifndef _ETHERNET_H +#define _ETHERNET_H + +#include <types.h> + +#define ETH_MTU_SIZE 1518 /**< Maximum Transfer Unit */ +#define ETH_ALEN 6 /**< HW address length */ +#define ETHERTYPE_IP 0x0800 +#define ETHERTYPE_IPv6 0x86DD +#define ETHERTYPE_ARP 0x0806 + +/** \struct ethhdr + * A header for Ethernet-packets. + */ +struct ethhdr { + uint8_t dest_mac[ETH_ALEN]; /**< Destination HW address */ + uint8_t src_mac[ETH_ALEN]; /**< Source HW address */ + uint16_t type; /**< Next level protocol type */ +}; + +/* Initializes ethernet layer */ +extern void set_mac_address(const uint8_t * own_mac); +extern const uint8_t * get_mac_address(void); + +/* Receives and handles packets, according to Receive-handle diagram */ +extern int32_t receive_ether(void); + +/* Sends an ethernet frame. */ +extern int send_ether(void* buffer, int len); + +/* fills ethernet header */ +extern void fill_ethhdr(uint8_t * packet, uint16_t eth_type, + const uint8_t * src_mac, const uint8_t * dest_mac); + +#endif diff --git a/clients/net-snk/app/netlib/ipv4.c b/clients/net-snk/app/netlib/ipv4.c new file mode 100644 index 0000000..df18970 --- /dev/null +++ b/clients/net-snk/app/netlib/ipv4.c @@ -0,0 +1,871 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + + +/*>>>>>>>>>>>>>>>>>>>>> DEFINITIONS & DECLARATIONS <<<<<<<<<<<<<<<<<<<<<<*/ + +#include <ipv4.h> +#include <udp.h> +#include <tcp.h> +#include <ethernet.h> +#include <sys/socket.h> +#include <string.h> + +/* ARP Message types */ +#define ARP_REQUEST 1 +#define ARP_REPLY 2 + +/* ARP talbe size (+1) */ +#define ARP_ENTRIES 10 + +/* ICMP Message types */ +#define ICMP_ECHO_REPLY 0 +#define ICMP_DST_UNREACHABLE 3 +#define ICMP_SRC_QUENCH 4 +#define ICMP_REDIRECT 5 +#define ICMP_ECHO_REQUEST 8 +#define ICMP_TIME_EXCEEDED 11 +#define ICMP_PARAMETER_PROBLEM 12 +#define ICMP_TIMESTAMP_REQUEST 13 +#define ICMP_TIMESTAMP_REPLY 14 +#define ICMP_INFORMATION_REQUEST 15 +#define ICMP_INFORMATION_REPLY 16 + +/** \struct arp_entry + * A entry that describes a mapping between IPv4- and MAC-address. + */ +typedef struct arp_entry arp_entry_t; +struct arp_entry { + uint32_t ipv4_addr; + uint8_t mac_addr[6]; + uint8_t eth_frame[ETH_MTU_SIZE]; + int eth_len; +}; + +/** \struct icmphdr + * ICMP packet + */ +struct icmphdr { + unsigned char type; + unsigned char code; + unsigned short int checksum; + union { + /* for type 3 "Destination Unreachable" */ + unsigned int unused; + /* for type 0 and 8 */ + struct echo { + unsigned short int id; + unsigned short int seq; + } echo; + } options; + union { + /* payload for destination unreachable */ + struct dun { + unsigned char iphdr[20]; + unsigned char data[64]; + } dun; + /* payload for echo or echo reply */ + /* maximum size supported is 84 */ + unsigned char data[84]; + } payload; +}; + +/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PROTOTYPES <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ + +static unsigned short +checksum(unsigned short *packet, int words); + +static void +arp_send_request(uint32_t dest_ip); + +static void +arp_send_reply(uint32_t src_ip, uint8_t * src_mac); + +static void +fill_arphdr(uint8_t * packet, uint8_t opcode, + const uint8_t * src_mac, uint32_t src_ip, + const uint8_t * dest_mac, uint32_t dest_ip); + +static arp_entry_t* +lookup_mac_addr(uint32_t ipv4_addr); + +static void +fill_udp_checksum(struct iphdr *ipv4_hdr); + +static int8_t +handle_icmp(struct iphdr * iph, uint8_t * packet, int32_t packetsize); + +/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>> LOCAL VARIABLES <<<<<<<<<<<<<<<<<<<<<<<<<*/ + +/* Routing parameters */ +static uint32_t own_ip = 0; +static uint32_t multicast_ip = 0; +static uint32_t router_ip = 0; +static uint32_t subnet_mask = 0; + +/* helper variables */ +static uint32_t ping_dst_ip; +static const uint8_t null_mac_addr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +static const uint8_t broadcast_mac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static uint8_t multicast_mac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + +/* There are only (ARP_ENTRIES-1) effective entries because + * the entry that is pointed by arp_producer is never used. + */ +static unsigned int arp_consumer = 0; +static unsigned int arp_producer = 0; +static arp_entry_t arp_table[ARP_ENTRIES]; + +/* Function pointer send_ip. Points either to send_ipv4() or send_ipv6() */ +int (*send_ip) (void *, int); + +/*>>>>>>>>>>>>>>>>>>>>>>>>>>>> IMPLEMENTATION <<<<<<<<<<<<<<<<<<<<<<<<<<<*/ + +/** + * IPv4: Initialize the environment for the IPv4 layer. + */ +static void +ipv4_init(void) +{ + int i; + + ping_dst_ip = 0; + + // clear ARP table + arp_consumer = 0; + arp_producer = 0; + for(i=0; i<ARP_ENTRIES; ++i) { + arp_table[i].ipv4_addr = 0; + memset(arp_table[i].mac_addr, 0, 6); + arp_table[i].eth_len = 0; + } + + /* Set IP send function to send_ipv4() */ + send_ip = &send_ipv4; +} + +/** + * IPv4: Set the own IPv4 address. + * + * @param _own_ip client IPv4 address (e.g. 127.0.0.1) + */ +void +set_ipv4_address(uint32_t _own_ip) +{ + own_ip = _own_ip; + ipv4_init(); +} + +/** + * IPv4: Get the own IPv4 address. + * + * @return client IPv4 address (e.g. 127.0.0.1) + */ +uint32_t +get_ipv4_address(void) +{ + return own_ip; +} + +/** + * IPv4: Set the IPv4 multicast address. + * + * @param _own_ip multicast IPv4 address (224.0.0.0 - 239.255.255.255) + */ +void +set_ipv4_multicast(uint32_t _multicast_ip) +{ + // is this IP Multicast out of range (224.0.0.0 - 239.255.255.255) + if((htonl(_multicast_ip) < 0xE0000000) + || (htonl(_multicast_ip) > 0xEFFFFFFF)) { + multicast_ip = 0; + memset(multicast_mac, 0xFF, 6); + return; + } + + multicast_ip = _multicast_ip; + multicast_mac[0] = 0x01; + multicast_mac[1] = 0x00; + multicast_mac[2] = 0x5E; + multicast_mac[3] = (uint8_t) 0x7F & (multicast_ip >> 16); + multicast_mac[4] = (uint8_t) 0xFF & (multicast_ip >> 8); + multicast_mac[5] = (uint8_t) 0xFF & (multicast_ip >> 0); +} + +/** + * IPv4: Get the IPv4 multicast address. + * + * @return multicast IPv4 address (224.0.0.0 - 239.255.255.255 or 0 if not set) + */ +uint32_t +get_ipv4_multicast(void) +{ + return multicast_ip; +} + +/** + * IPv4: Set the routers IPv4 address. + * + * @param _router_ip router IPv4 address + */ +void +set_ipv4_router(uint32_t _router_ip) +{ + router_ip = _router_ip; + ipv4_init(); +} + +/** + * IPv4: Get the routers IPv4 address. + * + * @return router IPv4 address + */ +uint32_t +get_ipv4_router(void) +{ + return router_ip; +} + +/** + * IPv4: Set the subnet mask. + * + * @param _subnet_mask netmask of the own IPv4 address + */ +void +set_ipv4_netmask(uint32_t _subnet_mask) +{ + subnet_mask = _subnet_mask; + ipv4_init(); +} + +/** + * IPv4: Get the subnet mask. + * + * @return netmask of the own IPv4 address + */ +uint32_t +get_ipv4_netmask(void) +{ + return subnet_mask; +} + +/** + * IPv4: Creates IP-packet. Places IP-header in a packet and fills it + * with corresponding information. + * <p> + * Use this function with similar functions for other network layers + * (fill_ethhdr, fill_udphdr, fill_dnshdr, fill_btphdr). + * + * @param packet Points to the place where IP-header must be placed. + * @param packetsize Size of the packet in bytes incl. this hdr and data. + * @param ip_proto Type of the next level protocol (e.g. UDP). + * @param ip_src Sender IP address + * @param ip_dst Receiver IP address + * @see iphdr + * @see fill_ethhdr + * @see fill_udphdr + * @see fill_dnshdr + * @see fill_btphdr + */ +void +fill_iphdr(uint8_t * packet, uint16_t packetsize, + uint8_t ip_proto, uint32_t ip_src, uint32_t ip_dst) { + struct iphdr * iph = (struct iphdr *) packet; + + iph -> ip_hlv = 0x45; + iph -> ip_tos = 0x10; + iph -> ip_len = htons(packetsize); + iph -> ip_id = htons(0); + iph -> ip_off = 0; + iph -> ip_ttl = 0xFF; + iph -> ip_p = ip_proto; + iph -> ip_src = htonl(ip_src); + iph -> ip_dst = htonl(ip_dst); + iph -> ip_sum = 0; +} + +/** + * IPv4: Handles IPv4-packets according to Receive-handle diagram. + * + * @param ip_packet IP-packet to be handled + * @param packetsize Length of the packet + * @return ZERO - packet handled successfully; + * NON ZERO - packet was not handled (e.g. bad format) + * @see receive_ether + * @see iphdr + */ +int8_t +handle_ipv4(uint8_t * ip_packet, int32_t packetsize) +{ + struct iphdr * iph; + int32_t old_sum; + static uint8_t ip_heap[65536 + ETH_MTU_SIZE]; + + if (packetsize < sizeof(struct iphdr)) + return -1; // packet is too small + + iph = (struct iphdr * ) ip_packet; + + /* Drop it if destination IPv4 address is no IPv4 Broadcast, no + * registered IPv4 Multicast and not our Unicast address + */ + if((multicast_ip == 0 && iph->ip_dst >= 0xE0000000 && iph->ip_dst <= 0xEFFFFFFF) + || (multicast_ip != iph->ip_dst && iph->ip_dst != 0xFFFFFFFF && + own_ip != 0 && iph->ip_dst != own_ip)) { + return -1; + } + + old_sum = iph -> ip_sum; + iph -> ip_sum = 0; + if (old_sum != checksum((uint16_t *) iph, sizeof (struct iphdr) >> 1)) + return -1; // Wrong IP checksum + + // is it the first fragment in a packet? + if (((iph -> ip_off) & 0x1FFF) == 0) { + // is it part of more fragments? + if (((iph -> ip_off) & 0x2000) == 0x2000) { + memcpy(ip_heap, ip_packet, iph->ip_len); + return 0; + } + } + // it's not the first fragment + else { + // get the first fragment + struct iphdr * iph_first = (struct iphdr * ) ip_heap; + + // is this fragment not part of the first one, then exit + if ((iph_first->ip_id != iph->ip_id ) || + (iph_first->ip_p != iph->ip_p ) || + (iph_first->ip_src != iph->ip_src) || + (iph_first->ip_dst != iph->ip_dst)) { + return 0; + } + + // this fragment is part of the first one! + memcpy(ip_heap + sizeof(struct iphdr) + + ((iph -> ip_off) & 0x1FFF) * 8, + ip_packet + sizeof(struct iphdr), + iph -> ip_len - sizeof(struct iphdr)); + + // is it part of more fragments? Then return. + if (((iph -> ip_off) & 0x2000) == 0x2000) { + return 0; + } + + // packet is completly reassambled now! + + // recalculate ip_len and set iph and ip_packet to the + iph_first->ip_len = iph->ip_len + ((iph->ip_off) & 0x1FFF) * 8; + + // set iph and ip_packet to the resulting packet. + ip_packet = ip_heap; + iph = (struct iphdr * ) ip_packet; + } + + switch (iph -> ip_p) { + case IPTYPE_ICMP: + return handle_icmp(iph, ip_packet + sizeof(struct iphdr), + iph -> ip_len - sizeof(struct iphdr)); + case IPTYPE_UDP: + return handle_udp(ip_packet + sizeof(struct iphdr), + iph -> ip_len - sizeof(struct iphdr)); + case IPTYPE_TCP: + return handle_tcp(ip_packet + sizeof(struct iphdr), + iph -> ip_len - sizeof(struct iphdr)); + default: + break; + } + return -1; // Unknown protocol +} + +/** + * IPv4: Send IPv4-packets. + * + * Before the packet is sent there are some patcches performed: + * - IPv4 source address is replaced by our unicast IPV4 address + * if it is set to 0 or 1 + * - IPv4 destination address is replaced by our multicast IPV4 address + * if it is set to 1 + * - IPv4 checksum is calculaded. + * - If payload type is UDP, then the UDP checksum is calculated also. + * + * We sent an ARP request first, if this is the first packet sent to + * the declared IPv4 destination address. In this case we store the + * the packet and sent it later if we receive the ARP response. + * If the MAC address is known already, then we send the packet immediatly. + * If there is already an ARP request pending, then we drop this packet + * and send again an ARP request. + * + * @param ip_packet IP-packet to be handled + * @param packetsize Length of the packet + * @return -2 - packet dropped (MAC address not resolved - ARP request pending) + * -1 - packet dropped (bad format) + * 0 - packet stored (ARP request sent - packet will be sent if + * ARP response is received) + * >0 - packet send (number of transmitted bytes is returned) + * + * @see receive_ether + * @see iphdr + */ +int +send_ipv4(void* buffer, int len) +{ + arp_entry_t *arp_entry; + struct iphdr *ip; + const uint8_t *mac_addr = 0; + + if(len + sizeof(struct ethhdr) > ETH_MTU_SIZE) + return -1; + + ip = (struct iphdr *) buffer; + + /* Replace source IPv4 address with our own unicast IPv4 address + * if it's 0 (= own unicast source address not specified). + */ + if(ip->ip_src == 0) { + ip->ip_src = htonl( own_ip ); + } + /* Replace source IPv4 address with our unicast IPv4 address and + * replace destination IPv4 address with our multicast IPv4 address + * if source address is set to 1. + */ + else if(ip->ip_src == 1) { + ip->ip_src = htonl( own_ip ); + ip->ip_dst = htonl( multicast_ip ); + } + + // Calculate the IPv4 checksum + ip->ip_sum = 0; + ip->ip_sum = checksum((uint16_t *) ip, sizeof (struct iphdr) >> 1); + + // if payload type is UDP, then we need to calculate the + // UDP checksum that depends on the IP header + if(ip->ip_p == IPTYPE_UDP) { + fill_udp_checksum(ip); + } + + // Check if the MAC address is already cached + if(~ip->ip_dst == 0 + || ( ((~subnet_mask) & ip->ip_dst) == ~subnet_mask && + ( subnet_mask & ip->ip_dst) == (subnet_mask & own_ip))) { + arp_entry = &arp_table[arp_producer]; + mac_addr = broadcast_mac; + } + else if(ip->ip_dst == multicast_ip) { + arp_entry = &arp_table[arp_producer]; + mac_addr = multicast_mac; + } + else { + // Check if IP address is in the same subnet as we are + if((subnet_mask & own_ip) == (subnet_mask & ip->ip_dst)) + arp_entry = lookup_mac_addr(ip->ip_dst); + // if not then we need to know the router's IP address + else + arp_entry = lookup_mac_addr(router_ip); + if(arp_entry && memcmp(arp_entry->mac_addr, null_mac_addr, 6) != 0) + mac_addr = arp_entry->mac_addr; + } + + // If we could not resolv the MAC address by our own... + if(!mac_addr) { + // send the ARP request + arp_send_request(ip->ip_dst); + + // drop the current packet if there is already a ARP request pending + if(arp_entry) + return -2; + + // take the next entry in the ARP table to prepare a the new ARP entry. + arp_entry = &arp_table[arp_producer]; + arp_producer = (arp_producer+1)%ARP_ENTRIES; + + // if ARP table is full then we must drop the oldes entry. + if(arp_consumer == arp_producer) + arp_consumer = (arp_consumer+1)%ARP_ENTRIES; + + // store the packet to be send if the ARP reply is received + arp_entry->ipv4_addr = ip->ip_dst; + memset(arp_entry->mac_addr, 0, 6); + fill_ethhdr (arp_entry->eth_frame, htons(ETHERTYPE_IP), + get_mac_address(), null_mac_addr); + memcpy(&arp_entry->eth_frame[sizeof(struct ethhdr)], + buffer, len); + arp_entry->eth_len = len + sizeof(struct ethhdr); + + return 0; + } + + // Send the packet with the known MAC address + fill_ethhdr(arp_entry->eth_frame, htons(ETHERTYPE_IP), + get_mac_address(), mac_addr); + memcpy(&arp_entry->eth_frame[sizeof(struct ethhdr)], buffer, len); + return send_ether(arp_entry->eth_frame, len + sizeof(struct ethhdr)); +} + +/** + * IPv4: Calculate UDP checksum. Places the result into the UDP-header. + * <p> + * Use this function after filling the UDP payload. + * + * @param ipv4_hdr Points to the place where IPv4-header starts. + */ + +static void +fill_udp_checksum(struct iphdr *ipv4_hdr) +{ + int i; + unsigned long checksum = 0; + struct iphdr ip_hdr; + char *ptr; + udp_hdr_t *udp_hdr; + + udp_hdr = (udp_hdr_t *) (ipv4_hdr + 1); + udp_hdr->uh_sum = 0; + + memset(&ip_hdr, 0, sizeof(struct iphdr)); + ip_hdr.ip_src = ipv4_hdr->ip_src; + ip_hdr.ip_dst = ipv4_hdr->ip_dst; + ip_hdr.ip_len = udp_hdr->uh_ulen; + ip_hdr.ip_p = ipv4_hdr->ip_p; + + ptr = (char*) udp_hdr; + for (i = 0; i < udp_hdr->uh_ulen; i+=2) + checksum += *((uint16_t*) &ptr[i]); + + ptr = (char*) &ip_hdr; + for (i = 0; i < sizeof(struct iphdr); i+=2) + checksum += *((uint16_t*) &ptr[i]); + + checksum = (checksum >> 16) + (checksum & 0xffff); + checksum += (checksum >> 16); + udp_hdr->uh_sum = ~checksum; +} + +/** + * IPv4: Calculates checksum for IP header. + * + * @param packet Points to the IP-header + * @param words Size of the packet in words incl. IP-header and data. + * @return Checksum + * @see iphdr + */ +static unsigned short +checksum(unsigned short * packet, int words) +{ + unsigned long checksum; + + for (checksum = 0; words > 0; words--) + checksum += *packet++; + checksum = (checksum >> 16) + (checksum & 0xffff); + checksum += (checksum >> 16); + + return ~checksum; +} + +static arp_entry_t* +lookup_mac_addr(uint32_t ipv4_addr) +{ + unsigned int i; + + for(i=arp_consumer; i != arp_producer; i = ((i+1)%ARP_ENTRIES) ) { + if(arp_table[i].ipv4_addr == ipv4_addr) + return &arp_table[i]; + } + return 0; +} + + +/** + * ARP: Sends an ARP-request package. + * For given IPv4 retrieves MAC via ARP (makes several attempts) + * + * @param dest_ip IP of the host which MAC should be obtained + */ +static void +arp_send_request(uint32_t dest_ip) +{ + arp_entry_t *arp_entry = &arp_table[arp_producer]; + + memset(arp_entry->eth_frame, 0, sizeof(struct ethhdr) + sizeof(struct arphdr)); + fill_arphdr(&arp_entry->eth_frame[sizeof(struct ethhdr)], ARP_REQUEST, + get_mac_address(), own_ip, broadcast_mac, dest_ip); + fill_ethhdr(arp_entry->eth_frame, ETHERTYPE_ARP, + get_mac_address(), broadcast_mac); + + send_ether(arp_entry->eth_frame, + sizeof(struct ethhdr) + sizeof(struct arphdr)); +} + +/** + * ARP: Sends an ARP-reply package. + * This package is used to serve foreign requests (in case IP in + * foreign request matches our host IP). + * + * @param src_ip requester IP address (foreign IP) + * @param src_mac requester MAC address (foreign MAC) + */ +static void +arp_send_reply(uint32_t src_ip, uint8_t * src_mac) +{ + arp_entry_t *arp_entry = &arp_table[arp_producer]; + + memset(arp_entry->eth_frame, 0, sizeof(struct ethhdr) + sizeof(struct arphdr)); + fill_ethhdr(arp_entry->eth_frame, ETHERTYPE_ARP, + get_mac_address(), src_mac); + fill_arphdr(&arp_entry->eth_frame[sizeof(struct ethhdr)], ARP_REPLY, + get_mac_address(), own_ip, src_mac, src_ip); + + send_ether(arp_entry->eth_frame, + sizeof(struct ethhdr) + sizeof(struct arphdr)); +} + +/** + * ARP: Creates ARP package. Places ARP-header in a packet and fills it + * with corresponding information. + * <p> + * Use this function with similar functions for other network layers + * (fill_ethhdr). + * + * @param packet Points to the place where ARP-header must be placed. + * @param opcode Identifies is it request (ARP_REQUEST) + * or reply (ARP_REPLY) package. + * @param src_mac sender MAC address + * @param src_ip sender IP address + * @param dest_mac receiver MAC address + * @param dest_ip receiver IP address + * @see arphdr + * @see fill_ethhdr + */ +static void +fill_arphdr(uint8_t * packet, uint8_t opcode, + const uint8_t * src_mac, uint32_t src_ip, + const uint8_t * dest_mac, uint32_t dest_ip) +{ + struct arphdr * arph = (struct arphdr *) packet; + + arph -> hw_type = htons(1); + arph -> proto_type = htons(ETHERTYPE_IP); + arph -> hw_len = 6; + arph -> proto_len = 4; + arph -> opcode = htons(opcode); + + memcpy(arph->src_mac, src_mac, 6); + arph->src_ip = htonl(src_ip); + memcpy(arph->dest_mac, dest_mac, 6); + arph->dest_ip = htonl(dest_ip); +} + +/** + * ARP: Handles ARP-messages according to Receive-handle diagram. + * Updates arp_table for outstanding ARP requests (see arp_getmac). + * + * @param packet ARP-packet to be handled + * @param packetsize length of the packet + * @return ZERO - packet handled successfully; + * NON ZERO - packet was not handled (e.g. bad format) + * @see arp_getmac + * @see receive_ether + * @see arphdr + */ +int8_t +handle_arp(uint8_t * packet, int32_t packetsize) +{ + struct arphdr * arph = (struct arphdr *) packet; + + if (packetsize < sizeof(struct arphdr)) + return -1; // Packet is too small + + if (arph -> hw_type != htons(1) || arph -> proto_type != htons(ETHERTYPE_IP)) + return -1; // Unknown hardware or unsupported protocol + + if (arph -> dest_ip != htonl(own_ip)) + return -1; // receiver IP doesn't match our IP + + switch(htons(arph -> opcode)) { + case ARP_REQUEST: + // foreign request + if(own_ip != 0) + arp_send_reply(htonl(arph->src_ip), arph -> src_mac); + return 0; // no error + case ARP_REPLY: { + unsigned int i; + // if it is not for us -> return immediately + if(memcmp(get_mac_address(), arph->dest_mac, 6)) { + return 0; // no error + } + + if(arph->src_ip == 0) { + // we are not interested for a MAC address if + // the IPv4 address is 0.0.0.0 or ff.ff.ff.ff + return -1; + } + + // now let's find the corresponding entry in the ARP table + + for(i=arp_consumer; i != arp_producer; i = ((i+1)%ARP_ENTRIES) ) { + if(arp_table[i].ipv4_addr == arph->src_ip) + break; + } + if(i == arp_producer || memcmp(arp_table[i].mac_addr, null_mac_addr, 6) != 0) { + // we have not asked to resolve this IPv4 address ! + return -1; + } + + memcpy(arp_table[i].mac_addr, arph->src_mac, 6); + + // do we have something to send + if(arp_table[i].eth_len > 0) { + struct ethhdr * ethh = (struct ethhdr *) arp_table[i].eth_frame; + memcpy(ethh -> dest_mac, arp_table[i].mac_addr, 6); + + send_ether(arp_table[i].eth_frame, arp_table[i].eth_len); + arp_table[i].eth_len = 0; + } + return 0; // no error + } + default: + break; + } + return -1; // Invalid message type +} + +/** + * ICMP: Send an ICMP Echo request to destination IPv4 address. + * This function does also set a global variable to the + * destination IPv4 address. If there is an ICMP Echo Reply + * received later then the variable is set back to 0. + * In other words, reading a value of 0 form this variable + * means that an answer to the request has been arrived. + * + * @param _ping_dst_ip destination IPv4 address + */ +void +ping_ipv4(uint32_t _ping_dst_ip) +{ + unsigned char packet[sizeof(struct iphdr) + sizeof(struct icmphdr)]; + struct icmphdr *icmp; + + ping_dst_ip = _ping_dst_ip; + + if(ping_dst_ip == 0) + return; + + fill_iphdr(packet, sizeof(struct iphdr) + sizeof(struct icmphdr), IPTYPE_ICMP, + 0, ping_dst_ip); + icmp = (struct icmphdr *) (packet + sizeof(struct iphdr)); + icmp->type = ICMP_ECHO_REQUEST; + icmp->code = 0; + icmp->checksum = 0; + icmp->options.echo.id = 0xd476; + icmp->options.echo.seq = 1; + + memset(icmp->payload.data, '*', sizeof(icmp->payload.data)); + + icmp->checksum = + checksum((unsigned short *) icmp, sizeof(struct icmphdr) >> 1); + send_ipv4(packet, sizeof(struct iphdr) + sizeof(struct icmphdr)); +} + +/** + * ICMP: Return host IPv4 address that we are waiting for a + * ICMP Echo reply message. If this value is 0 then we have + * received an reply. + * + * @return ping_dst_ip host IPv4 address + */ +uint32_t +pong_ipv4(void) +{ + return ping_dst_ip; +} + +/** + * ICMP: Handles ICMP-packets according to Receive-handle diagram. + * + * @param icmp_packet ICMP-packet to be handled + * @param packetsize Length of the packet + * @return ZERO - packet handled successfully; + * NON ZERO - packet was not handled (e.g. bad format) + * @see handle_ipv4 + */ +static int8_t +handle_icmp(struct iphdr * iph, uint8_t * packet, int32_t packetsize) +{ + struct icmphdr *icmp = (struct icmphdr *) packet; + + switch(icmp->type) { + case ICMP_ECHO_REPLY: + if (icmp->options.echo.id != 0xd476) + return -1; + if (icmp->options.echo.seq != 1) + return -1; + if(ping_dst_ip != iph->ip_src + || ping_dst_ip == 0) + return -1; + ping_dst_ip = 0; + break; + case ICMP_DST_UNREACHABLE: { + // We've got Destination Unreachable msg + // Inform corresponding upper network layers + struct iphdr * bad_iph = (struct iphdr * ) &icmp->payload; + + switch(bad_iph->ip_p) { + case IPTYPE_TCP: + handle_tcp_dun((uint8_t *) (bad_iph + 1), packetsize + - sizeof(struct icmphdr) + - sizeof(struct iphdr), icmp->code); + break; + case IPTYPE_UDP: + handle_udp_dun((uint8_t *) (bad_iph + 1), packetsize + - sizeof(struct icmphdr) + - sizeof(struct iphdr), icmp->code); + break; + } + break; + } + case ICMP_SRC_QUENCH: + break; + case ICMP_REDIRECT: + break; + case ICMP_ECHO_REQUEST: { + // We've got an Echo Request - answer with Echo Replay msg + unsigned char reply_packet[sizeof(struct iphdr) + packetsize]; + struct icmphdr *reply_icmph; + + fill_iphdr(reply_packet, sizeof(struct iphdr) + packetsize, + IPTYPE_ICMP, 0, iph->ip_src); + + reply_icmph = (struct icmphdr *) &reply_packet[sizeof(struct iphdr)]; + memcpy(reply_icmph, packet, packetsize); + reply_icmph -> type = ICMP_ECHO_REPLY; + reply_icmph -> checksum = 0; + reply_icmph->checksum = checksum((unsigned short *) reply_icmph, + sizeof(struct icmphdr) >> 1); + + send_ipv4(reply_packet, sizeof(struct iphdr) + packetsize); + break; + } + case ICMP_TIME_EXCEEDED: + break; + case ICMP_PARAMETER_PROBLEM: + break; + case ICMP_TIMESTAMP_REQUEST: + break; + case ICMP_TIMESTAMP_REPLY: + break; + case ICMP_INFORMATION_REQUEST: + break; + case ICMP_INFORMATION_REPLY: + break; + } + return 0; +} diff --git a/clients/net-snk/app/netlib/ipv4.h b/clients/net-snk/app/netlib/ipv4.h new file mode 100644 index 0000000..0e5a408 --- /dev/null +++ b/clients/net-snk/app/netlib/ipv4.h @@ -0,0 +1,96 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + + +#ifndef _IPV4_H_ +#define _IPV4_H_ + +#include <types.h> + +#define IPTYPE_ICMP 1 + +/** \struct iphdr + * A header for IP-packets. + * For more information see RFC 791. + */ +struct iphdr { + uint8_t ip_hlv; /**< Header length and version of the header */ + uint8_t ip_tos; /**< Type of Service */ + uint16_t ip_len; /**< Length in octets, inlc. this header and data */ + uint16_t ip_id; /**< ID is used to aid in assembling framents */ + uint16_t ip_off; /**< Info about fragmentation (control, offset) */ + uint8_t ip_ttl; /**< Time to Live */ + uint8_t ip_p; /**< Next level protocol type */ + uint16_t ip_sum; /**< Header checksum */ + uint32_t ip_src; /**< Source IP address */ + uint32_t ip_dst; /**< Destination IP address */ +}; +typedef struct iphdr ipv4_hdr_t; + +/* ICMP Error Codes */ +#define ICMP_NET_UNREACHABLE 0 +#define ICMP_HOST_UNREACHABLE 1 +#define ICMP_PROTOCOL_UNREACHABLE 2 +#define ICMP_PORT_UNREACHABLE 3 +#define ICMP_FRAGMENTATION_NEEDED 4 +#define ICMP_SOURCE_ROUTE_FAILED 5 + +/** \struct arphdr + * A header for ARP-messages, retains info about HW and proto addresses. + * For more information see RFC 826. + */ +struct arphdr { + uint16_t hw_type; /**< HW address space (1 for Ethernet) */ + uint16_t proto_type; /**< Protocol address space */ + uint8_t hw_len; /**< Byte length of each HW address */ + uint8_t proto_len; /**< Byte length of each proto address */ + uint16_t opcode; /**< Identifies is it request (1) or reply (2) */ + uint8_t src_mac[6]; /**< HW address of sender of this packet */ + uint32_t src_ip; /**< Proto address of sender of this packet */ + uint8_t dest_mac[6]; /**< HW address of target of this packet */ + uint32_t dest_ip; /**< Proto address of target of this packet */ +} __attribute((packed)); + +/*>>>>>>>>>>>>> Initialization of the IPv4 network layer. <<<<<<<<<<<<<*/ +extern void set_ipv4_address(uint32_t own_ip); +extern uint32_t get_ipv4_address(void); +extern void set_ipv4_multicast(uint32_t multicast_ip); +extern uint32_t get_ipv4_multicast(void); +extern void set_ipv4_router(uint32_t router_ip); +extern uint32_t get_ipv4_router(void); +extern void set_ipv4_netmask(uint32_t subnet_mask); +extern uint32_t get_ipv4_netmask(void); + +extern int (*send_ip) (void *, int); + +/* fills ip header */ +extern void fill_iphdr(uint8_t * packet, uint16_t packetsize, + uint8_t ip_proto, uint32_t ip_src, uint32_t ip_dst); + +/* Send a IPv4 packet. Adding the Ethernet-Header and resolving the + * MAC address is done transparent in the background if necessary. + */ +extern int send_ipv4(void* buffer, int len); + +/* Sends an ICMP Echo request to destination IPv4 address */ +extern void ping_ipv4(uint32_t _ping_dst_ip); + +/* Returns host IPv4 address that we are waiting for a response */ +extern uint32_t pong_ipv4(void); + +/* Handles IPv4-packets that are detected by receive_ether. */ +extern int8_t handle_ipv4(uint8_t * packet, int32_t packetsize); + +/* Handles ARP-packets that are detected by receive_ether. */ +extern int8_t handle_arp(uint8_t * packet, int32_t packetsize); + +#endif diff --git a/clients/net-snk/app/netlib/tcp.c b/clients/net-snk/app/netlib/tcp.c new file mode 100644 index 0000000..5511aa0 --- /dev/null +++ b/clients/net-snk/app/netlib/tcp.c @@ -0,0 +1,50 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +/*>>>>>>>>>>>>>>>>>>>>>>> DEFINITIONS & DECLARATIONS <<<<<<<<<<<<<<<<<<<<*/ + +#include <tcp.h> +#include <sys/socket.h> + + +/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>> LOCAL VARIABLES <<<<<<<<<<<<<<<<<<<<<<<<<*/ + +/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IMPLEMENTATION <<<<<<<<<<<<<<<<<<<<<<<<<<*/ + + +/** + * TCP: Handles TCP-packets according to Receive-handle diagram. + * + * @param tcp_packet TCP-packet to be handled + * @param packetsize Length of the packet + * @return ZERO - packet handled successfully; + * NON ZERO - packet was not handled (e.g. bad format) + */ +int8_t +handle_tcp(uint8_t * tcp_packet, int32_t packetsize) +{ + return -1; +} + + +/** + * NET: This function handles situation when "Destination unreachable" + * ICMP-error occurs during sending TCP-packet. + * + * @param err_code Error Code (e.g. "Host unreachable") + * @param packet original TCP-packet + * @param packetsize length of the packet + * @see handle_icmp + */ +void +handle_tcp_dun(uint8_t * tcp_packet, uint32_t packetsize, uint8_t err_code) { +} diff --git a/clients/net-snk/app/netlib/tcp.h b/clients/net-snk/app/netlib/tcp.h new file mode 100644 index 0000000..7d0c906 --- /dev/null +++ b/clients/net-snk/app/netlib/tcp.h @@ -0,0 +1,27 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#ifndef _TCP_H +#define _TCP_H + +#include <types.h> + +#define IPTYPE_TCP 6 + +/* Handles TCP-packets that are detected by any network layer. */ +extern int8_t handle_tcp(uint8_t * udp_packet, int32_t packetsize); + +/* Handles TCP related ICMP-Dest.Unreachable packets that are detected by + * the network layers. */ +extern void handle_tcp_dun(uint8_t * tcp_packet, uint32_t packetsize, uint8_t err_code); + +#endif diff --git a/clients/net-snk/app/netlib/tftp.c b/clients/net-snk/app/netlib/tftp.c index 017558e..e8e9d09 100644 --- a/clients/net-snk/app/netlib/tftp.c +++ b/clients/net-snk/app/netlib/tftp.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -10,17 +10,21 @@ * IBM Corporation - initial implementation *****************************************************************************/ +#include <tftp.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <sys/socket.h> -#include <netlib/netlib.h> -#include <netlib/icmp.h> +#include <ethernet.h> +#include <ipv4.h> +//#include <ipv6.h> +#include <udp.h> //#define __DEBUG__ +#define MAX_BLOCKSIZE 1428 #define BUFFER_LEN 2048 #define ACK_BUFFER_LEN 256 #define READ_BUFFER_LEN 256 @@ -41,6 +45,23 @@ #define ERROR 5 #define OACK 6 +/* Local variables */ +static unsigned char *buffer = NULL; +static unsigned short block = 0; +static unsigned short blocksize; +static char blocksize_str[6]; /* Blocksize string for read request */ +static int received_len = 0; +static int retries = 0; +static int huge_load; +static int len; +static int tftp_finished = 0; +static int lost_packets = 0; +static int tftp_errno = 0; +static int ip_version = 0; +static short port_number = -1; +static tftp_err_t *tftp_err; +static filename_ip_t *fn_ip; + /** * dump_package - Prints a package. * @@ -64,73 +85,51 @@ dump_package(unsigned char *buffer, unsigned int len) } #endif -/* UDP header checksum calculation */ - -static unsigned short -checksum(unsigned short *packet, int words, unsigned short *pseudo_ip) -{ - int i; - unsigned long checksum; - for (checksum = 0; words > 0; words--) - checksum += *packet++; - if (pseudo_ip) { - for (i = 0; i < 6; i++) - checksum += *pseudo_ip++; - } - checksum = (checksum >> 16) + (checksum & 0xffff); - checksum += (checksum >> 16); - return ~checksum; -} - - /** * send_rrq - Sends a read request package. - * - * @client: client IPv4 address (e.g. 127.0.0.1) - * @server: server IPv4 address (e.g. 127.0.0.1) - * @filename: name of the file which should be downloaded */ static void -send_rrq(int boot_device, filename_ip_t * fn_ip) +send_rrq(void) { - int i; + int ip_len = 0; + //int ip6_payload_len = 0; + unsigned short udp_len = 0; unsigned char mode[] = "octet"; unsigned char packet[READ_BUFFER_LEN]; - char *ptr; - struct ethhdr *ethh; - struct iphdr *ip; - struct udphdr *udph; - struct tftphdr *tftp; - struct pseudo_iphdr piph = { 0 }; + char *ptr = NULL; + struct iphdr *ip = NULL; + //struct ip6hdr *ip6 = NULL; + struct udphdr *udph = NULL; + struct tftphdr *tftp = NULL; memset(packet, 0, READ_BUFFER_LEN); - ethh = (struct ethhdr *) packet; - - memcpy(ethh->src_mac, fn_ip->own_mac, 6); - memcpy(ethh->dest_mac, fn_ip->server_mac, 6); - ethh->type = htons(ETHERTYPE_IP); - - ip = (struct iphdr *) ((unsigned char *) ethh + sizeof(struct ethhdr)); - ip->ip_hlv = 0x45; - ip->ip_tos = 0x00; - ip->ip_len = sizeof(struct iphdr) + sizeof(struct udphdr) - + strlen((char *) fn_ip->filename) + strlen((char *) mode) + 4 - + strlen("blksize") + strlen("1432") + 2; - ip->ip_id = 0x0; - ip->ip_off = 0x0000; - ip->ip_ttl = 60; - ip->ip_p = 17; - ip->ip_src = fn_ip->own_ip; - ip->ip_dst = fn_ip->server_ip; - ip->ip_sum = 0; - - udph = (struct udphdr *) (ip + 1); - udph->uh_sport = htons(2001); - udph->uh_dport = htons(69); - udph->uh_ulen = htons(sizeof(struct udphdr) + if (4 == ip_version) { + ip = (struct iphdr *) packet; + udph = (struct udphdr *) (ip + 1); + ip_len = sizeof(struct iphdr) + sizeof(struct udphdr) + + strlen((char *) fn_ip->filename) + strlen((char *) mode) + 4 + + strlen("blksize") + strlen(blocksize_str) + 2; + fill_iphdr ((uint8_t *) ip, ip_len, IPTYPE_UDP, 0, + fn_ip->server_ip); + } +/* + else if (6 == ip_version) { + ip6 = (struct ip6hdr *) packet; + udph = (struct udphdr *) (ip6 + 1); + ip6_payload_len = sizeof(struct udphdr) + + strlen((char *) fn_ip->filename) + strlen((char *) mode) + 4 + + strlen("blksize") + strlen(blocksize_str) + 2; + ip_len = sizeof(struct ip6hdr) + ip6_payload_len; + fill_ip6hdr ((uint8_t *) ip6, ip6_payload_len, IPTYPE_UDP, get_ipv6_address(), + &(fn_ip->server_ip6)); + + } +*/ + udp_len = htons(sizeof(struct udphdr) + strlen((char *) fn_ip->filename) + strlen((char *) mode) + 4 - + strlen("blksize") + strlen("1432") + 2); + + strlen("blksize") + strlen(blocksize_str) + 2); + fill_udphdr ((uint8_t *) udph, udp_len, htons(2001), htons(69)); tftp = (struct tftphdr *) (udph + 1); tftp->th_opcode = htons(RRQ); @@ -145,23 +144,12 @@ send_rrq(int boot_device, filename_ip_t * fn_ip) memcpy(ptr, "blksize", strlen("blksize") + 1); ptr += strlen("blksize") + 1; - memcpy(ptr, "1432", strlen("1432") + 1); + memcpy(ptr, blocksize_str, strlen(blocksize_str) + 1); - piph.ip_src = ip->ip_src; - piph.ip_dst = ip->ip_dst; - piph.ip_p = ip->ip_p; - piph.ip_ulen = udph->uh_ulen; + send_ip (packet, ip_len); - udph->uh_sum = 0; - udph->uh_sum = - checksum((unsigned short *) udph, udph->uh_ulen >> 1, - (unsigned short *) &piph); - - ip->ip_sum = - checksum((unsigned short *) ip, sizeof(struct iphdr) >> 1, 0); - i = send(boot_device, packet, ip->ip_len + sizeof(struct ethhdr), 0); #ifdef __DEBUG__ - printf("tftp RRQ %d bytes transmitted over socket.\n", i); + printf("tftp RRQ with %d bytes transmitted.\n", ip_len); #endif return; } @@ -169,68 +157,52 @@ send_rrq(int boot_device, filename_ip_t * fn_ip) /** * send_ack - Sends a acknowlege package. * - * @boot_device: - * @fn_ip: * @blckno: block number + * @dport: UDP destination port */ static void -send_ack(int boot_device, filename_ip_t * fn_ip, - int blckno, unsigned short dport) +send_ack(int blckno, unsigned short dport) { - int i; + int ip_len = 0; + //int ip6_payload_len = 0; + unsigned short udp_len = 0; unsigned char packet[ACK_BUFFER_LEN]; - struct ethhdr *ethh; - struct iphdr *ip; - struct udphdr *udph; - struct tftphdr *tftp; - struct pseudo_iphdr piph = { 0 }; + struct iphdr *ip = NULL; + //struct ip6hdr *ip6 = NULL; + struct udphdr *udph = NULL; + struct tftphdr *tftp = NULL; memset(packet, 0, ACK_BUFFER_LEN); - ethh = (struct ethhdr *) packet; - memcpy(ethh->src_mac, fn_ip->own_mac, 6); - memcpy(ethh->dest_mac, fn_ip->server_mac, 6); - ethh->type = htons(ETHERTYPE_IP); - - ip = (struct iphdr *) ((unsigned char *) ethh + sizeof(struct ethhdr)); - ip->ip_hlv = 0x45; - ip->ip_tos = 0x00; - ip->ip_len = sizeof(struct iphdr) + sizeof(struct udphdr) + 4; - ip->ip_id = 0; - ip->ip_off = 0x0000; - ip->ip_ttl = 60; - ip->ip_p = 17; - ip->ip_src = fn_ip->own_ip; - ip->ip_dst = fn_ip->server_ip; - - ip->ip_sum = 0; - - udph = (struct udphdr *) (ip + 1); - udph->uh_sport = htons(2001); - udph->uh_dport = htons(dport); - udph->uh_ulen = htons(sizeof(struct udphdr) + 4); + if (4 == ip_version) { + ip = (struct iphdr *) packet; + udph = (struct udphdr *) (ip + 1); + ip_len = sizeof(struct iphdr) + sizeof(struct udphdr) + 4; + fill_iphdr ((uint8_t *) ip, ip_len, IPTYPE_UDP, 0, + fn_ip->server_ip); + } +/* + else if (6 == ip_version) { + ip6 = (struct ip6hdr *) packet; + udph = (struct udphdr *) (ip6 + 1); + ip6_payload_len = sizeof(struct udphdr) + 4; + ip_len = sizeof(struct ethhdr) + sizeof(struct ip6hdr) + + ip6_payload_len; + fill_ip6hdr ((uint8_t *) ip6, ip6_payload_len, IPTYPE_UDP, get_ipv6_address(), + &(fn_ip->server_ip6)); + } +*/ + udp_len = htons(sizeof(struct udphdr) + 4); + fill_udphdr ((uint8_t *) udph, udp_len, htons(2001), htons(dport)); tftp = (struct tftphdr *) (udph + 1); tftp->th_opcode = htons(ACK); tftp->th_data = htons(blckno); - piph.ip_src = ip->ip_src; - piph.ip_dst = ip->ip_dst; - piph.ip_p = ip->ip_p; - piph.ip_ulen = udph->uh_ulen; - - udph->uh_sum = 0; - udph->uh_sum = - checksum((unsigned short *) udph, udph->uh_ulen >> 1, - (unsigned short *) &piph); - - ip->ip_sum = - checksum((unsigned short *) ip, sizeof(struct iphdr) >> 1, 0); - - i = send(boot_device, packet, ip->ip_len + sizeof(struct ethhdr), 0); + send_ip(packet, ip_len); #ifdef __DEBUG__ - printf("tftp ACK %d bytes transmitted over socket.\n", i); + printf("tftp ACK %d bytes transmitted.\n", ip_len); #endif return; @@ -239,120 +211,58 @@ send_ack(int boot_device, filename_ip_t * fn_ip, /** * send_error - Sends an error package. * - * @boot_device: socket handle - * @fn_ip: some OSI CEP-IDs * @error_code: Used sub code for error packet * @dport: UDP destination port */ static void -send_error(int boot_device, filename_ip_t * fn_ip, - int error_code, unsigned short dport) +send_error(int error_code, unsigned short dport) { - int i; + int ip_len = 0; + //int ip6_payload_len = 0; + unsigned short udp_len = 0; unsigned char packet[256]; - struct ethhdr *ethh; - struct iphdr *ip; - struct udphdr *udph; - struct tftphdr *tftp; - struct pseudo_iphdr piph = { 0 }; + //struct ip6hdr *ip6 = NULL; + struct iphdr *ip = NULL; + struct udphdr *udph = NULL; + struct tftphdr *tftp = NULL; memset(packet, 0, 256); - ethh = (struct ethhdr *) packet; - memcpy(ethh->src_mac, fn_ip->own_mac, 6); - memcpy(ethh->dest_mac, fn_ip->server_mac, 6); - ethh->type = htons(ETHERTYPE_IP); - - ip = (struct iphdr *) ((unsigned char *) ethh + sizeof(struct ethhdr)); - ip->ip_hlv = 0x45; - ip->ip_tos = 0x00; - ip->ip_len = sizeof(struct iphdr) + sizeof(struct udphdr) + 5; - ip->ip_id = 0; - ip->ip_off = 0x0000; - ip->ip_ttl = 60; - ip->ip_p = 17; - ip->ip_src = fn_ip->own_ip; - ip->ip_dst = fn_ip->server_ip; - - ip->ip_sum = 0; - - udph = (struct udphdr *) (ip + 1); - udph->uh_sport = htons(2001); - udph->uh_dport = htons(dport); - udph->uh_ulen = htons(sizeof(struct udphdr) + 5); + if (4 == ip_version) { + ip = (struct iphdr *) packet; + udph = (struct udphdr *) (ip + 1); + ip_len = sizeof(struct iphdr) + sizeof(struct udphdr) + 5; + fill_iphdr ((uint8_t *) ip, ip_len, IPTYPE_UDP, 0, + fn_ip->server_ip); + } +/* + else if (6 == ip_version) { + ip6 = (struct ip6hdr *) packet; + udph = (struct udphdr *) (ip6 + 1); + ip6_payload_len = sizeof(struct udphdr) + 5; + ip_len = sizeof(struct ethhdr) + sizeof(struct ip6hdr) + + ip6_payload_len; + fill_ip6hdr ((uint8_t *) ip6, ip6_payload_len, IPTYPE_UDP, get_ipv6_address(), + &(fn_ip->server_ip6)); + } +*/ + udp_len = htons(sizeof(struct udphdr) + 5); + fill_udphdr ((uint8_t *) udph, udp_len, htons(2001), htons(dport)); tftp = (struct tftphdr *) (udph + 1); tftp->th_opcode = htons(ERROR); tftp->th_data = htons(error_code); ((char *) &tftp->th_data)[2] = 0; - piph.ip_src = ip->ip_src; - piph.ip_dst = ip->ip_dst; - piph.ip_p = ip->ip_p; - piph.ip_ulen = udph->uh_ulen; - - udph->uh_sum = 0; - udph->uh_sum = - checksum((unsigned short *) udph, udph->uh_ulen >> 1, - (unsigned short *) &piph); - - ip->ip_sum = - checksum((unsigned short *) ip, sizeof(struct iphdr) >> 1, 0); - - i = send(boot_device, packet, ip->ip_len + sizeof(struct ethhdr), 0); + send_ip(packet, ip_len); #ifdef __DEBUG__ - printf("tftp ERROR %d bytes transmitted over socket.\n", i); + printf("tftp ERROR %d bytes transmitted.\n", ip_len); #endif return; } - -static int -send_arp_reply(int boot_device, filename_ip_t * fn_ip) -{ - int i; - unsigned int packetsize = sizeof(struct ethhdr) + sizeof(struct arphdr); - unsigned char packet[packetsize]; - struct ethhdr *ethh; - struct arphdr *arph; - - ethh = (struct ethhdr *) packet; - arph = (struct arphdr *) ((void *) ethh + sizeof(struct ethhdr)); - - memset(packet, 0, packetsize); - - memcpy(ethh->src_mac, fn_ip->own_mac, 6); - memcpy(ethh->dest_mac, fn_ip->server_mac, 6); - ethh->type = htons(ETHERTYPE_ARP); - - arph->hw_type = 1; - arph->proto_type = 0x800; - arph->hw_len = 6; - arph->proto_len = 4; - - memcpy(arph->src_mac, fn_ip->own_mac, 6); - arph->src_ip = fn_ip->own_ip; - - arph->dest_ip = fn_ip->server_ip; - - arph->opcode = 2; -#ifdef __DEBUG__ - printf("send arp reply\n"); -#endif -#if 0 - printf("Sending packet\n"); - printf("Packet is "); - for (i = 0; i < packetsize; i++) - printf(" %2.2x", packet[i]); - printf(".\n"); -#endif - - i = send(boot_device, packet, packetsize, 0); - return i; -} - static void print_progress(int urgent, int received_bytes) { @@ -397,8 +307,6 @@ get_blksize(unsigned char *buffer, unsigned int len) { unsigned char *orig = buffer; /* skip all headers until tftp has been reached */ - buffer += sizeof(struct ethhdr); - buffer += sizeof(struct iphdr); buffer += sizeof(struct udphdr); /* skip opc */ buffer += 2; @@ -424,242 +332,266 @@ get_blksize(unsigned char *buffer, unsigned int len) } /** - * this prints out some status characters + * Handle incoming tftp packets after read request was sent + * + * this function also prints out some status characters * \|-/ for each packet received * A for an arp packet * I for an ICMP packet * #+* for different unexpected TFTP packets (not very good) + * + * @param packet points to the UDP header of the packet + * @param len the length of the network packet + * @return ZERO if packet was handled successfully + * ERRORCODE if error occurred */ -static int -the_real_tftp(int boot_device, filename_ip_t * fn_ip, unsigned char *buffer, - int len, unsigned int retries, tftp_err_t * tftp_err, int huge_load) +int32_t +handle_tftp(uint8_t *packet, int32_t packetsize) { - int i, j = 0; - int received_len = 0; - struct ethhdr *ethh; - struct arphdr *arph; - - struct iphdr *ip; struct udphdr *udph; struct tftphdr *tftp; - struct icmphdr *icmp; - unsigned char packet[BUFFER_LEN]; - short port_number = -1; - unsigned short block = 0; - unsigned short blocksize = 512; - int lost_packets = 0; + /* buffer is only set if we are handling TFTP */ + if (buffer == NULL ) + return 0; - tftp_err->bad_tftp_packets = 0; - tftp_err->no_packets = 0; - - send_rrq(boot_device, fn_ip); - - printf(" Receiving data: "); - print_progress(-1, 0); - - set_timer(TICKS_SEC); - while (j++ < 0x100000) { - /* bad_tftp_packets are counted whenever we receive a TFTP packet - * which was not expected; if this gets larger than 'retries' - * we just exit */ - if (tftp_err->bad_tftp_packets > retries) { - return -40; - } - /* no_packets counts the times we have returned from recv() without - * any packet received; if this gets larger than 'retries' - * we also just exit */ - if (tftp_err->no_packets > retries) { - return -41; - } - /* don't wait longer than 0.5 seconds for packet to be recevied */ - do { - i = recv(boot_device, packet, BUFFER_LEN, 0); - if (i != 0) - break; - } while (get_timer() > 0); - - /* no packet received; no processing */ - if (i == 0) { - /* the server doesn't seem to retry let's help out a bit */ - if (tftp_err->no_packets > 4 && port_number != -1 - && block > 1) - send_ack(boot_device, fn_ip, block, - port_number); - tftp_err->no_packets++; - set_timer(TICKS_SEC); - continue; - } #ifndef __DEBUG__ - print_progress(0, received_len); + print_progress(0, received_len); #endif - ethh = (struct ethhdr *) packet; - arph = - (struct arphdr *) ((void *) ethh + sizeof(struct ethhdr)); - ip = (struct iphdr *) (packet + sizeof(struct ethhdr)); - udph = (struct udphdr *) ((void *) ip + sizeof(struct iphdr)); - tftp = - (struct tftphdr *) ((void *) udph + sizeof(struct udphdr)); - icmp = (struct icmphdr *) ((void *) ip + sizeof(struct iphdr)); - - if (memcmp(ethh->dest_mac, fn_ip->own_mac, 6) == 0) { - set_timer(TICKS_SEC); - tftp_err->no_packets = 0; - } + udph = (struct udphdr *) packet; + tftp = (struct tftphdr *) ((void *) udph + sizeof(struct udphdr)); + set_timer(TICKS_SEC); - if (ethh->type == htons(ETHERTYPE_ARP) && - arph->hw_type == 1 && - arph->proto_type == 0x800 && arph->opcode == 1) { - /* let's see if the arp request asks for our IP address - * else we will not answer */ - if (fn_ip->own_ip == arph->dest_ip) { #ifdef __DEBUG__ - printf("\bA "); + dump_package(packet, packetsize); #endif - send_arp_reply(boot_device, fn_ip); - } - continue; - } - /* check if packet is an ICMP packet */ - if (ip->ip_p == PROTO_ICMP) { -#ifdef __DEBUG__ - printf("\bI "); -#endif - i = handle_icmp(icmp); - if (i) - return i; + port_number = udph->uh_sport; + if (tftp->th_opcode == htons(OACK)) { + /* an OACK means that the server answers our blocksize request */ + blocksize = get_blksize(packet, packetsize); + if (!blocksize || blocksize > MAX_BLOCKSIZE) { + send_error(8, port_number); + tftp_errno = -8; + goto error; } - - /* only IPv4 UDP packets we want */ - if (ip->ip_hlv != 0x45 || ip->ip_p != 0x11) { + send_ack(0, port_number); + } else if (tftp->th_opcode == htons(ACK)) { + /* an ACK means that the server did not answers + * our blocksize request, therefore we will set the blocksize + * to the default value of 512 */ + blocksize = 512; + send_ack(0, port_number); + } else if ((unsigned char) tftp->th_opcode == ERROR) { #ifdef __DEBUG__ - printf("Unknown packet %x %x %x %x %x \n", ethh->type, - ip->ip_hlv, ip->ip_p, ip->ip_dst, fn_ip->own_ip); + printf("tftp->th_opcode : %x\n", tftp->th_opcode); + printf("tftp->th_data : %x\n", tftp->th_data); #endif - continue; + switch ( (uint8_t) tftp->th_data) { + case ENOTFOUND: + tftp_errno = -3; // ERROR: file not found + break; + case EACCESS: + tftp_errno = -4; // ERROR: access violation + break; + case EBADOP: + tftp_errno = -5; // ERROR: illegal TFTP operation + break; + case EBADID: + tftp_errno = -6; // ERROR: unknown transfer ID + break; + case ENOUSER: + tftp_errno = -7; // ERROR: no such user + break; + default: + tftp_errno = -1; // ERROR: unknown error } - - /* we only want packets for our own IP and broadcast UDP packets - * there will be probably never be a broadcast UDP TFTP packet - * but the RFC talks about it (crazy RFC) */ - if (!(ip->ip_dst == fn_ip->own_ip || ip->ip_dst == 0xFFFFFFFF)) - continue; -#ifdef __DEBUG__ - dump_package(packet, i); -#endif - - port_number = udph->uh_sport; - if (tftp->th_opcode == htons(OACK)) { - /* an OACK means that the server answers our blocksize request */ - blocksize = get_blksize(packet, i); - if (!blocksize || blocksize > 1432) { - send_error(boot_device, fn_ip, 8, port_number); - return -8; - } - send_ack(boot_device, fn_ip, 0, port_number); - } else if (tftp->th_opcode == htons(ACK)) { - /* an ACK means that the server did not answers - * our blocksize request, therefore we will set the blocksize - * to the default value of 512 */ - blocksize = 512; - send_ack(boot_device, fn_ip, 0, port_number); - } else if ((unsigned char) tftp->th_opcode == ERROR) { + goto error; + } else if (tftp->th_opcode == DATA) { + /* DATA PACKAGE */ + if (block + 1 == tftp->th_data) { + ++block; + } + else if( block == 0xffff && huge_load != 0 + && (tftp->th_data == 0 || tftp->th_data == 1) ) { + block = tftp->th_data; + } + else if (tftp->th_data == block) { #ifdef __DEBUG__ - printf("tftp->th_opcode : %x\n", tftp->th_opcode); - printf("tftp->th_data : %x\n", tftp->th_data); + printf + ("\nTFTP: Received block %x, expected block was %x\n", + tftp->th_data, block + 1); + printf("\b+ "); #endif - if ((unsigned char) tftp->th_data == ENOTFOUND) /* 1 */ - return -3; // ERROR: file not found - else if ((unsigned char) tftp->th_data == EACCESS) /* 2 */ - return -4; // ERROR: access violation - else if ((unsigned char) tftp->th_data == EBADOP) /* 4 */ - return -5; // ERROR: illegal TFTP operation - else if ((unsigned char) tftp->th_data == EBADID) /* 5 */ - return -6; // ERROR: unknown transfer ID - else if ((unsigned char) tftp->th_data == ENOUSER) /* 7 */ - return -7; // ERROR: no such user - return -1; // ERROR: unknown error - } else if (tftp->th_opcode == DATA) { - /* DATA PACKAGE */ - if (block + 1 == tftp->th_data) { - ++block; - } - else if( block == 0xffff && huge_load != 0 - && (tftp->th_data == 0 || tftp->th_data == 1) ) { - block = tftp->th_data; - } - else if (tftp->th_data == block) { + send_ack(tftp->th_data, port_number); + lost_packets++; + tftp_err->bad_tftp_packets++; + return 0; + } else if (tftp->th_data < block) { #ifdef __DEBUG__ - printf - ("\nTFTP: Received block %x, expected block was %x\n", - tftp->th_data, block + 1); - printf("\b+ "); + printf + ("\nTFTP: Received block %x, expected block was %x\n", + tftp->th_data, block + 1); + printf("\b* "); #endif - send_ack(boot_device, fn_ip, tftp->th_data, - port_number); - lost_packets++; - tftp_err->bad_tftp_packets++; - continue; - } else if (tftp->th_data < block) { + /* This means that an old data packet appears (again); + * this happens sometimes if we don't answer fast enough + * and a timeout is generated on the server side; + * as we already have this packet we just ignore it */ + tftp_err->bad_tftp_packets++; + return 0; + } else { + tftp_err->blocks_missed = block + 1; + tftp_err->blocks_received = tftp->th_data; + tftp_errno = -42; + goto error; + } + tftp_err->bad_tftp_packets = 0; + /* check if our buffer is large enough */ + if (received_len + udph->uh_ulen - 12 > len) { + tftp_errno = -2; + goto error; + } + memcpy(buffer + received_len, &tftp->th_data + 1, + udph->uh_ulen - 12); + send_ack(tftp->th_data, port_number); + received_len += udph->uh_ulen - 12; + /* Last packet reached if the payload of the UDP packet + * is smaller than blocksize + 12 + * 12 = UDP header (8) + 4 bytes TFTP payload */ + if (udph->uh_ulen < blocksize + 12) { + tftp_finished = 1; + return 0; + } + /* 0xffff is the highest block number possible + * see the TFTP RFCs */ + + if (block >= 0xffff && huge_load == 0) { + tftp_errno = -9; + goto error; + } + } else { #ifdef __DEBUG__ - printf - ("\nTFTP: Received block %x, expected block was %x\n", - tftp->th_data, block + 1); - printf("\b* "); + printf("Unknown packet %x\n", tftp->th_opcode); + printf("\b# "); #endif - /* This means that an old data packet appears (again); - * this happens sometimes if we don't answer fast enough - * and a timeout is generated on the server side; - * as we already have this packet we just ignore it */ - tftp_err->bad_tftp_packets++; - continue; - } else { - tftp_err->blocks_missed = block + 1; - tftp_err->blocks_received = tftp->th_data; - return -42; - } - - tftp_err->bad_tftp_packets = 0; - /* check if our buffer is large enough */ - if (received_len + udph->uh_ulen - 12 > len) - return -2; - memcpy(buffer + received_len, &tftp->th_data + 1, - udph->uh_ulen - 12); - send_ack(boot_device, fn_ip, tftp->th_data, - port_number); - received_len += udph->uh_ulen - 12; - /* Last packet reached if the payload of the UDP packet - * is smaller than blocksize + 12 - * 12 = UDP header (8) + 4 bytes TFTP payload */ - if (udph->uh_ulen < blocksize + 12) - break; - /* 0xffff is the highest block number possible - * see the TFTP RFCs */ - - if (block >= 0xffff && huge_load == 0) { - return -9; - } - } else { + tftp_err->bad_tftp_packets++; + return 0; + } + + return 0; + +error: #ifdef __DEBUG__ - printf("Unknown packet %x\n", tftp->th_opcode); - printf("\b# "); + printf("\nTFTP errno: %d\n", tftp_errno); #endif - tftp_err->bad_tftp_packets++; - continue; + tftp_finished = 1; + return tftp_errno; +} + +/** + * TFTP: This function handles situation when "Destination unreachable" + * ICMP-error occurs during sending TFTP-packet. + * + * @param err_code Error Code (e.g. "Host unreachable") + */ +void +handle_tftp_dun(uint8_t err_code) +{ + tftp_errno = - err_code - 10; + tftp_finished = 1; +} + +/** + * TFTP: Interface function to load files via TFTP. + * + * @param _fn_ip contains the following configuration information: + * client IP, TFTP-server IP, filename to be loaded + * @param _buffer destination buffer for the file + * @param _len size of destination buffer + * @param _retries max number of retries + * @param _tftp_err contains info about TFTP-errors (e.g. lost packets) + * @param _mode NON ZERO - multicast, ZERO - unicast + * @param _blocksize blocksize for DATA-packets + * @return ZERO - error condition occurs + * NON ZERO - size of received file + */ +int +tftp(filename_ip_t * _fn_ip, unsigned char *_buffer, int _len, + unsigned int _retries, tftp_err_t * _tftp_err, + int32_t _mode, int32_t _blocksize, int _ip_version) +{ + retries = _retries; + fn_ip = _fn_ip; + len = _len; + huge_load = _mode; + ip_version = _ip_version; + tftp_errno = 0; + tftp_err = _tftp_err; + tftp_err->bad_tftp_packets = 0; + tftp_err->no_packets = 0; + + /* Default blocksize must be 512 for TFTP servers + * which do not support the RRQ blocksize option */ + blocksize = 512; + + /* Prefered blocksize - used as option for the read request */ + if (_blocksize < 8) + _blocksize = 8; + else if (_blocksize > MAX_BLOCKSIZE) + _blocksize = MAX_BLOCKSIZE; + sprintf(blocksize_str, "%d", _blocksize); + + printf(" Receiving data: "); + print_progress(-1, 0); + + // Setting buffer to a non-zero address enabled handling of received TFTP packets. + buffer = _buffer; + + set_timer(TICKS_SEC); + send_rrq(); + + while (! tftp_finished) { + /* if timeout (no packet received) */ + if(get_timer() <= 0) { + /* the server doesn't seem to retry let's help out a bit */ + if (tftp_err->no_packets > 4 && port_number != -1 + && block > 1) + send_ack(block, port_number); + tftp_err->no_packets++; + set_timer(TICKS_SEC); + } + + /* handle received packets */ + receive_ether(); + + /* bad_tftp_packets are counted whenever we receive a TFTP packet + * which was not expected; if this gets larger than 'retries' + * we just exit */ + if (tftp_err->bad_tftp_packets > retries) { + tftp_errno = -40; + break; + } + + /* no_packets counts the times we have returned from receive_ether() + * without any packet received; if this gets larger than 'retries' + * we also just exit */ + if (tftp_err->no_packets > retries) { + tftp_errno = -41; + break; } } + + // Setting buffer to NULL disables handling of received TFTP packets. + buffer = NULL; + + if (tftp_errno) + return tftp_errno; + print_progress(-1, received_len); printf("\n"); if (lost_packets) printf("Lost ACK packets: %d\n", lost_packets); + return received_len; } - -int -tftp(int boot_device, filename_ip_t * fn_ip, unsigned char *buffer, int len, - unsigned int retries, tftp_err_t * tftp_err, int huge_load) -{ - return the_real_tftp(boot_device, fn_ip, buffer, len, retries, - tftp_err, huge_load); -} diff --git a/clients/net-snk/app/netlib/tftp.h b/clients/net-snk/app/netlib/tftp.h new file mode 100644 index 0000000..3f573b1 --- /dev/null +++ b/clients/net-snk/app/netlib/tftp.h @@ -0,0 +1,48 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + + +#ifndef _TFTP_H_ +#define _TFTP_H_ + +#include <types.h> +//#include <netlib/ipv6.h> + +struct tftphdr { + int16_t th_opcode; + uint16_t th_data; +}; + +typedef struct { + uint32_t own_ip; + //ip6_addr_t own_ip6; + uint32_t server_ip; + //ip6_addr_t server_ip6; + int8_t filename[256]; +} __attribute__ ((packed)) filename_ip_t ; + +typedef struct { + uint32_t bad_tftp_packets; + uint32_t no_packets; + uint32_t blocks_missed; + uint32_t blocks_received; +} tftp_err_t; + +int tftp(filename_ip_t *, unsigned char *, int, unsigned int, + tftp_err_t *, int32_t mode, int32_t blocksize, int ip_version); +int tftp_netsave(filename_ip_t *, uint8_t * buffer, int len, + int use_ci, unsigned int retries, tftp_err_t * tftp_err); + +int32_t handle_tftp(uint8_t *, int32_t); +void handle_tftp_dun(uint8_t err_code); + +#endif diff --git a/clients/net-snk/app/netlib/udp.c b/clients/net-snk/app/netlib/udp.c new file mode 100644 index 0000000..3bc20ef --- /dev/null +++ b/clients/net-snk/app/netlib/udp.c @@ -0,0 +1,153 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +/*>>>>>>>>>>>>>>>>>>>>>>> DEFINITIONS & DECLARATIONS <<<<<<<<<<<<<<<<<<<<*/ + +#include <udp.h> +#include <sys/socket.h> +#include <dhcp.h> +//#include <dhcpv6.h> +#include <dns.h> +#ifdef USE_MTFTP +#include <mtftp.h> +#else +#include <tftp.h> +#endif + + + +/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>> LOCAL VARIABLES <<<<<<<<<<<<<<<<<<<<<<<<<*/ + + +#ifdef USE_MTFTP + +uint16_t net_tftp_uport; +uint16_t net_mtftp_uport; + +void net_set_tftp_port(uint16_t tftp_port) { + net_tftp_uport = tftp_port; +} + +void net_set_mtftp_port(uint16_t tftp_port) { + net_mtftp_uport = tftp_port; +} + +#endif + +/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IMPLEMENTATION <<<<<<<<<<<<<<<<<<<<<<<<<<*/ + + +/** + * NET: Handles UDP-packets according to Receive-handle diagram. + * + * @param udp_packet UDP-packet to be handled + * @param packetsize Length of the packet + * @return ZERO - packet handled successfully; + * NON ZERO - packet was not handled (e.g. bad format) + * @see receive_ether + * @see udphdr + */ +int8_t +handle_udp(uint8_t * udp_packet, int32_t packetsize) { + struct udphdr * udph = (struct udphdr *) udp_packet; + + if (packetsize < sizeof(struct udphdr)) + return -1; // packet is too small + + switch (htons(udph -> uh_dport)) { + case UDPPORT_BOOTPC: + if (udph -> uh_sport == htons(UDPPORT_BOOTPS)) + return handle_dhcp(udp_packet + sizeof(struct udphdr), + packetsize - sizeof(struct udphdr)); + else + return -1; + case UDPPORT_DNSC: + if (udph -> uh_sport == htons(UDPPORT_DNSS)) + return handle_dns(udp_packet + sizeof(struct udphdr), + packetsize - sizeof(struct udphdr)); + else + return -1; +/* + case UDPPORT_DHCPV6C: + return handle_dhcpv6(udp_packet+sizeof(struct udphdr), + packetsize - sizeof(struct udphdr)); +*/ + case UDPPORT_TFTPC: +#ifdef USE_MTFTP + return handle_tftp(udp_packet + sizeof(struct udphdr), + packetsize - sizeof(struct udphdr)); +#else + return handle_tftp(udp_packet, packetsize); +#endif + default: +#ifdef USE_MTFTP + if (htons(udph -> uh_dport) == net_tftp_uport) + return handle_tftp(udp_packet + sizeof(struct udphdr), + packetsize - sizeof(struct udphdr)); + else if (htons(udph -> uh_dport) == net_mtftp_uport) + return handle_tftp(udp_packet + sizeof(struct udphdr), + packetsize - sizeof(struct udphdr)); +#endif + return -1; + } +} + +/** + * NET: This function handles situation when "Destination unreachable" + * ICMP-error occurs during sending UDP-packet. + * + * @param err_code Error Code (e.g. "Host unreachable") + * @param packet original UDP-packet + * @param packetsize length of the packet + * @see handle_icmp + */ +void +handle_udp_dun(uint8_t * udp_packet, uint32_t packetsize, uint8_t err_code) { + struct udphdr * udph = (struct udphdr *) udp_packet; + + if (packetsize < sizeof(struct udphdr)) + return; // packet is too small + + switch (htons(udph -> uh_sport)) { + case UDPPORT_TFTPC: + handle_tftp_dun(err_code); + break; + } +} + +/** + * NET: Creates UDP-packet. Places UDP-header in a packet and fills it + * with corresponding information. + * <p> + * Use this function with similar functions for other network layers + * (fill_ethhdr, fill_iphdr, fill_dnshdr, fill_btphdr). + * + * @param packet Points to the place where UDP-header must be placed. + * @param packetsize Size of the packet in bytes incl. this hdr and data. + * @param src_port UDP source port + * @param dest_port UDP destination port + * @see udphdr + * @see fill_ethhdr + * @see fill_iphdr + * @see fill_dnshdr + * @see fill_btphdr + */ +void +fill_udphdr(uint8_t * packet, uint16_t packetsize, + uint16_t src_port, uint16_t dest_port) { + struct udphdr * udph = (struct udphdr *) packet; + + udph -> uh_sport = htons(src_port); + udph -> uh_dport = htons(dest_port); + udph -> uh_ulen = htons(packetsize); + udph -> uh_sum = htons(0); +} diff --git a/clients/net-snk/app/netlib/udp.h b/clients/net-snk/app/netlib/udp.h new file mode 100644 index 0000000..0432f52 --- /dev/null +++ b/clients/net-snk/app/netlib/udp.h @@ -0,0 +1,58 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#ifndef _UDP_H +#define _UDP_H + +#include <types.h> + +#define IPTYPE_UDP 17 + +#define UDPPORT_BOOTPS 67 /**< UDP port of BootP/DHCP-server */ +#define UDPPORT_BOOTPC 68 /**< UDP port of BootP/DHCP-client */ +#define UDPPORT_DNSS 53 /**< UDP port of DNS-server */ +#define UDPPORT_DNSC 32769 /**< UDP port of DNS-client */ +#define UDPPORT_TFTPC 2001 /**< UDP port of TFTP-client */ +#define UDPPORT_DHCPV6C 546 /**< UDP port of DHCPv6-client */ + +/** \struct udphdr + * A header for UDP-packets. + * For more information see RFC 768. + */ +struct udphdr { + uint16_t uh_sport; /**< Source port */ + uint16_t uh_dport; /**< Destinantion port */ + uint16_t uh_ulen; /**< Length in octets, incl. this header and data */ + uint16_t uh_sum; /**< Checksum */ +}; +typedef struct udphdr udp_hdr_t; + +typedef int32_t *(*handle_upper_udp_t)(uint8_t *, int32_t); +typedef void *(*handle_upper_udp_dun_t)(uint8_t); + +/* Handles UDP-packets that are detected by any network layer. */ +extern int8_t handle_udp(uint8_t * udp_packet, int32_t packetsize); + +/* Handles UDP related ICMP-Dest.Unreachable packets that are detected by + * the network layers. */ +extern void handle_udp_dun(uint8_t * udp_packet, uint32_t packetsize, uint8_t err_code); + +/* fills udp header */ +extern void fill_udphdr(uint8_t *packet, uint16_t packetsize, + uint16_t src_port, uint16_t dest_port); + +#ifdef USE_MTFTP +extern void net_set_tftp_port(uint16_t tftp_port); +extern void net_set_mtftp_port(uint16_t tftp_port); +#endif + +#endif diff --git a/clients/net-snk/client.lds b/clients/net-snk/client.lds index 5943897..2ebf9d1 100644 --- a/clients/net-snk/client.lds +++ b/clients/net-snk/client.lds @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -15,7 +15,7 @@ OUTPUT_ARCH(powerpc:common64) ENTRY(_entry) SECTIONS { - .client 0xF000000: + .client 0xF000100: { __client_start = .; *(.text .stub .text.* .gnu.linkonce.t.*) diff --git a/clients/net-snk/include/crt0.h b/clients/net-snk/include/crt0.h index 4b8ee89..d8fce05 100644 --- a/clients/net-snk/include/crt0.h +++ b/clients/net-snk/include/crt0.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/include/endian.h b/clients/net-snk/include/endian.h index e57317d..b4b9a94 100644 --- a/clients/net-snk/include/endian.h +++ b/clients/net-snk/include/endian.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -14,7 +14,7 @@ #ifndef MY_ENDIAN_H #define MY_ENDIAN_H -#include "types.h" +#include <stdint.h> extern inline uint16_t bswap_16 (uint16_t x); extern inline uint32_t bswap_32 (uint32_t x); diff --git a/clients/net-snk/include/fcntl.h b/clients/net-snk/include/fcntl.h index 80b7846..69de2ce 100644 --- a/clients/net-snk/include/fcntl.h +++ b/clients/net-snk/include/fcntl.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/include/fileio.h b/clients/net-snk/include/fileio.h new file mode 100644 index 0000000..7c9a2b5 --- /dev/null +++ b/clients/net-snk/include/fileio.h @@ -0,0 +1,53 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#ifndef FILEIO_H +#define FILEIO_H +#include <sys/socket.h> + +struct snk_fileio_type; +typedef struct snk_fileio_type snk_fileio_t; + +#define FILEIO_TYPE_EMPTY 0 +#define FILEIO_TYPE_USED 1 + +typedef long (*fileio_read_t) + (snk_fileio_t *fileio, char *buf, long len); +typedef long (*fileio_write_t) + (snk_fileio_t *fileio, char *buf, long len); +typedef int (*fileio_ioctl_t) + (snk_fileio_t *fileio, int request, void *data); +typedef int (*fileio_bind_t) + (snk_fileio_t *fileio, const struct sockaddr *, long len); +typedef int (*fileio_connect_t) + (snk_fileio_t *fileio, const struct sockaddr *, long len); +typedef int (*fileio_close_t) + (snk_fileio_t *fileio); + +struct snk_fileio_type { + int type; + int idx; + + fileio_read_t read; + fileio_write_t write; + fileio_ioctl_t ioctl; + fileio_bind_t bind; + fileio_connect_t connect; + fileio_close_t close; + + void *data; +}; + +#define FILEIO_MAX 32 +extern snk_fileio_t fd_array[FILEIO_MAX]; + +#endif diff --git a/clients/net-snk/include/ioctl.h b/clients/net-snk/include/ioctl.h index 1991bfc..c993798 100644 --- a/clients/net-snk/include/ioctl.h +++ b/clients/net-snk/include/ioctl.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/include/kernel.h b/clients/net-snk/include/kernel.h index 531d82c..a7aff19 100644 --- a/clients/net-snk/include/kernel.h +++ b/clients/net-snk/include/kernel.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/include/macros.h b/clients/net-snk/include/macros.h index 9c86ea5..e8ad919 100644 --- a/clients/net-snk/include/macros.h +++ b/clients/net-snk/include/macros.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/include/netdriver_int.h b/clients/net-snk/include/netdriver_int.h index 68c1cc9..375f2c5 100644 --- a/clients/net-snk/include/netdriver_int.h +++ b/clients/net-snk/include/netdriver_int.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -13,11 +13,14 @@ #ifndef _NETDRIVER_INT_H #define _NETDRIVER_INT_H #include <stddef.h> +#include <unistd.h> /* ssize_t */ +#include <fileio.h> -/* Constants for different kinds of IOCTL requests - */ - -#define SIOCETHTOOL 0x1000 +#if defined(__GNUC__) && !defined(UNUSED) +# define UNUSED __attribute__((unused)) +#else +# define UNUSED +#endif typedef struct { unsigned int addr; @@ -37,21 +40,35 @@ typedef struct { unsigned int interrupt_line; } pci_config_t; -typedef int (*net_init_t) (pci_config_t * conf, char *mac_addr); -typedef int (*net_term_t) (pci_config_t * conf); -typedef int (*net_receive_t) (pci_config_t * conf, char *buffer, int len); -typedef int (*net_xmit_t) (pci_config_t * conf, char *buffer, int len); -typedef int (*net_ioctl_t) (pci_config_t * conf, int request, void *data); +#define MOD_TYPE_NETWORK 0 +#define MOD_TYPE_OTHER 1 + +typedef int (*mod_init_t) (void); +typedef int (*mod_term_t) (void); +typedef int (*mod_socket_t)(snk_fileio_t *, int dom, int type, int proto); +typedef int (*mod_open_t) (snk_fileio_t *, const char *, int); +typedef int (*mod_read_t) (char *, int); +typedef int (*mod_write_t) (char *, int); +typedef int (*mod_ioctl_t) (int, void *); typedef struct { int version; - net_init_t net_init; - net_term_t net_term; - net_receive_t net_receive; - net_xmit_t net_xmit; - net_ioctl_t net_ioctl; + int type; + int running; + void *link_addr; + mod_init_t init; + mod_term_t term; + mod_socket_t socket; + mod_open_t open; + mod_read_t read; + mod_write_t write; + mod_ioctl_t ioctl; + + char mac_addr[6]; } snk_module_t; +#define MODULES_MAX 10 +extern snk_module_t *snk_modules[MODULES_MAX]; typedef int (*print_t) (const char *, ...); typedef void (*us_delay_t) (unsigned int); @@ -61,11 +78,24 @@ typedef int (*pci_config_read_t) (long long puid, int size, typedef int (*pci_config_write_t) (long long puid, int size, int bus, int devfn, int offset, int value); typedef void *(*malloc_aligned_t) (size_t, int); +typedef void *(*malloc_t) (size_t); +typedef void (*free_t) (void *); +typedef int (*strcmp_t) (const char *, const char *); +typedef int (*snk_call_t) (int, char **); typedef unsigned int (*io_read_t) (void *, size_t); typedef int (*io_write_t) (void *, unsigned int, size_t); typedef unsigned int (*romfs_lookup_t) (const char *name, void **addr); typedef void (*translate_addr_t) (unsigned long *); +typedef int (*k_open_t) (const char *, int); +typedef int (*k_close_t) (int); +typedef ssize_t (*k_read_t) (int, void *, size_t); +typedef ssize_t (*k_write_t) (int, const void *, size_t); +typedef int (*k_ioctl_t) (int, int, void *); + +typedef void (*modules_remove_t) (int); +typedef snk_module_t *(*modules_load_t) (int); + typedef struct { int version; print_t print; @@ -73,15 +103,38 @@ typedef struct { ms_delay_t ms_delay; pci_config_read_t pci_config_read; pci_config_write_t pci_config_write; + malloc_t k_malloc; malloc_aligned_t k_malloc_aligned; + free_t k_free; + strcmp_t strcmp; + snk_call_t snk_call; io_read_t io_read; io_write_t io_write; romfs_lookup_t k_romfs_lookup; translate_addr_t translate_addr; + pci_config_t pci_conf; + k_open_t k_open; + k_close_t k_close; + k_read_t k_read; + k_write_t k_write; + k_ioctl_t k_ioctl; + modules_remove_t modules_remove; + modules_load_t modules_load; } snk_kernel_t; +/* Entry of module */ +snk_module_t *module_init(snk_kernel_t * snk_kernel_int, + pci_config_t * pciconf); -/* special structure and constants for IOCTL requests of type ETHTOOL + +/* + * Constants for different kinds of IOCTL requests + */ + +#define SIOCETHTOOL 0x1000 + +/* + * special structure and constants for IOCTL requests of type ETHTOOL */ #define ETHTOOL_GMAC 0x03 @@ -99,7 +152,8 @@ typedef struct { } ioctl_ethtool_version_t; -/* default structure and constants for IOCTL requests +/* + * default structure and constants for IOCTL requests */ #define IF_NAME_SIZE 0xFF @@ -113,7 +167,17 @@ typedef struct { } data; } ioctl_net_data_t; -/* Entry of module */ -snk_module_t *module_init(snk_kernel_t * snk_kernel_int, - pci_config_t * pciconf); +/* paflof */ +enum { + PAFLOF_GDEPTH, + PAFLOF_GIO_BEHAVIOR, + PAFLOF_GSTATUS, + PAFLOF_POP, + PAFLOF_PUSH, +}; +/* - clint */ +enum { + CLINT_EXECUTE +}; + #endif /* _NETDRIVER_INT_H */ diff --git a/clients/net-snk/include/of.h b/clients/net-snk/include/of.h index c638dd3..aced2d5 100644 --- a/clients/net-snk/include/of.h +++ b/clients/net-snk/include/of.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/include/pci.h b/clients/net-snk/include/pci.h index 4c2c18b..285a6d0 100644 --- a/clients/net-snk/include/pci.h +++ b/clients/net-snk/include/pci.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/include/rtas.h b/clients/net-snk/include/rtas.h index 5591050..ff579f4 100644 --- a/clients/net-snk/include/rtas.h +++ b/clients/net-snk/include/rtas.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/include/sys/socket.h b/clients/net-snk/include/sys/socket.h index 5c38e0a..83238be 100644 --- a/clients/net-snk/include/sys/socket.h +++ b/clients/net-snk/include/sys/socket.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -13,9 +13,36 @@ #ifndef _SOCKET_H #define _SOCKET_H +#include <stdint.h> #include "systemcall.h" +#define AF_PACKET 0 +#define AF_INET 1 +#define AF_INET6 2 + +#define SOCK_RAW 0 +#define SOCK_PACKET 1 +#define SOCK_DGRAM 2 +#define SOCK_STREAM 3 + +#define INADDR_ANY 0xFFFFFFFF + +#define IPPROTO_UDP 1 + +#define ETH_ALEN 6 /**< HW address length */ + +struct sockaddr { + uint16_t tra_port; + + uint16_t ipv4_proto; + uint32_t ipv4_addr; + + // protocol field is only used by "connect"-handler + uint16_t llc_proto; + uint8_t mac_addr[ETH_ALEN]; +}; + int socket(int, int, int, char *); int sendto(int, const void *, int, int, const void *, int); int send(int, void *, int, int); diff --git a/clients/net-snk/include/systemcall.h b/clients/net-snk/include/systemcall.h index 265d7d2..70aa92d 100644 --- a/clients/net-snk/include/systemcall.h +++ b/clients/net-snk/include/systemcall.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/include/time.h b/clients/net-snk/include/time.h index d57c2f9..206f5a4 100644 --- a/clients/net-snk/include/time.h +++ b/clients/net-snk/include/time.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/include/types.h b/clients/net-snk/include/types.h index 0036387..b5e5db3 100644 --- a/clients/net-snk/include/types.h +++ b/clients/net-snk/include/types.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -14,15 +14,7 @@ #ifndef _TYPES_H #define _TYPES_H -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; - -typedef signed char int8_t; -typedef signed short int16_t; -typedef signed int int32_t; -typedef signed long long int64_t; +#include <stdint.h> #ifndef u32 typedef unsigned int u32; diff --git a/clients/net-snk/kernel/Makefile b/clients/net-snk/kernel/Makefile index 73e8127..976d851 100644 --- a/clients/net-snk/kernel/Makefile +++ b/clients/net-snk/kernel/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -17,27 +17,15 @@ ifndef TOP endif include $(TOP)/make.rules -OBJS = entry.o init.o systemcall.o lowmem.o crt0.o endian.o timer.o -OBJDIRS = driver/net.o +OBJS = init.o systemcall.o crt0.o endian.o timer.o modules.o +OBJS2 = entry.o lowmem.o all: kernel.o -driver/net.o: - make -C driver - -kernel.o: subdirs $(OBJS) - $(LD) $(LDFLAGS) $(OBJDIRS) $(OBJS) -o $@ -r - -subdirs: - for dir in $(dir $(OBJDIRS)); do \ - $(MAKE) -C $$dir DIRECTORY=$(DIRECTORY)$$dir || exit 1; \ - done +kernel.o: $(OBJS) $(OBJS2) + $(LD) $(LDFLAGS) $(OBJS) $(OBJS2) -o $@ -r clean: $(RM) -f *.o *.a *.i - @for dir in $(dir $(OBJDIRS)); do \ - $(CLEAN); \ - $(MAKE) -C $$dir DIRECTORY=$(DIRECTORY)$$dir clean; \ - done include $(TOP)/make.depend diff --git a/clients/net-snk/kernel/crt0.c b/clients/net-snk/kernel/crt0.c index e3c443b..353bd95 100644 --- a/clients/net-snk/kernel/crt0.c +++ b/clients/net-snk/kernel/crt0.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/kernel/endian.c b/clients/net-snk/kernel/endian.c index 9748778..04182f5 100644 --- a/clients/net-snk/kernel/endian.c +++ b/clients/net-snk/kernel/endian.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/kernel/entry.S b/clients/net-snk/kernel/entry.S index 8db10af..c0c7a12 100644 --- a/clients/net-snk/kernel/entry.S +++ b/clients/net-snk/kernel/entry.S @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/kernel/init.c b/clients/net-snk/kernel/init.c index 76b35ed..8485f23 100644 --- a/clients/net-snk/kernel/init.c +++ b/clients/net-snk/kernel/init.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -11,41 +11,32 @@ *****************************************************************************/ #include <of.h> -#include <rtas.h> #include <pci.h> #include <kernel.h> -#include <types.h> +#include <stdint.h> #include <string.h> #include <cpu.h> +#include <fileio.h> +#include <stdlib.h> /* malloc */ +#include <ioctl.h> /* ioctl */ /* Application entry point .*/ extern int _start(unsigned char *arg_string, long len); +extern int main(int, char**); +void * malloc_aligned(size_t size, int align); +extern snk_module_t *insmod_by_type(int); +extern void rmmod_by_type(int); unsigned long exception_stack_frame; -ihandle_t fd_array[32]; -pci_config_t pci_device_array[32]; +snk_fileio_t fd_array[FILEIO_MAX]; extern uint64_t tb_freq; -void term_net_driver(void); - -static int -init_io() -{ - phandle_t chosen = of_finddevice("/chosen"); - - if (chosen == -1) - return -1; - - of_getprop(chosen, "stdin", &fd_array[0], sizeof(ihandle_t)); - of_getprop(chosen, "stdout", &fd_array[1], sizeof(ihandle_t)); - - if (of_write(fd_array[1], " ", 1) < 0) - return -2; - - return 0; -} +void modules_init(void); +void modules_term(void); +int glue_init(snk_kernel_t *, unsigned int *, size_t, size_t); +void glue_release(void); static char save_vector[0x4000]; extern char _lowmem_start; @@ -53,6 +44,35 @@ extern char _lowmem_end; extern char __client_start; extern char __client_end; +snk_kernel_t snk_kernel_interface = { + .version = 1, + .print = printk, + .us_delay = udelay, + .ms_delay = mdelay, + .k_malloc = malloc, + .k_malloc_aligned = malloc_aligned, + .k_free = free, + .strcmp = strcmp, + .snk_call = main, + .k_open = open, + .k_close = close, + .k_read = read, + .k_write = write, + .k_ioctl = ioctl, + .modules_remove = rmmod_by_type, + .modules_load = insmod_by_type, +}; + +void * +malloc_aligned(size_t size, int align) +{ + unsigned long p = (unsigned long) malloc(size + align - 1); + p = p + align - 1; + p = p & ~(align - 1); + + return (void *) p; +} + static void copy_exception_vectors() { @@ -85,84 +105,32 @@ restore_exception_vectors() flush_cache(dest, len); } -static long memory_size; - -static void -checkmemorysize() -{ - char buf[255]; - phandle_t ph; - memory_size = 0; - - struct reg { - long adr; - long size; - } reg; - - ph = of_peer(0); // begin from root-node - ph = of_child(ph); // get a child - - while (ph != 0) { - if (of_getprop(ph, "device_type", buf, 255) != -1) { - /* if device_type == memory */ - if (strcmp(buf, "memory") == 0) - if (of_getprop(ph, "reg", ®, 16) != -1) { - memory_size += reg.size; - } - } - ph = of_peer(ph); // get next siblings - } -} - -long -getmemsize() -{ - return memory_size; -} - -static void -get_timebase() -{ - unsigned int timebase; - phandle_t cpu; - phandle_t cpus = of_finddevice("/cpus"); - - if (cpus == -1) - return; - - cpu = of_child(cpus); - - if (cpu == -1) - return; - - of_getprop(cpu, "timebase-frequency", &timebase, 4); - tb_freq = (uint64_t) timebase; -} - int _start_kernel(unsigned long p0, unsigned long p1) { - int rc,claim_rc; - size_t _client_start = (size_t)&__client_start; - size_t _client_size = (size_t)&__client_end - (size_t)&__client_start; + int rc; + unsigned int timebase; - claim_rc=(int)(long)of_claim((void *)(long)_client_start, _client_size, 0); + /* initialize all file descriptor by marking them as empty */ + for(rc=0; rc<FILEIO_MAX; ++rc) { + fd_array[rc].type = FILEIO_TYPE_EMPTY; + fd_array[rc].idx = rc; + } - if (init_io() <= -1) + /* this is step is e.g. resposible to initialize file descriptor 0 and 1 for STDIO */ + rc = glue_init(&snk_kernel_interface, &timebase, (size_t)&__client_start, + (size_t)&__client_end - (size_t)&__client_start); + if(rc < 0) return -1; - copy_exception_vectors(); - checkmemorysize(); - get_timebase(); - rtas_init(); + tb_freq = (uint64_t) timebase; + copy_exception_vectors(); + modules_init(); rc = _start((unsigned char *) p0, p1); - - term_net_driver(); - + modules_term(); restore_exception_vectors(); - if (claim_rc >= 0) { - of_release((void *)(long)_client_start, _client_size); - } + + glue_release(); return rc; } diff --git a/clients/net-snk/kernel/lowmem.S b/clients/net-snk/kernel/lowmem.S index ad5127f..8d6cfc6 100644 --- a/clients/net-snk/kernel/lowmem.S +++ b/clients/net-snk/kernel/lowmem.S @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/kernel/modules.c b/clients/net-snk/kernel/modules.c new file mode 100644 index 0000000..9d4281c --- /dev/null +++ b/clients/net-snk/kernel/modules.c @@ -0,0 +1,208 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include <netdriver_int.h> +#include <kernel.h> +#include <of.h> +#include <rtas.h> +#include <cpu.h> /* flush_cache */ +//#include <stdlib.h> /* malloc */ +#include <unistd.h> /* open, close, read, write */ + +unsigned int read_io(void *, size_t); +int write_io(void *, unsigned int, size_t); + +extern void get_mac(char *mac); +extern snk_module_t of_module; + +typedef snk_module_t *(*module_init_t) (snk_kernel_t *, pci_config_t *); + +typedef struct { + const char *name; + void *link_addr; + int type; +} mod_descriptor_t; + +static const mod_descriptor_t modules[] = { + { "net_e1000" , (void*) 0xF800000, MOD_TYPE_NETWORK }, + { "net_bcm" , (void*) 0xF800000, MOD_TYPE_NETWORK }, + { "net_nx203x", (void*) 0xF800000, MOD_TYPE_NETWORK }, + { "net_mcmal" , (void*) 0xF800000, MOD_TYPE_NETWORK }, + { "net_spider", (void*) 0xF800000, MOD_TYPE_NETWORK }, + { "mod_paflof", (void*) 0x6200000, MOD_TYPE_OTHER }, + { 0 , (void*) 0 } +}; + +snk_module_t *snk_modules[MODULES_MAX]; + +extern snk_kernel_t snk_kernel_interface; + +/* Load module and call init code. + Init code will check, if module is responsible for device. + Returns -1, if not responsible for device, 0 otherwise. +*/ + +static int +load_module(const char *name) +{ + int len, i; + void *addr; + void *link_addr; + module_init_t module_init; + + /* find module in module list and lookup link address */ + for(i=0; modules[i].name; ++i) { + if(strcmp(modules[i].name, name) == 0) + break; + } + if( modules[i].name == 0 ) { + /* module not in list */ + return -1; + } + link_addr = modules[i].link_addr; + + /* check if link address is used already */ + for(i=0; i<MODULES_MAX; ++i) { + if(snk_modules[i] && snk_modules[i]->link_addr == link_addr) { + /* busy, can't load modules */ + return -2; + } + } + + /* find empty position in array of loaded modules */ + for(i=0; i<MODULES_MAX; ++i) { + if(snk_modules[i] == 0) { + break; + } + } + if(i == MODULES_MAX) { + // no space avaliable! + return -3; + } + + /* Read module from FLASH */ + len = romfs_lookup(name, &addr); + if (len <= 0) { + /* file not found */ + return -4; + } + /* Copy image from flash to RAM + * FIXME fix address 8MB + */ + + memcpy(link_addr, addr, len); + + flush_cache(link_addr, len); + + /* Module starts with opd structure of the module_init + * function. + */ + module_init = (module_init_t) link_addr; + + snk_modules[i] = module_init(&snk_kernel_interface, &snk_kernel_interface.pci_conf); + if(snk_modules[i] == 0) { + /* no device found that can be managed by this module */ + return -5; + } + + if(snk_modules[i]->type == MOD_TYPE_NETWORK) { + /* Get mac address from device tree */ + get_mac(snk_modules[i]->mac_addr); + } + + return i; +} + +void +modules_init(void) +{ + int i; + + snk_kernel_interface.io_read = read_io; + snk_kernel_interface.io_write = write_io; + + snk_modules[0] = &of_module; + + /* Setup Module List */ + for(i=1; i<MODULES_MAX; ++i) { + snk_modules[i] = 0; + } + + /* Load all modules */ + for(i=0; modules[i].name; ++i) { + load_module(modules[i].name); + } +} + +void +modules_term() +{ + int i; + + /* remove all modules */ + for(i=0; i<MODULES_MAX; ++i) { + if(snk_modules[i] && snk_modules[i]->running != 0) { + snk_modules[i]->term(); + } + snk_modules[i] = 0; + } +} + +snk_module_t * +get_module_by_type(int type) { + int i; + + for(i=0; i<MODULES_MAX; ++i) { + if(snk_modules[i] && snk_modules[i]->type == type) { + return snk_modules[i]; + } + } + return 0; +} + +/** + * insmod_by_type - Load first module of given type + * + * @param type Type of module that we want to load + * @return module descriptor on success + * NULL if not successful + */ +snk_module_t * +insmod_by_type(int type) { + int i, j; + for(i = 0; modules[i].name; ++i) { + if(modules[i].type != type) + continue; + j = load_module(modules[i].name); + if(j >= 0) + return snk_modules[j]; + } + return 0; +} + +/** + * rmmod_by_type - Remove all module of given type + * + * @param type Type of module that we want to load + */ +void +rmmod_by_type(int type) { + int i; + + for (i = 0; i < MODULES_MAX; ++i) { + if (snk_modules[i] && snk_modules[i]->type == type) { + if (snk_modules[i]->running) + snk_modules[i]->term(); + snk_modules[i] = 0; + } + } +} diff --git a/clients/net-snk/kernel/systemcall.c b/clients/net-snk/kernel/systemcall.c index f15cae1..3c70e7d 100644 --- a/clients/net-snk/kernel/systemcall.c +++ b/clients/net-snk/kernel/systemcall.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -14,17 +14,101 @@ #include <of.h> #include <systemcall.h> #include <stdarg.h> +#include <netdriver_int.h> +#include <string.h> +#include <fileio.h> -extern ihandle_t fd_array[32]; - -int _socket (int, int, int, char*); -long _recv (int, void*, int, int); -long _sendto (int, void*, int, int, void*, int); -long _send (int, void*, int, int); -long _ioctl (int, int, void*); -int vsprintf(char *, const char *, va_list); +//extern ihandle_t fd_array[32]; +extern snk_module_t *get_module_by_type(int type); +extern int vsprintf(char *, const char *, va_list); +extern void _exit(int status); -long +int printk(const char*, ...); + +static int +_syscall_open(const char* name, int flags) +{ + int fd, i; + + /* search free file descriptor */ + for(fd=0; fd<FILEIO_MAX; ++fd) { + if(fd_array[fd].type == FILEIO_TYPE_EMPTY) { + break; + } + } + if(fd == FILEIO_MAX) { + printk ("Can not open \"%s\" because file descriptor list is full\n", name); + /* there is no free file descriptor avaliable */ + return -2; + } + + for(i=0; i<MODULES_MAX; ++i) { + if(!snk_modules[i] || !snk_modules[i]->open) { + continue; + } + + if(snk_modules[i]->running == 0) { + snk_modules[i]->init(); + } + + if(snk_modules[i]->open(&fd_array[fd], name, flags) == 0) + break; + } + + if(i==MODULES_MAX) { + /* file not found */ + return -1; + } + + return fd; +} + +static int +_syscall_socket(int domain, int type, int proto, char *mac_addr) +{ + snk_module_t *net_module; + + net_module = get_module_by_type(MOD_TYPE_NETWORK); + if( !net_module || !net_module->init) { + printk("No net_init function available"); + return -1; + } + + /* Init net device driver */ + if(net_module->running == 0) { + net_module->init(); + } + + if(net_module->running == 0) + return -2; + + memcpy(mac_addr, &net_module->mac_addr[0], 6); + return 0; +} + +static int +_syscall_close(int fd) +{ + if(fd < 0 || fd >= FILEIO_MAX + || fd_array[fd].type == FILEIO_TYPE_EMPTY + || fd_array[fd].close == 0) + return -1; + + return fd_array[fd].close(&fd_array[fd]); +} + +static long +_syscall_read (int fd, char *buf, long len) +{ + if(fd < 0 || fd >= FILEIO_MAX + || fd_array[fd].type == FILEIO_TYPE_EMPTY + || fd_array[fd].read == 0) + return -1; + + return fd_array[fd].read(&fd_array[fd], buf, len); +} + +static long _syscall_write (int fd, char *buf, long len) { char dest_buf[512]; @@ -42,130 +126,160 @@ _syscall_write (int fd, char *buf, long len) len = dest_buf_ptr - &dest_buf[0]; buf = &dest_buf[0]; } - return of_write (fd_array[fd], buf, len); -} -int -printk(const char* fmt, ...) -{ - int count; - va_list ap; - char buffer[256]; - va_start (ap, fmt); - count=vsprintf(buffer, fmt, ap); - _syscall_write (1, buffer, count); - va_end (ap); - return count; -} + if(fd < 0 || fd >= FILEIO_MAX + || fd_array[fd].type == FILEIO_TYPE_EMPTY + || fd_array[fd].write == 0) + return -1; -long -_syscall_read (int fd, char *buf, long len) -{ - return of_read (fd_array[fd], buf, len); + return fd_array[fd].write(&fd_array[fd], buf, len); } -long +static long _syscall_lseek (int fd, long offset, int whence) { + return 0; // this syscall is unused !!! +#if 0 if (whence != 0) return -1; of_seek (fd_array[fd], (unsigned int) (offset>>32), (unsigned int) (offset & 0xffffffffULL)); return offset; +#endif } -void -_syscall_close(int fd) +static int +_syscall_ioctl (int fd, int request, void* data) { - of_close(fd_array[fd]); + if (fd < 0 + || fd >= FILEIO_MAX + || fd_array[fd].type == FILEIO_TYPE_EMPTY) + return -1; + if (!fd_array[fd].ioctl) { /* for backwards compatibility with network modules */ + snk_module_t *net_module; + + net_module = get_module_by_type(MOD_TYPE_NETWORK); + if ( !net_module || !net_module->ioctl ) { + printk("No net_ioctl function available"); + return -1; + } + + return net_module->ioctl(request, data); + } + + return fd_array[fd].ioctl(&fd_array[fd], request, data); } -int -_syscall_ioctl (int fd, int request, void* data) +static long +_syscall_recv(int fd, void *packet, int packet_len, int flags) { - return _ioctl (fd, request, data); + snk_module_t *net_module; + + net_module = get_module_by_type(MOD_TYPE_NETWORK); + if( !net_module || !net_module->read ) { + printk("No net_receive function available"); + return -1; + } + + return net_module->read(packet, packet_len); } -long -_syscall_socket (long which, long arg0, long arg1, long arg2, - long arg3, long arg4, long arg5) +static long +_syscall_send(int fd, void *packet, int packet_len, int flags) { - long rc = -1; - switch (which) - { - case _sock_sc_nr: - rc = _socket (arg0, arg1, arg2, (char*) arg3); - break; - case _recv_sc_nr: - rc = _recv (arg0, (void *) arg1, arg2, arg3); - break; - case _send_sc_nr: - rc = _send (arg0, (void *) arg1, arg2, arg3); - break; - case _sendto_sc_nr: - rc = _sendto (arg0, (void *) arg1, arg2, arg3, (void *) arg4, arg5); - break; - } - return rc; + snk_module_t *net_module; + + net_module = get_module_by_type(MOD_TYPE_NETWORK); + if( !net_module || !net_module->write ) { + printk("No net_xmit function available"); + return -1; + } + + return net_module->write(packet, packet_len); } -int -_syscall_open(const char* name, int flags) +static long +_syscall_sendto(int fd, void *packet, int packet_len, int flags, + void *sock_addr, int sock_addr_len) { - static int fd = 2; - ihandle_t ihandle; + return _syscall_send(fd, packet, packet_len, flags); +} + + + + - if ((ihandle = of_open (name)) == 0) - { - printk ("Cannot open %s\n", name); - return -1; - } - fd++; - fd_array[fd] = ihandle; - return fd; -} long _system_call(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long arg6, int nr) { - long rc = -1; - switch (nr) - { + long rc = -1; + switch (nr) + { case _open_sc_nr: - rc = _syscall_open ((void *) arg0, arg1); - break; + rc = _syscall_open ((void *) arg0, arg1); + break; case _read_sc_nr: - rc = _syscall_read (arg0, (void *) arg1, arg2); - break; + rc = _syscall_read (arg0, (void *) arg1, arg2); + break; case _close_sc_nr: - _syscall_close (arg0); - break; + _syscall_close (arg0); + break; case _lseek_sc_nr: - rc = _syscall_lseek (arg0, arg1, arg2); - break; + rc = _syscall_lseek (arg0, arg1, arg2); + break; case _write_sc_nr: - rc = _syscall_write (arg0, (void *) arg1, arg2); - break; + rc = _syscall_write (arg0, (void *) arg1, arg2); + break; case _ioctl_sc_nr: - rc = _syscall_ioctl (arg0, arg1, (void *) arg2); - break; + rc = _syscall_ioctl (arg0, arg1, (void *) arg2); + break; case _socket_sc_nr: - rc = _syscall_socket (arg0, arg1, arg2, arg3, - arg4, arg5, arg6); - break; - } - return rc; -} + switch (arg0) + { + case _sock_sc_nr: + rc = _syscall_socket (arg1, arg2, arg3, (char*) arg4); + break; + case _recv_sc_nr: + rc = _syscall_recv (arg1, (void *) arg2, arg3, arg4); + break; + case _send_sc_nr: + rc = _syscall_send (arg1, (void *) arg2, arg3, arg4); + break; + case _sendto_sc_nr: + rc = _syscall_sendto (arg1, (void *) arg2, arg3, arg4, (void *) arg5, arg6); + break; + default: + break; + } + break; + default: + break; + } -void _exit(int status); + return rc; +} void exit(int status) { _exit(status); } + +int +printk(const char* fmt, ...) +{ + int count; + va_list ap; + char buffer[256]; + va_start (ap, fmt); + count=vsprintf(buffer, fmt, ap); + _syscall_write (1, buffer, count); + va_end (ap); + return count; +} diff --git a/clients/net-snk/kernel/timer.c b/clients/net-snk/kernel/timer.c index a57a463..630a9b4 100644 --- a/clients/net-snk/kernel/timer.c +++ b/clients/net-snk/kernel/timer.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/libc/Makefile b/clients/net-snk/libc/Makefile index 82e2b4c..aed7d9b 100644 --- a/clients/net-snk/libc/Makefile +++ b/clients/net-snk/libc/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -22,14 +22,15 @@ CFLAGS = -g -I$(TOP)/include -I$(LIBCMNDIR)/libc/include -O2 \ -fno-builtin -ffreestanding -nostdinc -msoft-float -Wall LDFLAGS= -nostdlib -OBJS = socket/socket.o time/time.o sbrk.o io.o ioctl.o -SUBDIRS = $(filter-out ./,$(dir $(OBJS))) +OBJS = sbrk.o io.o ioctl.o +OBJDIRS = socket/socket.o time/time.o +SUBDIRS = $(filter-out ./,$(dir $(OBJDIRS))) all: libc-glue.o libc-glue.o: subdirs sbrk.o io.o ioctl.o - $(LD) $(LDFLAGS) $(OBJS) -o $@ -r + $(LD) $(LDFLAGS) $(OBJS) $(OBJDIRS) -o $@ -r subdirs : @@ -45,4 +46,3 @@ clean: done include $(TOP)/make.depend - diff --git a/clients/net-snk/libc/io.c b/clients/net-snk/libc/io.c index 937e51a..0e8b7e8 100644 --- a/clients/net-snk/libc/io.c +++ b/clients/net-snk/libc/io.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/libc/ioctl.c b/clients/net-snk/libc/ioctl.c index 64d666c..370472c 100644 --- a/clients/net-snk/libc/ioctl.c +++ b/clients/net-snk/libc/ioctl.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/libc/sbrk.c b/clients/net-snk/libc/sbrk.c index 2969018..002e831 100644 --- a/clients/net-snk/libc/sbrk.c +++ b/clients/net-snk/libc/sbrk.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/libc/socket/Makefile b/clients/net-snk/libc/socket/Makefile index c18fe15..d4bd4be 100644 --- a/clients/net-snk/libc/socket/Makefile +++ b/clients/net-snk/libc/socket/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -18,24 +18,27 @@ endif include $(TOP)/make.rules -CFLAGS = -g -I$(TOP)/include -O2 -fno-builtin -ffreestanding -msoft-float -Wall +CFLAGS = -g -I$(TOP)/include -I$(LIBCMNDIR)/libc/include -O2 \ + -fno-builtin -ffreestanding -msoft-float -Wall LDFLAGS= -nostdlib -OBJS=send.c +OBJS = send.o all: socket.o -socket.o: $(OBJS:.c=.o) - $(LD) $(LDFLAGS) -r $^ -o $@ +socket.o: $(OBJS) + $(LD) $(LDFLAGS) -r $< -o $@ %.o : %.c - $(CC) $(CFLAGS) -c $^ -o $@ + $(CC) $(CFLAGS) -c $< -o $@ clean: $(RM) -f *.o *.i *.s distclean mrproper: clean + +include $(TOP)/make.depend diff --git a/clients/net-snk/libc/socket/send.c b/clients/net-snk/libc/socket/send.c index 0095822..7526f29 100644 --- a/clients/net-snk/libc/socket/send.c +++ b/clients/net-snk/libc/socket/send.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/libc/time/Makefile b/clients/net-snk/libc/time/Makefile index 1db98e7..fa90b01 100644 --- a/clients/net-snk/libc/time/Makefile +++ b/clients/net-snk/libc/time/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -24,20 +24,22 @@ CFLAGS = -g -I$(TOP)/include -I$(LIBCMNDIR)/libc/include -O2 -msoft-float \ LDFLAGS= -nostdlib -OBJS=timer.c ftime.c +OBJS = timer.o ftime.o all: time.o -time.o: $(OBJS:.c=.o) - $(LD) $(LDFLAGS) -r $^ -o $@ +time.o: $(OBJS) + $(LD) $(LDFLAGS) -r $< -o $@ %.o : %.c - $(CC) $(CFLAGS) -c $^ -o $@ + $(CC) $(CFLAGS) -c $< -o $@ clean: $(RM) -f *.o *.i *.s distclean mrproper: clean + +include $(TOP)/make.depend diff --git a/clients/net-snk/libc/time/ftime.c b/clients/net-snk/libc/time/ftime.c index 139988e..e092ba5 100644 --- a/clients/net-snk/libc/time/ftime.c +++ b/clients/net-snk/libc/time/ftime.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/libc/time/timer.c b/clients/net-snk/libc/time/timer.c index b0effaa..08477f1 100644 --- a/clients/net-snk/libc/time/timer.c +++ b/clients/net-snk/libc/time/timer.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/make.depend b/clients/net-snk/make.depend index 31997fc..e995741 100644 --- a/clients/net-snk/make.depend +++ b/clients/net-snk/make.depend @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License diff --git a/clients/net-snk/make.rules b/clients/net-snk/make.rules index 0bc0e2a..060e659 100644 --- a/clients/net-snk/make.rules +++ b/clients/net-snk/make.rules @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -21,7 +21,11 @@ LIBCMNDIR ?= $(ROOTDIR)/lib CFLAGS = -g -I. -I$(TOP)/include -I$(LIBCMNDIR)/libc/include \ -I$(LIBCMNDIR)/libbootmsg -I$(INCLCMNDIR)/$(CPUARCH) \ -O2 -fno-builtin -ffreestanding -msoft-float -mno-altivec \ - -Wall $(FLAG) + -Wall $(FLAG) -nostdinc +ifeq ($(SNK_LJTAG_PROCESS), 1) +CFLAGS += -I$(TOP)/../../board-malta/include +CFLAGS += -I$(TOP)/../../include/cbea +endif LDFLAGS = -nostdlib ASFLAGS = -I. -I$(TOP)/include -Wa,-mregnames -I$(INCLCMNDIR)/$(CPUARCH) DD = dd diff --git a/clients/net-snk/oflib/Makefile b/clients/net-snk/oflib/Makefile index c4a8219..aad3e89 100644 --- a/clients/net-snk/oflib/Makefile +++ b/clients/net-snk/oflib/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License diff --git a/clients/net-snk/oflib/entry.S b/clients/net-snk/oflib/entry.S index e88c617..5deeb04 100644 --- a/clients/net-snk/oflib/entry.S +++ b/clients/net-snk/oflib/entry.S @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/oflib/of.c b/clients/net-snk/oflib/of.c index 7c65c2e..5b8256d 100644 --- a/clients/net-snk/oflib/of.c +++ b/clients/net-snk/oflib/of.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -12,10 +12,39 @@ #include <of.h> +#include <rtas.h> #include <string.h> +#include <netdriver_int.h> +#include <fileio.h> +#include <types.h> extern void call_client_interface(of_arg_t *); +static int ofmod_init(void); +static int ofmod_term(void); +static int ofmod_open(snk_fileio_t*, const char* name, int flags); +static int ofmod_read(char *buffer, int len); +static int ofmod_write(char *buffer, int len); +static int ofmod_ioctl(int request, void *data); + +snk_module_t of_module = { + .version = 1, + .type = MOD_TYPE_OTHER, + .running = 1, + .link_addr = (char*) 1, + .init = ofmod_init, + .term = ofmod_term, + .open = ofmod_open, + .write = ofmod_write, + .read = ofmod_read, + .ioctl = ofmod_ioctl +}; + +static ihandle_t fd_ihandle_array[FILEIO_MAX]; +static int claim_rc = 0; +static void* client_start; +static size_t client_size; + extern inline int of_0_1(const char *serv) { @@ -355,3 +384,484 @@ bootmsg_cp(short id) { (void) of_1_0("bootmsg-cp", id); } + + +static long +of_fileio_read(snk_fileio_t *fileio, char *buf, long len) +{ + if(!fileio) + return -1; + return of_read( * (ihandle_t*) fileio->data, buf, len ); +} + +static long +of_fileio_write(snk_fileio_t *fileio, char *buf, long len) +{ + if(!fileio) + return -1; + return of_write( * (ihandle_t*) fileio->data, buf, len ); +} + +static int +of_fileio_close(snk_fileio_t *fileio) +{ + if(!fileio) + return -1; + + fileio->type = FILEIO_TYPE_EMPTY; + of_close( * (ihandle_t*) fileio->data ); + return 0; +} + + +#define CONFIG_SPACE 0 +#define IO_SPACE 1 +#define MEM_SPACE 2 + +#define ASSIGNED_ADDRESS_PROPERTY 0 +#define REG_PROPERTY 1 + +#define DEBUG_TRANSLATE_ADDRESS 0 +#if DEBUG_TRANSLATE_ADDRESS != 0 +#define DEBUG_TR(str...) printk(str) +#else +#define DEBUG_TR(str...) +#endif + +/** + * pci_address_type tries to find the type for which a + * mapping should be done. This is PCI specific and is done by + * looking at the first 32bit of the phys-addr in + * assigned-addresses + * + * @param node the node of the device which requests + * translatation + * @param address the address which needs to be translated + * @param prop_type the type of the property to search in (either REG_PROPERTY or ASSIGNED_ADDRESS_PROPERTY) + * @return the corresponding type (config, i/o, mem) + */ +static int +pci_address_type(phandle_t node, uint64_t address, uint8_t prop_type) +{ + char *prop_name = "assigned-addresses"; + if (prop_type == REG_PROPERTY) + prop_name = "reg"; + /* #address-cells */ + const unsigned int nac = 3; //PCI + /* #size-cells */ + const unsigned int nsc = 2; //PCI + /* up to 11 pairs of (phys-addr(3) size(2)) */ + unsigned char buf[11 * (nac + nsc) * sizeof(int)]; + unsigned int *assigned_ptr; + int result = -1; + int len; + len = of_getprop(node, prop_name, buf, 11 * (nac + nsc) * sizeof(int)); + assigned_ptr = (unsigned int *) &buf[0]; + while (len > 0) { + if ((prop_type == REG_PROPERTY) + && ((assigned_ptr[0] & 0xFF) != 0)) { + //BARs and Expansion ROM must be in assigned-addresses... so in reg + // we only look for those without config space offset set... + assigned_ptr += (nac + nsc); + len -= (nac + nsc) * sizeof(int); + continue; + } + DEBUG_TR("%s %x size %x\n", prop_name, assigned_ptr[2], + assigned_ptr[4]); + if (address >= assigned_ptr[2] + && address <= assigned_ptr[2] + assigned_ptr[4]) { + DEBUG_TR("found a match\n"); + result = (assigned_ptr[0] & 0x03000000) >> 24; + break; + } + assigned_ptr += (nac + nsc); + len -= (nac + nsc) * sizeof(int); + } + /* this can only handle 32bit memory space and should be + * removed as soon as translations for 64bit are available */ + return (result == 3) ? MEM_SPACE : result; +} + +/** + * this is a hack which returns the lower 64 bit of any number of cells + * all the higher bits will silently discarded + * right now this works pretty good as long 64 bit addresses is all we want + * + * @param addr a pointer to the first address cell + * @param nc number of cells addr points to + * @return the lower 64 bit to which addr points + */ +static uint64_t +get_dt_address(uint32_t *addr, uint32_t nc) +{ + uint64_t result = 0; + while (nc--) + result = (result << 32) | *(addr++); + return result; +} + +/** + * this functions tries to find a mapping for the given address + * it assumes that if we have #address-cells == 3 that we are trying + * to do a PCI translation + * + * @param addr a pointer to the address that should be translated + * if a translation has been found the address will + * be modified + * @param type this is required for PCI devices to find the + * correct translation + * @param ranges this is one "range" containing the translation + * information (one range = nac + pnac + nsc) + * @param nac the OF property #address-cells + * @param nsc the OF property #size-cells + * @param pnac the OF property #address-cells from the parent node + * @return -1 if no translation was possible; else 0 + */ +static int +map_one_range(uint64_t *addr, int type, uint32_t *ranges, uint32_t nac, + uint32_t nsc, uint32_t pnac) +{ + long offset; + /* cm - child mapping */ + /* pm - parent mapping */ + uint64_t cm, size, pm; + /* only check for the type if nac == 3 (PCI) */ + DEBUG_TR("type %x, nac %x\n", ranges[0], nac); + if (((ranges[0] & 0x03000000) >> 24) != type && nac == 3) + return -1; + /* okay, it is the same type let's see if we find a mapping */ + size = get_dt_address(ranges + nac + pnac, nsc); + if (nac == 3) /* skip type if PCI */ + cm = get_dt_address(ranges + 1, nac - 1); + else + cm = get_dt_address(ranges, nac); + + DEBUG_TR("\t\tchild_mapping %lx\n", cm); + DEBUG_TR("\t\tsize %lx\n", size); + DEBUG_TR("\t\t*address %lx\n", (uint64_t) * addr); + if (cm + size <= (uint64_t) * addr || cm > (uint64_t) * addr) + /* it is not inside the mapping range */ + return -1; + /* get the offset */ + offset = *addr - cm; + /* and add the offset on the parent mapping */ + if (pnac == 3) /* skip type if PCI */ + pm = get_dt_address(ranges + nac + 1, pnac - 1); + else + pm = get_dt_address(ranges + nac, pnac); + DEBUG_TR("\t\tparent_mapping %lx\n", pm); + *addr = pm + offset; + DEBUG_TR("\t\t*address %lx\n", *addr); + return 0; +} + +/** + * translate_address_dev tries to translate the device specific address + * to a host specific address by walking up in the device tree + * + * @param address a pointer to a 64 bit value which will be + * translated + * @param current_node phandle of the device from which the + * translation will be started + */ +void +translate_address_dev(uint64_t *addr, phandle_t current_node) +{ + unsigned char buf[1024]; + phandle_t parent; + unsigned int pnac; + unsigned int nac; + unsigned int nsc; + int addr_type; + int len; + unsigned int *ranges; + unsigned int one_range; + DEBUG_TR("translate address %lx, node: %lx\n", *addr, current_node); + of_getprop(current_node, "name", buf, 400); + DEBUG_TR("current node: %s\n", buf); + addr_type = + pci_address_type(current_node, *addr, ASSIGNED_ADDRESS_PROPERTY); + if (addr_type == -1) { + // check in "reg" property if not found in "assigned-addresses" + addr_type = pci_address_type(current_node, *addr, REG_PROPERTY); + } + DEBUG_TR("address_type %x\n", addr_type); + current_node = of_parent(current_node); + while (1) { + parent = of_parent(current_node); + if (!parent) { + DEBUG_TR("reached root node...\n"); + break; + } + of_getprop(current_node, "#address-cells", &nac, 4); + of_getprop(current_node, "#size-cells", &nsc, 4); + of_getprop(parent, "#address-cells", &pnac, 4); + one_range = nac + pnac + nsc; + len = of_getprop(current_node, "ranges", buf, 400); + if (len < 0) { + DEBUG_TR("no 'ranges' property; not translatable\n"); + return; + } + ranges = (unsigned int *) &buf[0]; + while (len > 0) { + if (!map_one_range + ((uint64_t *) addr, addr_type, ranges, nac, nsc, + pnac)) + /* after a successful mapping we stop + * going through the ranges */ + break; + ranges += one_range; + len -= one_range * sizeof(int); + } + DEBUG_TR("address %lx\n", *addr); + of_getprop(current_node, "name", buf, 400); + DEBUG_TR("current node: %s\n", buf); + DEBUG_TR("\t#address-cells: %x\n", nac); + DEBUG_TR("\t#size-cells: %x\n", nsc); + of_getprop(parent, "name", buf, 400); + DEBUG_TR("parent node: %s\n", buf); + DEBUG_TR("\t#address-cells: %x\n", pnac); + current_node = parent; + } +} + +static phandle_t +get_boot_device(void) +{ + char buf[1024]; + phandle_t dev = of_finddevice("/chosen"); + + if (dev == -1) { + dev = of_finddevice("/aliases"); + if (dev == -1) + return dev; + of_getprop(dev, "net", buf, 1024); + } else + of_getprop(dev, "bootpath", buf, 1024); + + return of_finddevice(buf); +} + +/** + * translate_address tries to translate the device specific address + * of the boot device to a host specific address + * + * @param address a pointer to a 64 bit value which will be + * translated + */ +void +translate_address(unsigned long *addr) +{ + translate_address_dev((uint64_t*) addr, get_boot_device()); +} + +/** + * get_puid walks up in the device tree until it finds a parent + * node without a reg property. get_puid is assuming that if the + * parent node has no reg property it has found the pci host bridge + * + * this is not the correct way to find PHBs but it seems to work + * for all our systems + * + * @param node the device for which to find the puid + * + * @return the puid or 0 + */ +uint64_t +get_puid(phandle_t node) +{ + uint64_t puid = 0; + uint64_t tmp = 0; + phandle_t curr_node = of_parent(node); + if (!curr_node) + /* no parent found */ + return 0; + for (;;) { + puid = tmp; + if (of_getprop(curr_node, "reg", &tmp, 8) < 8) { + /* if the found PHB is not directly under + * root we need to translate the found address */ + translate_address_dev(&puid, node); + return puid; + } + curr_node = of_parent(curr_node); + if (!curr_node) + return 0; + } + return 0; +} + +/* Fill in the pci config structure from the device tree */ +static int +set_pci_config(pci_config_t * pci_config) +{ + unsigned char buf[1024]; + int len, bar_nr; + unsigned int *assigned_ptr; + phandle_t net = get_boot_device(); + + if (net == -1) + return -1; + of_getprop(net, "vendor-id", &pci_config->vendor_id, 4); + of_getprop(net, "device-id", &pci_config->device_id, 4); + of_getprop(net, "revision-id", &pci_config->revision_id, 4); + of_getprop(net, "class-code", &pci_config->class_code, 4); + of_getprop(net, "interrupts", &pci_config->interrupt_line, 4); + + len = of_getprop(net, "assigned-addresses", buf, 400); + if (len <= 0) + return -1; + + assigned_ptr = (unsigned int *) &buf[0]; + pci_config->bus = (assigned_ptr[0] & 0x00ff0000) >> 16; + pci_config->devfn = (assigned_ptr[0] & 0x0000ff00) >> 8; + + while (len > 0) { + /* Fixme 64 bit bars */ + bar_nr = ((assigned_ptr[0] & 0xff) - 0x10) / 4; + pci_config->bars[bar_nr].type = + (assigned_ptr[0] & 0x0f000000) >> 24; + pci_config->bars[bar_nr].addr = assigned_ptr[2]; + pci_config->bars[bar_nr].size = assigned_ptr[4]; + assigned_ptr += 5; + len -= 5 * sizeof(int); + } + + pci_config->puid = get_puid(net); + + return 0; +} + +void +get_mac(char *mac) +{ + phandle_t net = get_boot_device(); + + if (net == -1) + return; + + of_getprop(net, "local-mac-address", mac, 6); +} + +static void +get_timebase(unsigned int *timebase) +{ + phandle_t cpu; + phandle_t cpus = of_finddevice("/cpus"); + + if (cpus == -1) + return; + + cpu = of_child(cpus); + + if (cpu == -1) + return; + + of_getprop(cpu, "timebase-frequency", timebase, 4); +} + +int +glue_init(snk_kernel_t * snk_kernel_interface, unsigned int * timebase, + size_t _client_start, size_t _client_size) +{ + phandle_t chosen = of_finddevice("/chosen"); + + client_start = (void *) (long) _client_start; + client_size = _client_size; + + if (chosen == -1) + return -1; + + fd_array[0].type = FILEIO_TYPE_USED; + fd_array[0].read = of_fileio_read; + fd_array[0].write = of_fileio_write; + fd_array[0].ioctl = 0; + fd_array[0].close = of_fileio_close; + fd_array[0].data = &fd_ihandle_array[0]; + of_getprop(chosen, "stdin", fd_array[0].data, sizeof(ihandle_t)); + + fd_array[1].type = FILEIO_TYPE_USED; + fd_array[1].read = of_fileio_read; + fd_array[1].write = of_fileio_write; + fd_array[1].ioctl = 0; + fd_array[1].close = of_fileio_close; + fd_array[1].data = &fd_ihandle_array[1]; + of_getprop(chosen, "stdout", fd_array[1].data, sizeof(ihandle_t)); + + if (of_write(fd_ihandle_array[1], " ", 1) < 0) + return -2; + + /* Setup Kernel Struct */ + if (set_pci_config(&snk_kernel_interface->pci_conf) == -1) { + snk_kernel_interface->print(" No net device found \n"); + } + + get_timebase(timebase); + rtas_init(); + + snk_kernel_interface->k_romfs_lookup = romfs_lookup; + snk_kernel_interface->translate_addr = translate_address; + snk_kernel_interface->pci_config_read = rtas_pci_config_read; + snk_kernel_interface->pci_config_write = rtas_pci_config_write; + claim_rc=(int)(long)of_claim(client_start, client_size, 0); + + return 0; +} + +void +glue_release(void) +{ + if (claim_rc >= 0) { + of_release(client_start, client_size); + } +} + +static int +ofmod_init(void) +{ + of_module.running = 1; + return 0; +} + +static int +ofmod_term(void) +{ + of_module.running = 0; + return 0; +} + +static int +ofmod_open(snk_fileio_t *fileio, const char* name, int flags) +{ + if ((fd_ihandle_array[fileio->idx] = of_open (name)) == 0) + { + /* this module can not open this file */ + return -1; + } + + fileio->type = FILEIO_TYPE_USED; + fileio->read = of_fileio_read; + fileio->write = of_fileio_write; + fileio->close = of_fileio_close; + fileio->data = &fd_ihandle_array[fileio->idx]; + return 0; +} + +static int +ofmod_read(char *buffer, int len) +{ + return len; +} + +static int +ofmod_write(char *buffer, int len) +{ + return len; +} + +static int +ofmod_ioctl(int request, void *data) +{ + return 0; +} + diff --git a/clients/net-snk/oflib/pci.c b/clients/net-snk/oflib/pci.c index 6b774fa..dac629a 100644 --- a/clients/net-snk/oflib/pci.c +++ b/clients/net-snk/oflib/pci.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/oflib/rtas.c b/clients/net-snk/oflib/rtas.c index 037baf0..63d6e2f 100644 --- a/clients/net-snk/oflib/rtas.c +++ b/clients/net-snk/oflib/rtas.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/net-snk/sec-client.lds b/clients/net-snk/sec-client.lds index a1b13a4..0ca24ab 100644 --- a/clients/net-snk/sec-client.lds +++ b/clients/net-snk/sec-client.lds @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/takeover/Makefile b/clients/takeover/Makefile index c11b5db..a700d32 100644 --- a/clients/takeover/Makefile +++ b/clients/takeover/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -51,8 +51,8 @@ ppc32wrap.o: ppc32wrap.S $(CROSS)gcc -m32 -a32 $(CFLAGS) -c $< -o $@ clean distclean: - make -C $(LIBCMNDIR) clean - make -C $(CLIENTSDIR) clean + make -C $(LIBCMNDIR) $@ + make -C $(CLIENTSDIR) $@ $(RM) *.o *.bin *.elf $(RM) takeover.elf32 takeover.elf64 takeover.tmp %.o: %.oco diff --git a/clients/takeover/client.lds b/clients/takeover/client.lds index 2352db5..2701d8e 100644 --- a/clients/takeover/client.lds +++ b/clients/takeover/client.lds @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/takeover/entry.S b/clients/takeover/entry.S index 32f2300..ff52dc6 100644 --- a/clients/takeover/entry.S +++ b/clients/takeover/entry.S @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/takeover/main.c b/clients/takeover/main.c index 3568a1f..b785f8e 100644 --- a/clients/takeover/main.c +++ b/clients/takeover/main.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -18,20 +18,82 @@ #include <cpu.h> #include <takeover.h> +extern void call_client_interface(of_arg_t *); + #define boot_rom_bin_start _binary_______boot_rom_bin_start #define boot_rom_bin_end _binary_______boot_rom_bin_end extern char boot_rom_bin_start; extern char boot_rom_bin_end; -extern ihandle_t fd_array[32]; -size_t -write(int fd, void *buf, size_t cnt) +#if defined(__GNUC__) +# define UNUSED __attribute__((unused)) +#else +# define UNUSED +#endif + + +/* + * These functions are just dummy implemented to resolve symbols for linking to other objects + */ + +int +open(const char *name UNUSED, int flags UNUSED) +{ + return 0; +} + +int +close(int fd UNUSED) +{ + return 0; +} + +ssize_t +read(int fd UNUSED, void *buf UNUSED, size_t count UNUSED) { - of_write((ihandle_t) fd_array[1], buf, cnt); return 0; } +int +ioctl(int fd UNUSED, int req UNUSED, void *data UNUSED) +{ + return 0; +} + +/* + * These functions are required for using libc.a + */ +ssize_t +write(int fd, const void *buf, size_t len) +{ + char dst_buf[512]; + char *dst_buf_ptr; + char *src_buf_ptr; + int i; + + src_buf_ptr = (char *) buf; + if (fd == 1 || fd == 2) + { + dst_buf_ptr = &dst_buf[0]; + for (i = 0; i < len && i < 256; i++) + { + *dst_buf_ptr++ = *src_buf_ptr++; + if (src_buf_ptr[-1] == '\n') + *dst_buf_ptr++ = '\r'; + } + len = dst_buf_ptr - &dst_buf[0]; + src_buf_ptr = &dst_buf[0]; + } + + if(fd < 0 || fd >= FILEIO_MAX + || fd_array[fd].type == FILEIO_TYPE_EMPTY + || fd_array[fd].write == 0) + return -1; + + return fd_array[fd].write(&fd_array[fd], src_buf_ptr, len); +} + void * sbrk(int incr) { @@ -74,7 +136,7 @@ startCpu(int num, int addr, int reg) volatile unsigned long slaveQuitt; int takeoverFlag; -int +void main(int argc, char *argv[]) { phandle_t cpus; @@ -82,7 +144,6 @@ main(int argc, char *argv[]) unsigned long slaveMask; extern int slaveLoop[]; extern int slaveLoopNoTakeover[]; - char devtype[100]; int rcode; int index = 0; int delay = 100; @@ -104,7 +165,7 @@ main(int argc, char *argv[]) if (strcmp(devType, "cpu") == 0) { of_getprop(cpu, "reg", ®, sizeof(reg)); if (index) { - printf("\r\n takeover on cpu%d (%x, %x) ", index, + printf("\r\n takeover on cpu%d (%x, %lx) ", index, cpu, reg); slaveQuitt = -1; if (takeoverFlag) diff --git a/clients/takeover/ppc32wrap.S b/clients/takeover/ppc32wrap.S index ff96095..90afa26 100644 --- a/clients/takeover/ppc32wrap.S +++ b/clients/takeover/ppc32wrap.S @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/clients/takeover/takeover.h b/clients/takeover/takeover.h index f5201ef..1949f71 100644 --- a/clients/takeover/takeover.h +++ b/clients/takeover/takeover.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/include/calculatecrc.h b/include/calculatecrc.h index 9f646e5..2168478 100644 --- a/include/calculatecrc.h +++ b/include/calculatecrc.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/include/libelf.h b/include/libelf.h index 229e86b..905c76b 100644 --- a/include/libelf.h +++ b/include/libelf.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/include/macros.h b/include/macros.h index 79c67c4..f519bb8 100644 --- a/include/macros.h +++ b/include/macros.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/include/memmap.h b/include/memmap.h index 5c9687a..abf3c1f 100644 --- a/include/memmap.h +++ b/include/memmap.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/include/pcd.h b/include/pcd.h index 078d8fc..9794b76 100644 --- a/include/pcd.h +++ b/include/pcd.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -36,7 +36,7 @@ /* ... and so on.. */ /**************************************************************/ #define PCDF_MEM_NUM 0 -#define PCDF_MEMN_BASE(N) (8 + (N * 8)) +#define PCDF_MEMN_BASE(N) (8 + ((N) * 16)) #define PCDF_MEMN_SIZE(M) (PCDF_MEMN_BASE(M) + 8) /* PCD File Definition ****************************************/ diff --git a/include/ppc970/cache.h b/include/ppc970/cache.h new file mode 100644 index 0000000..284ebde --- /dev/null +++ b/include/ppc970/cache.h @@ -0,0 +1,40 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#ifndef __CACHE_H +#define __CACHE_H + +#include <cpu.h> +#include <stdint.h> + +#define cache_inhibited_access(type,name) \ + static inline type ci_read_##name(type * addr) \ + { \ + type val; \ + set_ci(); \ + val = *addr; \ + clr_ci(); \ + return val; \ + } \ + static inline void ci_write_##name(type * addr, type data) \ + { \ + set_ci(); \ + *addr = data; \ + clr_ci(); \ + } + +cache_inhibited_access(uint8_t, 8) +cache_inhibited_access(uint16_t, 16) +cache_inhibited_access(uint32_t, 32) +cache_inhibited_access(uint64_t, 64) + +#endif diff --git a/include/ppc970/cpu.h b/include/ppc970/cpu.h index 001bb84..772767d 100644 --- a/include/ppc970/cpu.h +++ b/include/ppc970/cpu.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/include/romfs.h b/include/romfs.h index 612d805..7228502 100644 --- a/include/romfs.h +++ b/include/romfs.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/include/rtas.h b/include/rtas.h index c2f1029..e44dedb 100644 --- a/include/rtas.h +++ b/include/rtas.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/include/rtas_table.h b/include/rtas_table.h index ee161e7..cdf9db7 100644 --- a/include/rtas_table.h +++ b/include/rtas_table.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/include/termctrl.h b/include/termctrl.h index 082d3f1..502ecae 100644 --- a/include/termctrl.h +++ b/include/termctrl.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/include/types.h b/include/types.h index d41f23e..cbadd7c 100644 --- a/include/types.h +++ b/include/types.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/include/xvect.h b/include/xvect.h index bcece53..5926b18 100644 --- a/include/xvect.h +++ b/include/xvect.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/Makefile b/lib/Makefile index 4f3b4d8..34d3c23 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -10,7 +10,8 @@ # * IBM Corporation - initial implementation # ****************************************************************************/ -SUBDIRS = libc libipmi libbootmsg libbases libelf +SUBDIRS = libc libipmi libbootmsg libbases libnvram libelf + all: subdirs diff --git a/lib/libbases/Makefile b/lib/libbases/Makefile index fe1845c..add4ed1 100644 --- a/lib/libbases/Makefile +++ b/lib/libbases/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -15,8 +15,6 @@ TOPCMNDIR ?= ../.. include $(TOPCMNDIR)/make.rules ASFLAGS = $(FLAG) $(RELEASE) $(CPUARCHDEF) -Wa,-mregnames -CFLAGS = -g -O2 -fno-builtin -ffreestanding -nostdinc -msoft-float \ - -mno-altivec -mabi=no-altivec -Wall CPPFLAGS = -I../libc/include $(CPUARCHDEF) -I$(INCLBRDDIR) -I. -I../../include LDFLAGS = -nostdlib diff --git a/lib/libbases/libbases.code b/lib/libbases/libbases.code index 7f0a752..7dc941d 100644 --- a/lib/libbases/libbases.code +++ b/lib/libbases/libbases.code @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libbases/libbases.in b/lib/libbases/libbases.in index ed63de6..844a55d 100644 --- a/lib/libbases/libbases.in +++ b/lib/libbases/libbases.in @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libbootmsg/Makefile b/lib/libbootmsg/Makefile index 285a171..6804b8d 100644 --- a/lib/libbootmsg/Makefile +++ b/lib/libbootmsg/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -12,11 +12,7 @@ TOPCMNDIR ?= ../.. -include $(TOPCMNDIR)/make.rules - ASFLAGS = $(FLAG) $(RELEASE) $(CPUARCHDEF) -Wa,-mregnames -CFLAGS = -g -O2 -fno-builtin -ffreestanding -nostdinc -msoft-float \ - -mno-altivec -mabi=no-altivec -Wall CPPFLAGS = -I../libc/include $(CPUARCHDEF) -I$(INCLBRDDIR) -I. -I../../include LDFLAGS = -nostdlib @@ -25,10 +21,24 @@ TARGET = ../libbootmsg.a all: $(TARGET) - -# SRCS = bootmsg.c +ifeq ($(CPUARCH),cbea) +SRCS = +SRCSS = bootmsg_lvl.S +else +ifeq ($(CPUARCH),ppc970) SRCS = SRCSS = bootmsg_lvl.S +else +ifeq ($(CPUARCH),p5) +SRCS = +SRCSS = bootmsg_lvl.S +else +SRCS = bootmsg.c +SRCSS = +endif +endif +endif + OBJS = $(SRCS:%.c=%.o) $(SRCSS:%.S=%.o) @@ -52,7 +62,7 @@ depend: $(MAKE) Makefile.dep Makefile.dep: Makefile - $(CC) -MM $(CPPFLAGS) $(CFLAGS) $(SRCSS) > Makefile.dep + $(CC) -MM $(CPPFLAGS) $(CFLAGS) $(SRCS) $(SRCSS) > Makefile.dep # Include dependency file if available: -include Makefile.dep diff --git a/lib/libbootmsg/bootmsg.code b/lib/libbootmsg/bootmsg.code index e43afa1..ae370af 100644 --- a/lib/libbootmsg/bootmsg.code +++ b/lib/libbootmsg/bootmsg.code @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -47,7 +47,15 @@ PRIM(bootmsg_X2d_setlevel) bootmsg_setlevel(area, lvl); MIRP -// : bootmsg-setlevel ( -- ) +// : bootmsg-checklevel ( area lvl -- [true|false] ) +PRIM(bootmsg_X2d_checklevel) + char lvl = TOS.n; POP; + short area = TOS.n; POP; + PUSH; + TOS.n = (bootmsg_checklevel(area, lvl)) ? -1 : 0; +MIRP + +// : bootmsg-nvupdate ( -- ) PRIM(bootmsg_X2d_nvupdate) bootmsg_nvupdate(); MIRP diff --git a/lib/libbootmsg/bootmsg.in b/lib/libbootmsg/bootmsg.in index 66492b3..73e01e3 100644 --- a/lib/libbootmsg/bootmsg.in +++ b/lib/libbootmsg/bootmsg.in @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -16,3 +16,4 @@ cod(bootmsg-error) cod(bootmsg-debugcp) cod(bootmsg-setlevel) cod(bootmsg-nvupdate) +cod(bootmsg-checklevel) diff --git a/lib/libbootmsg/bootmsg_lvl.S b/lib/libbootmsg/bootmsg_lvl.S index 1f8ec16..04ace12 100644 --- a/lib/libbootmsg/bootmsg_lvl.S +++ b/lib/libbootmsg/bootmsg_lvl.S @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -131,6 +131,23 @@ ENTRY(bootmsg_debugcp) ble print_msg // if UserLevel<=SystemLevel print and return blr // else return +//***************************************************************************** +// Check warning level +// input : r3=cp-id, r4=level +// change : r3,r4,r5,r6,r7,r9,r10,r11 +// output : r3 (true, false) +// r3=cp-id, r4=level +ENTRY(bootmsg_checklevel) + mflr r11 + mr r5, r4 + slwi r3, r3, 8 + bl GET_WRNG_LVL // check UserLevel against SystemLevel + li r3, 0 // return 0 + bgt 0f // IF ( UserLevel < SystemLevel ) + li r3, 1 // | return 1 +0: mtlr r11 // FI + blr + // r3=area|pkg, r4=level ENTRY(bootmsg_setlevel) mflr r5 @@ -150,7 +167,7 @@ ENTRY(bootmsg_setlevel) ENTRY(bootmsg_nvupdate) mflr r10 LOAD64(r3, SB_NVRAM_FWONLY_adr) - lbz r4, 0(r3) + lwz r4, 0(r3) cmpwi r4, 0x424E // find bootmsg area header bne 0f @@ -167,39 +184,11 @@ ENTRY(bootmsg_nvupdate) bdnz+ 1b b 2f -0: // find last partition an resize it - li r4, 0x10 - mtctr r4 - li r4, 0x0 - li r7, 0x0 - LOAD64(r5, SB_NVRAM_adr) - LOAD64(r8, NVRAM_LENGTH) -1: - bdz+ 2f - add r5, r5, r4 - lhz r6, 2(r5) - rldicl r6, r6, 4, 0 - mr r4, r6 - add r7, r7, r4 - cmpw r7, r8 - ble 1b - - sub r7, r7, r4 // write new size - sub r6, r8, r7 - sradi r6, r6, 4 - sth r6, 2(r5) - - mr r7, r3 - mr r8, r5 - mr r3, r5 - bl .calPartitionHeaderChecksum - stb r3, 1(r8) // write checksum - - mr r3, r7 +0: LOAD64(r5, bootmsg_area_size) mtctr r5 li r4, 0x424E // clear bootmsg log area - stb r4, 0(r3) + stw r4, 0(r3) li r4, 0 1: stdu r4, 8(r3) diff --git a/lib/libbootmsg/libbootmsg.h b/lib/libbootmsg/libbootmsg.h index be0ad7e..9d0bd15 100644 --- a/lib/libbootmsg/libbootmsg.h +++ b/lib/libbootmsg/libbootmsg.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -16,5 +16,6 @@ void bootmsg_error(short p, const char *str); void bootmsg_warning(short p, const char *str, short lvl); void bootmsg_debugcp(short p, const char *str, short lvl); void bootmsg_setlevel(short p, short level); -void *bootmsg_nvupdate(); +int bootmsg_checklevel(short p, short level); +void *bootmsg_nvupdate(void); #endif /* _LIBBOOTMSG_H */ diff --git a/lib/libc/Makefile b/lib/libc/Makefile index 57b9694..0c762ec 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -17,11 +17,11 @@ STRINGCMNDIR = $(LIBCCMNDIR)/string CTYPECMNDIR = $(LIBCCMNDIR)/ctype STDLIBCMNDIR = $(LIBCCMNDIR)/stdlib STDIOCMNDIR = $(LIBCCMNDIR)/stdio +GETOPTCMNDIR = $(LIBCCMNDIR)/getopt include $(TOPCMNDIR)/make.rules -CFLAGS = -g -O2 -fno-builtin -ffreestanding -nostdinc -msoft-float -mno-altivec -mabi=no-altivec -Wall CPPFLAGS = -I$(LIBCCMNDIR)/include LDFLAGS= -nostdlib @@ -40,8 +40,9 @@ include $(STRINGCMNDIR)/Makefile.inc include $(CTYPECMNDIR)/Makefile.inc include $(STDLIBCMNDIR)/Makefile.inc include $(STDIOCMNDIR)/Makefile.inc +include $(GETOPTCMNDIR)/Makefile.inc -OBJS = $(STRING_OBJS) $(CTYPE_OBJS) $(STDLIB_OBJS) $(STDIO_OBJS) +OBJS = $(STRING_OBJS) $(CTYPE_OBJS) $(STDLIB_OBJS) $(STDIO_OBJS) $(GETOPT_OBJS) ifneq ($(NATIVEBUILD),1) # These parts of the libc use assembler, so they can only be compiled when diff --git a/lib/libc/ctype/Makefile.inc b/lib/libc/ctype/Makefile.inc index 8486a8a..25513a9 100644 --- a/lib/libc/ctype/Makefile.inc +++ b/lib/libc/ctype/Makefile.inc @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -11,7 +11,7 @@ # ****************************************************************************/ -CTYPE_SRC_C = isdigit.c isspace.c isxdigit.c tolower.c toupper.c +CTYPE_SRC_C = isdigit.c isprint.c isspace.c isxdigit.c tolower.c toupper.c CTYPE_SRC_ASM = CTYPE_SRCS = $(CTYPE_SRC_C:%=$(CTYPECMNDIR)/%) $(CTYPE_SRC_ASM:%=$(CTYPECMNDIR)/%) CTYPE_OBJS = $(CTYPE_SRC_C:%.c=%.o) $(CTYPE_SRC_ASM:%.S=%.o) diff --git a/lib/libc/ctype/isdigit.c b/lib/libc/ctype/isdigit.c index b3d1835..62d08a1 100644 --- a/lib/libc/ctype/isdigit.c +++ b/lib/libc/ctype/isdigit.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/ctype/isprint.c b/lib/libc/ctype/isprint.c new file mode 100644 index 0000000..c74880f --- /dev/null +++ b/lib/libc/ctype/isprint.c @@ -0,0 +1,18 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include <ctype.h> + +int isprint(int ch) +{ + return (ch >= 32 && ch < 127); +} diff --git a/lib/libc/ctype/isspace.c b/lib/libc/ctype/isspace.c index 0e749d7..5123019 100644 --- a/lib/libc/ctype/isspace.c +++ b/lib/libc/ctype/isspace.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/ctype/isxdigit.c b/lib/libc/ctype/isxdigit.c index 2b55d1a..9d323f3 100644 --- a/lib/libc/ctype/isxdigit.c +++ b/lib/libc/ctype/isxdigit.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/ctype/tolower.c b/lib/libc/ctype/tolower.c index f7eb03b..f775e90 100644 --- a/lib/libc/ctype/tolower.c +++ b/lib/libc/ctype/tolower.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/ctype/toupper.c b/lib/libc/ctype/toupper.c index 0eba9d0..9bcee52 100644 --- a/lib/libc/ctype/toupper.c +++ b/lib/libc/ctype/toupper.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/getopt/Makefile.inc b/lib/libc/getopt/Makefile.inc new file mode 100644 index 0000000..8a2e32f --- /dev/null +++ b/lib/libc/getopt/Makefile.inc @@ -0,0 +1,17 @@ +# ***************************************************************************** +# * Copyright (c) 2004, 2008 IBM Corporation +# * All rights reserved. +# * This program and the accompanying materials +# * are made available under the terms of the BSD License +# * which accompanies this distribution, and is available at +# * http://www.opensource.org/licenses/bsd-license.php +# * +# * Contributors: +# * IBM Corporation - initial implementation +# ****************************************************************************/ + +GETOPT_SRC_C = getopt.c +GETOPT_OBJS = $(GETOPT_SRC_C:%.c=%.o) + +%.o : $(GETOPTCMNDIR)/%.c + $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ diff --git a/lib/libc/getopt/getopt.c b/lib/libc/getopt/getopt.c new file mode 100644 index 0000000..be626dd --- /dev/null +++ b/lib/libc/getopt/getopt.c @@ -0,0 +1,470 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +/* + * includes + ******************************************************************************* + */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <getopt.h> + +/* + * global variables, types & constants + * may be removed if already defined + ******************************************************************************* + */ +int opterr = 1; +int optopt = 0; +int optind = 1; +char *optarg = NULL; + +/* + * internal values needed by getopt + * DO NOT CHANGE or REMOVE + */ +enum { + OPTIONAL_ARG = 0, + MANDATORY_ARG = 1, + NO_ARG = 2 +}; + +/* + * variables needed by getopt & getopt_long! + * DO NOT REMOVE + */ +static char *optstart = NULL; + +int +getopt(int argc, char **argv, const char *options) +{ + char *optptr; + char *argptr; + int optman; + int idx; + int ret = 0; + int argpresent; + + /* + * reset used global values + */ + optopt = 0; + optarg = NULL; + + /* + * reset getopt if a new argv pointer is passed + */ + if (optstart != argv[0]) { + optopt = 0; + optind = 1; + optarg = NULL; + optstart = argv[0]; + } + + /* + * return if no more arguments are available + */ + if (optind >= argc) { + return -1; + } + + /* + * start parsing argv[optind] + */ + idx = 0; + + /* + * return if the option does not begin with a '-' or has more than 2 characters + */ + if (argv[optind][idx] != '-') { + + if (opterr != 0) { + printf("unknown option \'%s\', expecting \'-\'\n", + argv[optind]); + } + + optopt = (int) argv[optind][idx]; + optind++; + + return '?'; + } + + /* + * continue to the next character in argv[optind] + */ + idx++; + + /* + * identify the option + * make sure if an option contains a ':' to invalidate the option + */ + optptr = strchr(argv[optind], ':'); + + if (optptr == NULL) { + optptr = strchr(options, (int) argv[optind][idx]); + } else { + optptr = NULL; + } + + /* + * check whether the option is present + */ + if (optptr == NULL) { + /* + * unknown option detected + */ + if (opterr != 0) { + printf("unknown option \'%s\'\n", argv[optind]); + } + + optopt = (int) argv[optind][idx]; + optind++; + + return '?'; + } + + /* + * the option is present in the option string + * setup return value + */ + ret = (int) *optptr; + + /* + * get option argument if needed + */ + optptr++; + + /* + * determine between mandatory and optional argument + */ + optman = NO_ARG; + + if (*optptr == ':') { + optman--; // now set to MANDATORY_ARG + } + + if (optman == MANDATORY_ARG) { + optptr++; + + if (*optptr == ':') { + optman--; // now set to OPTIONAL_ARG + } + + } + + /* + * if strlen( argv[optind ) is greater than 2, + * the argument is in the same argv + */ + if (strlen(argv[optind]) > 2) { + argptr = &argv[optind][2]; + + /* + * do not allow '-' in an argument + */ + if (strchr(argptr, '-') != NULL) { + + if (opterr != 0) { + printf + ("illegal argument value \'%s\' for option \'-%c\'\n", + argptr, ret); + } + + optopt = ret; + + return '?'; + } + + } else { + /* + * move on to the next argv + * it now either contains an argument or the next option + */ + optind++; + + /* + * make sure not to overflow + */ + if (optind < argc) { + argptr = argv[optind]; + } else { + argptr = NULL; + } + + } + + /* + * do the needed actions for the argument state + */ + switch (optman) { + case OPTIONAL_ARG: + + if (argptr == NULL) { + break; + } + + if (*argptr != '-') { + /* + * argument present + */ + optarg = argptr; + optind++; + + } + + + break; + + case MANDATORY_ARG: + argpresent = (argptr != NULL); + + if (argpresent) { + argpresent = (*argptr != '-'); + } + + if (argpresent) { + /* + * argument present + */ + optarg = argptr; + optind++; + } else { + /* + * mandatory argument missing + */ + if (opterr != 0) { + printf + ("missing argument for option \'-%c\'\n", + ret); + } + + optopt = ret; + + /* + * if the first character of options is a ':' + * return a ':' instead of a '?' in case of + * a missing argument + */ + if (*options == ':') { + ret = ':'; + } else { + ret = '?'; + } + + } + + + break; + + case NO_ARG: + + if (strlen(argv[optind - 1]) > 2) { + + if (opterr != 0) { + printf + ("too many arguments for option \'-%c\'\n", + ret); + } + + optopt = ret; + ret = '?'; + } + + + break; + + } + + return ret; +} + +int +getopt_long(int argc, char **argv, const char *shortopts, + const struct option *longopts, int *indexptr) +{ + struct option *optptr = (struct option *) longopts; + int optidx = 0; + int idx; + int ret = 0; + int argpresent; + + /* + * reset used global values + */ + optopt = 0; + optarg = NULL; + + /* + * reset indexptr + */ + *indexptr = -1; + + /* + * reset getopt if a new argv pointer is passed + */ + if (optstart != argv[0]) { + optopt = 0; + optind = 1; + optarg = NULL; + optstart = argv[0]; + } + + /* + * return if no more arguments are available + */ + if (optind >= argc) { + return -1; + } + + /* + * start parsing argv[optind] + */ + idx = 0; + + /* + * return if the option does not begin with a '-' + */ + if (argv[optind][idx] != '-') { + printf("unknown option \'%s\', expecting \'-\'\n", + argv[optind]); + + optind++; + + return '?'; + } + + /* + * move on to the next character in argv[optind] + */ + idx++; + + /* + * return getopt() in case of a short option + */ + if (argv[optind][idx] != '-') { + return getopt(argc, argv, shortopts); + } + + /* + * handle a long option + */ + idx++; + + while (optptr->name != NULL) { + + if (strcmp(&argv[optind][idx], optptr->name) == 0) { + break; + } + + optptr++; + optidx++; + } + + /* + * no matching option found + */ + if (optptr->name == NULL) { + printf("unknown option \'%s\'\n", argv[optind]); + + optind++; + + return '?'; + } + + /* + * option was found, set up index pointer + */ + *indexptr = optidx; + + /* + * get argument + */ + optind++; + + switch (optptr->has_arg) { + case no_argument: + /* + * nothing to do + */ + + break; + + case required_argument: + argpresent = (optind != argc); + + if (argpresent) { + argpresent = (argv[optind][0] != '-'); + } + + if (argpresent) { + /* + * argument present + */ + optarg = argv[optind]; + optind++; + } else { + /* + * mandatory argument missing + */ + printf("missing argument for option \'%s\'\n", + argv[optind - 1]); + + ret = '?'; + } + + + break; + + case optional_argument: + + if (optind == argc) { + break; + } + + if (argv[optind][0] != '-') { + /* + * argument present + */ + optarg = argv[optind]; + optind++; + } + + + break; + + default: + printf("unknown argument option for option \'%s\'\n", + argv[optind - 1]); + + ret = '?'; + + break; + + } + + /* + * setup return values + */ + if (ret != '?') { + + if (optptr->flag == NULL) { + ret = optptr->val; + } else { + *optptr->flag = optptr->val; + ret = 0; + } + + } + + return ret; +} diff --git a/lib/libc/include/ctype.h b/lib/libc/include/ctype.h index 3e5e47b..9051a75 100644 --- a/lib/libc/include/ctype.h +++ b/lib/libc/include/ctype.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -15,6 +15,7 @@ int isdigit(int c); int isxdigit(int c); +int isprint(int c); int isspace(int c); int tolower(int c); diff --git a/lib/libc/include/errno.h b/lib/libc/include/errno.h index eea7a36..d585934 100644 --- a/lib/libc/include/errno.h +++ b/lib/libc/include/errno.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/include/getopt.h b/lib/libc/include/getopt.h new file mode 100644 index 0000000..5956986 --- /dev/null +++ b/lib/libc/include/getopt.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#ifndef GETOPT_H +#define GETOPT_H + +extern char *optarg; +extern int optind; +extern int opterr; +extern int optopt; + +struct option { + const char *name; + int has_arg; + int *flag; + int val; +}; + +enum { + no_argument = 0, + required_argument, + optional_argument +}; + +int getopt(int argc, char **, const char *); +int getopt_long(int argc, char **, const char *, const struct option *, int *); + +#endif /* GETOPT_H */ diff --git a/lib/libc/include/limits.h b/lib/libc/include/limits.h index ce694ea..4726835 100644 --- a/lib/libc/include/limits.h +++ b/lib/libc/include/limits.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/include/stdarg.h b/lib/libc/include/stdarg.h index 422c598..d3d12f7 100644 --- a/lib/libc/include/stdarg.h +++ b/lib/libc/include/stdarg.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/include/stddef.h b/lib/libc/include/stddef.h index 318e2bb..ba2d960 100644 --- a/lib/libc/include/stddef.h +++ b/lib/libc/include/stddef.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/include/stdint.h b/lib/libc/include/stdint.h index e455f19..518a723 100644 --- a/lib/libc/include/stdint.h +++ b/lib/libc/include/stdint.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/include/stdio.h b/lib/libc/include/stdio.h index 096e035..84cddea 100644 --- a/lib/libc/include/stdio.h +++ b/lib/libc/include/stdio.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/include/stdlib.h b/lib/libc/include/stdlib.h index ad0ef4f..dff57f5 100644 --- a/lib/libc/include/stdlib.h +++ b/lib/libc/include/stdlib.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -23,6 +23,8 @@ void *realloc(void *ptr, size_t size); void free(void *ptr); void *memalign(size_t boundary, size_t size); +int atoi(const char *str); +long atol(const char *str); unsigned long int strtoul(const char *nptr, char **endptr, int base); long int strtol(const char *nptr, char **endptr, int base); diff --git a/lib/libc/include/string.h b/lib/libc/include/string.h index d792b1b..ebc7568 100644 --- a/lib/libc/include/string.h +++ b/lib/libc/include/string.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/include/unistd.h b/lib/libc/include/unistd.h index c09c45d..f1b1c62 100644 --- a/lib/libc/include/unistd.h +++ b/lib/libc/include/unistd.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdio/Makefile.inc b/lib/libc/stdio/Makefile.inc index 8783570..ac5302d 100644 --- a/lib/libc/stdio/Makefile.inc +++ b/lib/libc/stdio/Makefile.inc @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License diff --git a/lib/libc/stdio/fileno.c b/lib/libc/stdio/fileno.c index de77906..6e23951 100644 --- a/lib/libc/stdio/fileno.c +++ b/lib/libc/stdio/fileno.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdio/fprintf.c b/lib/libc/stdio/fprintf.c index 2337464..866df39 100644 --- a/lib/libc/stdio/fprintf.c +++ b/lib/libc/stdio/fprintf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdio/fscanf.c b/lib/libc/stdio/fscanf.c index e2e28de..321b163 100644 --- a/lib/libc/stdio/fscanf.c +++ b/lib/libc/stdio/fscanf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdio/printf.c b/lib/libc/stdio/printf.c index e73798b..01f4592 100644 --- a/lib/libc/stdio/printf.c +++ b/lib/libc/stdio/printf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdio/putc.c b/lib/libc/stdio/putc.c index b21e37b..230e9d1 100644 --- a/lib/libc/stdio/putc.c +++ b/lib/libc/stdio/putc.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdio/putchar.c b/lib/libc/stdio/putchar.c index 524423e..5c750d9 100644 --- a/lib/libc/stdio/putchar.c +++ b/lib/libc/stdio/putchar.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdio/puts.c b/lib/libc/stdio/puts.c index bf2b8af..3f48dbf 100644 --- a/lib/libc/stdio/puts.c +++ b/lib/libc/stdio/puts.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdio/scanf.c b/lib/libc/stdio/scanf.c index 9ff8f00..96b6399 100644 --- a/lib/libc/stdio/scanf.c +++ b/lib/libc/stdio/scanf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdio/setvbuf.c b/lib/libc/stdio/setvbuf.c index fcc10f5..9b62dd8 100644 --- a/lib/libc/stdio/setvbuf.c +++ b/lib/libc/stdio/setvbuf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdio/sprintf.c b/lib/libc/stdio/sprintf.c index c84255b..9c4540e 100644 --- a/lib/libc/stdio/sprintf.c +++ b/lib/libc/stdio/sprintf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdio/stdchnls.c b/lib/libc/stdio/stdchnls.c index 9b45be0..41ed958 100644 --- a/lib/libc/stdio/stdchnls.c +++ b/lib/libc/stdio/stdchnls.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c index 9a657ec..765feea 100644 --- a/lib/libc/stdio/vfprintf.c +++ b/lib/libc/stdio/vfprintf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdio/vfscanf.c b/lib/libc/stdio/vfscanf.c index 7a9f237..4ddd210 100644 --- a/lib/libc/stdio/vfscanf.c +++ b/lib/libc/stdio/vfscanf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -18,20 +18,20 @@ static int -_getc(FILE *stream) +_getc(FILE * stream) { int count; char c; if (stream->mode == _IONBF || stream->buf == NULL) { - if (read(stream->fd,&c,1) == 1) - return (int)c; + if (read(stream->fd, &c, 1) == 1) + return (int) c; else return EOF; } if (stream->pos == 0 || stream->pos >= BUFSIZ || - stream->buf[stream->pos] == '\0') { + stream->buf[stream->pos] == '\0') { count = read(stream->fd, stream->buf, BUFSIZ); if (count < 0) count = 0; @@ -44,16 +44,16 @@ _getc(FILE *stream) } static void -_ungetc(int ch, FILE *stream) +_ungetc(int ch, FILE * stream) { - if(stream->mode != _IONBF && stream->pos > 0) + if (stream->mode != _IONBF && stream->pos > 0) stream->pos--; } static int _is_voidage(int ch) { - if(ch == ' ' || ch == '\t' || ch == '\n' || ch == '\0') + if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\0') return 1; else return 0; @@ -61,143 +61,150 @@ _is_voidage(int ch) static int -_scanf(FILE *stream, const char *fmt, va_list *ap) +_scanf(FILE * stream, const char *fmt, va_list * ap) { - int i=0; + int i = 0; int length = 0; - fmt++; + fmt++; + + while (*fmt != '\0') { - while(*fmt != '\0') { - char tbuf[256]; char ch; - switch(*fmt) { - case 'd': - case 'i': - ch = _getc(stream); - if(length == 0) { - while(!_is_voidage(ch) && isdigit(ch)) { - tbuf[i] = ch; - ch = _getc(stream); - i++; - } - } else { - while(!_is_voidage(ch) && i < length && isdigit(ch)) { - tbuf[i] = ch; - ch = _getc(stream); - i++; - } + switch (*fmt) { + case 'd': + case 'i': + ch = _getc(stream); + if (length == 0) { + while (!_is_voidage(ch) && isdigit(ch)) { + tbuf[i] = ch; + ch = _getc(stream); + i++; } - _ungetc(ch, stream); - tbuf[i] = '\0'; - - ch = _getc(stream); - if(!_is_voidage(ch)) - _ungetc(ch, stream); - - if(strlen(tbuf) == 0) - return 0; - - *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 10); - break; - case 'X': - case 'x': - ch = _getc(stream); - if(length == 0) { - while(!_is_voidage(ch) && isxdigit(ch)) { - tbuf[i] = ch; - ch = _getc(stream); - i++; - } - } else { - while(!_is_voidage(ch) && i < length && isxdigit(ch)) { - tbuf[i] = ch; - ch = _getc(stream); - i++; - } + } else { + while (!_is_voidage(ch) && i < length + && isdigit(ch)) { + tbuf[i] = ch; + ch = _getc(stream); + i++; } + } + /* We tried to understand what this is good for... + * but we did not. We know for sure that it does not + * work on SLOF if this is active. */ + /* _ungetc(ch, stream); */ + tbuf[i] = '\0'; + + /* ch = _getc(stream); */ + if (!_is_voidage(ch)) _ungetc(ch, stream); - tbuf[i] = '\0'; - - ch = _getc(stream); - if(!_is_voidage(ch)) - _ungetc(ch, stream); - - if(strlen(tbuf) == 0) - return 0; - - *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 16); - break; - case 'O': - case 'o': - ch = _getc(stream); - if(length == 0) { - while(!_is_voidage(ch) && !(ch < '0' || ch > '7')) { - tbuf[i] = ch; - ch = _getc(stream); - i++; - } - } else { - while(!_is_voidage(ch) && i < length && !(ch < '0' || ch > '7')) { - tbuf[i] = ch; - ch = _getc(stream); - i++; - } + + if (strlen(tbuf) == 0) + return 0; + + *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 10); + break; + case 'X': + case 'x': + ch = _getc(stream); + if (length == 0) { + while (!_is_voidage(ch) && isxdigit(ch)) { + tbuf[i] = ch; + ch = _getc(stream); + i++; + } + } else { + while (!_is_voidage(ch) && i < length + && isxdigit(ch)) { + tbuf[i] = ch; + ch = _getc(stream); + i++; } + } + /* _ungetc(ch, stream); */ + tbuf[i] = '\0'; + + /* ch = _getc(stream); */ + if (!_is_voidage(ch)) _ungetc(ch, stream); - tbuf[i] = '\0'; - - ch = _getc(stream); - if(!_is_voidage(ch)) - _ungetc(ch, stream); - if(strlen(tbuf) == 0) - return 0; + if (strlen(tbuf) == 0) + return 0; - *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 8); - break; - case 'c': - ch = _getc(stream); - while(_is_voidage(ch)) + *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 16); + break; + case 'O': + case 'o': + ch = _getc(stream); + if (length == 0) { + while (!_is_voidage(ch) + && !(ch < '0' || ch > '7')) { + tbuf[i] = ch; ch = _getc(stream); - - *(va_arg(*ap, char *)) = ch; - - ch = _getc(stream); - if(!_is_voidage(ch)) - _ungetc(ch, stream); + i++; + } + } else { + while (!_is_voidage(ch) && i < length + && !(ch < '0' || ch > '7')) { + tbuf[i] = ch; + ch = _getc(stream); + i++; + } + } + /* _ungetc(ch, stream); */ + tbuf[i] = '\0'; + + /* ch = _getc(stream); */ + if (!_is_voidage(ch)) + _ungetc(ch, stream); + + if (strlen(tbuf) == 0) + return 0; - break; - case 's': + *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 8); + break; + case 'c': + ch = _getc(stream); + while (_is_voidage(ch)) ch = _getc(stream); - if(length == 0) { - while(!_is_voidage(ch)) { - tbuf[i] = ch; - ch = _getc(stream); - i++; - } - } else { - while(!_is_voidage(ch) && i < length) { - tbuf[i] = ch; - ch = _getc(stream); - i++; - } + + *(va_arg(*ap, char *)) = ch; + + ch = _getc(stream); + if (!_is_voidage(ch)) + _ungetc(ch, stream); + + break; + case 's': + ch = _getc(stream); + if (length == 0) { + while (!_is_voidage(ch)) { + tbuf[i] = ch; + ch = _getc(stream); + i++; + } + } else { + while (!_is_voidage(ch) && i < length) { + tbuf[i] = ch; + ch = _getc(stream); + i++; } + } + /* _ungetc(ch, stream); */ + tbuf[i] = '\0'; + + /* ch = _getc(stream); */ + if (!_is_voidage(ch)) _ungetc(ch, stream); - tbuf[i] = '\0'; - - ch = _getc(stream); - if(!_is_voidage(ch)) - _ungetc(ch, stream); - - strcpy(va_arg(*ap, char *), tbuf); - break; - default: - if(*fmt >= '0' && *fmt <= '9') - length += *fmt - '0'; - break; + + strcpy(va_arg(*ap, char *), tbuf); + break; + default: + if (*fmt >= '0' && *fmt <= '9') + length += *fmt - '0'; + break; } fmt++; } @@ -208,34 +215,36 @@ _scanf(FILE *stream, const char *fmt, va_list *ap) int -vfscanf(FILE *stream, const char *fmt, va_list ap) +vfscanf(FILE * stream, const char *fmt, va_list ap) { int args = 0; - while(*fmt != '\0') { - - if(*fmt == '%') { - + while (*fmt != '\0') { + + if (*fmt == '%') { + char formstr[20]; - int i=0; - + int i = 0; + do { formstr[i] = *fmt; fmt++; i++; - } while(!(*fmt == 'd' || *fmt == 'i' || *fmt == 'x' || *fmt == 'X' - || *fmt == 'p' || *fmt == 'c' || *fmt == 's' || *fmt == '%' - || *fmt == 'O' || *fmt == 'o' )); + } while (! + (*fmt == 'd' || *fmt == 'i' || *fmt == 'x' + || *fmt == 'X' || *fmt == 'p' || *fmt == 'c' + || *fmt == 's' || *fmt == '%' || *fmt == 'O' + || *fmt == 'o')); formstr[i++] = *fmt; formstr[i] = '\0'; - if(*fmt != '%') { - if(_scanf(stream, formstr, &ap) <= 0) + if (*fmt != '%') { + if (_scanf(stream, formstr, &ap) <= 0) return args; else args++; } - } + } fmt++; @@ -244,13 +253,14 @@ vfscanf(FILE *stream, const char *fmt, va_list ap) return args; } -int getc(FILE *stream) +int +getc(FILE * stream) { return _getc(stream); } -int getchar(void) +int +getchar(void) { return _getc(stdin); } - diff --git a/lib/libc/stdio/vsnprintf.c b/lib/libc/stdio/vsnprintf.c index 200512f..e78fb3d 100644 --- a/lib/libc/stdio/vsnprintf.c +++ b/lib/libc/stdio/vsnprintf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdio/vsprintf.c b/lib/libc/stdio/vsprintf.c index c565a89..0dfd737 100644 --- a/lib/libc/stdio/vsprintf.c +++ b/lib/libc/stdio/vsprintf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdio/vsscanf.c b/lib/libc/stdio/vsscanf.c index 68760b5..b9603e9 100644 --- a/lib/libc/stdio/vsscanf.c +++ b/lib/libc/stdio/vsscanf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc index 5b854fc..702f6d7 100644 --- a/lib/libc/stdlib/Makefile.inc +++ b/lib/libc/stdlib/Makefile.inc @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -11,7 +11,7 @@ # ****************************************************************************/ -STDLIB_SRC_C = error.c strtoul.c strtol.c rand.c \ +STDLIB_SRC_C = error.c atoi.c atol.c strtoul.c strtol.c rand.c \ malloc.c memalign.c realloc.c free.c STDLIB_SRC_ASM = diff --git a/lib/libc/stdlib/atoi.c b/lib/libc/stdlib/atoi.c new file mode 100644 index 0000000..d2fb33b --- /dev/null +++ b/lib/libc/stdlib/atoi.c @@ -0,0 +1,18 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include <stdlib.h> + +int atoi(const char *str) +{ + return strtol(str, NULL, 0); +} diff --git a/lib/libc/stdlib/atol.c b/lib/libc/stdlib/atol.c new file mode 100644 index 0000000..a6aa47b --- /dev/null +++ b/lib/libc/stdlib/atol.c @@ -0,0 +1,18 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include <stdlib.h> + +long atol(const char *str) +{ + return strtol(str, NULL, 0); +} diff --git a/lib/libc/stdlib/error.c b/lib/libc/stdlib/error.c index d440f7c..81020ca 100644 --- a/lib/libc/stdlib/error.c +++ b/lib/libc/stdlib/error.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdlib/free.c b/lib/libc/stdlib/free.c index 7aff279..9005450 100644 --- a/lib/libc/stdlib/free.c +++ b/lib/libc/stdlib/free.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c index 4bc4b79..b2a3138 100644 --- a/lib/libc/stdlib/malloc.c +++ b/lib/libc/stdlib/malloc.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdlib/malloc_defs.h b/lib/libc/stdlib/malloc_defs.h index 59fcd91..1933026 100644 --- a/lib/libc/stdlib/malloc_defs.h +++ b/lib/libc/stdlib/malloc_defs.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdlib/memalign.c b/lib/libc/stdlib/memalign.c index 0bb430e..3b678aa 100644 --- a/lib/libc/stdlib/memalign.c +++ b/lib/libc/stdlib/memalign.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdlib/rand.c b/lib/libc/stdlib/rand.c index d3a0254..87e3efd 100644 --- a/lib/libc/stdlib/rand.c +++ b/lib/libc/stdlib/rand.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdlib/realloc.c b/lib/libc/stdlib/realloc.c index d1dfdfb..652e900 100644 --- a/lib/libc/stdlib/realloc.c +++ b/lib/libc/stdlib/realloc.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/stdlib/strtol.c b/lib/libc/stdlib/strtol.c index ee14a39..aae5e54 100644 --- a/lib/libc/stdlib/strtol.c +++ b/lib/libc/stdlib/strtol.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -9,106 +9,105 @@ * Contributors: * IBM Corporation - initial implementation *****************************************************************************/ -
-long int strtol(const char *S, char **PTR,int BASE)
-{
- long rval = 0;
- short int negative = 0;
- short int digit;
- // *PTR is S, unless PTR is NULL, in which case i override it with my own ptr
- char* ptr;
- if (PTR == 0)
- {
- //override
- PTR = &ptr;
- }
- // i use PTR to advance through the string
- *PTR = (char *) S;
- //check if BASE is ok
- if ((BASE < 0) || BASE > 36)
- {
- return 0;
- }
- // ignore white space at beginning of S
- while ((**PTR == ' ')
- || (**PTR == '\t')
- || (**PTR == '\n')
- || (**PTR == '\r')
- )
- {
- (*PTR)++;
- }
- // check if S starts with "-" in which case the return value is negative
- if (**PTR == '-')
- {
- negative = 1;
- (*PTR)++;
- }
- // if BASE is 0... determine the base from the first chars...
- if (BASE == 0)
- {
- // if S starts with "0x", BASE = 16, else 10
- if ((**PTR == '0') && (*((*PTR)+1) == 'x'))
- {
- BASE = 16;
- (*PTR)++;
- (*PTR)++;
- }
- else
- {
- BASE = 10;
- }
- }
- if (BASE == 16)
- {
- // S may start with "0x"
- if ((**PTR == '0') && (*((*PTR)+1) == 'x'))
- {
- (*PTR)++;
- (*PTR)++;
- }
- }
- //until end of string
- while (**PTR)
- {
- if (((**PTR) >= '0') && ((**PTR) <= '9'))
- {
- //digit (0..9)
- digit = **PTR - '0';
- }
- else if (((**PTR) >= 'a') && ((**PTR) <='z'))
- {
- //alphanumeric digit lowercase(a (10) .. z (35) )
- digit = (**PTR - 'a') + 10;
- }
- else if (((**PTR) >= 'A') && ((**PTR) <='Z'))
- {
- //alphanumeric digit uppercase(a (10) .. z (35) )
- digit = (**PTR - 'A') + 10;
- }
- else
- {
- //end of parseable number reached...
- break;
- }
- if (digit < BASE)
- {
- rval = (rval * BASE) + digit;
- }
- else
- {
- //digit found, but its too big for current base
- //end of parseable number reached...
- break;
- }
- //next...
- (*PTR)++;
- }
- if (negative)
- {
- return rval * -1;
- }
- //else
- return rval;
-}
-
+ +long int strtol(const char *S, char **PTR,int BASE) +{ + long rval = 0; + short int negative = 0; + short int digit; + // *PTR is S, unless PTR is NULL, in which case i override it with my own ptr + char* ptr; + if (PTR == 0) + { + //override + PTR = &ptr; + } + // i use PTR to advance through the string + *PTR = (char *) S; + //check if BASE is ok + if ((BASE < 0) || BASE > 36) + { + return 0; + } + // ignore white space at beginning of S + while ((**PTR == ' ') + || (**PTR == '\t') + || (**PTR == '\n') + || (**PTR == '\r') + ) + { + (*PTR)++; + } + // check if S starts with "-" in which case the return value is negative + if (**PTR == '-') + { + negative = 1; + (*PTR)++; + } + // if BASE is 0... determine the base from the first chars... + if (BASE == 0) + { + // if S starts with "0x", BASE = 16, else 10 + if ((**PTR == '0') && (*((*PTR)+1) == 'x')) + { + BASE = 16; + (*PTR)++; + (*PTR)++; + } + else + { + BASE = 10; + } + } + if (BASE == 16) + { + // S may start with "0x" + if ((**PTR == '0') && (*((*PTR)+1) == 'x')) + { + (*PTR)++; + (*PTR)++; + } + } + //until end of string + while (**PTR) + { + if (((**PTR) >= '0') && ((**PTR) <= '9')) + { + //digit (0..9) + digit = **PTR - '0'; + } + else if (((**PTR) >= 'a') && ((**PTR) <='z')) + { + //alphanumeric digit lowercase(a (10) .. z (35) ) + digit = (**PTR - 'a') + 10; + } + else if (((**PTR) >= 'A') && ((**PTR) <='Z')) + { + //alphanumeric digit uppercase(a (10) .. z (35) ) + digit = (**PTR - 'A') + 10; + } + else + { + //end of parseable number reached... + break; + } + if (digit < BASE) + { + rval = (rval * BASE) + digit; + } + else + { + //digit found, but its too big for current base + //end of parseable number reached... + break; + } + //next... + (*PTR)++; + } + if (negative) + { + return rval * -1; + } + //else + return rval; +} diff --git a/lib/libc/stdlib/strtoul.c b/lib/libc/stdlib/strtoul.c index 74cdccd..3a86c50 100644 --- a/lib/libc/stdlib/strtoul.c +++ b/lib/libc/stdlib/strtoul.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -9,95 +9,95 @@ * Contributors: * IBM Corporation - initial implementation *****************************************************************************/ -
-unsigned long int strtoul(const char *S, char **PTR,int BASE)
-{
- unsigned long rval = 0;
- short int digit;
- // *PTR is S, unless PTR is NULL, in which case i override it with my own ptr
- char* ptr;
- if (PTR == 0)
- {
- //override
- PTR = &ptr;
- }
- // i use PTR to advance through the string
- *PTR = (char *) S;
- //check if BASE is ok
- if ((BASE < 0) || BASE > 36)
- {
- return 0;
- }
- // ignore white space at beginning of S
- while ((**PTR == ' ')
- || (**PTR == '\t')
- || (**PTR == '\n')
- || (**PTR == '\r')
- )
- {
- (*PTR)++;
- }
- // if BASE is 0... determine the base from the first chars...
- if (BASE == 0)
- {
- // if S starts with "0x", BASE = 16, else 10
- if ((**PTR == '0') && (*((*PTR)+1) == 'x'))
- {
- BASE = 16;
- (*PTR)++;
- (*PTR)++;
- }
- else
- {
- BASE = 10;
- }
- }
- if (BASE == 16)
- {
- // S may start with "0x"
- if ((**PTR == '0') && (*((*PTR)+1) == 'x'))
- {
- (*PTR)++;
- (*PTR)++;
- }
- }
- //until end of string
- while (**PTR)
- {
- if (((**PTR) >= '0') && ((**PTR) <='9'))
- {
- //digit (0..9)
- digit = **PTR - '0';
- }
- else if (((**PTR) >= 'a') && ((**PTR) <='z'))
- {
- //alphanumeric digit lowercase(a (10) .. z (35) )
- digit = (**PTR - 'a') + 10;
- }
- else if (((**PTR) >= 'A') && ((**PTR) <='Z'))
- {
- //alphanumeric digit uppercase(a (10) .. z (35) )
- digit = (**PTR - 'A') + 10;
- }
- else
- {
- //end of parseable number reached...
- break;
- }
- if (digit < BASE)
- {
- rval = (rval * BASE) + digit;
- }
- else
- {
- //digit found, but its too big for current base
- //end of parseable number reached...
- break;
- }
- //next...
- (*PTR)++;
- }
- //done
- return rval;
-}
-
+ +unsigned long int strtoul(const char *S, char **PTR,int BASE) +{ + unsigned long rval = 0; + short int digit; + // *PTR is S, unless PTR is NULL, in which case i override it with my own ptr + char* ptr; + if (PTR == 0) + { + //override + PTR = &ptr; + } + // i use PTR to advance through the string + *PTR = (char *) S; + //check if BASE is ok + if ((BASE < 0) || BASE > 36) + { + return 0; + } + // ignore white space at beginning of S + while ((**PTR == ' ') + || (**PTR == '\t') + || (**PTR == '\n') + || (**PTR == '\r') + ) + { + (*PTR)++; + } + // if BASE is 0... determine the base from the first chars... + if (BASE == 0) + { + // if S starts with "0x", BASE = 16, else 10 + if ((**PTR == '0') && (*((*PTR)+1) == 'x')) + { + BASE = 16; + (*PTR)++; + (*PTR)++; + } + else + { + BASE = 10; + } + } + if (BASE == 16) + { + // S may start with "0x" + if ((**PTR == '0') && (*((*PTR)+1) == 'x')) + { + (*PTR)++; + (*PTR)++; + } + } + //until end of string + while (**PTR) + { + if (((**PTR) >= '0') && ((**PTR) <='9')) + { + //digit (0..9) + digit = **PTR - '0'; + } + else if (((**PTR) >= 'a') && ((**PTR) <='z')) + { + //alphanumeric digit lowercase(a (10) .. z (35) ) + digit = (**PTR - 'a') + 10; + } + else if (((**PTR) >= 'A') && ((**PTR) <='Z')) + { + //alphanumeric digit uppercase(a (10) .. z (35) ) + digit = (**PTR - 'A') + 10; + } + else + { + //end of parseable number reached... + break; + } + if (digit < BASE) + { + rval = (rval * BASE) + digit; + } + else + { + //digit found, but its too big for current base + //end of parseable number reached... + break; + } + //next... + (*PTR)++; + } + //done + return rval; +} + diff --git a/lib/libc/string/Makefile.inc b/lib/libc/string/Makefile.inc index e857bbc..7ccf3c4 100644 --- a/lib/libc/string/Makefile.inc +++ b/lib/libc/string/Makefile.inc @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -13,7 +13,7 @@ STRING_SRC_C = strcat.c strchr.c strcmp.c strcpy.c strlen.c strncmp.c \ strncpy.c strstr.c memset.c memcpy.c memmove.c memchr.c \ - memcmp.c strcasecmp.c strncasecmp.c + memcmp.c strcasecmp.c strncasecmp.c strtok.c STRING_SRC_ASM = STRING_SRCS = $(STRING_SRC_C:%=$(STRINGCMNDIR)/%) $(STRING_SRC_ASM:%=$(STRINGCMNDIR)/%) STRING_OBJS = $(STRING_SRC_C:%.c=%.o) $(STRING_SRC_ASM:%.S=%.o) diff --git a/lib/libc/string/memchr.c b/lib/libc/string/memchr.c index d4e9b7f..c3fe751 100644 --- a/lib/libc/string/memchr.c +++ b/lib/libc/string/memchr.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/string/memcmp.c b/lib/libc/string/memcmp.c index b64d560..3b69cef 100644 --- a/lib/libc/string/memcmp.c +++ b/lib/libc/string/memcmp.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/string/memcpy.c b/lib/libc/string/memcpy.c index 36a4a3c..00f419b 100644 --- a/lib/libc/string/memcpy.c +++ b/lib/libc/string/memcpy.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/string/memmove.c b/lib/libc/string/memmove.c index 7ceee33..3acf1a9 100644 --- a/lib/libc/string/memmove.c +++ b/lib/libc/string/memmove.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/string/memset.c b/lib/libc/string/memset.c index 0f5a660..f8dfbf5 100644 --- a/lib/libc/string/memset.c +++ b/lib/libc/string/memset.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/string/strcasecmp.c b/lib/libc/string/strcasecmp.c index 98cde44..f75294f 100644 --- a/lib/libc/string/strcasecmp.c +++ b/lib/libc/string/strcasecmp.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/string/strcat.c b/lib/libc/string/strcat.c index eadd6b9..eb597a0 100644 --- a/lib/libc/string/strcat.c +++ b/lib/libc/string/strcat.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/string/strchr.c b/lib/libc/string/strchr.c index 214eaa9..528a319 100644 --- a/lib/libc/string/strchr.c +++ b/lib/libc/string/strchr.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/string/strcmp.c b/lib/libc/string/strcmp.c index 4a765ea..48eaed2 100644 --- a/lib/libc/string/strcmp.c +++ b/lib/libc/string/strcmp.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/string/strcpy.c b/lib/libc/string/strcpy.c index 4c888ca..48eb62c 100644 --- a/lib/libc/string/strcpy.c +++ b/lib/libc/string/strcpy.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/string/strlen.c b/lib/libc/string/strlen.c index c091f75..37a1b78 100644 --- a/lib/libc/string/strlen.c +++ b/lib/libc/string/strlen.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/string/strncasecmp.c b/lib/libc/string/strncasecmp.c index 1aa6639..4140931 100644 --- a/lib/libc/string/strncasecmp.c +++ b/lib/libc/string/strncasecmp.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/string/strncmp.c b/lib/libc/string/strncmp.c index 357d113..a886736 100644 --- a/lib/libc/string/strncmp.c +++ b/lib/libc/string/strncmp.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/string/strncpy.c b/lib/libc/string/strncpy.c index a2667d8..0f41f93 100644 --- a/lib/libc/string/strncpy.c +++ b/lib/libc/string/strncpy.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/string/strstr.c b/lib/libc/string/strstr.c index f94af6d..3e090d2 100644 --- a/lib/libc/string/strstr.c +++ b/lib/libc/string/strstr.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libc/string/strtok.c b/lib/libc/string/strtok.c new file mode 100644 index 0000000..665c08d --- /dev/null +++ b/lib/libc/string/strtok.c @@ -0,0 +1,45 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include <string.h> + +char * +strtok(char *src, const char *pattern) +{ + static char *nxtTok; + char *retVal = NULL; + + if (!src) + src = nxtTok; + + while (*src) { + const char *pp = pattern; + while (*pp) { + if (*pp == *src) { + break; + } + pp++; + } + if (!*pp) { + if (!retVal) + retVal = src; + else if (!src[-1]) + break; + } else + *src = '\0'; + src++; + } + + nxtTok = src; + + return retVal; +} diff --git a/lib/libelf/Makefile b/lib/libelf/Makefile index 3bd56ce..82ef0bb 100644 --- a/lib/libelf/Makefile +++ b/lib/libelf/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -14,9 +14,7 @@ TOPCMNDIR ?= ../.. include $(TOPCMNDIR)/make.rules -CFLAGS = -g -O2 -fno-builtin -ffreestanding -nostdinc -msoft-float \ - -mno-altivec -mabi=no-altivec -Wall -CPPFLAGS = -I../libc/include $(CPUARCHDEF) -I$(INCLCMNDIR)/$(CPUARCH) +CPPFLAGS = -I../libc/include $(CPUARCHDEF) -I$(INCLCMNDIR) -I$(INCLCMNDIR)/$(CPUARCH) LDFLAGS= -nostdlib TARGET = ../libelf.a diff --git a/lib/libelf/elf.c b/lib/libelf/elf.c index 93e5762..359f628 100644 --- a/lib/libelf/elf.c +++ b/lib/libelf/elf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -14,6 +14,7 @@ #include <string.h> #include <cpu.h> +#include <libelf.h> struct ehdr { unsigned int ei_ident; diff --git a/lib/libelf/libelf.code b/lib/libelf/libelf.code index 01efdf3..6e019fc 100644 --- a/lib/libelf/libelf.code +++ b/lib/libelf/libelf.code @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libelf/libelf.in b/lib/libelf/libelf.in index 1b74d51..1fea40c 100644 --- a/lib/libelf/libelf.in +++ b/lib/libelf/libelf.in @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/lib/libipmi/libipmi.code b/lib/libipmi/libipmi.code index 761a50d..59c1244 100644 --- a/lib/libipmi/libipmi.code +++ b/lib/libipmi/libipmi.code @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -103,3 +103,18 @@ PRIM(IPMI_X2d_OEM_X2d_BIOS2SP) TOS.n = ipmi_oem_bios2sp(swid, type, addr, len); MIRP +// : ipmi-set-sensor ( param-1 ... param-n n command sensor - errorcode ) +PRIM(IPMI_X2d_SET_X2d_SENSOR) + int sensor = TOS.n; POP; + int cmd = TOS.n; POP; + int n = TOS.n; + int i = n; + uint8_t param[10]; + while (i>0) { + i--; + POP; param[i]=TOS.n; + }; + TOS.n = ipmi_set_sensor((cmd<<8)+sensor,n, + param[0],param[1],param[2],param[3],param[4], + param[5],param[6],param[7],param[8],param[9]); +MIRP diff --git a/lib/libipmi/libipmi.h b/lib/libipmi/libipmi.h index 5651180..9ac8308 100644 --- a/lib/libipmi/libipmi.h +++ b/lib/libipmi/libipmi.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -19,6 +19,7 @@ extern int ipmi_kcs_cmd(uint8_t *, uint8_t *, uint32_t, uint32_t *); extern void ipmi_system_reboot(void); extern void ipmi_power_off(void); +extern int ipmi_set_sensor(const int sensor, int number_of_args, ...); extern int ipmi_oem_stop_bootwatchdog(void); extern int ipmi_oem_set_bootwatchdog(uint16_t seconds); diff --git a/lib/libipmi/libipmi.in b/lib/libipmi/libipmi.in index a0d0f12..5b0e0ec 100644 --- a/lib/libipmi/libipmi.in +++ b/lib/libipmi/libipmi.in @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -21,3 +21,4 @@ cod(IPMI-OEM-READ-VPD) cod(IPMI-OEM-WRITE-VPD) cod(IPMI-OEM-GET-BLADE-DESCR) cod(IPMI-OEM-BIOS2SP) +cod(IPMI-SET-SENSOR) diff --git a/lib/libnvram/Makefile b/lib/libnvram/Makefile new file mode 100644 index 0000000..6c9ec84 --- /dev/null +++ b/lib/libnvram/Makefile @@ -0,0 +1,49 @@ +# ***************************************************************************** +# * Copyright (c) 2004, 2008 IBM Corporation +# * All rights reserved. +# * This program and the accompanying materials +# * are made available under the terms of the BSD License +# * which accompanies this distribution, and is available at +# * http://www.opensource.org/licenses/bsd-license.php +# * +# * Contributors: +# * IBM Corporation - initial implementation +# ****************************************************************************/ + +SRCS = nvram.c envvar.c + +TOPCMNDIR ?= ../.. + +ASFLAGS = $(FLAG) $(RELEASE) $(CPUARCHDEF) -Wa,-mregnames +CPPFLAGS = -I../libc/include $(CPUARCHDEF) -I$(INCLBRDDIR) -I$(INCLCMNDIR)/$(CPUARCH) -I. -I../../include +LDFLAGS = -nostdlib + +TARGET = ../libnvram.a + +all: $(TARGET) + +OBJS = $(SRCS:%.c=%.o) + +$(TARGET): $(OBJS) + $(AR) -rc $@ $(OBJS) + $(RANLIB) $@ + + +clean: + $(RM) $(TARGET) $(OBJS) + +distclean: clean + $(RM) Makefile.dep + + +# Rules for creating the dependency file: +depend: + $(RM) Makefile.dep + $(MAKE) Makefile.dep + +Makefile.dep: Makefile + + +# Include dependency file if available: +-include Makefile.dep + diff --git a/lib/libnvram/envvar.c b/lib/libnvram/envvar.c new file mode 100644 index 0000000..eec7db7 --- /dev/null +++ b/lib/libnvram/envvar.c @@ -0,0 +1,244 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include <stdint.h> +#include "../libc/include/stdio.h" +#include "../libc/include/string.h" +#include "../libc/include/stdlib.h" +#include "nvram.h" + +/* returns the offset of the first byte after the searched envvar */ +static int get_past_env_pos(partition_t part, char *envvar) +{ + int offset, len; + static char temp[256]; + uint8_t data; + + offset=part.addr; + + memset(temp, 0, 256); + + do { + len=0; + while((data=nvram_read_byte(offset++)) && len < 256) { + temp[len++]=data; + } + if (!strncmp(envvar, temp, strlen(envvar))) { + return offset; + } + } while (len); + + return -1; +} + +/** + * @param partition name of the envvar partition + * @param envvar name of the environment variable + * @return pointer to temporary string containing the value of envvar + */ + +char *get_env(partition_t part, char *envvar) +{ + static char temp[256+1]; + int len, offset; + uint8_t data; + + DEBUG("get_env %s... ", envvar); + if(!part.addr) { + /* ERROR: No environment variable partition */ + DEBUG("invalid partition.\n"); + return NULL; + } + + offset=part.addr; + + do { + len=0; + while((data=nvram_read_byte(offset++)) && len < 256) { + temp[len++]=data; + } + temp[len]=0; + + if (!strncmp(envvar, temp, strlen(envvar))) { + int pos=0; + while (temp[pos]!='=' && pos < len) pos++; + // DEBUG("value='%s'\n", temp+pos+1); + return temp+pos+1; + } + } while (len); + + DEBUG("not found\n"); + return NULL; +} + +static int find_last_envvar(partition_t part) +{ + uint8_t last, current; + int offset, len; + + offset=part.addr; + len=part.len; + + last=nvram_read_byte(part.addr); + + for (offset=part.addr; offset<(int)(part.addr+part.len); offset++) { + current=nvram_read_byte(offset); + if(!last && !current) + return offset; + + last=current; + } + + return -1; +} + +int add_env(partition_t part, char *envvar, char *value) +{ + int freespace, last, len, offset; + unsigned int i; + + /* Find offset where we can write */ + last = find_last_envvar(part); + + /* How much space do we have left? */ + freespace = part.addr+part.len-last; + + /* how long is the entry we want to write? */ + len = strlen(envvar) + strlen(value) + 2; + + if(freespace<len) { + // TODO try to increase partition size + return -1; + } + + offset=last; + + for(i=0; i<strlen(envvar); i++) + nvram_write_byte(offset++, envvar[i]); + + nvram_write_byte(offset++, '='); + + for(i=0; i<strlen(value); i++) + nvram_write_byte(offset++, value[i]); + + return 0; +} + +int del_env(partition_t part, char *envvar) +{ + int last, current, pos, i; + char *buffer; + + if(!part.addr) + return -1; + + last=find_last_envvar(part); + current = pos = get_past_env_pos(part, envvar); + + // TODO is this really required? + /* go back to non-0 value */ + current--; + + while (nvram_read_byte(current)) + current--; + + // TODO is this required? + current++; + + buffer=get_nvram_buffer(last-pos); + + for (i=0; i<last-pos; i++) + buffer[i]=nvram_read_byte(i+pos); + + for (i=0; i<last-pos; i++) + nvram_write_byte(i+current, buffer[i]); + + free_nvram_buffer(buffer); + + erase_nvram(last, current+last-pos); + + return 0; +} + +int set_env(partition_t part, char *envvar, char *value) +{ + char *oldvalue, *buffer; + int last, current, buffersize, i; + + DEBUG("set_env %lx[%lx]: %s=%s\n", part.addr, part.len, envvar, value); + + if(!part.addr) + return -1; + + /* Check whether the environment variable exists already */ + oldvalue = get_env(part, envvar); + + if(oldvalue==NULL) + return add_env(part, envvar, value); + + + /* The value did not change. So we succeeded! */ + if(!strncmp(oldvalue, value, strlen(value)+1)) + return 0; + + /* we need to overwrite environment variables, back them up first */ + + // DEBUG("overwriting existing environment variable\n"); + + /* allocate a buffer */ + last=find_last_envvar(part); + current=get_past_env_pos(part, envvar); + buffersize = last - current; + buffer=get_nvram_buffer(buffersize); + if(!buffer) + return -1; + + for (i=0; i<buffersize; i++) { + buffer[i] = nvram_read_byte(current+i); + } + + /* walk back until the = */ + while (nvram_read_byte(current)!='=') { + current--; + } + + /* Start at envvar= */ + current++; + + /* Write the new value */ + for(i=0; i<(int)strlen(value); i++) { + nvram_write_byte(current++, value[i]); + } + + /* Write end of string marker */ + nvram_write_byte(current++, 0); + + /* Copy back the buffer */ + for (i=0; i<buffersize; i++) { + nvram_write_byte(current++, buffer[i]); + } + + free_nvram_buffer(buffer); + + /* If the new environment variable content is shorter than the old one, + * we need to erase the rest of the bytes + */ + + if (current<last) { + for(i=current; i<last; i++) { + nvram_write_byte(i, 0); + } + } + + return 0; /* success */ +} + diff --git a/lib/libnvram/libnvram.code b/lib/libnvram/libnvram.code new file mode 100644 index 0000000..f1fd414 --- /dev/null +++ b/lib/libnvram/libnvram.code @@ -0,0 +1,279 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ +#include <nvram.h> + +#define STRING_INIT(str) \ + char str[255]; \ + char * str##_address; \ + int str##_length; + +#define STRING_FROM_STACK(str) \ + str##_length = TOS.u; POP; \ + str##_address = TOS.a; POP; \ + memcpy(str, str##_address, str##_length); \ + memset(str + str##_length, 0, 255 - str##_length); + +PRIM(nvram_X2d_c_X40) + unsigned int offset = TOS.u; + TOS.u=nvram_read_byte(offset); +MIRP + +PRIM(nvram_X2d_w_X40) + unsigned int offset = TOS.u; + TOS.u=nvram_read_word(offset); +MIRP + +PRIM(nvram_X2d_l_X40) + unsigned int offset = TOS.u; + TOS.u=nvram_read_dword(offset); +MIRP + +PRIM(nvram_X2d_x_X40) + unsigned int offset = TOS.u; + TOS.u=nvram_read_qword(offset); +MIRP + +PRIM(nvram_X2d_c_X21) + nvram_write_byte(TOS.u, NOS.u); + POP; POP; +MIRP + +PRIM(nvram_X2d_w_X21) + nvram_write_word(TOS.u, NOS.u); + POP; POP; +MIRP + +PRIM(nvram_X2d_l_X21) + nvram_write_dword(TOS.u, NOS.u); + POP; POP; +MIRP + +PRIM(nvram_X2d_x_X21) + nvram_write_qword(TOS.u, NOS.u); + POP; POP; +MIRP + +/* get-nvram-partition ( type -- addr len FAILED? ) */ +PRIM(get_X2d_nvram_X2d_partition) + partition_t partition; + unsigned int ptype = TOS.u; + partition = get_partition(ptype, NULL); + if(partition.len && partition.len != -1) { + TOS.u = partition.addr; + PUSH; + TOS.u = partition.len; + PUSH; + TOS.u = 0; // FALSE + } else { + TOS.u = -1; // TRUE + } +MIRP + +/* get-named-nvram-partition ( name.addr name.len -- addr len FAILED? ) */ +PRIM(get_X2d_named_X2d_nvram_X2d_partition) + STRING_INIT(name) + partition_t partition; + + STRING_FROM_STACK(name) + partition = get_partition(-1, name); + + if(partition.len && partition.len != -1) { + PUSH; + TOS.u = partition.addr; + PUSH; + TOS.u = partition.len; + PUSH; + TOS.u = 0; // FALSE + } else { + PUSH; + TOS.u = -1; // TRUE + } +MIRP + + + +/* new-nvram-partition ( type name.addr name.len len -- part.offs part.len FALSE | TRUE) */ +PRIM(new_X2d_nvram_X2d_partition) + int type, len, i, slen; + char name[12], *addr; + partition_t partition; + + len = TOS.u; POP; + slen = TOS.u; POP; + addr = (char *)TOS.u; POP; + type = TOS.u; POP; + + for (i=0; i<12; i++) { + if(slen>i) + name[i]=addr[i]; + else + name[i]=0; + } + + partition=new_nvram_partition(type, name, len); + + if(!partition.len) { + PUSH; TOS.u = -1; // TRUE + } else { + PUSH; TOS.u = partition.addr; + PUSH; TOS.u = partition.len; + PUSH; TOS.u = 0; // FALSE + } +MIRP + +/* inrease-nvram-partition ( part.offs part.len new-len -- FALSE | TRUE ) */ +PRIM(increase_X2d_nvram_X2d_partition) + int len, ret; + partition_t partition; + + // FIXME + partition.addr = TOS.u; POP; + partition.len = TOS.u; POP; + len = TOS.u; POP; + + ret=increase_nvram_partition_size(partition, len); + + PUSH; + + if(!ret) + TOS.u=-1; // TRUE + else + TOS.u=0; // FALSE + +MIRP + +PRIM(internal_X2d_reset_X2d_nvram) + reset_nvram(); +MIRP + +PRIM(wipe_X2d_nvram) + wipe_nvram(); +MIRP + +PRIM(nvram_X2d_debug) + nvram_debug(); +MIRP + +// ( part.start part.len name.addr name.len -- var.addr var.len TRUE | false ) +PRIM(internal_X2d_get_X2d_env) + STRING_INIT(name) + partition_t part; + char *val; + + STRING_FROM_STACK(name) + part.len = TOS.u; POP; + part.addr = TOS.u; POP; + + val=get_env(part, name); + if(val) { + PUSH; TOS.a = val; + PUSH; TOS.u = strlen(val); + PUSH; TOS.u = -1; // TRUE + } else { + PUSH; TOS.u = 0; // FALSE + } +MIRP + +// ( part.start part.len name.addr name.len val.addr val.len -- FALSE|TRUE) +PRIM(internal_X2d_add_X2d_env) + STRING_INIT(name) + STRING_INIT(value) + partition_t part; + int ret; + + STRING_FROM_STACK(value) + STRING_FROM_STACK(name) + part.len = TOS.u; POP; + part.addr = TOS.u; POP; + + ret=add_env(part, name, value); + if(ret) { + PUSH; TOS.u = -1; // TRUE + } else { + PUSH; TOS.u = 0; // FALSE + } +MIRP + +// ( part.addr part.len name.addr name.len -- FALSE|TRUE) +PRIM(internal_X2d_del_X2d_env) + STRING_INIT(name) + partition_t part; + int ret; + + STRING_FROM_STACK(name); + part.len = TOS.u; POP; + part.addr = TOS.u; POP; + + ret=del_env(part, name); + if(ret) { + PUSH; TOS.u = -1; // TRUE + } else { + PUSH; TOS.u = 0; // FALSE + } + +MIRP + +// internal-set-env ( part.addr part.len name.addr name.len val.addr val.len -- FALSE|TRUE) +PRIM(internal_X2d_set_X2d_env) + STRING_INIT(name) + STRING_INIT(value) + partition_t part; + int ret; + + STRING_FROM_STACK(value) + STRING_FROM_STACK(name) + part.len = TOS.u; POP; + part.addr = TOS.u; POP; + + ret=set_env(part, name, value); + if(ret) { + PUSH; TOS.u = -1; // TRUE + } else { + PUSH; TOS.u = 0; // FALSE + } +MIRP + +// ( part.addr part.len -- FALSE|TRUE) +PRIM(erase_X2d_nvram_X2d_partition) + partition_t part; + int ret; + + part.len = TOS.u; POP; + part.addr = TOS.u; POP; + + ret=clear_nvram_partition(part); + if(ret) { + PUSH; TOS.u = -1; // TRUE + } else { + PUSH; TOS.u = 0; // FALSE + } + +MIRP + +// ( part.addr part.len -- FALSE|TRUE) +PRIM(delete_X2d_nvram_X2d_partition) + partition_t part; + int ret; + + part.len = TOS.u; POP; + part.addr = TOS.u; POP; + + ret=delete_nvram_partition(part); + if(ret) { + PUSH; TOS.u = -1; // TRUE + } else { + PUSH; TOS.u = 0; // FALSE + } + +MIRP + + diff --git a/lib/libnvram/libnvram.in b/lib/libnvram/libnvram.in new file mode 100644 index 0000000..33ab3bc --- /dev/null +++ b/lib/libnvram/libnvram.in @@ -0,0 +1,41 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +/* NVRAM access primitives */ +cod(nvram-c@) +cod(nvram-c!) +cod(nvram-w@) +cod(nvram-w!) +cod(nvram-l@) +cod(nvram-l!) +cod(nvram-x@) +cod(nvram-x!) + +/* Generic NVRAM helpers */ +cod(internal-reset-nvram) +cod(nvram-debug) +cod(wipe-nvram) + +/* NVRAM Partition Handling */ +cod(get-nvram-partition) +cod(get-named-nvram-partition) +cod(new-nvram-partition) +cod(increase-nvram-partition) +cod(erase-nvram-partition) +cod(delete-nvram-partition) + +/* NVRAM environment access words */ +cod(internal-get-env) +cod(internal-add-env) +cod(internal-del-env) +cod(internal-set-env) + diff --git a/lib/libnvram/nvram.c b/lib/libnvram/nvram.c new file mode 100644 index 0000000..a31bb53 --- /dev/null +++ b/lib/libnvram/nvram.c @@ -0,0 +1,518 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include "cache.h" + +#include "../libc/include/stdio.h" +#include "../libc/include/string.h" +#include "../libc/include/stdlib.h" + +#include "nvram.h" + +#include <stdarg.h> +#include <string.h> +#include <southbridge.h> +#include <nvramlog.h> + +void asm_cout(long Character,long UART,long NVRAM); + +static volatile uint8_t *nvram=(volatile uint8_t *)SB_NVRAM_adr; + +/* This is extremely ugly, but still better than implementing + * another sbrk() around it. + */ +static char nvram_buffer[NVRAM_LENGTH]; +static uint8_t nvram_buffer_locked=0x00; + +/** + * producer for nvram access functions. Since these functions are + * basically all the same except for the used data types, produce + * them via the following macro to keep the code from bloating. + */ + +#define nvram_access(type,size,name) \ + type nvram_read_##name(unsigned int offset) \ + { \ + type *pos; \ + if (offset > (NVRAM_LENGTH - sizeof(type))) \ + return 0; \ + pos = (type *)(nvram+offset); \ + return ci_read_##size(pos); \ + } \ + void nvram_write_##name(unsigned int offset, type data) \ + { \ + type *pos; \ + if (offset > (NVRAM_LENGTH - sizeof(type))) \ + return; \ + pos = (type *)(nvram+offset); \ + ci_write_##size(pos, data); \ + } + +nvram_access(uint8_t, 8, byte) +nvram_access(uint16_t, 16, word) +nvram_access(uint32_t, 32, dword) +nvram_access(uint64_t, 64, qword) + +/** + * This function is a minimal abstraction for our temporary + * buffer. It should have been malloced, but since there is no + * usable malloc, we go this route. + * + * @return pointer to temporary buffer + */ + +char *get_nvram_buffer(int len) +{ + if(len>NVRAM_LENGTH) + return NULL; + + if(nvram_buffer_locked) + return NULL; + + nvram_buffer_locked = 0xff; + + return nvram_buffer; +} + +/** + * @param buffer pointer to the allocated buffer. This + * is unused, but nice in case we ever get a real malloc + */ + +void free_nvram_buffer(char *buffer __attribute__((unused))) +{ + nvram_buffer_locked = 0x00; +} + +/** + * @param fmt format string, like in printf + * @param ... variable number of arguments + */ + +int nvramlog_printf(const char* fmt, ...) +{ + char buff[256]; + int count, i; + va_list ap; + + va_start(ap, fmt); + count = vsprintf(buff, fmt, ap); + va_end(ap); + + for (i=0; i<count; i++) + asm_cout(buff[i], 0, 1); + + return count; +} + +/** + * @param offset start offset of the partition header + */ + +static uint8_t get_partition_type(int offset) +{ + return nvram_read_byte(offset); +} + +/** + * @param offset start offset of the partition header + */ + +static uint8_t get_partition_header_checksum(int offset) +{ + return nvram_read_byte(offset+1); +} + +/** + * @param offset start offset of the partition header + */ + +static uint16_t get_partition_len(int offset) +{ + return nvram_read_word(offset+2); +} + +/** + * @param offset start offset of the partition header + * @return static char array containing the partition name + * + * NOTE: If the partition name needs to be non-temporary, strdup + * and use the copy instead. + */ + +static char * get_partition_name(int offset) +{ + static char name[12]; + int i; + for (i=0; i<12; i++) + name[i]=nvram_read_byte(offset+4+i); + + // DEBUG("name: \"%s\"\n", name); + return name; +} + +static uint8_t calc_partition_header_checksum(int offset) +{ + uint16_t plainsum; + uint8_t checksum; + int i; + + plainsum = nvram_read_byte(offset); + + for (i=2; i<PARTITION_HEADER_SIZE; i++) + plainsum+=nvram_read_byte(offset+i); + + checksum=(plainsum>>8)+(plainsum&0xff); + + return checksum; +} + +static int calc_used_nvram_space(void) +{ + int walk, len; + + for (walk=0; walk<NVRAM_LENGTH;) { + if(get_partition_header_checksum(walk) != + calc_partition_header_checksum(walk)) { + /* If there's no valid entry, bail out */ + break; + } + + len=get_partition_len(walk); + // DEBUG("... part len=%x, %x\n", len, len*16); + + if(!len) { + /* If there's a partition type but no len, bail out. + * Don't bail out if type is 0. This can be used to + * find the offset of the first free byte. + */ + break; + } + + walk += len * 16; + } + DEBUG("used nvram space: %d\n", walk); + + return walk; +} + +/** + * + * @param type partition type. Set this to the partition type you are looking + * for. If there are several partitions with the same type, only + * the first partition with that type will be found. + * Set to -1 to ignore. Set to 0 to find free unpartitioned space. + * + * @param name partition name. Set this to the name of the partition you are + * looking for. If there are several partitions with the same name, + * only the first partition with that name will be found. + * Set to NULL to ignore. + * + * To disambiguate the partitions you should have a unique name if you plan to + * have several partitions of the same type. + * + */ + +partition_t get_partition(unsigned int type, char *name) +{ + partition_t ret={0,-1}; + int walk, len; + + for (walk=0; walk<NVRAM_LENGTH;) { + // DEBUG("get_partition: walk=%x\n", walk); + if(get_partition_header_checksum(walk) != + calc_partition_header_checksum(walk)) { + /* If there's no valid entry, bail out */ + break; + } + + len=get_partition_len(walk); + if(type && !len) { + /* If there's a partition type but no len, bail out. + * Don't bail out if type is 0. This can be used to + * find the offset of the first free byte. + */ + break; + } + + /* Check if either type or name or both do not match. */ + if ( (type!=(unsigned int)-1 && type != get_partition_type(walk)) || + (name && strncmp(get_partition_name(walk), name, 12)) ) { + /* We hit another partition. Continue + * at the end of this partition + */ + walk += len*16; + continue; + } + + ret.addr=walk+PARTITION_HEADER_SIZE; + ret.len=(len*16)-PARTITION_HEADER_SIZE; + break; + } + + return ret; +} + +void erase_nvram(int offset, int len) +{ + int i; + + for (i=offset; i<offset+len; i++) + nvram_write_byte(i, 0); +} + +void wipe_nvram(void) +{ + erase_nvram(0, NVRAM_LENGTH); +} + +/** + * @param partition partition structure pointing to the partition to wipe. + * @param header_only if header_only is != 0 only the partition header is + * nulled out, not the whole partition. + */ + +int wipe_partition(partition_t partition, int header_only) +{ + int pstart, len; + + pstart=partition.addr-PARTITION_HEADER_SIZE; + + len=PARTITION_HEADER_SIZE; + + if(!header_only) + len += partition.len; + + erase_nvram(pstart, len); + + return 0; +} + + +static partition_t create_nvram_partition(int type, const char *name, int len) +{ + partition_t ret = { 0, 0 }; + int offset, plen; + unsigned int i; + + plen = ALIGN(len+PARTITION_HEADER_SIZE, 16); + + DEBUG("Creating partition type=%x, name=%s, len=%d plen=%d\n", + type, name, len, plen); + + offset = calc_used_nvram_space(); + + if (NVRAM_LENGTH-(calc_used_nvram_space())<plen) { + DEBUG("Not enough free space.\n"); + return ret; + } + + DEBUG("Writing header."); + + nvram_write_byte(offset, type); + nvram_write_word(offset+2, plen/16); + + for (i=0; i<strlen(name); i++) + nvram_write_byte(offset+4+i, name[i]); + + nvram_write_byte(offset+1, calc_partition_header_checksum(offset)); + + ret.addr = offset+PARTITION_HEADER_SIZE; + ret.len = len; + + DEBUG("partition created: addr=%lx len=%lx\n", ret.addr, ret.len); + + return ret; +} + +static int create_free_partition(void) +{ + int free_space; + partition_t free_part; + + free_space = NVRAM_LENGTH - calc_used_nvram_space() - PARTITION_HEADER_SIZE; + free_part = create_nvram_partition(0x7f, "free space", free_space); + + return (free_part.addr != 0); +} + +partition_t new_nvram_partition(int type, char *name, int len) +{ + partition_t free_part, new_part = { 0, 0 }; + + /* NOTE: Assume all free space is consumed by the "free space" + * partition. This means a partition can not be increased in the middle + * of reset_nvram, which is obviously not a big loss. + */ + + free_part=get_partition(0x7f, NULL); + if( free_part.len && free_part.len != -1) + wipe_partition(free_part, 1); + + new_part = create_nvram_partition(type, name, len); + + if(new_part.len != len) { + new_part.len = 0; + new_part.addr = 0; + } + + create_free_partition(); + + return new_part; +} + +/** + * @param partition partition structure pointing to the partition to wipe. + */ + +int delete_nvram_partition(partition_t partition) +{ + int i; + partition_t free_part; + + if(!partition.len || partition.len == -1) + return 0; + + for (i=partition.addr+partition.len; i< NVRAM_LENGTH; i++) + nvram_write_byte(i - partition.len - PARTITION_HEADER_SIZE, nvram_read_byte(i)); + + erase_nvram(NVRAM_LENGTH-partition.len-PARTITION_HEADER_SIZE, + partition.len-PARTITION_HEADER_SIZE); + + free_part=get_partition(0x7f, NULL); + wipe_partition(free_part, 0); + create_free_partition(); + + return 1; +} + +int clear_nvram_partition(partition_t part) +{ + if(!part.addr) + return 0; + + erase_nvram(part.addr, part.len); + + return 1; +} + + +int increase_nvram_partition_size(partition_t partition, int newsize) +{ + partition_t free_part; + int free_offset, end_offset, i; + + /* We don't support shrinking partitions (yet) */ + if (newsize < partition.len) { + return 0; + } + + /* NOTE: Assume all free space is consumed by the "free space" + * partition. This means a partition can not be increased in the middle + * of reset_nvram, which is obviously not a big loss. + */ + + free_part=get_partition(0x7f, NULL); + + // FIXME: It could be 16 byte more. Also handle empty "free" partition. + if (free_part.len == -1 || free_part.len < newsize - partition.len ) { + return 0; + } + + free_offset=free_part.addr - PARTITION_HEADER_SIZE; // first unused byte + end_offset=partition.addr + partition.len; // last used byte of partition + 1 + + if(free_offset > end_offset) { + int j, bufferlen; + char *overlap_buffer; + + bufferlen=free_offset - end_offset; + + overlap_buffer=get_nvram_buffer(bufferlen); + if(!overlap_buffer) { + return 0; + } + + for (i=end_offset, j=0; i<free_offset; i++, j++) + overlap_buffer[j]=nvram_read_byte(i); + + /* Only wipe the header. The free space partition is empty per + * definition + */ + + wipe_partition(free_part, 1); + + for (i=partition.addr+newsize, j=0; i<(int)(partition.addr+newsize+bufferlen); i++, j++) + nvram_write_byte(i, overlap_buffer[j]); + + free_nvram_buffer(overlap_buffer); + } else { + /* Only wipe the header. */ + wipe_partition(free_part, 1); + } + + /* Clear the new partition space */ + erase_nvram(partition.addr+partition.len, newsize-partition.len); + + nvram_write_word(partition.addr - 16 + 2, newsize); + + create_free_partition(); + + return 1; +} + +static void init_cpulog_partition(partition_t cpulog) +{ + unsigned int offset=cpulog.addr; + + /* see board-xxx/include/nvramlog.h for information */ + nvram_write_word(offset+0, 0x40); // offset + nvram_write_word(offset+2, 0x00); // flags + nvram_write_dword(offset+4, 0x01); // pointer + +} + +void reset_nvram(void) +{ + partition_t cpulog0, cpulog1; + char header[12]; + + DEBUG("Erasing NVRAM\n"); + erase_nvram(0, NVRAM_LENGTH); + + DEBUG("Creating CPU log partitions\n"); + *(uint32_t *)&(header[0]) = be32_to_cpu(LLFW_LOG_BE0_NAME_PREFIX); + *(uint64_t *)&(header[4]) = be64_to_cpu(LLFW_LOG_BE0_NAME); + cpulog0=create_nvram_partition(LLFW_LOG_BE0_SIGNATURE, header, + (LLFW_LOG_BE0_LENGTH*16)-PARTITION_HEADER_SIZE); + + *(uint32_t *)&(header[0]) = be32_to_cpu(LLFW_LOG_BE1_NAME_PREFIX); + *(uint64_t *)&(header[4]) = be64_to_cpu(LLFW_LOG_BE1_NAME); + cpulog1=create_nvram_partition(LLFW_LOG_BE1_SIGNATURE, header, + (LLFW_LOG_BE1_LENGTH*16)-PARTITION_HEADER_SIZE); + + DEBUG("Initializing CPU log partitions\n"); + init_cpulog_partition(cpulog0); + init_cpulog_partition(cpulog1); + + nvramlog_printf("Creating common NVRAM partition\r\n"); + create_nvram_partition(0x70, "common", 0x01000-PARTITION_HEADER_SIZE); + + create_free_partition(); +} + +void nvram_debug(void) +{ + printf("\nNVRAM_BASE: %lx\n", (unsigned long)SB_NVRAM_adr); + printf("NVRAM_LEN: %x\n", NVRAM_LENGTH); +} + diff --git a/lib/libnvram/nvram.h b/lib/libnvram/nvram.h new file mode 100644 index 0000000..d15b85e --- /dev/null +++ b/lib/libnvram/nvram.h @@ -0,0 +1,90 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#ifndef __NVRAM_H +#define __NVRAM_H 1 + +/* data structures */ + +typedef struct { + unsigned long addr; + long len; +} partition_t; + +/* macros */ + +#define DEBUG(x...) +// #define DEBUG(x...) printf(x); + +#ifndef ALIGN +#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) +#endif + +#define NULL ((void *)0) + +#define PARTITION_HEADER_SIZE 16 + +/* FIXME this should be done complete and in a more prominent place */ +#define __LITTLE_ENDIAN 1234 +#define __BIG_ENDIAN 4321 +#ifdef __i386__ +#define __BYTE_ORDER __LITTLE_ENDIAN +#else +#define __BYTE_ORDER __BIG_ENDIAN +#endif +#if __BYTE_ORDER == __BIG_ENDIAN +#define cpu_to_be64(x) (x) +#define be64_to_cpu(x) (x) +#define cpu_to_be32(x) (x) +#define be32_to_cpu(x) (x) +#else +#include <byteswap.h> +#define cpu_to_be64(x) bswap_64(x) +#define be64_to_cpu(x) bswap_64(x) +#define cpu_to_be32(x) bswap_32(x) +#define be32_to_cpu(x) bswap_32(x) +#endif + +/* exported functions */ + +#define nvram_access_proto(type,name) \ + type nvram_read_##name(unsigned int offset); \ + void nvram_write_##name(unsigned int offset, type data); + +nvram_access_proto(uint8_t, byte) +nvram_access_proto(uint16_t, word) +nvram_access_proto(uint32_t, dword) +nvram_access_proto(uint64_t, qword) + +/* nvram.c */ + +char *get_nvram_buffer(int len); +void free_nvram_buffer(char *buffer); +int nvramlog_printf(const char* fmt, ...); +partition_t get_partition(unsigned int type, char *name); +void erase_nvram(int offset, int len); +int wipe_partition(partition_t partition, int header_only); +partition_t new_nvram_partition(int type, char *name, int len); +int increase_nvram_partition_size(partition_t partition, int newsize); +int clear_nvram_partition(partition_t part); +int delete_nvram_partition(partition_t part); +void reset_nvram(void); +void wipe_nvram(void); +void nvram_debug(void); + +/* envvar.c */ +char *get_env(partition_t part, char *envvar); +int add_env(partition_t part, char *envvar, char *value); +int del_env(partition_t part, char *envvar); +int set_env(partition_t part, char *envvar, char *value); + +#endif diff --git a/llfw/boot_abort.S b/llfw/boot_abort.S index e35bd25..996bdd7 100644 --- a/llfw/boot_abort.S +++ b/llfw/boot_abort.S @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/llfw/boot_abort.h b/llfw/boot_abort.h index abf9269..b708206 100644 --- a/llfw/boot_abort.h +++ b/llfw/boot_abort.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/llfw/clib/Makefile.inc b/llfw/clib/Makefile.inc index 2de8e94..7003798 100644 --- a/llfw/clib/Makefile.inc +++ b/llfw/clib/Makefile.inc @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License diff --git a/llfw/clib/iolib.c b/llfw/clib/iolib.c index 3f90baa..56b7caf 100644 --- a/llfw/clib/iolib.c +++ b/llfw/clib/iolib.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/llfw/clib/iolib.h b/llfw/clib/iolib.h index 9678d94..30dfa37 100644 --- a/llfw/clib/iolib.h +++ b/llfw/clib/iolib.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/llfw/io_generic/Makefile.inc b/llfw/io_generic/Makefile.inc index 4aa6d6e..b660725 100644 --- a/llfw/io_generic/Makefile.inc +++ b/llfw/io_generic/Makefile.inc @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License diff --git a/llfw/io_generic/io_generic.S b/llfw/io_generic/io_generic.S index e639124..9c1db41 100644 --- a/llfw/io_generic/io_generic.S +++ b/llfw/io_generic/io_generic.S @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/llfw/nvramlog.S b/llfw/nvramlog.S index d44e534..c6e7418 100644 --- a/llfw/nvramlog.S +++ b/llfw/nvramlog.S @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/llfw/romfs.S b/llfw/romfs.S index 2a2e141..325f79e 100644 --- a/llfw/romfs.S +++ b/llfw/romfs.S @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/llfw/romfs_wrap.c b/llfw/romfs_wrap.c index 649f5c0..323d975 100644 --- a/llfw/romfs_wrap.c +++ b/llfw/romfs_wrap.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -15,27 +15,34 @@ ############################################################################# CROSS ?= powerpc64-linux- +CELLSIZE ?= 64 HOSTCC ?= gcc HOSTCFLAGS = -g -Wall -W -O2 -I. -I../include DD = dd -ONLY_LD = $(CROSS)ld -melf64ppc +ONLY_LD = $(CROSS)ld -melf$(CELLSIZE)ppc ifdef NEW_BUILD MAKEFLAGS = --silent -CC = echo -e "\t[CC]\t$(DIRECTORY)$@"; $(CROSS)gcc -m64 -AS = echo -e "\t[AS]\t$(DIRECTORY)$@"; $(CROSS)as -m64 +CC = echo -e "\t[CC]\t$(DIRECTORY)$@"; $(CROSS)gcc -m$(CELLSIZE) +AS = echo -e "\t[AS]\t$(DIRECTORY)$@"; $(CROSS)as -m$(CELLSIZE) LD = echo -e "\t[LD]\t$(DIRECTORY)$@"; $(ONLY_LD) CLEAN = echo -e "\t[CLEAN]\t$(DIRECTORY)$$dir" else -CC = $(CROSS)gcc -m64 -AS = $(CROSS)as -m64 +CC = $(CROSS)gcc -m$(CELLSIZE) +AS = $(CROSS)as -m$(CELLSIZE) LD = $(ONLY_LD) CLEAN = echo -n endif -OBJCOPY = $(CROSS)objcopy -OBJDUMP = $(CROSS)objdump -STRIP = $(CROSS)strip -AR = $(CROSS)ar -RANLIB = $(CROSS)ranlib +OBJCOPY ?= $(CROSS)objcopy +OBJDUMP ?= $(CROSS)objdump +STRIP ?= $(CROSS)strip +AR ?= $(CROSS)ar +RANLIB ?= $(CROSS)ranlib + +CFLAGS ?= -g -O2 -fno-builtin -ffreestanding -nostdinc -msoft-float \ + -mno-altivec -mabi=no-altivec -Wall + +export CC AS LD CLEAN OBJCOPY OBJDUMP STRIP AR RANLIB CFLAGS + diff --git a/other-licence/Makefile b/other-licence/Makefile index 5395f64..fb5397d 100644 --- a/other-licence/Makefile +++ b/other-licence/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -20,6 +20,7 @@ SUBDIRS=common bcm ifeq ($(SNK_BIOSEMU_APPS), 1) SUBDIRS += x86emu endif +CLEANSUBDIRS = $(SUBDIRS) all : @@ -27,4 +28,4 @@ all : # Common targets for all subdirectories: clean distclean depend: - for subdir in $(SUBDIRS) ; do $(MAKE) -C $${subdir} $@ ; done + for subdir in $(CLEANSUBDIRS) ; do $(MAKE) -C $${subdir} $@ ; done diff --git a/other-licence/bcm/Makefile b/other-licence/bcm/Makefile index 0df7dc0..b7b386d 100644 --- a/other-licence/bcm/Makefile +++ b/other-licence/bcm/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -16,7 +16,7 @@ ifndef TOP endif include $(TOP)/make.rules -CFLAGS = -O2 -I. -I../common -fno-builtin -ffreestanding -msoft-float -Wall +CFLAGS = -O2 -I. -I../common -I$(TOP)/clients/net-snk/include -I$(TOP)/lib/libc/include -fno-builtin -ffreestanding -msoft-float -Wall -nostdinc SRCS = bcm57xx.c diff --git a/other-licence/bcm/bcm57xx.c b/other-licence/bcm/bcm57xx.c index 5cedb6f..65b319b 100644 --- a/other-licence/bcm/bcm57xx.c +++ b/other-licence/bcm/bcm57xx.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -279,6 +279,27 @@ static u08_t bcm_pcicfg_devfn; static bcm_status_t bcm_status; /* + * snk module interface + ****************************************************************************** + */ +static int bcm_init ( void ); +static int bcm_term ( void ); +static int bcm_xmit ( char *f_buffer_pc, int f_len_i ); +static int bcm_receive( char *f_buffer_pc, int f_len_i ); +static int bcm_ioctl ( int request, void* data ); + +snk_module_t snk_module_interface = { + .version = 1, + .type = MOD_TYPE_NETWORK, + .running = 0, + .init = bcm_init, + .term = bcm_term, + .write = bcm_xmit, + .read = bcm_receive, + .ioctl = bcm_ioctl +}; + +/* * implementation ****************************************************************************** */ @@ -289,7 +310,7 @@ static bcm_status_t bcm_status; ****************************************************************************** */ int -check_driver( pci_config_t *pcicfg ); +check_driver( pci_config_t *pci_conf ); /* @@ -641,9 +662,10 @@ static i32_t bcm_mii_read16( u32_t f_reg_u32, u16_t *f_value_pu16 ) { static const u32_t RD_VAL = ( ( ((u32_t) 0x1) << 21 ) | BIT32( 29 ) | BIT32( 27 ) ); - i32_t l_autopoll_i32 = 0; - u32_t l_rdval_u32; - u32_t i; + i32_t l_autopoll_i32 = 0; + u32_t l_rdval_u32; + u32_t i; + u16_t first_not_busy; /* * only 0x00-0x1f are valid registers @@ -669,11 +691,16 @@ bcm_mii_read16( u32_t f_reg_u32, u16_t *f_value_pu16 ) /* * wait for transaction to complete + * ERRATA workaround: must read two "not busy" states to indicate transaction complete */ - i = 25; + i = 25; + first_not_busy = 0; l_rdval_u32 = bcm_read_reg32( MI_COM_R ); - while( ( --i ) && - ( ( l_rdval_u32 & BIT32( 29 ) ) != 0 ) ) { + while( ( --i ) && + ( (first_not_busy == 0) || ( ( l_rdval_u32 & BIT32( 29 ) ) != 0 ) ) ) { + /* Is this the first clear BUSY state? */ + if ( ( l_rdval_u32 & BIT32( 29 ) ) == 0 ) + first_not_busy++; us_delay( 10 ); l_rdval_u32 = bcm_read_reg32( MI_COM_R ); } @@ -1068,12 +1095,13 @@ bcm_nvram_write( u32_t f_addr_u32, u32_t f_value_u32, u32_t lock ) static i32_t bcm_mii_phy_init( void ) { - static const u32_t PHY_STAT_R = (u32_t) 0x01; - static const u32_t AUX_STAT_R = (u32_t) 0x19; - static const u32_t MODE_GMII = BIT32( 3 ); - static const u32_t MODE_MII = BIT32( 2 ); - static const u32_t MII_MSK = ( MODE_GMII | MODE_MII ); - static const u16_t GIGA_ETH = ( BIT16( 10 ) | BIT16( 9 ) ); + static const u32_t PHY_STAT_R = (u32_t) 0x01; + static const u32_t AUX_STAT_R = (u32_t) 0x19; + static const u32_t MODE_GMII = BIT32( 3 ); + static const u32_t MODE_MII = BIT32( 2 ); + static const u32_t NEG_POLARITY = BIT32( 10 ); + static const u32_t MII_MSK = ( MODE_GMII | MODE_MII ); + static const u16_t GIGA_ETH = ( BIT16( 10 ) | BIT16( 9 ) ); i32_t i; u16_t v; @@ -1141,6 +1169,13 @@ bcm_mii_phy_init( void ) } + if( IS_5704 && !IS_SERDES ) { +#ifdef BCM_DEBUG + printk( "bcm57xx: set the link ready signal for 5704C to negative polarity\n" ); +#endif + i |= NEG_POLARITY; // set the link ready signal for 5704C to negative polarity + } + bcm_write_reg32( ETH_MAC_MODE_R, i ); return 0; @@ -1677,7 +1712,7 @@ bcm_fw_halt( void ) #ifdef BCM_SW_AUTONEG static void -bcm_sw_autoneg( pci_config_t *pcicfg ) { +bcm_sw_autoneg( void ) { u32_t i, j, k; u32_t SerDesCfg; u32_t SgDigControl; @@ -1839,7 +1874,7 @@ bcm_sw_autoneg( pci_config_t *pcicfg ) { #endif static int -bcm_handle_events( pci_config_t *pcicfg ) { +bcm_handle_events( void ) { #ifdef BCM_DEBUG #ifdef BCM_SHOW_ASF_REGS // ASF REGISTER CHECK @@ -1863,7 +1898,7 @@ bcm_handle_events( pci_config_t *pcicfg ) { if( ( bcm_read_reg32( ETH_MAC_STAT_R ) & ( BIT32( 12 ) | BIT32( 3 ) | BIT32( 0 ) ) ) != 0 ) { // link timer procedure - bcm_sw_autoneg( pcicfg ); + bcm_sw_autoneg(); } #endif @@ -1908,7 +1943,7 @@ bcm_handle_events( pci_config_t *pcicfg ) { * bcm_receive */ static int -bcm_receive( pci_config_t *pcicfg, char *f_buffer_pc, int f_len_i ) +bcm_receive( char *f_buffer_pc, int f_len_i ) { u32_t l_rxret_prod_u32 = bcm_read_reg32( RXRET_PROD_IND ); u32_t l_rxret_cons_u32 = bcm_read_reg32( RXRET_CONS_IND ); @@ -1925,7 +1960,7 @@ bcm_receive( pci_config_t *pcicfg, char *f_buffer_pc, int f_len_i ) * done by the indice reads */ - bcm_handle_events( pcicfg ); + bcm_handle_events(); /* * if producer index == consumer index then nothing was received @@ -2048,7 +2083,7 @@ bcm_receive( pci_config_t *pcicfg, char *f_buffer_pc, int f_len_i ) } static int -bcm_xmit( pci_config_t *pcicfg, char *f_buffer_pc, int f_len_i ) +bcm_xmit( char *f_buffer_pc, int f_len_i ) { u32_t l_tx_cons_u32 = bcm_read_reg32( TX_CONS_IND ); u32_t l_tx_prod_u32 = bcm_read_reg32( TX_PROD_IND ); @@ -2079,7 +2114,7 @@ bcm_xmit( pci_config_t *pcicfg, char *f_buffer_pc, int f_len_i ) #endif #endif - bcm_handle_events( pcicfg ); + bcm_handle_events(); /* * make all consumed bd's available in the ring again @@ -2163,7 +2198,7 @@ bcm_xmit( pci_config_t *pcicfg, char *f_buffer_pc, int f_len_i ) } int -check_driver( pci_config_t *pcicfg ) +check_driver( pci_config_t *pci_conf ) { u64_t i; @@ -2172,7 +2207,7 @@ check_driver( pci_config_t *pcicfg ) * by verifying vendor & device id * vendor id 0x14e4 == Broadcom */ - if( pcicfg->vendor_id != 0x14e4 ) { + if( pci_conf->vendor_id != 0x14e4 ) { #ifdef BCM_DEBUG printk( "bcm57xx: netdevice not supported, illegal vendor id\n" ); #endif @@ -2180,22 +2215,40 @@ check_driver( pci_config_t *pcicfg ) } for( i = 0; bcm_dev[i].m_dev_u32 != 0; i++ ) { - if( bcm_dev[i].m_dev_u32 == - (u32_t) pcicfg->device_id ) { + if( bcm_dev[i].m_dev_u32 == (u32_t) pci_conf->device_id ) { // success - bcm_device_u64 = bcm_dev[i].m_devmsk_u64; - return 0; + break; } } + + if(bcm_dev[i].m_dev_u32 == 0) { #ifdef BCM_DEBUG - printk( "bcm57xx: netdevice not supported, illegal device ID\n" ); + printk( "bcm57xx: netdevice not supported, illegal device ID\n" ); #endif + return -1; + } + + /* + * initialize static variables + */ + bcm_device_u64 = bcm_dev[i].m_devmsk_u64; + bcm_rxret_ring_sz = 0; + bcm_baseaddr_u64 = 0; + bcm_memaddr_u64 = 0; + + bcm_tx_start_u32 = 0; + bcm_tx_stop_u32 = 0; + bcm_tx_bufavail_u32 = 0; + + bcm_pcicfg_puid = pci_conf->puid; + bcm_pcicfg_bus = pci_conf->bus; + bcm_pcicfg_devfn = pci_conf->devfn; - return -1; + return 0; } static void -bcm_wol_activate( pci_config_t *pcicfg ) +bcm_wol_activate(void) { #ifdef BCM_DEBUG u16_t reg_pwr_cap; @@ -2214,18 +2267,18 @@ bcm_wol_activate( pci_config_t *pcicfg ) // ms_delay( 100 ); #ifdef BCM_DEBUG - reg_pwr_cap = snk_kernel_interface->pci_config_read( pcicfg->puid, + reg_pwr_cap = snk_kernel_interface->pci_config_read( bcm_pcicfg_puid, 2, - pcicfg->bus, - pcicfg->devfn, + bcm_pcicfg_bus, + bcm_pcicfg_devfn, 0x4a ); printk( "bcm57xx: PM Capability Register: %04X\n", reg_pwr_cap ); #endif /* get curretn power control register */ - reg_pwr_crtl = snk_kernel_interface->pci_config_read( pcicfg->puid, + reg_pwr_crtl = snk_kernel_interface->pci_config_read( bcm_pcicfg_puid, 2, - pcicfg->bus, - pcicfg->devfn, + bcm_pcicfg_bus, + bcm_pcicfg_devfn, 0x4c ); #ifdef BCM_DEBUG @@ -2235,10 +2288,10 @@ bcm_wol_activate( pci_config_t *pcicfg ) /* switch to power state D0 */ reg_pwr_crtl |= 0x8000; reg_pwr_crtl &= ~(0x0003); - snk_kernel_interface->pci_config_write( pcicfg->puid, + snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, 2, - pcicfg->bus, - pcicfg->devfn, + bcm_pcicfg_bus, + bcm_pcicfg_devfn, 0x4c, reg_pwr_crtl ); ms_delay(10); @@ -2253,20 +2306,20 @@ bcm_wol_activate( pci_config_t *pcicfg ) /* switch to power state D3hot */ /* reg_pwr_crtl |= 0x0103; - snk_kernel_interface->pci_config_write( pcicfg->puid, + snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, 2, - pcicfg->bus, - pcicfg->devfn, + bcm_pcicfg_bus, + bcm_pcicfg_devfn, 0x4c, reg_pwr_crtl ); ms_delay(10); */ #ifdef BCM_DEBUG - reg_pwr_crtl = snk_kernel_interface->pci_config_read( pcicfg->puid, + reg_pwr_crtl = snk_kernel_interface->pci_config_read( bcm_pcicfg_puid, 2, - pcicfg->bus, - pcicfg->devfn, + bcm_pcicfg_bus, + bcm_pcicfg_devfn, 0x4c ); printk( "bcm57xx: PM Control/Status Register: %04X\n", reg_pwr_crtl ); @@ -2278,36 +2331,17 @@ bcm_wol_activate( pci_config_t *pcicfg ) } static int -bcm_init( pci_config_t *pcicfg, char *mac_addr ) +bcm_init( void ) { static const u32_t lc_Maxwait_u32 = (u32_t) 1000; u32_t l_baseaddrL_u32; u32_t l_baseaddrH_u32; u32_t i; + char *mac_addr = snk_module_interface.mac_addr; - /* - * initialize static variables - */ - bcm_device_u64 = 0; - bcm_rxret_ring_sz = 0; - bcm_baseaddr_u64 = 0; - bcm_memaddr_u64 = 0; - - bcm_tx_start_u32 = 0; - bcm_tx_stop_u32 = 0; - bcm_tx_bufavail_u32 = 0; - - /* - * check driver - */ - if( check_driver( pcicfg ) < 0 ) { - return -1; + if(snk_module_interface.running != 0) { + return 0; } - - bcm_pcicfg_puid = pcicfg->puid; - bcm_pcicfg_bus = pcicfg->bus; - bcm_pcicfg_devfn = pcicfg->devfn; - #ifdef BCM_DEBUG printk( "bcm57xx: detected device " ); if( IS_5703 ) { @@ -2329,17 +2363,17 @@ bcm_init( pci_config_t *pcicfg, char *mac_addr ) * setup register & memory base addresses of NIC */ l_baseaddrL_u32 = ( (u32_t) ~0xf & - (u32_t) snk_kernel_interface->pci_config_read( pcicfg->puid, + (u32_t) snk_kernel_interface->pci_config_read( bcm_pcicfg_puid, 4, - pcicfg->bus, - pcicfg->devfn, + bcm_pcicfg_bus, + bcm_pcicfg_devfn, PCI_BAR1_R ) ); l_baseaddrH_u32 = - (u32_t) snk_kernel_interface->pci_config_read( pcicfg->puid, + (u32_t) snk_kernel_interface->pci_config_read( bcm_pcicfg_puid, 4, - pcicfg->bus, - pcicfg->devfn, + bcm_pcicfg_bus, + bcm_pcicfg_devfn, PCI_BAR2_R ); bcm_baseaddr_u64 = (u64_t) l_baseaddrH_u32; bcm_baseaddr_u64 <<= 32; @@ -2348,9 +2382,9 @@ bcm_init( pci_config_t *pcicfg, char *mac_addr ) bcm_memaddr_u64 = bcm_baseaddr_u64 + BCM_MEMORY_OFFS; #ifdef BCM_DEBUG - printk( "bcm57xx: PCI-Puid = 0x%X\n", pcicfg->puid ); - printk( "bcm57xx: PCI-Bus = 0x%X\n", pcicfg->bus ); - printk( "bcm57xx: PCI-DevFn = 0x%X\n", pcicfg->devfn ); + printk( "bcm57xx: PCI-Puid = 0x%X\n", bcm_pcicfg_puid ); + printk( "bcm57xx: PCI-Bus = 0x%X\n", bcm_pcicfg_bus ); + printk( "bcm57xx: PCI-DevFn = 0x%X\n", bcm_pcicfg_devfn ); printk( "bcm57xx: device's register base high address = 0x%08X\n", l_baseaddrH_u32 ); printk( "bcm57xx: device's register base low address = 0x%08X\n", l_baseaddrL_u32 ); printk( "bcm57xx: device's register address = 0x%lx\n", bcm_baseaddr_u64 ); @@ -2364,19 +2398,19 @@ bcm_init( pci_config_t *pcicfg, char *mac_addr ) // step 1: enable bus master & memory space in command reg i = ( BIT32( 10 ) | BIT32( 2 ) | BIT32( 1 ) ); - snk_kernel_interface->pci_config_write( pcicfg->puid, + snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, 2, - pcicfg->bus, - pcicfg->devfn, + bcm_pcicfg_bus, + bcm_pcicfg_devfn, PCI_COM_R, ( int ) i ); // step 2: disable & mask interrupts & enable pci byte/word swapping & enable indirect addressing mode i = ( BIT32( 8 ) | BIT32( 7 ) | BIT32( 3 ) | BIT32( 2 ) | BIT32( 1 ) | BIT32( 0 ) ); - snk_kernel_interface->pci_config_write( pcicfg->puid, + snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, 4, - pcicfg->bus, - pcicfg->devfn, + bcm_pcicfg_bus, + bcm_pcicfg_devfn, PCI_MISC_HCTRL_R, ( int ) i ); @@ -2399,10 +2433,10 @@ bcm_init( pci_config_t *pcicfg, char *mac_addr ) // step 5: prepare the chip for writing TG3_MAGIC_NUMBER bcm_setb_reg32( MEMARB_MODE_R, BIT32( 1 ) ); i = ( BIT32( 8 ) | BIT32( 7 ) | BIT32( 3 ) | BIT32( 2 ) | BIT32( 1 ) | BIT32( 0 ) ); - snk_kernel_interface->pci_config_write( pcicfg->puid, + snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, 4, - pcicfg->bus, - pcicfg->devfn, + bcm_pcicfg_bus, + bcm_pcicfg_devfn, PCI_MISC_HCTRL_R, ( int ) i ); bcm_write_reg32( MODE_CTRL_R, BIT32( 23 ) | BIT32( 20 ) | @@ -2427,19 +2461,19 @@ bcm_init( pci_config_t *pcicfg, char *mac_addr ) // step 9: disable & mask interrupts & enable indirect addressing mode & // enable pci byte/word swapping initialize the misc host control register i = ( BIT32( 8 ) | BIT32( 7 ) | BIT32( 3 ) | BIT32( 2 ) | BIT32( 1 ) | BIT32( 0 ) ); - snk_kernel_interface->pci_config_write( pcicfg->puid, + snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, 4, - pcicfg->bus, - pcicfg->devfn, + bcm_pcicfg_bus, + bcm_pcicfg_devfn, PCI_MISC_HCTRL_R, ( int ) i ); // step 10: set but master et cetera i = ( BIT32( 10 ) | BIT32( 2 ) | BIT32( 1 ) ); - snk_kernel_interface->pci_config_write( pcicfg->puid, + snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, 2, - pcicfg->bus, - pcicfg->devfn, + bcm_pcicfg_bus, + bcm_pcicfg_devfn, PCI_COM_R, ( int ) i ); @@ -2452,10 +2486,10 @@ bcm_init( pci_config_t *pcicfg, char *mac_addr ) // step 13: omitted, only for BCM5700 // step 14: s. step 10 i = ( BIT32( 8 ) | BIT32( 7 ) | BIT32( 3 ) | BIT32( 2 ) | BIT32( 1 ) | BIT32( 0 ) ); - snk_kernel_interface->pci_config_write( pcicfg->puid, + snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, 4, - pcicfg->bus, - pcicfg->devfn, + bcm_pcicfg_bus, + bcm_pcicfg_devfn, PCI_MISC_HCTRL_R, ( int ) i ); // step 15: set byte swapping (incl. step 27/28/29/30) @@ -2469,9 +2503,9 @@ bcm_init( pci_config_t *pcicfg, char *mac_addr ) i = 1000; while( ( --i ) && ( bcm_read_mem32( BCM_FW_MBX ) != ~BCM_MAGIC_NUMBER ) ) { -//#ifdef BCM_DEBUG +#ifdef BCM_DEBUG printk( "." ); -//#endif +#endif ms_delay( 1 ); } @@ -2863,12 +2897,14 @@ bcm_init( pci_config_t *pcicfg, char *mac_addr ) // enable heartbeat timer bcm_write_reg32( ASF_HEARTBEAT_TIMER_R, 0x5 ); + + snk_module_interface.running = 1; // off we go.. return 0; } static int -bcm_reset( pci_config_t *pcicfg ) +bcm_reset( void ) { u32_t i; @@ -2892,10 +2928,10 @@ bcm_reset( pci_config_t *pcicfg ) */ i = ( BIT32( 10 ) | BIT32( 2 ) | BIT32( 1 ) ); - snk_kernel_interface->pci_config_write( pcicfg->puid, + snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, 2, - pcicfg->bus, - pcicfg->devfn, + bcm_pcicfg_bus, + bcm_pcicfg_devfn, PCI_COM_R, ( int ) i ); @@ -2903,10 +2939,10 @@ bcm_reset( pci_config_t *pcicfg ) // enable pci byte/word swapping initialize the misc host control register i = ( BIT32( 7 ) | BIT32( 5 ) | BIT32( 4 ) | BIT32( 3 ) | BIT32( 2 ) | BIT32( 1 ) | BIT32( 0 ) ); - snk_kernel_interface->pci_config_write( pcicfg->puid, + snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, 4, - pcicfg->bus, - pcicfg->devfn, + bcm_pcicfg_bus, + bcm_pcicfg_devfn, PCI_MISC_HCTRL_R, ( int ) i ); @@ -2936,12 +2972,16 @@ bcm_reset( pci_config_t *pcicfg ) return 0; } -static int -bcm_term( pci_config_t *pcicfg ) +static int +bcm_term( void ) { u32_t i; u16_t v; + if(snk_module_interface.running == 0) { + return 0; + } + #ifdef BCM_DEBUG printk( "bcm57xx: driver shutdown.." ); #endif @@ -3067,7 +3107,7 @@ bcm_term( pci_config_t *pcicfg ) /* * controller reset */ - if( bcm_reset( pcicfg ) != 0 ) { + if( bcm_reset() != 0 ) { return -1; } @@ -3085,7 +3125,7 @@ bcm_term( pci_config_t *pcicfg ) /* * activate Wake-on-LAN */ - bcm_wol_activate( pcicfg ); + bcm_wol_activate(); /* * PCI shutdown @@ -3098,14 +3138,15 @@ bcm_term( pci_config_t *pcicfg ) // bcm_clrb_reg32( PCI_COM_R, BIT32( 10 ) | BIT32( 2 ) | BIT32( 1 ) ); - snk_kernel_interface->pci_config_write( pcicfg->puid, + snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, 2, - pcicfg->bus, - pcicfg->devfn, + bcm_pcicfg_bus, + bcm_pcicfg_devfn, PCI_COM_R, BIT32(8) | BIT32(6) ); // no more networking... + snk_module_interface.running = 0; return 0; } @@ -3261,7 +3302,7 @@ bcm_setmac(char mac_addr1[6], char mac_addr2[6]) } static int -bcm_ioctl( pci_config_t *pcicfg, int request, void* data ) +bcm_ioctl( int request, void* data ) { u32_t l_baseaddrL_u32; u32_t l_baseaddrH_u32; @@ -3274,17 +3315,6 @@ bcm_ioctl( pci_config_t *pcicfg, int request, void* data ) return -1; } - /* - * check driver - */ - if( check_driver( pcicfg ) < 0 ) { - return -1; - } - - bcm_pcicfg_puid = pcicfg->puid; - bcm_pcicfg_bus = pcicfg->bus; - bcm_pcicfg_devfn = pcicfg->devfn; - #ifdef BCM_DEBUG printk( "bcm57xx: detected device " ); if( IS_5703 ) { @@ -3304,17 +3334,17 @@ bcm_ioctl( pci_config_t *pcicfg, int request, void* data ) * setup register & memory base addresses of NIC */ l_baseaddrL_u32 = ( (u32_t) ~0xf & - (u32_t) snk_kernel_interface->pci_config_read( pcicfg->puid, + (u32_t) snk_kernel_interface->pci_config_read( bcm_pcicfg_puid, 4, - pcicfg->bus, - pcicfg->devfn, + bcm_pcicfg_bus, + bcm_pcicfg_devfn, PCI_BAR1_R ) ); l_baseaddrH_u32 = - (u32_t) snk_kernel_interface->pci_config_read( pcicfg->puid, + (u32_t) snk_kernel_interface->pci_config_read( bcm_pcicfg_puid, 4, - pcicfg->bus, - pcicfg->devfn, + bcm_pcicfg_bus, + bcm_pcicfg_devfn, PCI_BAR2_R ); bcm_baseaddr_u64 = (u64_t) l_baseaddrH_u32; @@ -3331,19 +3361,19 @@ bcm_ioctl( pci_config_t *pcicfg, int request, void* data ) // step 1: enable bus master & memory space in command reg i = ( BIT32( 10 ) | BIT32( 2 ) | BIT32( 1 ) ); - snk_kernel_interface->pci_config_write( pcicfg->puid, + snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, 2, - pcicfg->bus, - pcicfg->devfn, + bcm_pcicfg_bus, + bcm_pcicfg_devfn, PCI_COM_R, ( int ) i ); // step 2: disable & mask interrupts & enable pci byte/word swapping & enable indirect addressing mode i = ( BIT32( 7 ) | BIT32( 3 ) | BIT32( 2 ) | BIT32( 1 ) | BIT32( 0 ) ); - snk_kernel_interface->pci_config_write( pcicfg->puid, + snk_kernel_interface->pci_config_write( bcm_pcicfg_puid, 4, - pcicfg->bus, - pcicfg->devfn, + bcm_pcicfg_bus, + bcm_pcicfg_devfn, PCI_MISC_HCTRL_R, ( int ) i ); @@ -3391,20 +3421,8 @@ bcm_ioctl( pci_config_t *pcicfg, int request, void* data ) break; } - bcm_term(pcicfg); + snk_module_interface.running = 1; + bcm_term(); return ret_val; } -/* - * snk module interface - ****************************************************************************** - */ -snk_module_t snk_module_interface = { - .version = 1, - .net_init = bcm_init, - .net_term = bcm_term, - .net_xmit = bcm_xmit, - .net_receive = bcm_receive, - .net_ioctl = bcm_ioctl -}; - diff --git a/other-licence/bcm/bcm57xx.h b/other-licence/bcm/bcm57xx.h index e6c8937..d968313 100644 --- a/other-licence/bcm/bcm57xx.h +++ b/other-licence/bcm/bcm57xx.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/other-licence/bcm/types.h b/other-licence/bcm/types.h index b33a931..fb562d7 100644 --- a/other-licence/bcm/types.h +++ b/other-licence/bcm/types.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/other-licence/common/Makefile b/other-licence/common/Makefile index bdff820..8b3ebe1 100644 --- a/other-licence/common/Makefile +++ b/other-licence/common/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -16,13 +16,12 @@ ifndef TOP endif include $(TOP)/make.rules -CFLAGS = -O2 -I./ -fno-builtin -ffreestanding -msoft-float -Wall +CFLAGS = -O2 -I./ -I$(TOP)/clients/net-snk/include/ -I$(TOP)/lib/libc/include/ -fno-builtin -ffreestanding -msoft-float -nostdinc -Wall SRCS = module_entry.c OBJS = $(SRCS:.c=.o) - all: Makefile.dep $(OBJS) diff --git a/other-licence/common/module.lds b/other-licence/common/module.lds index 5427279..c17a055 100644 --- a/other-licence/common/module.lds +++ b/other-licence/common/module.lds @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/other-licence/common/module_entry.c b/other-licence/common/module_entry.c index 314babf..423d908 100644 --- a/other-licence/common/module_entry.c +++ b/other-licence/common/module_entry.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -11,11 +11,13 @@ *****************************************************************************/ #include "netdriver_int.h" + extern snk_module_t snk_module_interface; + snk_kernel_t *snk_kernel_interface = 0; -extern int -check_driver( pci_config_t *pcicfg ); +extern int +check_driver( pci_config_t *pci_conf ); static void* @@ -32,28 +34,31 @@ extern char __bss_start; extern char __bss_size; snk_module_t* -module_init( snk_kernel_t *snk_kernel_int, pci_config_t *pciconf ) +module_init(snk_kernel_t *snk_kernel_int, pci_config_t *pciconf) { /* Need to clear bss, heavy linker script dependency, expert change only */ char *bss = &__bss_start; unsigned long long bss_size = (unsigned long long) &__bss_size; - if(((unsigned long long) bss) + bss_size >= 0xFF00000) { - snk_kernel_int->print("BSS size too big!\n"); + if (((unsigned long long) bss) + bss_size >= 0xFF00000 + || bss_size >= 0x2000000) { + snk_kernel_int->print("BSS size (%llu bytes) is too big!\n", bss_size); return 0; } - memset( bss, 0, bss_size ); + memset(bss, 0, bss_size); - if( snk_kernel_int->version != snk_module_interface.version ) { + if (snk_kernel_int->version != snk_module_interface.version) { return 0; - } else { - snk_kernel_interface = snk_kernel_int; } + snk_kernel_interface = snk_kernel_int; + /* Check if this is the right driver */ - if( check_driver( pciconf ) < 0 ) { + if (check_driver(pciconf) < 0) { return 0; } + + snk_module_interface.link_addr = module_init; return &snk_module_interface; } diff --git a/other-licence/x86emu/Makefile b/other-licence/x86emu/Makefile index 0729a25..5f1fac4 100644 --- a/other-licence/x86emu/Makefile +++ b/other-licence/x86emu/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -9,6 +9,7 @@ # * Contributors: # * IBM Corporation - initial implementation # ****************************************************************************/ + ifndef TOP TOP = $(shell while ! test -e make.rules; do cd .. ; done; pwd) export TOP @@ -22,7 +23,7 @@ ASFLAGS = -I./include -Wa,-mregnames #NOTE: -DDEBUG only needed for debugging/tracing... #CFLAGS = -DDEBUG -I. -I./include -I./include/x86emu -I$(ROOTDIR)/include -I$(ROOTDIR)/lib/libc/include -g -O2 -msoft-float -Wall -save-temps -nostdinc -fno-builtin -ffreestanding -CFLAGS = -UDEBUG -m64 -I. -I./include -I./include/x86emu -I$(ROOTDIR)/include -I$(ROOTDIR)/lib/libc/include -O3 -Wall -save-temps -nostdinc -fno-builtin -ffreestanding +CFLAGS = -UDEBUG -m64 -I. -I./include -I./include/x86emu -I$(TOP)/clients/net-snk/include -I$(ROOTDIR)/include -I$(ROOTDIR)/lib/libc/include -O3 -Wall -nostdinc -fno-builtin -ffreestanding X86EMU_OBJS = debug.o decode.o fpu.o ops2.o ops.o prim_ops.o sys.o diff --git a/other-licence/x86emu/debug.c b/other-licence/x86emu/debug.c index 53ec99a..0c531ea 100644 --- a/other-licence/x86emu/debug.c +++ b/other-licence/x86emu/debug.c @@ -52,7 +52,11 @@ static int parse_line (char *s, int *ps, int *n); void X86EMU_trace_regs (void) { if (DEBUG_TRACE()) { - x86emu_dump_regs(); + if (M.x86.mode & (SYSMODE_PREFIX_DATA | SYSMODE_PREFIX_ADDR)) { + x86emu_dump_xregs(); + } else { + x86emu_dump_regs(); + } } if (DEBUG_DECODE() && ! DEBUG_DECODE_NOPRINT()) { printk("%04x:%04x ",M.x86.saved_cs, M.x86.saved_ip); diff --git a/other-licence/x86emu/include/x86emu/regs.h b/other-licence/x86emu/include/x86emu/regs.h index 585e4db..aa48c8e 100644 --- a/other-licence/x86emu/include/x86emu/regs.h +++ b/other-licence/x86emu/include/x86emu/regs.h @@ -231,6 +231,9 @@ struct i386_segment_regs { #define SYSMODE_PREFIX_REPNE 0x00000100 #define SYSMODE_PREFIX_DATA 0x00000200 #define SYSMODE_PREFIX_ADDR 0x00000400 +//phueper: for REP(E|NE) Instructions, we need to decide wether it should be using +//the 32bit ECX register as or the 16bit CX register as count register +#define SYSMODE_32BIT_REP 0x00000800 #define SYSMODE_INTR_PENDING 0x10000000 #define SYSMODE_EXTRN_INTR 0x20000000 #define SYSMODE_HALTED 0x40000000 @@ -250,7 +253,8 @@ struct i386_segment_regs { SYSMODE_SEGOVR_GS | \ SYSMODE_SEGOVR_SS | \ SYSMODE_PREFIX_DATA | \ - SYSMODE_PREFIX_ADDR) + SYSMODE_PREFIX_ADDR | \ + SYSMODE_32BIT_REP) #define INTR_SYNCH 0x1 #define INTR_ASYNCH 0x2 diff --git a/other-licence/x86emu/ops.c b/other-licence/x86emu/ops.c index bf10615..00376d8 100644 --- a/other-licence/x86emu/ops.c +++ b/other-licence/x86emu/ops.c @@ -2516,9 +2516,11 @@ void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1)) count = 1; if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { /* dont care whether REPE or REPNE */ - /* move them until CX is ZERO. */ - count = M.x86.R_CX; + /* move them until (E)CX is ZERO. */ + count = (M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX; M.x86.R_CX = 0; + if (M.x86.mode & SYSMODE_32BIT_REP) + M.x86.R_ECX = 0; M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); } while (count--) { @@ -2561,9 +2563,11 @@ void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1)) count = 1; if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { /* dont care whether REPE or REPNE */ - /* move them until CX is ZERO. */ - count = M.x86.R_CX; + /* move them until (E)CX is ZERO. */ + count = (M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX; M.x86.R_CX = 0; + if (M.x86.mode & SYSMODE_32BIT_REP) + M.x86.R_ECX = 0; M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); } while (count--) { @@ -2602,12 +2606,15 @@ void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1)) if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { /* REPE */ - /* move them until CX is ZERO. */ - while (M.x86.R_CX != 0) { + /* move them until (E)CX is ZERO. */ + while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) { val1 = fetch_data_byte(M.x86.R_SI); val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); cmp_byte(val1, val2); - M.x86.R_CX -= 1; + if (M.x86.mode & SYSMODE_32BIT_REP) + M.x86.R_ECX -= 1; + else + M.x86.R_CX -= 1; M.x86.R_SI += inc; M.x86.R_DI += inc; if ( (M.x86.mode & SYSMODE_PREFIX_REPE) && (ACCESS_FLAG(F_ZF) == 0) ) break; @@ -2650,8 +2657,8 @@ void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1)) TRACE_AND_STEP(); if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { /* REPE */ - /* move them until CX is ZERO. */ - while (M.x86.R_CX != 0) { + /* move them until (E)CX is ZERO. */ + while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) { if (M.x86.mode & SYSMODE_PREFIX_DATA) { val1 = fetch_data_long(M.x86.R_SI); val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); @@ -2661,7 +2668,10 @@ void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1)) val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); cmp_word((u16)val1, (u16)val2); } - M.x86.R_CX -= 1; + if (M.x86.mode & SYSMODE_32BIT_REP) + M.x86.R_ECX -= 1; + else + M.x86.R_CX -= 1; M.x86.R_SI += inc; M.x86.R_DI += inc; if ( (M.x86.mode & SYSMODE_PREFIX_REPE) && ACCESS_FLAG(F_ZF) == 0 ) break; @@ -2749,10 +2759,13 @@ void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1)) TRACE_AND_STEP(); if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { /* dont care whether REPE or REPNE */ - /* move them until CX is ZERO. */ - while (M.x86.R_CX != 0) { + /* move them until (E)CX is ZERO. */ + while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) { store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL); - M.x86.R_CX -= 1; + if (M.x86.mode & SYSMODE_32BIT_REP) + M.x86.R_ECX -= 1; + else + M.x86.R_CX -= 1; M.x86.R_DI += inc; if (M.x86.intr & INTR_HALTED) break; @@ -2793,9 +2806,11 @@ void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1)) count = 1; if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { /* dont care whether REPE or REPNE */ - /* move them until CX is ZERO. */ - count = M.x86.R_CX; + /* move them until (E)CX is ZERO. */ + count = (M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX; M.x86.R_CX = 0; + if (M.x86.mode & SYSMODE_32BIT_REP) + M.x86.R_ECX = 0; M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); } while (count--) { @@ -2829,10 +2844,13 @@ void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1)) inc = 1; if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { /* dont care whether REPE or REPNE */ - /* move them until CX is ZERO. */ - while (M.x86.R_CX != 0) { + /* move them until (E)CX is ZERO. */ + while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) { M.x86.R_AL = fetch_data_byte(M.x86.R_SI); - M.x86.R_CX -= 1; + if (M.x86.mode & SYSMODE_32BIT_REP) + M.x86.R_ECX -= 1; + else + M.x86.R_CX -= 1; M.x86.R_SI += inc; if (M.x86.intr & INTR_HALTED) break; @@ -2873,9 +2891,11 @@ void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1)) count = 1; if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { /* dont care whether REPE or REPNE */ - /* move them until CX is ZERO. */ - count = M.x86.R_CX; + /* move them until (E)CX is ZERO. */ + count = (M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX; M.x86.R_CX = 0; + if (M.x86.mode & SYSMODE_32BIT_REP) + M.x86.R_ECX = 0; M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); } while (count--) { @@ -2910,11 +2930,14 @@ void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1)) inc = 1; if (M.x86.mode & SYSMODE_PREFIX_REPE) { /* REPE */ - /* move them until CX is ZERO. */ - while (M.x86.R_CX != 0) { + /* move them until (E)CX is ZERO. */ + while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) { val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); cmp_byte(M.x86.R_AL, val2); - M.x86.R_CX -= 1; + if (M.x86.mode & SYSMODE_32BIT_REP) + M.x86.R_ECX -= 1; + else + M.x86.R_CX -= 1; M.x86.R_DI += inc; if (ACCESS_FLAG(F_ZF) == 0) break; @@ -2924,11 +2947,14 @@ void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1)) M.x86.mode &= ~SYSMODE_PREFIX_REPE; } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { /* REPNE */ - /* move them until CX is ZERO. */ - while (M.x86.R_CX != 0) { + /* move them until (E)CX is ZERO. */ + while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) { val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); cmp_byte(M.x86.R_AL, val2); - M.x86.R_CX -= 1; + if (M.x86.mode & SYSMODE_32BIT_REP) + M.x86.R_ECX -= 1; + else + M.x86.R_CX -= 1; M.x86.R_DI += inc; if (ACCESS_FLAG(F_ZF)) break; /* zero flag set means equal */ @@ -2971,8 +2997,8 @@ void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1)) TRACE_AND_STEP(); if (M.x86.mode & SYSMODE_PREFIX_REPE) { /* REPE */ - /* move them until CX is ZERO. */ - while (M.x86.R_CX != 0) { + /* move them until (E)CX is ZERO. */ + while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) { if (M.x86.mode & SYSMODE_PREFIX_DATA) { val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); cmp_long(M.x86.R_EAX, val); @@ -2980,7 +3006,10 @@ void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1)) val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); cmp_word(M.x86.R_AX, (u16)val); } - M.x86.R_CX -= 1; + if (M.x86.mode & SYSMODE_32BIT_REP) + M.x86.R_ECX -= 1; + else + M.x86.R_CX -= 1; M.x86.R_DI += inc; if (ACCESS_FLAG(F_ZF) == 0) break; @@ -2990,8 +3019,8 @@ void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1)) M.x86.mode &= ~SYSMODE_PREFIX_REPE; } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { /* REPNE */ - /* move them until CX is ZERO. */ - while (M.x86.R_CX != 0) { + /* move them until (E)CX is ZERO. */ + while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) { if (M.x86.mode & SYSMODE_PREFIX_DATA) { val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); cmp_long(M.x86.R_EAX, val); @@ -2999,7 +3028,10 @@ void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1)) val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); cmp_word(M.x86.R_AX, (u16)val); } - M.x86.R_CX -= 1; + if (M.x86.mode & SYSMODE_32BIT_REP) + M.x86.R_ECX -= 1; + else + M.x86.R_CX -= 1; M.x86.R_DI += inc; if (ACCESS_FLAG(F_ZF)) break; /* zero flag set means equal */ @@ -4044,8 +4076,11 @@ void x86emuOp_loopne(u8 X86EMU_UNUSED(op1)) ip += (s16) M.x86.R_IP; DECODE_PRINTF2("%04x\n", ip); TRACE_AND_STEP(); - M.x86.R_CX -= 1; - if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */ + if (M.x86.mode & SYSMODE_PREFIX_ADDR) + M.x86.R_ECX -= 1; + else + M.x86.R_CX -= 1; + if (((M.x86.mode & SYSMODE_PREFIX_ADDR) ? M.x86.R_ECX : M.x86.R_CX) != 0 && !ACCESS_FLAG(F_ZF)) /* (E)CX != 0 and !ZF */ M.x86.R_IP = ip; DECODE_CLEAR_SEGOVR(); END_OF_INSTR(); @@ -4065,8 +4100,11 @@ void x86emuOp_loope(u8 X86EMU_UNUSED(op1)) ip += (s16) M.x86.R_IP; DECODE_PRINTF2("%04x\n", ip); TRACE_AND_STEP(); - M.x86.R_CX -= 1; - if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */ + if (M.x86.mode & SYSMODE_PREFIX_ADDR) + M.x86.R_ECX -= 1; + else + M.x86.R_CX -= 1; + if (((M.x86.mode & SYSMODE_PREFIX_ADDR) ? M.x86.R_ECX : M.x86.R_CX) != 0 && ACCESS_FLAG(F_ZF)) /* (E)CX != 0 and ZF */ M.x86.R_IP = ip; DECODE_CLEAR_SEGOVR(); END_OF_INSTR(); @@ -4086,8 +4124,11 @@ void x86emuOp_loop(u8 X86EMU_UNUSED(op1)) ip += (s16) M.x86.R_IP; DECODE_PRINTF2("%04x\n", ip); TRACE_AND_STEP(); - M.x86.R_CX -= 1; - if (M.x86.R_CX != 0) + if (M.x86.mode & SYSMODE_PREFIX_ADDR) + M.x86.R_ECX -= 1; + else + M.x86.R_CX -= 1; + if (((M.x86.mode & SYSMODE_PREFIX_ADDR) ? M.x86.R_ECX : M.x86.R_CX) != 0) /* (E)CX != 0 */ M.x86.R_IP = ip; DECODE_CLEAR_SEGOVR(); END_OF_INSTR(); @@ -4384,6 +4425,8 @@ void x86emuOp_repne(u8 X86EMU_UNUSED(op1)) DECODE_PRINTF("REPNE\n"); TRACE_AND_STEP(); M.x86.mode |= SYSMODE_PREFIX_REPNE; + if (M.x86.mode & SYSMODE_PREFIX_ADDR) + M.x86.mode |= SYSMODE_32BIT_REP; DECODE_CLEAR_SEGOVR(); END_OF_INSTR(); } @@ -4398,6 +4441,8 @@ void x86emuOp_repe(u8 X86EMU_UNUSED(op1)) DECODE_PRINTF("REPE\n"); TRACE_AND_STEP(); M.x86.mode |= SYSMODE_PREFIX_REPE; + if (M.x86.mode & SYSMODE_PREFIX_ADDR) + M.x86.mode |= SYSMODE_32BIT_REP; DECODE_CLEAR_SEGOVR(); END_OF_INSTR(); } diff --git a/other-licence/x86emu/prim_ops.c b/other-licence/x86emu/prim_ops.c index fa19cb4..a796e70 100644 --- a/other-licence/x86emu/prim_ops.c +++ b/other-licence/x86emu/prim_ops.c @@ -2312,16 +2312,15 @@ void ins(int size) } if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { /* dont care whether REPE or REPNE */ - /* in until CX is ZERO. */ - u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ? + /* in until (E)CX is ZERO. */ + u32 count = ((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX); - while (count--) { single_in(size); M.x86.R_DI += inc; } M.x86.R_CX = 0; - if (M.x86.mode & SYSMODE_PREFIX_DATA) { + if (M.x86.mode & SYSMODE_32BIT_REP) { M.x86.R_ECX = 0; } M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); @@ -2355,15 +2354,15 @@ void outs(int size) } if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { /* dont care whether REPE or REPNE */ - /* out until CX is ZERO. */ - u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ? + /* out until (E)CX is ZERO. */ + u32 count = ((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX); while (count--) { single_out(size); M.x86.R_SI += inc; } M.x86.R_CX = 0; - if (M.x86.mode & SYSMODE_PREFIX_DATA) { + if (M.x86.mode & SYSMODE_32BIT_REP) { M.x86.R_ECX = 0; } M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); diff --git a/other-licence/x86emu/x86emu_changes.diff b/other-licence/x86emu/x86emu_changes.diff index 91d2442..9f03d63 100644 --- a/other-licence/x86emu/x86emu_changes.diff +++ b/other-licence/x86emu/x86emu_changes.diff @@ -2,10 +2,24 @@ Index: debug.c =================================================================== RCS file: /cvs/osdf/cvs/host/other-licence/x86emu/debug.c,v retrieving revision 1.1 -diff -u -u -r1.1 debug.c +retrieving revision 1.3 +diff -u -u -r1.1 -r1.3 --- debug.c 7 Sep 2007 10:01:21 -0000 1.1 -+++ debug.c 19 Oct 2007 08:29:16 -0000 -@@ -185,7 +185,7 @@ ++++ debug.c 15 Jan 2008 13:49:25 -0000 1.3 +@@ -52,7 +52,11 @@ + void X86EMU_trace_regs (void) + { + if (DEBUG_TRACE()) { +- x86emu_dump_regs(); ++ if (M.x86.mode & (SYSMODE_PREFIX_DATA | SYSMODE_PREFIX_ADDR)) { ++ x86emu_dump_xregs(); ++ } else { ++ x86emu_dump_regs(); ++ } + } + if (DEBUG_DECODE() && ! DEBUG_DECODE_NOPRINT()) { + printk("%04x:%04x ",M.x86.saved_cs, M.x86.saved_ip); +@@ -185,7 +189,7 @@ for (i=0; i< M.x86.enc_pos; i++) { sprintf(buf1+2*i,"%02x", fetch_data_byte_abs(s,o+i)); } @@ -18,10 +32,25 @@ Index: ops.c =================================================================== RCS file: /cvs/osdf/cvs/host/other-licence/x86emu/ops.c,v retrieving revision 1.1 -diff -u -u -r1.1 ops.c +retrieving revision 1.3 +diff -u -u -r1.1 -r1.3 --- ops.c 7 Sep 2007 10:01:21 -0000 1.1 -+++ ops.c 19 Oct 2007 08:29:16 -0000 -@@ -2526,6 +2526,8 @@ ++++ ops.c 15 Jan 2008 13:46:40 -0000 1.3 +@@ -2516,9 +2516,11 @@ + count = 1; + if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ +- /* move them until CX is ZERO. */ +- count = M.x86.R_CX; ++ /* move them until (E)CX is ZERO. */ ++ count = (M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX; + M.x86.R_CX = 0; ++ if (M.x86.mode & SYSMODE_32BIT_REP) ++ M.x86.R_ECX = 0; + M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } + while (count--) { +@@ -2526,6 +2528,8 @@ store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val); M.x86.R_SI += inc; M.x86.R_DI += inc; @@ -30,7 +59,21 @@ diff -u -u -r1.1 ops.c } DECODE_CLEAR_SEGOVR(); END_OF_INSTR(); -@@ -2574,6 +2576,8 @@ +@@ -2559,9 +2563,11 @@ + count = 1; + if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ +- /* move them until CX is ZERO. */ +- count = M.x86.R_CX; ++ /* move them until (E)CX is ZERO. */ ++ count = (M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX; + M.x86.R_CX = 0; ++ if (M.x86.mode & SYSMODE_32BIT_REP) ++ M.x86.R_ECX = 0; + M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } + while (count--) { +@@ -2574,6 +2580,8 @@ } M.x86.R_SI += inc; M.x86.R_DI += inc; @@ -39,7 +82,23 @@ diff -u -u -r1.1 ops.c } DECODE_CLEAR_SEGOVR(); END_OF_INSTR(); -@@ -2608,6 +2612,8 @@ +@@ -2598,16 +2606,21 @@ + + if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* REPE */ +- /* move them until CX is ZERO. */ +- while (M.x86.R_CX != 0) { ++ /* move them until (E)CX is ZERO. */ ++ while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) { + val1 = fetch_data_byte(M.x86.R_SI); + val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); + cmp_byte(val1, val2); +- M.x86.R_CX -= 1; ++ if (M.x86.mode & SYSMODE_32BIT_REP) ++ M.x86.R_ECX -= 1; ++ else ++ M.x86.R_CX -= 1; + M.x86.R_SI += inc; M.x86.R_DI += inc; if ( (M.x86.mode & SYSMODE_PREFIX_REPE) && (ACCESS_FLAG(F_ZF) == 0) ) break; if ( (M.x86.mode & SYSMODE_PREFIX_REPNE) && ACCESS_FLAG(F_ZF) ) break; @@ -48,7 +107,27 @@ diff -u -u -r1.1 ops.c } M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); } else { -@@ -2660,6 +2666,8 @@ +@@ -2644,8 +2657,8 @@ + TRACE_AND_STEP(); + if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* REPE */ +- /* move them until CX is ZERO. */ +- while (M.x86.R_CX != 0) { ++ /* move them until (E)CX is ZERO. */ ++ while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) { + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + val1 = fetch_data_long(M.x86.R_SI); + val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); +@@ -2655,11 +2668,16 @@ + val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); + cmp_word((u16)val1, (u16)val2); + } +- M.x86.R_CX -= 1; ++ if (M.x86.mode & SYSMODE_32BIT_REP) ++ M.x86.R_ECX -= 1; ++ else ++ M.x86.R_CX -= 1; + M.x86.R_SI += inc; M.x86.R_DI += inc; if ( (M.x86.mode & SYSMODE_PREFIX_REPE) && ACCESS_FLAG(F_ZF) == 0 ) break; if ( (M.x86.mode & SYSMODE_PREFIX_REPNE) && ACCESS_FLAG(F_ZF) ) break; @@ -57,16 +136,41 @@ diff -u -u -r1.1 ops.c } M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); } else { -@@ -2746,6 +2754,8 @@ +@@ -2741,11 +2759,16 @@ + TRACE_AND_STEP(); + if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ +- /* move them until CX is ZERO. */ +- while (M.x86.R_CX != 0) { ++ /* move them until (E)CX is ZERO. */ ++ while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) { store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL); - M.x86.R_CX -= 1; +- M.x86.R_CX -= 1; ++ if (M.x86.mode & SYSMODE_32BIT_REP) ++ M.x86.R_ECX -= 1; ++ else ++ M.x86.R_CX -= 1; M.x86.R_DI += inc; + if (M.x86.intr & INTR_HALTED) + break; } M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); } else { -@@ -2795,6 +2805,8 @@ +@@ -2783,9 +2806,11 @@ + count = 1; + if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ +- /* move them until CX is ZERO. */ +- count = M.x86.R_CX; ++ /* move them until (E)CX is ZERO. */ ++ count = (M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX; + M.x86.R_CX = 0; ++ if (M.x86.mode & SYSMODE_32BIT_REP) ++ M.x86.R_ECX = 0; + M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } + while (count--) { +@@ -2795,6 +2820,8 @@ store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX); } M.x86.R_DI += inc; @@ -75,16 +179,41 @@ diff -u -u -r1.1 ops.c } DECODE_CLEAR_SEGOVR(); END_OF_INSTR(); -@@ -2822,6 +2834,8 @@ +@@ -2817,11 +2844,16 @@ + inc = 1; + if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ +- /* move them until CX is ZERO. */ +- while (M.x86.R_CX != 0) { ++ /* move them until (E)CX is ZERO. */ ++ while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) { M.x86.R_AL = fetch_data_byte(M.x86.R_SI); - M.x86.R_CX -= 1; +- M.x86.R_CX -= 1; ++ if (M.x86.mode & SYSMODE_32BIT_REP) ++ M.x86.R_ECX -= 1; ++ else ++ M.x86.R_CX -= 1; M.x86.R_SI += inc; + if (M.x86.intr & INTR_HALTED) + break; } M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); } else { -@@ -2871,6 +2885,8 @@ +@@ -2859,9 +2891,11 @@ + count = 1; + if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ +- /* move them until CX is ZERO. */ +- count = M.x86.R_CX; ++ /* move them until (E)CX is ZERO. */ ++ count = (M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX; + M.x86.R_CX = 0; ++ if (M.x86.mode & SYSMODE_32BIT_REP) ++ M.x86.R_ECX = 0; + M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); + } + while (count--) { +@@ -2871,6 +2905,8 @@ M.x86.R_AX = fetch_data_word(M.x86.R_SI); } M.x86.R_SI += inc; @@ -93,7 +222,21 @@ diff -u -u -r1.1 ops.c } DECODE_CLEAR_SEGOVR(); END_OF_INSTR(); -@@ -2902,6 +2918,8 @@ +@@ -2894,26 +2930,36 @@ + inc = 1; + if (M.x86.mode & SYSMODE_PREFIX_REPE) { + /* REPE */ +- /* move them until CX is ZERO. */ +- while (M.x86.R_CX != 0) { ++ /* move them until (E)CX is ZERO. */ ++ while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) { + val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); + cmp_byte(M.x86.R_AL, val2); +- M.x86.R_CX -= 1; ++ if (M.x86.mode & SYSMODE_32BIT_REP) ++ M.x86.R_ECX -= 1; ++ else ++ M.x86.R_CX -= 1; M.x86.R_DI += inc; if (ACCESS_FLAG(F_ZF) == 0) break; @@ -102,7 +245,18 @@ diff -u -u -r1.1 ops.c } M.x86.mode &= ~SYSMODE_PREFIX_REPE; } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { -@@ -2914,6 +2932,8 @@ + /* REPNE */ +- /* move them until CX is ZERO. */ +- while (M.x86.R_CX != 0) { ++ /* move them until (E)CX is ZERO. */ ++ while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) { + val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); + cmp_byte(M.x86.R_AL, val2); +- M.x86.R_CX -= 1; ++ if (M.x86.mode & SYSMODE_32BIT_REP) ++ M.x86.R_ECX -= 1; ++ else ++ M.x86.R_CX -= 1; M.x86.R_DI += inc; if (ACCESS_FLAG(F_ZF)) break; /* zero flag set means equal */ @@ -111,7 +265,26 @@ diff -u -u -r1.1 ops.c } M.x86.mode &= ~SYSMODE_PREFIX_REPNE; } else { -@@ -2964,6 +2984,8 @@ +@@ -2951,8 +2997,8 @@ + TRACE_AND_STEP(); + if (M.x86.mode & SYSMODE_PREFIX_REPE) { + /* REPE */ +- /* move them until CX is ZERO. */ +- while (M.x86.R_CX != 0) { ++ /* move them until (E)CX is ZERO. */ ++ while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) { + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); + cmp_long(M.x86.R_EAX, val); +@@ -2960,16 +3006,21 @@ + val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); + cmp_word(M.x86.R_AX, (u16)val); + } +- M.x86.R_CX -= 1; ++ if (M.x86.mode & SYSMODE_32BIT_REP) ++ M.x86.R_ECX -= 1; ++ else ++ M.x86.R_CX -= 1; M.x86.R_DI += inc; if (ACCESS_FLAG(F_ZF) == 0) break; @@ -120,7 +293,23 @@ diff -u -u -r1.1 ops.c } M.x86.mode &= ~SYSMODE_PREFIX_REPE; } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { -@@ -2981,6 +3003,8 @@ + /* REPNE */ +- /* move them until CX is ZERO. */ +- while (M.x86.R_CX != 0) { ++ /* move them until (E)CX is ZERO. */ ++ while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) { + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); + cmp_long(M.x86.R_EAX, val); +@@ -2977,10 +3028,15 @@ + val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); + cmp_word(M.x86.R_AX, (u16)val); + } +- M.x86.R_CX -= 1; ++ if (M.x86.mode & SYSMODE_32BIT_REP) ++ M.x86.R_ECX -= 1; ++ else ++ M.x86.R_CX -= 1; M.x86.R_DI += inc; if (ACCESS_FLAG(F_ZF)) break; /* zero flag set means equal */ @@ -129,7 +318,49 @@ diff -u -u -r1.1 ops.c } M.x86.mode &= ~SYSMODE_PREFIX_REPNE; } else { -@@ -4213,6 +4237,7 @@ +@@ -4020,8 +4076,11 @@ + ip += (s16) M.x86.R_IP; + DECODE_PRINTF2("%04x\n", ip); + TRACE_AND_STEP(); +- M.x86.R_CX -= 1; +- if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */ ++ if (M.x86.mode & SYSMODE_PREFIX_ADDR) ++ M.x86.R_ECX -= 1; ++ else ++ M.x86.R_CX -= 1; ++ if (((M.x86.mode & SYSMODE_PREFIX_ADDR) ? M.x86.R_ECX : M.x86.R_CX) != 0 && !ACCESS_FLAG(F_ZF)) /* (E)CX != 0 and !ZF */ + M.x86.R_IP = ip; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +@@ -4041,8 +4100,11 @@ + ip += (s16) M.x86.R_IP; + DECODE_PRINTF2("%04x\n", ip); + TRACE_AND_STEP(); +- M.x86.R_CX -= 1; +- if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */ ++ if (M.x86.mode & SYSMODE_PREFIX_ADDR) ++ M.x86.R_ECX -= 1; ++ else ++ M.x86.R_CX -= 1; ++ if (((M.x86.mode & SYSMODE_PREFIX_ADDR) ? M.x86.R_ECX : M.x86.R_CX) != 0 && ACCESS_FLAG(F_ZF)) /* (E)CX != 0 and ZF */ + M.x86.R_IP = ip; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +@@ -4062,8 +4124,11 @@ + ip += (s16) M.x86.R_IP; + DECODE_PRINTF2("%04x\n", ip); + TRACE_AND_STEP(); +- M.x86.R_CX -= 1; +- if (M.x86.R_CX != 0) ++ if (M.x86.mode & SYSMODE_PREFIX_ADDR) ++ M.x86.R_ECX -= 1; ++ else ++ M.x86.R_CX -= 1; ++ if (((M.x86.mode & SYSMODE_PREFIX_ADDR) ? M.x86.R_ECX : M.x86.R_CX) != 0) /* (E)CX != 0 */ + M.x86.R_IP = ip; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +@@ -4213,6 +4278,7 @@ ip = (s16)fetch_word_imm(); ip += (s16)M.x86.R_IP; DECODE_PRINTF2("%04x\n", ip); @@ -137,7 +368,7 @@ diff -u -u -r1.1 ops.c TRACE_AND_STEP(); M.x86.R_IP = (u16)ip; DECODE_CLEAR_SEGOVR(); -@@ -4233,6 +4258,7 @@ +@@ -4233,6 +4299,7 @@ cs = fetch_word_imm(); DECODE_PRINTF2("%04x:", cs); DECODE_PRINTF2("%04x\n", ip); @@ -145,7 +376,7 @@ diff -u -u -r1.1 ops.c TRACE_AND_STEP(); M.x86.R_IP = ip; M.x86.R_CS = cs; -@@ -4254,6 +4280,7 @@ +@@ -4254,6 +4321,7 @@ offset = (s8)fetch_byte_imm(); target = (u16)(M.x86.R_IP + offset); DECODE_PRINTF2("%x\n", target); @@ -153,7 +384,25 @@ diff -u -u -r1.1 ops.c TRACE_AND_STEP(); M.x86.R_IP = target; DECODE_CLEAR_SEGOVR(); -@@ -5013,12 +5040,14 @@ +@@ -4357,6 +4425,8 @@ + DECODE_PRINTF("REPNE\n"); + TRACE_AND_STEP(); + M.x86.mode |= SYSMODE_PREFIX_REPNE; ++ if (M.x86.mode & SYSMODE_PREFIX_ADDR) ++ M.x86.mode |= SYSMODE_32BIT_REP; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); + } +@@ -4371,6 +4441,8 @@ + DECODE_PRINTF("REPE\n"); + TRACE_AND_STEP(); + M.x86.mode |= SYSMODE_PREFIX_REPE; ++ if (M.x86.mode & SYSMODE_PREFIX_ADDR) ++ M.x86.mode |= SYSMODE_32BIT_REP; + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); + } +@@ -5013,12 +5085,14 @@ break; case 4: /* jmp word ptr ... */ destval = fetch_data_word(destoffset); @@ -168,6 +417,53 @@ diff -u -u -r1.1 ops.c TRACE_AND_STEP(); M.x86.R_IP = destval; M.x86.R_CS = destval2; +Index: prim_ops.c +=================================================================== +RCS file: /cvs/osdf/cvs/host/other-licence/x86emu/prim_ops.c,v +retrieving revision 1.1 +retrieving revision 1.2 +diff -u -u -r1.1 -r1.2 +--- prim_ops.c 7 Sep 2007 10:01:21 -0000 1.1 ++++ prim_ops.c 15 Jan 2008 13:46:40 -0000 1.2 +@@ -2312,16 +2312,15 @@ + } + if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ +- /* in until CX is ZERO. */ +- u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ? ++ /* in until (E)CX is ZERO. */ ++ u32 count = ((M.x86.mode & SYSMODE_32BIT_REP) ? + M.x86.R_ECX : M.x86.R_CX); +- + while (count--) { + single_in(size); + M.x86.R_DI += inc; + } + M.x86.R_CX = 0; +- if (M.x86.mode & SYSMODE_PREFIX_DATA) { ++ if (M.x86.mode & SYSMODE_32BIT_REP) { + M.x86.R_ECX = 0; + } + M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); +@@ -2355,15 +2354,15 @@ + } + if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { + /* dont care whether REPE or REPNE */ +- /* out until CX is ZERO. */ +- u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ? ++ /* out until (E)CX is ZERO. */ ++ u32 count = ((M.x86.mode & SYSMODE_32BIT_REP) ? + M.x86.R_ECX : M.x86.R_CX); + while (count--) { + single_out(size); + M.x86.R_SI += inc; + } + M.x86.R_CX = 0; +- if (M.x86.mode & SYSMODE_PREFIX_DATA) { ++ if (M.x86.mode & SYSMODE_32BIT_REP) { + M.x86.R_ECX = 0; + } + M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); Index: sys.c =================================================================== RCS file: /cvs/osdf/cvs/host/other-licence/x86emu/sys.c,v @@ -251,9 +547,10 @@ Index: include/x86emu/debug.h =================================================================== RCS file: /cvs/osdf/cvs/host/other-licence/x86emu/include/x86emu/debug.h,v retrieving revision 1.1 -diff -u -u -r1.1 debug.h +retrieving revision 1.3 +diff -u -u -r1.1 -r1.3 --- include/x86emu/debug.h 7 Sep 2007 10:01:21 -0000 1.1 -+++ include/x86emu/debug.h 19 Oct 2007 08:29:16 -0000 ++++ include/x86emu/debug.h 19 Oct 2007 08:42:15 -0000 1.3 @@ -40,8 +40,6 @@ #ifndef __X86EMU_DEBUG_H #define __X86EMU_DEBUG_H @@ -301,10 +598,31 @@ Index: include/x86emu/regs.h =================================================================== RCS file: /cvs/osdf/cvs/host/other-licence/x86emu/include/x86emu/regs.h,v retrieving revision 1.1 -diff -u -u -r1.1 regs.h +retrieving revision 1.4 +diff -u -u -r1.1 -r1.4 --- include/x86emu/regs.h 7 Sep 2007 10:01:21 -0000 1.1 -+++ include/x86emu/regs.h 19 Oct 2007 08:29:16 -0000 -@@ -274,9 +274,9 @@ ++++ include/x86emu/regs.h 15 Jan 2008 13:46:40 -0000 1.4 +@@ -231,6 +231,9 @@ + #define SYSMODE_PREFIX_REPNE 0x00000100 + #define SYSMODE_PREFIX_DATA 0x00000200 + #define SYSMODE_PREFIX_ADDR 0x00000400 ++//phueper: for REP(E|NE) Instructions, we need to decide wether it should be using ++//the 32bit ECX register as or the 16bit CX register as count register ++#define SYSMODE_32BIT_REP 0x00000800 + #define SYSMODE_INTR_PENDING 0x10000000 + #define SYSMODE_EXTRN_INTR 0x20000000 + #define SYSMODE_HALTED 0x40000000 +@@ -250,7 +253,8 @@ + SYSMODE_SEGOVR_GS | \ + SYSMODE_SEGOVR_SS | \ + SYSMODE_PREFIX_DATA | \ +- SYSMODE_PREFIX_ADDR) ++ SYSMODE_PREFIX_ADDR | \ ++ SYSMODE_32BIT_REP) + + #define INTR_SYNCH 0x1 + #define INTR_ASYNCH 0x2 +@@ -274,9 +278,9 @@ */ u32 mode; volatile int intr; /* mask of pending interrupts */ @@ -316,7 +634,7 @@ diff -u -u -r1.1 regs.h u16 saved_ip; u16 saved_cs; int enc_pos; -@@ -366,7 +366,7 @@ +@@ -366,7 +370,7 @@ /* Function to log information at runtime */ @@ -329,9 +647,10 @@ Index: include/x86emu/x86emu.h =================================================================== RCS file: /cvs/osdf/cvs/host/other-licence/x86emu/include/x86emu/x86emu.h,v retrieving revision 1.1 -diff -u -u -r1.1 x86emu.h +retrieving revision 1.3 +diff -u -u -r1.1 -r1.3 --- include/x86emu/x86emu.h 7 Sep 2007 10:01:21 -0000 1.1 -+++ include/x86emu/x86emu.h 19 Oct 2007 08:29:16 -0000 ++++ include/x86emu/x86emu.h 19 Oct 2007 08:42:15 -0000 1.3 @@ -42,14 +42,6 @@ #ifndef __X86EMU_X86EMU_H #define __X86EMU_X86EMU_H diff --git a/other-licence/x86emu/x86emu_download.sh b/other-licence/x86emu/x86emu_download.sh index 43ca332..36b1e10 100755 --- a/other-licence/x86emu/x86emu_download.sh +++ b/other-licence/x86emu/x86emu_download.sh @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -47,7 +47,7 @@ cp -v x86emu/x86emu/*.c . cp -v x86emu/x86emu/*.h include/x86emu cp -v x86emu/include/x86emu/*.h include/x86emu -echo "Removing checked out subversion directory..." +echo "Removing checkedout subversion director..." rm -rf x86emu diff --git a/romfs/tools/Makefile b/romfs/tools/Makefile index dcdba83..8f399a8 100644 --- a/romfs/tools/Makefile +++ b/romfs/tools/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -10,6 +10,11 @@ # * IBM Corporation - initial implementation # ****************************************************************************/ +# FIXME review -I ... +# export NEW_BUILD=1 + +TOPCMNDIR ?= ../.. +INCLCMNDIR ?= ../../include include $(TOPCMNDIR)/make.rules @@ -20,9 +25,14 @@ CFLAGS += $(FLAG) SRCS = build_ffs.c cfg_parse.c create_flash.c create_crc.c OBJS = $(SRCS:%.c=%.o) +all: build_romfs + build_romfs: $(OBJS) $(HOSTCC) $(HOSTCFLAGS) $(FLAG) -o $@ $^ +testing: build_romfs + make -C test + %.o: %.c $(HOSTCC) $(CPPFLAGS) $(HOSTCFLAGS) $(FLAG) -c $< -o $@ @@ -39,7 +49,7 @@ depend: $(MAKE) Makefile.dep Makefile.dep: Makefile - $(HOSTCC) -MM $(CPPFLAGS) $(CFLAGS) $(SRCS) > Makefile.dep + $(HOSTCC) -MM $(CPPFLAGS) $(HOSTCFLAGS) $(SRCS) > Makefile.dep # Include dependency file if available: -include Makefile.dep diff --git a/romfs/tools/build_ffs.c b/romfs/tools/build_ffs.c index 1374123..d00fecb 100644 --- a/romfs/tools/build_ffs.c +++ b/romfs/tools/build_ffs.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -15,7 +15,6 @@ #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> -#include <netinet/in.h> #include <fcntl.h> #include <string.h> #include <unistd.h> @@ -25,346 +24,453 @@ #define FFS_TARGET_HEADER_SIZE (4 * 8) -/* put this somewhere else */ -#define FLAG_LLFW 1 +extern int verbose; -unsigned int glob_rom_pos = 0; -unsigned int glob_num_files = 0; +#define pad8_num(x) (((x) + 7) & ~7) -typedef struct { - uint32_t high; - uint32_t low; -} uint64s_t; +static int +file_exist(const char *name, int errdisp) +{ + struct stat fileinfo; + + memset((void *) &fileinfo, 0, sizeof(struct stat)); + if (stat(name, &fileinfo) != 0) { + if (0 != errdisp) { + perror(name); + } + return 0; + } + if (S_ISREG(fileinfo.st_mode)) { + return 1; + } + return 0; +} + +static int +file_getsize(const char *name) +{ + int rc; + struct stat fi; + + rc = stat(name, &fi); + if (rc != 0) + return -1; + return fi.st_size; +} + +static int +ffshdr_compare(const void *_a, const void *_b) +{ + const struct ffs_header_t *a = *(struct ffs_header_t * const *) _a; + const struct ffs_header_t *b = *(struct ffs_header_t * const *) _b; + + if (a->romaddr == b->romaddr) + return 0; + if (a->romaddr > b->romaddr) + return 1; + return -1; +} + +static void +hdr_print(struct ffs_header_t *hdr) +{ + printf("hdr: %p\n", hdr); + printf("\taddr: %08llx token: %s\n" + "\tflags: %08llx romaddr: %08llx image_len: %08x\n" + "\tsave_len: %08llx ffsize: %08x hdrsize: %08x\n" + "\ttokensize: %08x\n", + hdr->addr, hdr->token, hdr->flags, hdr->romaddr, + hdr->imagefile_length, hdr->save_data_len, + hdr->ffsize, hdr->hdrsize, hdr->tokensize); +} + +int +reorder_ffs_chain(struct ffs_chain_t *fs) +{ + int i, j; + int free_space; + unsigned long long addr; + struct ffs_header_t *hdr; + int fix, flx, res, tab_size = fs->count; + struct ffs_header_t *fix_tab[tab_size]; /* fixed offset */ + struct ffs_header_t *flx_tab[tab_size]; /* flexible offset */ + struct ffs_header_t *res_tab[tab_size]; /* result */ + + /* determine size data to be able to do the reordering */ + for (hdr = fs->first; hdr; hdr = hdr->next) { + if (hdr->linked_to) + hdr->imagefile_length = 0; + else + hdr->imagefile_length = file_getsize(hdr->imagefile); + if (hdr->imagefile_length == -1) + return -1; + + hdr->tokensize = pad8_num(strlen(hdr->token) + 1); + hdr->hdrsize = FFS_TARGET_HEADER_SIZE + hdr->tokensize; + hdr->ffsize = + hdr->hdrsize + pad8_num(hdr->imagefile_length) + 8; + } + + memset(res_tab, 0, tab_size * sizeof(struct ffs_header_t *)); + memset(fix_tab, 0, tab_size * sizeof(struct ffs_header_t *)); + memset(flx_tab, 0, tab_size * sizeof(struct ffs_header_t *)); + + /* now start with entries having fixed offs, reorder if needed */ + for (fix = 0, flx = 0, hdr = fs->first; hdr; hdr = hdr->next) + if (needs_fix_offset(hdr)) + fix_tab[fix++] = hdr; + else + flx_tab[flx++] = hdr; + qsort(fix_tab, fix, sizeof(struct ffs_header_t *), ffshdr_compare); + + /* + * for fixed files we need to also remove the hdrsize from the + * free space because it placed in front of the romaddr + */ + for (addr = 0, res = 0, i = 0, j = 0; i < fix; i++) { + fix_tab[i]->addr = fix_tab[i]->romaddr - fix_tab[i]->hdrsize; + free_space = fix_tab[i]->addr - addr; + + /* insert as many flexible files as possible */ + for (; free_space > 0 && j < flx; j++) { + if (flx_tab[j]->ffsize <= free_space) { /* fits */ + flx_tab[j]->addr = addr; + free_space -= flx_tab[j]->ffsize; + addr += flx_tab[j]->ffsize; + res_tab[res++] = flx_tab[j]; + } else + break; + } + res_tab[res++] = fix_tab[i]; + addr = fix_tab[i]->romaddr + fix_tab[i]->ffsize - + fix_tab[i]->hdrsize; + } + /* at the end fill up the table with remaining flx entries */ + for (; j < flx; j++) { + flx_tab[j]->addr = addr; + addr += flx_tab[j]->ffsize; + res_tab[res++] = flx_tab[j]; + } + + if (verbose) { + printf("--- resulting order ---\n"); + for (i = 0; i < tab_size; i++) + hdr_print(res_tab[i]); + } -int file_exist(char *, int); -/* change done 2005-March-09 */ -int write_to_file(int fd, unsigned char *buf, int size); -/* by Rolf Schaefer */ + /* to check if the requested romfs images is greater than + * the specified romfs_size it is necessary to add 8 for + * the CRC to the totalsize */ + addr += 8; -#define pad8_num(x) ((x) + (-(x) & 7)) + /* sanity checking if user specified maximum romfs size */ + if ((fs->romfs_size != 0) && addr > fs->romfs_size) { + fprintf(stderr, "[build_romfs] romfs_size specified as %d " + "bytes, but %lld bytes need to be written.\n", + fs->romfs_size, addr); + return 1; + } + + /* resort result list */ + for (i = 0; i < tab_size - 1; i++) + res_tab[i]->next = res_tab[i + 1]; + res_tab[i]->next = NULL; + fs->first = res_tab[0]; + return 0; +} + +/** + * allocate memory for a romfs file including header + */ +static unsigned char * +malloc_file(int hdrsz, int datasz, int *ffsz) +{ + void *tmp; + + /* complete file size is: + * header + 8byte aligned(data) + end of file marker (-1) */ + *ffsz = hdrsz + pad8_num(datasz) + 8; + /* get the mem */ + tmp = malloc(*ffsz); + + if (!tmp) + return NULL; + + memset(tmp, 0, *ffsz); + + return (unsigned char *) tmp; +} + +static int +copy_file(struct ffs_header_t *hdr, unsigned char *ffile, int datasize, + int ffile_offset, int ffsize) +{ + int cnt = 0; + int imgfd; + int i; + + if (!file_exist(hdr->imagefile, 1)) { + printf("access error to file: %s\n", hdr->imagefile); + free(ffile); + return -1; + } + + imgfd = open(hdr->imagefile, O_RDONLY); + if (0 >= imgfd) { + perror(hdr->imagefile); + free(ffile); + return -1; + } + + /* now copy file to file buffer */ + /* FIXME using fread might be a good idea so + that we do not need to deal with shortened + reads/writes. Also error handling looks + broken to me. Are we sure that all data is + read when exiting this loop? */ + while (1) { + i = read(imgfd, ffile + ffile_offset, ffsize - ffile_offset); + if (i <= 0) + break; + ffile_offset += i; + cnt += i; + } + + /* sanity check */ + if (cnt != datasize) { + printf("BUG!!! copy error on image file [%s](e%d, g%d)\n", + hdr->imagefile, datasize, cnt); + close(imgfd); + free(ffile); + return -1; + } + + close(imgfd); + + return cnt; +} + +static uint64_t +next_file_offset(struct ffs_header_t *hdr, int rom_pos, int ffsize) +{ + uint64_t tmp; + + /* no next file; end of filesystem */ + if (hdr->next == NULL) + return 0; + + if (hdr->next->romaddr > 0) { + /* the next file does not follow directly after the + * current file because it requested to be + * placed at a special address; + * we need to calculate the offset of the + * next file; + * the next file starts at hdr->next->romaddr which + * is the address requested by the user */ + tmp = hdr->next->romaddr; + /* the next file starts, however, a bit earlier; + * we need to point at the header of the next file; + * therefore it is necessary to subtract the header size + * of the _next_ file */ + tmp -= FFS_TARGET_HEADER_SIZE; + /* also remove the length of the filename of the _next_ + * file */ + tmp -= pad8_num(strlen(hdr->next->token) + 1); + /* and it needs to be relative to the current file */ + tmp -= rom_pos; + return tmp; + } + + /* if no special treatment is required the next file just + * follows after the current file; + * therefore just return the complete filesize as offset */ + return ffsize; +} -int build_ffs(struct ffs_chain_t *fs, char *outfile) +static int +next_file_address(struct ffs_header_t *hdr, unsigned int rom_pos, int hdrsize, + unsigned int num_files) { - int ofdCRC; /* change done 2005-April-07 by Rolf Schaefer */ - int ofd, ffsize, datasize, imgfd, i, cnt; + /* check if file wants a specific address */ + void *tmp; + + if ((hdr->flags & FLAG_LLFW) == 0) + /* flag to get a specific address has been set */ + return rom_pos; + + if (hdr->romaddr == 0) + /* if the requested address is 0 then + * something is not right; ignore the flag */ + return rom_pos; + + /* check if romaddress is below current position */ + if (hdr->romaddr < (rom_pos + hdrsize)) { + printf("[%s] ERROR: requested impossible " "romaddr of %llx\n", + hdr->token, hdr->romaddr); + return -1; + } + + /* spin offset to new positon */ + if (pad8_num(hdr->romaddr) != hdr->romaddr) { + printf("BUG!!!! pad8_num(hdr->romaddr) != hdr->romaddr\n"); + return -1; + } + + tmp = malloc(hdr->romaddr - rom_pos - hdrsize); + + if (!tmp) + return -1; + + memset(tmp, 0, hdr->romaddr - rom_pos - hdrsize); + if (buildDataStream(tmp, hdr->romaddr - rom_pos - hdrsize)) { + free(tmp); + printf("write failed\n"); + return -1; + } + + free(tmp); + + if (!num_files) + printf("\nWARNING: The filesystem will have no entry header!\n" + " It is still usable but you need to find\n" + " the FS by yourself in the image.\n\n"); + + return hdr->romaddr - hdrsize; +} + +int +build_ffs(struct ffs_chain_t *fs, const char *outfile, int notime) +{ + int ofdCRC; + int ffsize, datasize, i; int tokensize, hdrsize, ffile_offset, hdrbegin; struct ffs_header_t *hdr; - unsigned char *ffile, c; - struct stat fileinfo; - uint64s_t val64; + unsigned char *ffile; + unsigned int rom_pos = 0; + unsigned int num_files = 0; + uint64_t tmp; if (NULL == fs->first) { return 1; } hdr = fs->first; - + /* check output file and open it for creation */ if (file_exist(outfile, 0)) { - printf("Output file (%s) will be overwritten\n", - outfile); + printf("Output file (%s) will be overwritten\n", outfile); } - ofd = open(".crc_flash", O_CREAT | O_WRONLY | O_TRUNC, 0666); - ofdCRC = open(outfile, O_CREAT | O_WRONLY | O_TRUNC, 0666); /* change done 2005-April-07 by Rolf Schaefer */ - if (0 > ofd || 0 > ofdCRC) { - perror(outfile); - return 1; - } + while (hdr) { - while (1) { - /* - * first estimate the size of the file including header - * to allocate the memory in advance. - */ - if (NULL == hdr->linked_to) { - memset((void*)&fileinfo, 0, sizeof(struct stat)); - if (stat(hdr->imagefile, &fileinfo) != 0) { - perror(hdr->imagefile); - return 1; - } - datasize = fileinfo.st_size; - } else { - datasize = 0; + if (hdr->linked_to) { + printf("\nBUG!!! links not supported anymore\n"); + return 1; } - ffile_offset = 0, - tokensize = pad8_num(strlen(hdr->token) + 1 /* ens trl 0 */); - hdrsize = FFS_TARGET_HEADER_SIZE + tokensize; - ffsize = hdrsize + pad8_num(datasize) + 8 /* -1 */; - /* get the mem */ - ffile = (unsigned char*) malloc(ffsize); + /* add +1 to strlen for zero termination */ + tokensize = pad8_num(strlen(hdr->token) + 1); + hdrsize = FFS_TARGET_HEADER_SIZE + tokensize; + datasize = file_getsize(hdr->imagefile); + + if (datasize == -1) { + perror(hdr->imagefile); + return 1; + } + + ffile_offset = 0; + ffile = malloc_file(hdrsize, datasize, &ffsize); + if (NULL == ffile) { perror("alloc mem for ffile"); return 1; } - memset((void*)ffile, 0 , ffsize); /* check if file wants a specific address */ - if ((hdr->romaddr > 0) || (0 != (hdr->flags & FLAG_LLFW))) { - /* check if romaddress is below current position */ - if (hdr->romaddr < (glob_rom_pos + hdrsize)) { - printf("[%s] ERROR: requested impossible " - "romaddr of %llx\n", - hdr->token, hdr->romaddr); - close(ofd); - free(ffile); - return 1; - } - - /* spin offset to new positon */ - if (pad8_num(hdr->romaddr) != hdr->romaddr) { - printf("BUG!!!! pad8_num(hdr->romaddr) != hdr->romaddr\n"); - close(ofd); - free(ffile); - return 1; - } - i = hdr->romaddr - glob_rom_pos - hdrsize; - while (0 < i) { - c = 0; -/* change done 09.03.2005 */ - if (0 != write_to_file(ofd, &c, 1)) { -/* by Rolf Schaefer */ - printf("write failed\n"); - close(ofd); - free(ffile); - } - glob_rom_pos++; - i--; - } - if (glob_rom_pos != (hdr->romaddr - hdrsize)) { - printf("BUG!!! hdr->romaddr != glob_rom_pos (%llx, %x)\n", - hdr->romaddr, glob_rom_pos); - } - if (0 == glob_num_files) { - printf("\nWARNING: The filesystem will have no " - "entry header !\n" - " It is still usable but you need " - "to find\n" - " the FS by yourself in the image.\n\n"); - } - } - hdrbegin = glob_rom_pos; - ///printf("OFFS=%6x FSIZE=%6d ", glob_rom_pos, ffsize); - - /* write header ********************************************/ - /* next addr ***********************************************/ - val64.high= 0; - val64.low = 0; - //printf("\n\n\nFFS_TARGET_HEADER_SIZE = %d\n", FFS_TARGET_HEADER_SIZE); - //printf( "FFS_TARGET_HEADER_SIZE = 0x%x\n", FFS_TARGET_HEADER_SIZE); - //printf( "glob_rom_pos = 0x%x\n", glob_rom_pos); - //printf( "ffsize = %d\n", ffsize); - //printf( "ffsize = 0x%x\n", ffsize); - - if (NULL != hdr->next) { - //printf( "next-romaddr = 0x%lx\n", hdr->next->romaddr); - //printf( "strlen(hdr->next->token= %d\n", pad8_num(strlen(hdr->next->token))); - //printf( "strlen(hdr->next->token= 0x%d\n", pad8_num(strlen(hdr->next->token))); - if (hdr->next->romaddr > 0) { - /* FIXME this is quite ugly, any other idea? */ - val64.low = hdr->next->romaddr - - (FFS_TARGET_HEADER_SIZE + - pad8_num(strlen(hdr->next->token))); - val64.low -= glob_rom_pos; - val64.low = htonl(val64.low); - } - //printf( "val64.low = 0x%lx\n", val64.low); - - if (0 == val64.low) { - //next address relative to rombase - //val64.low = htonl(glob_rom_pos + ffsize); - // - //changed next pointer to be relative - //to current fileposition; needed to glue - //different romfs-volumes together - val64.low = htonl(ffsize); - } - } - //printf("\n\n\n"); - - memcpy(ffile + ffile_offset, &val64, 8); - glob_rom_pos += 8; - ffile_offset += 8; + rom_pos = next_file_address(hdr, rom_pos, hdrsize, num_files); + hdrbegin = rom_pos; - /* length **************************************************/ - if (NULL == hdr->linked_to) { - val64.low = htonl(datasize); - hdr->save_data_len = datasize; - } else { - printf("\nBUG!!! links not supported anymore\n"); - close(ofd); + if (hdrbegin == -1) { + /* something went wrong */ free(ffile); return 1; - - /* - if (0 == hdr->linked_to->save_data_valid) { - printf("ERROR: this version does not support" - "forward references in links\n"); - close(ofd); - free(ffile); - return 1; - } - val64.low = htonl(hdr->linked_to->save_data_len); - */ } - memcpy(ffile + ffile_offset, &val64, 8); - glob_rom_pos += 8; + + /* write header ******************************************* */ + /* next addr ********************************************** */ + tmp = next_file_offset(hdr, rom_pos, ffsize); + + *(uint64_t *) (ffile + ffile_offset) = cpu_to_be64(tmp); + rom_pos += 8; ffile_offset += 8; - /* flags ***************************************************/ - val64.low = htonl(hdr->flags); - memcpy(ffile + ffile_offset, &val64, 8); - glob_rom_pos += 8; + /* length ************************************************* */ + hdr->save_data_len = datasize; + + *(uint64_t *) (ffile + ffile_offset) = cpu_to_be64(datasize); + rom_pos += 8; ffile_offset += 8; - /* datapointer *********************************************/ - if (NULL == hdr->linked_to) { - //save-data pointer is relative to rombase - hdr->save_data = hdrbegin + hdrsize; - hdr->save_data_valid = 1; - //pointer relative to rombase: - //val64.low = htonl(hdr->save_data); - // - //changed pointers to be relative to file: - val64.low = htonl(hdr->save_data - hdrbegin); - } else { - printf("\nBUG!!! links not supported anymore\n"); - close(ofd); - free(ffile); - return 1; + /* flags ************************************************** */ + *(uint64_t *) (ffile + ffile_offset) = cpu_to_be64(hdr->flags); + rom_pos += 8; + ffile_offset += 8; - /* - if (0 == hdr->linked_to->save_data_valid) { - printf("ERROR: this version does not support" - "forward references in links\n"); - close(ofd); - free(ffile); - return 1; - } - val64.low = htonl(hdr->linked_to->save_data); - */ - } - memcpy(ffile + ffile_offset, &val64, 8); - glob_rom_pos += 8; + /* datapointer ******************************************** */ + + //save-data pointer is relative to rombase + hdr->save_data = hdrbegin + hdrsize; + hdr->save_data_valid = 1; + //changed pointers to be relative to file: + tmp = hdr->save_data - hdrbegin; + + *(uint64_t *) (ffile + ffile_offset) = cpu_to_be64(tmp); + rom_pos += 8; ffile_offset += 8; - /* name (token) ********************************************/ + /* name (token) ******************************************* */ memset(ffile + ffile_offset, 0, tokensize); - strcpy((char *)ffile + ffile_offset, hdr->token); - glob_rom_pos += tokensize; + strcpy((char *) ffile + ffile_offset, hdr->token); + rom_pos += tokensize; ffile_offset += tokensize; - /* image file **********************************************/ - if (NULL == hdr->linked_to) { - if (! file_exist(hdr->imagefile, 1)) { - printf("access error to file: %s\n", hdr->imagefile); - close(ofd); - free(ffile); - return 1; - } - - imgfd = open(hdr->imagefile, O_RDONLY); - if (0 >= imgfd) { - perror(hdr->imagefile); - close(ofd); - free(ffile); - return 1; - } - - /* now copy file to file buffer */ - cnt = 0; - while (1) { - i = read(imgfd, ffile + ffile_offset, ffsize-ffile_offset); - if (i <= 0) break; - glob_rom_pos += i; - ffile_offset += i; - cnt += i; - } - - /* pad file */ - glob_rom_pos += pad8_num(datasize) - datasize; - ffile_offset += pad8_num(datasize) - datasize; - - /* sanity check */ - if (cnt != datasize) { - printf("BUG!!! copy error on image file [%s](e%d, g%d)\n", - hdr->imagefile, datasize, cnt); - close(imgfd); - close(ofd); - free(ffile); - return 1; - } - close(imgfd); - } + /* image file ********************************************* */ + i = copy_file(hdr, ffile, datasize, ffile_offset, ffsize); + + if (i == -1) + return 1; - /* limiter *************************************************/ - val64.low = -1; - val64.high = -1; - memcpy(ffile + ffile_offset, &val64, 8); - glob_rom_pos += 8; + /* pad file */ + rom_pos += i + pad8_num(datasize) - datasize; + ffile_offset += i + pad8_num(datasize) - datasize; + + /* limiter ************************************************ */ + *(uint64_t *) (ffile + ffile_offset) = -1; + rom_pos += 8; ffile_offset += 8; - /* *********************************************************/ - ///printf("FLEN=%6d TOK=%-11s FILE=%s\n", - /// ffsize, - /// hdr->token, - /// hdr->imagefile); -/* change done 9.3.2005*/ - if (write_to_file(ofd, ffile, ffsize) != 0) { - printf("Failed while processing file '%s' (size = %d bytes)\n", - hdr->imagefile, datasize); + if (buildDataStream(ffile, ffsize) != 0) { + printf + ("Failed while processing file '%s' (size = %d bytes)\n", + hdr->imagefile, datasize); return 1; } -/* by Rolf Schaefer */ free(ffile); hdr = hdr->next; - glob_num_files++; - - if (NULL == hdr) break; + num_files++; } -/* change done 09.03.2005 */ - writeDataStream(ofdCRC); -/* by Rolf Schaefer */ - close(ofd); - close(ofdCRC); - - return 0; -} - -int file_exist(char *name, int errdisp) -{ - struct stat fileinfo; - memset((void*)&fileinfo, 0, sizeof(struct stat)); - if (stat(name, &fileinfo) != 0) { - if (0 != errdisp) { - perror(name); - } - return 0; - } - if (S_ISREG(fileinfo.st_mode)) { + /* + * FIXME Current limination seems to be about 4MiB. + */ + ofdCRC = open(outfile, O_CREAT | O_WRONLY | O_TRUNC, 0666); + if (0 > ofdCRC) { + perror(outfile); return 1; } - return 0; -} - -/* changes done 2005_March-09 */ -int write_to_file(int fd, unsigned char *buf, int size) -{ - int i; - - if (buildDataStream(buf, size) != 0) - return -1; - - for ( ; size; size -= i, buf += i) { - i = write(fd, buf, size); - if (i < 0) { - perror("write to image"); - return 1; - } - } - -/*by Rolf Schaefer */ + i = writeDataStream(ofdCRC, notime); + close(ofdCRC); + if (i) + return 1; return 0; } diff --git a/romfs/tools/cfg_parse.c b/romfs/tools/cfg_parse.c index da4d75b..5137fbe 100644 --- a/romfs/tools/cfg_parse.c +++ b/romfs/tools/cfg_parse.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -19,28 +19,32 @@ #include <cfgparse.h> -int glob_come_from_cr = 0; +static int inbetween_white(char *s, int max, char **start, char **end, + char **next); +static int add_header(struct ffs_chain_t *, struct ffs_header_t *); -int find_next_entry(int file, struct ffs_chain_t *chain) +static int glob_come_from_cr = 0; + +static int +find_next_entry(int file, struct ffs_chain_t *chain) { #define MAX_LINE_SIZE 1024 - char lnbuf[MAX_LINE_SIZE], b0=0, b1=0; + char lnbuf[MAX_LINE_SIZE], b0 = 0, b1 = 0; char *start, *end, *next; - struct ffs_header_t *hdr; //, *hdr2; + struct ffs_header_t *hdr; //, *hdr2; int lc, rc; char c; - + /* search for new config line */ if (0 == glob_come_from_cr) { while (1 == (rc = read(file, &c, 1))) { //printf("b0=%c b1=%c c=%c\n", - // b0, b1, c); + // b0, b1, c); b0 = b1; b1 = c; /* this looks for starting sign "<CR>[^#]" */ - if ( ((0x0a == b0) || (0x0d == b0)) && - (('#' != b1) && (0x0a != b1) && - (0x0d != b1))) { + if (((0x0a == b0) || (0x0d == b0)) && + (('#' != b1) && (0x0a != b1) && (0x0d != b1))) { break; } } @@ -60,7 +64,7 @@ int find_next_entry(int file, struct ffs_chain_t *chain) } /* now buffer it until end of line */ - memset((void*) lnbuf, 0, MAX_LINE_SIZE); + memset((void *) lnbuf, 0, MAX_LINE_SIZE); lnbuf[0] = c; lc = 1; while ((1 == read(file, &(lnbuf[lc]), 1)) && (lc < MAX_LINE_SIZE)) { @@ -79,7 +83,7 @@ int find_next_entry(int file, struct ffs_chain_t *chain) perror("alloc memory"); return 2; } - memset((void*)hdr, 0, sizeof(struct ffs_header_t)); + memset((void *) hdr, 0, sizeof(struct ffs_header_t)); /* attach header to chain */ if (0 != add_header(chain, hdr)) { @@ -127,19 +131,20 @@ int find_next_entry(int file, struct ffs_chain_t *chain) /* check if entry is linked to another header */ if (':' == *start) { - printf("\nERROR: links are removed as feature in this version\n"); + printf + ("\nERROR: links are removed as feature in this version\n"); return 2; /* - start++; - if (0 != find_entry_by_token(chain, hdr->imagefile+1, &hdr2)) { - printf("[%s]: link to [%s] not found\n", - hdr->token, hdr->imagefile+1); - dump_fs_contents(chain); - return 2; - } - hdr->linked_to = hdr2; - */ + start++; + if (0 != find_entry_by_token(chain, hdr->imagefile+1, &hdr2)) { + printf("[%s]: link to [%s] not found\n", + hdr->token, hdr->imagefile+1); + dump_fs_contents(chain); + return 2; + } + hdr->linked_to = hdr2; + */ } /**********************************************************/ @@ -175,21 +180,27 @@ int find_next_entry(int file, struct ffs_chain_t *chain) return 0; } -void debug_print_range(char *s, char *e) +int +read_config(int conf_file, struct ffs_chain_t *ffs_chain) { - while (s < e) { - printf("%c", *s); - s++; + int rc; + + while (1) { + rc = find_next_entry(conf_file, ffs_chain); + if (rc != 0) + break; } + return rc; } -int inbetween_white(char *s, int max, char **start, char **end, char **next) +static int +inbetween_white(char *s, int max, char **start, char **end, char **next) { int pos = 0, posalt; if (NULL != *start) { pos = *start - s; - s = *start; + s = *start; } /* wind to first non white */ @@ -212,7 +223,7 @@ int inbetween_white(char *s, int max, char **start, char **end, char **next) /* wind to end of non white or end of buffer */ posalt = pos; while (pos < max) { - if ((' ' == *s) || (' ' == *s) || + if ((' ' == *s) || (' ' == *s) || (0x0a == *s) || (0x0d == *s)) { break; } @@ -235,11 +246,13 @@ int inbetween_white(char *s, int max, char **start, char **end, char **next) return 0; } -int add_header(struct ffs_chain_t *chain, struct ffs_header_t *hdr) +int +add_header(struct ffs_chain_t *chain, struct ffs_header_t *hdr) { struct ffs_header_t *next; if (NULL == chain->first) { + chain->count = 1; chain->first = hdr; return 0; } @@ -250,40 +263,13 @@ int add_header(struct ffs_chain_t *chain, struct ffs_header_t *hdr) next = next->next; } next->next = hdr; + chain->count++; return 0; } -int find_entry_by_token(struct ffs_chain_t *chain, char *token, - struct ffs_header_t **hdr) -{ - struct ffs_header_t *next; - - if (NULL == chain->first) { - *hdr = NULL; - return 1; - } - next = chain->first; - - //printf("debug: search for [%s]...\n", token); - - while (1) { - //printf(" > [%s]\n", next->token); - if (strcmp(token, next->token) == 0) { - *hdr = next; - //printf(" > found\n"); - break; - } - if (NULL == next->next) { - //printf(" > reached end of chain, not found\n"); - return 1; - } - next = next->next; - } - return 0; -} - -void dump_fs_contents(struct ffs_chain_t *chain) +void +dump_fs_contents(struct ffs_chain_t *chain) { struct ffs_header_t *next; @@ -308,11 +294,11 @@ void dump_fs_contents(struct ffs_chain_t *chain) printf("flags<%llx>, ", next->flags); printf("romaddr<%llx>, ", next->romaddr); - + if (NULL != next->linked_to) { printf("linked to [%s]", next->linked_to->token); } - + printf("\n"); if (NULL == next->next) { break; @@ -320,10 +306,11 @@ void dump_fs_contents(struct ffs_chain_t *chain) next = next->next; } - + } -void free_chain_memory(struct ffs_chain_t *chain) +void +free_chain_memory(struct ffs_chain_t *chain) { struct ffs_header_t *hdr, *next_hdr; @@ -353,7 +340,8 @@ void free_chain_memory(struct ffs_chain_t *chain) /* * Detect duplicate entries in the romfs list */ -void find_duplicates(struct ffs_chain_t *chain) +void +find_duplicates(struct ffs_chain_t *chain) { struct ffs_header_t *act, *sub; @@ -366,12 +354,12 @@ void find_duplicates(struct ffs_chain_t *chain) do { sub = act->next; while (sub != NULL) { - + if (act->token == NULL || sub->token == NULL) { printf("find_duplicates: token not set!\n"); - } - else if (strcmp(act->token, sub->token) == 0) { - printf("*** NOTE: duplicate romfs file '%s'.\n", act->token); + } else if (strcmp(act->token, sub->token) == 0) { + printf("*** NOTE: duplicate romfs file '%s'.\n", + act->token); } sub = sub->next; } @@ -379,5 +367,5 @@ void find_duplicates(struct ffs_chain_t *chain) act = act->next; } while (act != NULL); - + } diff --git a/romfs/tools/cfgparse.h b/romfs/tools/cfgparse.h index 7ccf9b7..ed5c885 100644 --- a/romfs/tools/cfgparse.h +++ b/romfs/tools/cfgparse.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -12,31 +12,48 @@ #ifndef CFGPARSE_H #define CFGPARSE_H +#include <byteswap.h> +#include <endian.h> + +#if __BYTE_ORDER == __BIG_ENDIAN +#define cpu_to_be64(x) (x) +#else +#define cpu_to_be64(x) bswap_64(x) +#endif + struct ffs_chain_t { + int count; + unsigned int romfs_size; struct ffs_header_t *first; }; +#define FLAG_LLFW 1 /* low level firmware at fix offs in romfs */ + +#define needs_fix_offset(hdr) ((hdr)->flags & FLAG_LLFW) + struct ffs_header_t { unsigned long long flags; unsigned long long romaddr; - char *token; - char *imagefile; - int imagefile_length; + char *token; + char *imagefile; + int imagefile_length; struct ffs_header_t *linked_to; struct ffs_header_t *next; unsigned long long save_data; unsigned long long save_data_len; int save_data_valid; + + unsigned long long addr; /* tmp */ + int hdrsize; /* tmp */ + int tokensize; /* tmp */ + int ffsize; /* tmp */ }; -int find_next_entry(int file, struct ffs_chain_t *chain); -int inbetween_white(char *s, int max, char **start, char **end, char **next); -void debug_print_range(char *s, char *e); -void free_chain_memory(struct ffs_chain_t *chain); -int add_header(struct ffs_chain_t *, struct ffs_header_t *); -int find_entry_by_token(struct ffs_chain_t *, char *, struct ffs_header_t **); void dump_fs_contents(struct ffs_chain_t *chain); void find_duplicates(struct ffs_chain_t *chain); +void free_chain_memory(struct ffs_chain_t *chain); -int build_ffs(struct ffs_chain_t *fs, char *outfile); +int read_config(int conf_file, struct ffs_chain_t *ffs_chain); +int reorder_ffs_chain(struct ffs_chain_t *fs); +int build_ffs(struct ffs_chain_t *fs, const char *outfile, int notime); #endif diff --git a/romfs/tools/create_crc.c b/romfs/tools/create_crc.c index 2db79b7..38235e5 100644 --- a/romfs/tools/create_crc.c +++ b/romfs/tools/create_crc.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -24,460 +24,444 @@ #include <time.h> #include <calculatecrc.h> #include <product.h> -#include <byteswap.h> -#include <endian.h> - -int createHeaderImage(void); -unsigned int calCRCEthernet32(unsigned char *TextPtr, unsigned long int TextLength, unsigned int AccumCRC); -int createCRCParameter(uint64_t *ui64RegisterMask, unsigned int *iRegisterLength); -uint64_t calCRCbyte(unsigned char *TextPtr, uint32_t Residual, uint64_t AccumCRC); -uint64_t calCRCword(unsigned char *TextPtr, uint32_t Residual, uint64_t AccumCRC); +#include "createcrc.h" + +int createHeaderImage(int); +unsigned int calCRCEthernet32(unsigned char *TextPtr, + unsigned long int TextLength, + unsigned int AccumCRC); +int createCRCParameter(uint64_t * ui64RegisterMask, + unsigned int *iRegisterLength); +uint64_t calCRCbyte(unsigned char *TextPtr, uint32_t Residual, + uint64_t AccumCRC); +uint64_t calCRCword(unsigned char *TextPtr, uint32_t Residual, + uint64_t AccumCRC); uint64_t checkCRC(unsigned char *TextPtr, uint32_t Residual, uint64_t AccumCRC); -int insert64bit(uint64_t ui64CRC, uint32_t uliPosition); -static uint64_t ui64globalFileSize=0; // file length in bytes -static unsigned char pucFileStream[4400000]; // space for the file stream >= 4MB + 4bytes -static uint64_t ui64globalHeaderSize=0; // header length in bytes -static int iglobalHeaderFlag = 1; // flag to filter detect the header in buildDataStream() +/* file length in bytes */ +static uint64_t ui64globalFileSize = 0; +/* space for the file stream >= 4MB + 4bytes */ +static unsigned char pucFileStream[4400000]; +/* header length in bytes */ +static uint64_t ui64globalHeaderSize = 0; +/* flag to filter detect the header in buildDataStream() */ +static int iglobalHeaderFlag = 1; static uint64_t ui64Generator1; -/*----------------------------------------------------------------------*/ -/* */ -/* Build the file image and store it as Data Stream of bytes */ -/* calculate a first CRC for the first file and */ -/* chatch the position of this CRC */ -/*----------------------------------------------------------------------*/ -int buildDataStream(unsigned char *pucbuf, int size) + +/** + * Build the file image and store it as Data Stream of bytes + * calculate a first CRC for the first file and + * catch the position of this CRC + */ +int +buildDataStream(unsigned char *pucbuf, int size) { if (ui64globalFileSize + size > sizeof(pucFileStream)) { printf("Error: File size is too big!\n"); return -1; } - for( ; size; size -=1, pucbuf +=1) { + /* copy the data into the destination buffer */ + memcpy(pucFileStream + ui64globalFileSize, pucbuf, size); + ui64globalFileSize += size; - pucFileStream[ui64globalFileSize] = *pucbuf; - ui64globalFileSize++; - } - if(iglobalHeaderFlag == 1) { // catch header + if (iglobalHeaderFlag == 1) { // catch header - ui64globalHeaderSize = ui64globalFileSize; - iglobalHeaderFlag = 0; - } + ui64globalHeaderSize = ui64globalFileSize; + iglobalHeaderFlag = 0; + } return 0; } -/*--------------------------------------------------------------------------------- */ -/* + -+ write Header.img + -+ + -+ note: use insert64bit to write all uint64_t variables because of + -+ Big Endian - Little Endian problem between Intel CPU and PowerPC CPU */ -/* -------------------------------------------------------------------------------- */ -int createHeaderImage(void) + +/** + * write Header.img + */ +int +createHeaderImage(int notime) { int iCounter; - uint64_t ui64RomAddr, ui64DataAddr, ui64FlashlenAddr; + uint64_t ui64RomAddr, ui64DataAddr; time_t caltime; - struct tm *tm; + struct tm *tm; char *pcVersion; - char dastr[16]; - unsigned long long da; + char dastr[16] = { 0, }; + unsigned long long da = 0; union { unsigned char pcArray[FLASHFS_HEADER_DATA_SIZE]; struct stH stHeader; } uHeader; - memset(uHeader.pcArray,0x00, FLASHFS_HEADER_DATA_SIZE); // initialize Header + /* initialize Header */ + memset(uHeader.pcArray, 0x00, FLASHFS_HEADER_DATA_SIZE); /* read driver info */ - if(NULL != (pcVersion = getenv("DRIVER_NAME"))) { - strncpy(uHeader.stHeader.version, pcVersion,16); - } - else if (NULL != (pcVersion = getenv("USER")) ) { - strncpy(uHeader.stHeader.version, pcVersion,16); - } - else if(pcVersion == NULL) { - strncpy(uHeader.stHeader.version, "No known user!",16 ); - } - - /* read time and write it into data stream */ - if ( (caltime = time(NULL)) ==-1) { - printf("time error\n"); - } - if ( (tm = localtime(&caltime)) == NULL) { - printf("local time error\n"); + if (NULL != (pcVersion = getenv("DRIVER_NAME"))) { + strncpy(uHeader.stHeader.version, pcVersion, 16); + } else if (NULL != (pcVersion = getenv("USER"))) { + strncpy(uHeader.stHeader.version, pcVersion, 16); + } else if (pcVersion == NULL) { + strncpy(uHeader.stHeader.version, "No known user!", 16); } - // length must be 13 instead 12 because of terminating NUL. Therefore uH.stH.platform_revison - // must be writen later to overwrite the terminating NUL - if(strftime(dastr, 15, "0x%Y%m%d%H%M", tm) == 0) { - printf("strftime error\n"); + if (!notime) { + /* read time and write it into data stream */ + if ((caltime = time(NULL)) == -1) { + printf("time error\n"); + } + if ((tm = localtime(&caltime)) == NULL) { + printf("local time error\n"); + } + // length must be 13 instead 12 because of terminating + // NUL. Therefore uH.stH.platform_revison must be + // writen later to overwrite the terminating NUL + if (strftime(dastr, 15, "0x%Y%m%d%H%M", tm) == 0) { + printf("strftime error\n"); + } + da = cpu_to_be64(strtoll(dastr, NULL, 16)); } - da=strtoll(dastr,NULL, 16); - #if __BYTE_ORDER == __LITTLE_ENDIAN - da=__bswap_64(da) >> 16; - #else - da = da << 16; - #endif memcpy(uHeader.stHeader.date, &da, 8); - strcpy(uHeader.stHeader.magic,FLASHFS_MAGIC); // write Magic value into data stream - strcpy(uHeader.stHeader.platform_name,FLASHFS_PLATFORM_MAGIC); // write platform name into data stream - strcpy(uHeader.stHeader.platform_revision,FLASHFS_PLATFORM_REVISION); // write platform recision into data stream - - - /* fill end of file info (8 bytes of FF) into data stream */ - uHeader.stHeader.ui64FileEnd = (uint64_t)(0xFFFFFFFF); - uHeader.stHeader.ui64FileEnd = (uHeader.stHeader.ui64FileEnd << 32) + (uint64_t)0xFFFFFFFF; + /* write Magic value into data stream */ + strcpy(uHeader.stHeader.magic, FLASHFS_MAGIC); + /* write platform name into data stream */ + strcpy(uHeader.stHeader.platform_name, FLASHFS_PLATFORM_MAGIC); + /* write platform revision into data stream */ + strcpy(uHeader.stHeader.platform_revision, FLASHFS_PLATFORM_REVISION); - /* read address of next file and address of header date, both are 64 bit values */ - ui64RomAddr = 0; - ui64DataAddr = 0; - for(iCounter = 0; iCounter < 8; iCounter++) { - ui64RomAddr = ( ui64RomAddr << 8 ) + pucFileStream[FLASHFS_ROMADDR + iCounter]; // addr of next file - ui64DataAddr = ( ui64DataAddr << 8) + pucFileStream[FLASHFS_DATADDR + iCounter]; // addr of header data + /* fill end of file info (8 bytes of FF) into data stream */ + uHeader.stHeader.ui64FileEnd = -1; + + /* read address of next file and address of header date, both are 64 bit values */ + ui64RomAddr = 0; + ui64DataAddr = 0; + for (iCounter = 0; iCounter < 8; iCounter++) { + /* addr of next file */ + ui64RomAddr = (ui64RomAddr << 8) + pucFileStream[FLASHFS_ROMADDR + iCounter]; + /* addr of header data */ + ui64DataAddr = (ui64DataAddr << 8) + pucFileStream[FLASHFS_DATADDR + iCounter]; } /* calculate final flash-header-size and flash-file-size */ - ui64globalHeaderSize = (uint32_t)ui64DataAddr + (uint32_t)FLASHFS_HEADER_DATA_SIZE; // calculate end addr of header - ui64globalHeaderSize -=8; // cut 64 bit to place CRC for File-End - ui64globalFileSize += 8; // add 64 bit to place CRC behind File-End - - if( ui64globalHeaderSize < ui64RomAddr ) { - memset( &pucFileStream[ui64DataAddr], 0, (ui64RomAddr-ui64DataAddr)); // fill free space in Header with zeros - // place data to header - memcpy( &pucFileStream[ui64DataAddr], uHeader.pcArray, FLASHFS_HEADER_DATA_SIZE); // insert header data - - // insert header length into data stream - ui64FlashlenAddr = (uint64_t)FLASHFS_HEADER_SIZE_ADDR; - insert64bit(ui64globalHeaderSize, ui64FlashlenAddr ); - - // insert flash length into data stream - ui64FlashlenAddr = ((uint64_t)ui64DataAddr +(uint64_t)FLASHFS_FILE_SIZE_ADDR ); - insert64bit(ui64globalFileSize, ui64FlashlenAddr); - - // insert zeros as placeholder for CRC - insert64bit(0, (ui64globalHeaderSize -8) ); - insert64bit(0, (ui64globalFileSize -8) ); - - return 0; - } - else { - printf("%s\n","--- Header File to long"); + /* calculate end addr of header */ + ui64globalHeaderSize = (uint32_t) ui64DataAddr + (uint32_t) FLASHFS_HEADER_DATA_SIZE; + /* cut 64 bit to place CRC for File-End */ + ui64globalHeaderSize -= 8; + /* add 64 bit to place CRC behind File-End */ + ui64globalFileSize += 8; + + if (ui64globalHeaderSize >= ui64RomAddr) { + printf("%s\n", "--- Header File to long"); return 1; } + + /* fill free space in Header with zeros */ + memset(&pucFileStream[ui64DataAddr], 0, (ui64RomAddr - ui64DataAddr)); + /* place data to header */ + memcpy(&pucFileStream[ui64DataAddr], uHeader.pcArray, + FLASHFS_HEADER_DATA_SIZE); + + /* insert header length into data stream */ + *(uint64_t *) (pucFileStream + FLASHFS_HEADER_SIZE_ADDR) = + cpu_to_be64(ui64globalHeaderSize); + + /* insert flash length into data stream */ + *(uint64_t *) (pucFileStream + ui64DataAddr + FLASHFS_FILE_SIZE_ADDR) = + cpu_to_be64(ui64globalFileSize); + + /* insert zeros as placeholder for CRC */ + *(uint64_t *) (pucFileStream + ui64globalHeaderSize - 8) = 0; + *(uint64_t *) (pucFileStream + ui64globalFileSize - 8) = 0; + + return 0; } -/*--------------------------------------------------------------------- */ -/* */ -/* calculate standart ethernet 32 bit CRC */ -/* generator polynome is 0x104C11DB7 */ -/* this algorithm can be used for encoding and decoding */ -/*----------------------------------------------------------------------*/ -unsigned int calCRCEthernet32(unsigned char *TextPtr, unsigned long int TextLength, unsigned int AccumCRC) { - const unsigned int CrcTableHigh[16] = { - 0x00000000, 0x4C11DB70, 0x9823B6E0, 0xD4326D90, - 0x34867077, 0x7897AB07, 0xACA5C697, 0xE0B41DE7, - 0x690CE0EE, 0x251D3B9E, 0xF12F560E, 0xBD3E8D7E, - 0x5D8A9099, 0x119B4BE9, 0xC5A92679, 0x89B8FD09 - }; - const unsigned CrcTableLow[16] = { - 0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9, - 0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005, - 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61, - 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD - }; - - unsigned char* Buffer = TextPtr; - unsigned long int Residual = TextLength; - - - while ( Residual > 0 ) { - unsigned int Temp = ((AccumCRC >> 24) ^ *Buffer) & 0x000000ff; - AccumCRC <<= 8; - AccumCRC ^= CrcTableHigh[ Temp/16 ]; - AccumCRC ^= CrcTableLow[ Temp%16 ]; - ++Buffer; - --Residual; - } - return AccumCRC; + +/** + * calculate standart ethernet 32 bit CRC + * generator polynome is 0x104C11DB7 + * this algorithm can be used for encoding and decoding + */ +unsigned int +calCRCEthernet32(unsigned char *TextPtr, unsigned long int TextLength, + unsigned int AccumCRC) +{ + const unsigned int CrcTableHigh[16] = { + 0x00000000, 0x4C11DB70, 0x9823B6E0, 0xD4326D90, + 0x34867077, 0x7897AB07, 0xACA5C697, 0xE0B41DE7, + 0x690CE0EE, 0x251D3B9E, 0xF12F560E, 0xBD3E8D7E, + 0x5D8A9099, 0x119B4BE9, 0xC5A92679, 0x89B8FD09 + }; + const unsigned CrcTableLow[16] = { + 0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9, + 0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005, + 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61, + 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD + }; + + unsigned char *Buffer = TextPtr; + unsigned long int Residual = TextLength; + + + while (Residual > 0) { + unsigned int Temp = ((AccumCRC >> 24) ^ *Buffer) & 0x000000ff; + AccumCRC <<= 8; + AccumCRC ^= CrcTableHigh[Temp / 16]; + AccumCRC ^= CrcTableLow[Temp % 16]; + ++Buffer; + --Residual; + } + return AccumCRC; } -/*------------------------------------------------------- calculate CRC */ -/* */ -/* */ -/*----------------------------------------------------------------------*/ -/* create CRC Parameter: CRC Polynome, Shiftregister Mask and length */ -// ui64Generator[0] = 0; -// ui64Generator[1] = 0x42F0E1EB; -// ui64Generator[1] = (ui64Generator[1] << 32) + 0xA9EA3693; -// iRegisterLength = 63; -// ui64RegisterMask = 0xffffffff; -// ui64RegisterMask = ((ui64RegisterMask) << 32) + 0xffffffff; -/* ucl=0x00000000ffffffff = Mask for 32 bit LSFR to cut down number of bits - in the variable to get the same length as LFSR - - il = length of LSFR = degree of generator polynom reduce il by one to calculate the degree - of the highest register in LSFR - - Examples: - CRC-16 for Tap: x16 + x15 + x2 + 1 - generator = 0x8005, il = 16, ucl = 0x000000000000FFFF - - CRC-16 for Floppy: x16 + x12 + x5 +1 - generator = 0x1021, il = 16, ucl = 0x000000000000FFFF - - CRC-32 for Ethernet: x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 - generator = 0x04C11DB7, il = 32, ucl = 0x00000000FFFFFFFF - - CRC-64 SP-TrEMBL x64 + x4 + x3 + x + 1 (maximal-length LFSR) - renerator = 0x1B, il = 64, ucl = 0xFFFFFFFFFFFFFFFF - - CRC-64 improved x64 + x63 + x61 + x59 + x58 + x56 + x55 + x52 + x49 + x48 + x47 + x46+ x44 + - x41 + x37 + x36 + x34 + x32 + x31 + x28 + x26 + x23 + x22 + x19 + x16 + x13 + - x12 + x10 + x9 + x6 + x4 + x3 + 1 (see http://www.cs.ud.ac.uk/staff/D.Jones/crcbote.pdf) - grenerator = 0xAD93D23594C9362D, il = 64, ucl = 0xFFFFFFFFFFFFFFFF - - CRC-64 DLT1 spec x64 + x62 + x57 + x55 + x54 + x53 + x52 + x47 + x46 + x45 + x40 + x39 + x38 + x37 + - x35 + x33 + x32 + x31 + x29 + x27 + x24 + x23 + x22 + x21 + x19 + x17 + x13 + x12 + - x10 + x9 + x7 + x4 + x + 1 - (see http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-182.pdf -> page63) - generator = 0x42F0E1EBA9EA3693 - - CRC-64 from internet G(x)= 1006003C000F0D50B -*/ - -/*--------------------------------------------------------------------- */ -int createCRCParameter(uint64_t *ui64RegisterMask, unsigned int *uiRegisterLength) + +/** + * create CRC Parameter: CRC Polynome, Shiftregister Mask and length + * + * ui64Generator[0] = 0; + * ui64Generator[1] = 0x42F0E1EB; + * ui64Generator[1] = (ui64Generator[1] << 32) + 0xA9EA3693; + * iRegisterLength = 63; + * ui64RegisterMask = 0xffffffff; + * ui64RegisterMask = ((ui64RegisterMask) << 32) + 0xffffffff; + * + * ucl=0x00000000ffffffff = Mask for 32 bit LSFR to cut down number of bits + * in the variable to get the same length as LFSR + * + * il = length of LSFR = degree of generator polynom reduce il by one to calculate the degree + * of the highest register in LSFR + * + * Examples: + * CRC-16 for Tap: x16 + x15 + x2 + 1 + * generator = 0x8005, il = 16, ucl = 0x000000000000FFFF + * + * CRC-16 for Floppy: x16 + x12 + x5 +1 + * generator = 0x1021, il = 16, ucl = 0x000000000000FFFF + * + * CRC-32 for Ethernet: x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 + * generator = 0x04C11DB7, il = 32, ucl = 0x00000000FFFFFFFF + * + * CRC-64 SP-TrEMBL x64 + x4 + x3 + x + 1 (maximal-length LFSR) + * generator = 0x1B, il = 64, ucl = 0xFFFFFFFFFFFFFFFF + * + * CRC-64 improved + * x64 + x63 + x61 + x59 + x58 + x56 + x55 + x52 + x49 + x48 + x47 + x46+ x44 + + * x41 + x37 + x36 + x34 + x32 + x31 + x28 + x26 + x23 + x22 + x19 + x16 + x13 + + * x12 + x10 + x9 + x6 + x4 + x3 + 1 + * (see http://www.cs.ud.ac.uk/staff/D.Jones/crcbote.pdf) + * generator = 0xAD93D23594C9362D, il = 64, ucl = 0xFFFFFFFFFFFFFFFF + * + * CRC-64 DLT1 spec + * x64 + x62 + x57 + x55 + x54 + x53 + x52 + x47 + x46 + x45 + x40 + x39 + x38 + x37 + + * x35 + x33 + x32 + x31 + x29 + x27 + x24 + x23 + x22 + x21 + x19 + x17 + x13 + x12 + + * x10 + x9 + x7 + x4 + x + 1 + * (see http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-182.pdf -> page63) + * generator = 0x42F0E1EBA9EA3693 + * + * CRC-64 from internet G(x)= 1006003C000F0D50B + */ +int +createCRCParameter(uint64_t * ui64RegisterMask, unsigned int *uiRegisterLength) { - enum Generators {Tape_16, Floppy_16, Ethernet_32, SPTrEMBL_64, SPTrEMBL_improved_64,DLT1_64}; + enum Generators { Tape_16, Floppy_16, Ethernet_32, SPTrEMBL_64, + SPTrEMBL_improved_64, DLT1_64 + }; enum Generators Generator; Generator = CRC_METHODE; - switch (Generator){ - case Tape_16:{ - *ui64RegisterMask = 0x0000ffff; - ui64Generator1 = 0x00008005; - *uiRegisterLength = 16; + switch (Generator) { + case Tape_16:{ + *ui64RegisterMask = 0x0000ffff; + ui64Generator1 = 0x00008005; + *uiRegisterLength = 16; break; } - case Floppy_16: { - *ui64RegisterMask = 0x0000ffff; - ui64Generator1 = 0x00001021; - *uiRegisterLength = 16; + case Floppy_16:{ + *ui64RegisterMask = 0x0000ffff; + ui64Generator1 = 0x00001021; + *uiRegisterLength = 16; break; } - case Ethernet_32: { - *ui64RegisterMask = 0xffffffff; - ui64Generator1 = 0x04C11DB7; - *uiRegisterLength = 32; + case Ethernet_32:{ + *ui64RegisterMask = 0xffffffff; + ui64Generator1 = 0x04C11DB7; + *uiRegisterLength = 32; break; } - case SPTrEMBL_64: { - *ui64RegisterMask = 0xffffffff; - *ui64RegisterMask = ((*ui64RegisterMask) << 32) + 0xffffffff; - ui64Generator1 = 0x0000001B; - *uiRegisterLength = 64; + case SPTrEMBL_64:{ + *ui64RegisterMask = 0xffffffff; + *ui64RegisterMask = + ((*ui64RegisterMask) << 32) + 0xffffffff; + ui64Generator1 = 0x0000001B; + *uiRegisterLength = 64; break; } - case SPTrEMBL_improved_64: { - *ui64RegisterMask = 0xffffffff; - *ui64RegisterMask = ((*ui64RegisterMask) << 32) + 0xffffffff; - ui64Generator1 = 0xAD93D235; - ui64Generator1 = (ui64Generator1 << 32) + 0x94C9362D; - *uiRegisterLength = 64; + case SPTrEMBL_improved_64:{ + *ui64RegisterMask = 0xffffffff; + *ui64RegisterMask = + ((*ui64RegisterMask) << 32) + 0xffffffff; + ui64Generator1 = 0xAD93D235; + ui64Generator1 = (ui64Generator1 << 32) + 0x94C9362D; + *uiRegisterLength = 64; break; } - case DLT1_64:{ - *ui64RegisterMask = 0xffffffff; - *ui64RegisterMask = ((*ui64RegisterMask) << 32) + 0xffffffff; - ui64Generator1 = 0x42F0E1EB; - ui64Generator1 = (ui64Generator1 << 32) + 0xA9EA3693; - *uiRegisterLength = 64; - break; + case DLT1_64:{ + *ui64RegisterMask = 0xffffffff; + *ui64RegisterMask = + ((*ui64RegisterMask) << 32) + 0xffffffff; + ui64Generator1 = 0x42F0E1EB; + ui64Generator1 = (ui64Generator1 << 32) + 0xA9EA3693; + *uiRegisterLength = 64; + break; } } - (*uiRegisterLength)--; + (*uiRegisterLength)--; return 0; } -/*------------------------------------------------ create CRC Parameter */ -/* */ -/* Check CRC by using Linear Feadback Shift Register (LFSR) */ -/*----------------------------------------------------------------------*/ -uint64_t calCRCbyte(unsigned char *cPtr, uint32_t ui32NoWords, uint64_t AccumCRC) { - uint64_t ui64Mask, ui64Generator0; +/** + * Check CRC by using Linear Feadback Shift Register (LFSR) + */ +uint64_t +calCRCbyte(unsigned char *cPtr, uint32_t ui32NoWords, uint64_t AccumCRC) +{ + + uint64_t ui64Mask, ui64Generator0; uint8_t ui8Buffer; unsigned int uiRegisterLength; - int iShift; + int iShift; - createCRCParameter(&ui64Mask, &uiRegisterLength); + createCRCParameter(&ui64Mask, &uiRegisterLength); ui8Buffer = (*cPtr); - while ( ui32NoWords > 0) { - for (iShift = 7;iShift >= 0; iShift--) { - - ui64Generator0 = (AccumCRC >> uiRegisterLength); - AccumCRC <<= 1; - ui64Generator0 &= 0x01; - ui64Generator0 = (0-ui64Generator0); - AccumCRC ^= (ui64Generator1 & ui64Generator0); - } - AccumCRC ^= ui8Buffer; - AccumCRC &= ui64Mask; - ui32NoWords -= 1; - cPtr += 1; + while (ui32NoWords > 0) { + for (iShift = 7; iShift >= 0; iShift--) { + + ui64Generator0 = (AccumCRC >> uiRegisterLength); + AccumCRC <<= 1; + ui64Generator0 &= 0x01; + ui64Generator0 = (0 - ui64Generator0); + AccumCRC ^= (ui64Generator1 & ui64Generator0); + } + AccumCRC ^= ui8Buffer; + AccumCRC &= ui64Mask; + ui32NoWords -= 1; + cPtr += 1; ui8Buffer = (*cPtr); - } - return AccumCRC; + } + return AccumCRC; } -/*--------------------------------------------------------------checkCRC */ -/* */ -/* Check CRC by using Linear Feadback Shift Register (LFSR) */ -/*----------------------------------------------------------------------*/ -uint64_t calCRCword(unsigned char *cPtr, uint32_t ui32NoWords, uint64_t AccumCRC) { - uint64_t ui64Mask, ui64Generator0; +/** + * Check CRC by using Linear Feadback Shift Register (LFSR) + */ +uint64_t +calCRCword(unsigned char *cPtr, uint32_t ui32NoWords, uint64_t AccumCRC) +{ + + uint64_t ui64Mask, ui64Generator0; uint16_t ui16Buffer; unsigned int uiRegisterLength; - int iShift; + int iShift; - createCRCParameter(&ui64Mask, &uiRegisterLength); + createCRCParameter(&ui64Mask, &uiRegisterLength); - if( (ui32NoWords%2) != 0) { // if Data string does not end at word boundery add one byte - ui32NoWords++; + if ((ui32NoWords % 2) != 0) { + /* if Data string does not end at word boundery add one byte */ + ui32NoWords++; cPtr[ui32NoWords] = 0; } - ui16Buffer = ( (*(cPtr+0)) * 256) + (*(cPtr+1)); - while ( ui32NoWords > 0) { - for (iShift = 15;iShift >= 0; iShift--) { - ui64Generator0 = (AccumCRC >> uiRegisterLength); - AccumCRC <<= 1; - ui64Generator0 &= 0x01; - ui64Generator0 = (0-ui64Generator0); - AccumCRC ^= (ui64Generator1 & ui64Generator0); - } - AccumCRC ^= ui16Buffer; - AccumCRC &= ui64Mask; - ui32NoWords -= 2; - cPtr += 2; - ui16Buffer = ( (*(cPtr+0)) * 256) + (*(cPtr+1)); - } - return AccumCRC; + ui16Buffer = ((*(cPtr + 0)) * 256) + (*(cPtr + 1)); + while (ui32NoWords > 0) { + for (iShift = 15; iShift >= 0; iShift--) { + ui64Generator0 = (AccumCRC >> uiRegisterLength); + AccumCRC <<= 1; + ui64Generator0 &= 0x01; + ui64Generator0 = (0 - ui64Generator0); + AccumCRC ^= (ui64Generator1 & ui64Generator0); + } + AccumCRC ^= ui16Buffer; + AccumCRC &= ui64Mask; + ui32NoWords -= 2; + cPtr += 2; + ui16Buffer = ((*(cPtr + 0)) * 256) + (*(cPtr + 1)); + } + return AccumCRC; } -/*------------------------------------------------------------- checkCRCnew */ -/* */ -/* */ -/*------------------------------------------------------------------------- */ -uint64_t checkCRC(unsigned char *cPtr, uint32_t ui32NoWords, uint64_t AccumCRC) { - enum Generators {Ethernet_32}; +uint64_t +checkCRC(unsigned char *cPtr, uint32_t ui32NoWords, uint64_t AccumCRC) +{ + + enum Generators { Ethernet_32 }; enum Generators Generator; uint64_t ui64Buffer = AccumCRC; Generator = CRC_METHODE; switch (Generator) { - case Ethernet_32: { - // (ui32NoWords - 4),no need of 4 bytes 0x as with shift-register method - AccumCRC = calCRCEthernet32( cPtr, (ui32NoWords-4), AccumCRC ); - break; + case Ethernet_32:{ + /* (ui32NoWords - 4),no need of 4 bytes 0x as + * with shift-register method */ + AccumCRC = + calCRCEthernet32(cPtr, (ui32NoWords - 4), AccumCRC); + break; } - default :{ - AccumCRC = calCRCword( cPtr, ui32NoWords, AccumCRC); + default:{ + AccumCRC = calCRCword(cPtr, ui32NoWords, AccumCRC); break; } } - - if( calCRCbyte(cPtr, ui32NoWords, ui64Buffer) != AccumCRC) { + + if (calCRCbyte(cPtr, ui32NoWords, ui64Buffer) != AccumCRC) { printf("\n --- big Endian - small Endian problem --- \n"); AccumCRC--; } - - return( AccumCRC); -} - - -/*--------------------------------------------------------------------- CRC */ -/* */ -/* Insert 64 bit as Big Endian */ -/* into DataStream starting at (uli)Position */ -/*------------------------------------------------------------------------- */ -int insert64bit(uint64_t ui64CRC, uint32_t ui32Position) -{ - - pucFileStream[ui32Position] = (char) ((ui64CRC >> 56) & 0x00FF); - pucFileStream[ui32Position+1] = (char) ((ui64CRC >> 48) & 0x00FF); - pucFileStream[ui32Position+2] = (char) ((ui64CRC >> 40) & 0x00FF); - pucFileStream[ui32Position+3] = (char) ((ui64CRC >> 32) & 0x00FF); - pucFileStream[ui32Position+4] = (char) ((ui64CRC >> 24) & 0x00FF); - pucFileStream[ui32Position+5] = (char) ((ui64CRC >> 16) & 0x00FF); - pucFileStream[ui32Position+6] = (char) ((ui64CRC >> 8) & 0x00FF); - pucFileStream[ui32Position+7] = (char) (ui64CRC & 0x00FF); - - return 0; + return (AccumCRC); } -/*----------------------------------------------------------- insertCRC */ -/* */ -/* insert header and file CRC into data stream */ -/* do CRC check on header and file */ -/* write data stream to disk */ -/*----------------------------------------------------------------------*/ -int writeDataStream(int iofd) + +/** + * insert header and file CRC into data stream + * do CRC check on header and file + * write data stream to disk + */ +int +writeDataStream(int iofd, int notime) { - uint64_t ui64FileCRC=0, ui64HeaderCRC=0, ui64RegisterMask; + uint64_t ui64FileCRC = 0, ui64HeaderCRC = 0, ui64RegisterMask; unsigned int uiRegisterLength; - if(0 != createHeaderImage()) { + if (0 != createHeaderImage(notime)) { return 1; } - createCRCParameter( &ui64RegisterMask, &uiRegisterLength); + createCRCParameter(&ui64RegisterMask, &uiRegisterLength); -/* calculate CRC---------------------------------------------------- */ + /* calculate CRC */ ui64HeaderCRC = checkCRC(pucFileStream, ui64globalHeaderSize, 0); - insert64bit(ui64HeaderCRC, (ui64globalHeaderSize-8) ); + *(uint64_t *) (pucFileStream + ui64globalHeaderSize - 8) = + cpu_to_be64(ui64HeaderCRC); ui64FileCRC = checkCRC(pucFileStream, ui64globalFileSize, 0); - insert64bit(ui64FileCRC, (ui64globalFileSize -8) ); - -/* report CRCs and proof if CRCs are correct implemented */ - //printf("\n"); - //printf("%s%X%X\n","Generator = 0x1",(uint32_t)(ui64Generator1>>32),(uint32_t)ui64Generator1); - - //printf("%s%x%s%u%-9s%s%X%X\n","header size = 0x", (uint32_t)ui64globalHeaderSize, "/", (uint32_t)ui64globalHeaderSize," bytes","file CRC = 0x",(uint32_t)(ui64HeaderCRC >> 32),(uint32_t)ui64HeaderCRC); - - //printf("Firmware Header CRC = 0x%08x\n", (uint32_t)ui64HeaderCRC); - //printf("Flash Image CRC = 0x%08x\n", (uint32_t)ui64FileCRC); + *(uint64_t *) (pucFileStream + ui64globalFileSize - 8) = + cpu_to_be64(ui64FileCRC); - //printf("%s%x%s%u%-9s%s%X%X\n","flash size = 0x", (uint32_t)ui64globalFileSize, "/", (uint32_t)ui64globalFileSize," bytes","file CRC = 0x",(uint32_t)(ui64FileCRC >> 32),(uint32_t)ui64FileCRC); + /* check CRC-implementation */ + ui64HeaderCRC = calCRCword(pucFileStream, ui64globalHeaderSize, 0); + ui64FileCRC = calCRCword(pucFileStream, ui64globalFileSize, 0); -/* check CRC-implementation */ - ui64HeaderCRC = calCRCword( pucFileStream, ui64globalHeaderSize, 0); - ui64FileCRC = calCRCword( pucFileStream, ui64globalFileSize, 0); - - //printf("%s%X%X\n","header CRC check = 0x", (uint32_t)(ui64HeaderCRC >> 32),(uint32_t)ui64HeaderCRC); - //printf("%s%X%X\n","flash CRC check = 0x", (uint32_t)(ui64FileCRC >> 32),(uint32_t)ui64FileCRC); - - if( (ui64HeaderCRC == 0) && (ui64FileCRC == 0) ) { - //printf("\n%s\n","CRCs correct implemented. ---> Data will be written to disk."); - /* write file image to disk */ - if (0 < write(iofd, pucFileStream, ui64globalFileSize)) { - return 0; - } - else { - printf("<< write failed >>\n"); - return -1; - } - - } - else { - printf("\n\n %s \n %s \n\n","CRCs not correct implemented."," ---> Data will not be written do disk."); + if ((ui64HeaderCRC != 0) || (ui64FileCRC != 0)) { + printf("\n\n %s \n %s \n\n", "CRCs not correct implemented.", + " ---> Data will not be written do disk."); return -1; } -} -/*----------------------------------------------------- writeDataStream */ + /* write file image to disk */ + if (0 < write(iofd, pucFileStream, ui64globalFileSize)) + return 0; + printf("<< write failed >>\n"); + return -1; +} diff --git a/romfs/tools/create_flash.c b/romfs/tools/create_flash.c index 1c968bd..f99fd62 100644 --- a/romfs/tools/create_flash.c +++ b/romfs/tools/create_flash.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -16,72 +16,148 @@ #include <fcntl.h> #include <string.h> #include <unistd.h> +#include <getopt.h> #include <cfgparse.h> -#undef DEBUGGING +int verbose = 0; -#ifdef DEBUGGING -#define dprintf(_x...) printf(_x) -#else -#define dprintf(_x...) -#endif +#define dprintf(fmt, args...) if (verbose) printf(fmt, ##args) -void print_usage() +static void +print_usage(void) { - printf("args: description_file output_file\n\n"); + printf + ("Usage: build_romfs [-?] [--help] [-s|--romfs-size <romfs_size>]\n" + "\t[-p|--smart-pad] [-n|--notime] <config-file> <output-file>\n"); } -int main (int argc, char *argv[]) +unsigned long +str_to_num(const char *str) +{ + char *s = (char *) str; + unsigned long num = strtoul(s, &s, 0); + if (s) { + if (s[0] == 'K') + num <<= 10; + if (s[0] == 'M') + num <<= 20; + } + return num; +} + +/* + * NOTE: We should consider to install an exit handler which does the + * unlink() of the output file. In case of error we just do exit() and + * forget about all the clumsy error handling free/close code, which + * blows up the code significantly and makes it hard to read. + */ +int +main(int argc, char *argv[]) { int conf_file, rc; struct ffs_chain_t ffs_chain; + int c; + int smart_pad = 0; /* default */ + int notime = 0; + const char *config_file = "boot_rom.ffs"; + const char *output_file = "boot_rom.bin"; - if (argc != 3) { + memset((void *) &ffs_chain, 0, sizeof(struct ffs_chain_t)); + + while (1) { + int option_index = 0; + static struct option long_options[] = { + {"romfs-size", 1, 0, 's'}, + {"smart-pad", 0, 0, 'p'}, + {"notime", 0, 0, 'n'}, + {"verbose", 0, 0, 'v'}, + {"help", 1, 0, 'h'}, + {0, 0, 0, 0} + }; + c = getopt_long(argc, argv, "s:ph?nv", long_options, + &option_index); + if (c == -1) + break; + + switch (c) { + case 's': + ffs_chain.romfs_size = str_to_num(optarg); + break; + case 'p': + smart_pad = 1; + break; + case 'n': + notime = 1; + break; + case 'v': + verbose = 1; + break; + case '?': + case 'h': + print_usage(); + return EXIT_SUCCESS; + default: + printf("?? getopt returned character code 0%o ??\n", c); + } + } + + /* two files must always be specified: config-file and output-file */ + if (optind + 2 != argc) { print_usage(); return EXIT_FAILURE; } - dprintf("ROMFS FILESYSTEM CREATION V0.1 (bad parser)\n"); - dprintf("Build directory structure...\n"); + config_file = argv[optind++]; + output_file = argv[optind++]; + + dprintf("ROMFS FILESYSTEM CREATION V0.3 (bad parser)\n" + "Build directory structure...\n" + " smart padding %s, maximum romfs size %d bytes\n", + smart_pad ? "enabled" : "disabled", ffs_chain.romfs_size); - memset((void*) &ffs_chain, 0, sizeof(struct ffs_chain_t)); - conf_file = open(argv[1], O_RDONLY); + conf_file = open(config_file, O_RDONLY); if (0 >= conf_file) { perror("load config file:"); return EXIT_FAILURE; } - while (0 == (rc = find_next_entry(conf_file, &ffs_chain))); + rc = read_config(conf_file, &ffs_chain); + close(conf_file); + if (rc < 1) { + fprintf(stderr, "flash cannot be built due to config errors\n"); + return EXIT_FAILURE; + } + + rc = EXIT_SUCCESS; - if (1 >= rc) { -#ifdef DEBUGGING + if (verbose) dump_fs_contents(&ffs_chain); -#endif - dprintf("Build ffs and write to image file...\n"); - if (build_ffs(&ffs_chain, argv[2]) != 0) { - fprintf(stderr, "build ffs failed\n"); - rc = EXIT_FAILURE; - } else { - rc = EXIT_SUCCESS; - } - } else { - fprintf(stderr, "flash cannot be built due to config errors\n"); + if (smart_pad) + /* FIXME: size is only verified during reorder */ + rc = reorder_ffs_chain(&ffs_chain); + + if (rc == EXIT_FAILURE) + goto out; + + dprintf("Build ffs and write to image file...\n"); + if (build_ffs(&ffs_chain, output_file, notime) != 0) { + fprintf(stderr, "build ffs failed\n"); rc = EXIT_FAILURE; + } else { + rc = EXIT_SUCCESS; } - /* Check if there are any duplicate entries in the image: */ + /* Check if there are any duplicate entries in the image, + print warning if this is the case. */ find_duplicates(&ffs_chain); - free_chain_memory(&ffs_chain); - close(conf_file); dprintf("\n"); + out: /* If the build failed, remove the target image file */ - if (rc == EXIT_FAILURE) { - unlink(argv[2]); - } + if (rc == EXIT_FAILURE) + unlink(output_file); return rc; } - diff --git a/romfs/tools/createcrc.h b/romfs/tools/createcrc.h index 10490ad..1f23598 100644 --- a/romfs/tools/createcrc.h +++ b/romfs/tools/createcrc.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -14,5 +14,6 @@ int buildDataStream(unsigned char *pucbuf, int size); int createHeaderImgage(char *pcFilename); -void writeDataStream(int ofd); +int writeDataStream(int ofd, int notime); + #endif diff --git a/rtas/Makefile.inc b/rtas/Makefile.inc index b7799c5..4297f86 100644 --- a/rtas/Makefile.inc +++ b/rtas/Makefile.inc @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License diff --git a/rtas/flash/block_lists.c b/rtas/flash/block_lists.c index 52f4ee5..4c08e3f 100644 --- a/rtas/flash/block_lists.c +++ b/rtas/flash/block_lists.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/rtas/flash/block_lists.h b/rtas/flash/block_lists.h index cad4668..80044c3 100644 --- a/rtas/flash/block_lists.h +++ b/rtas/flash/block_lists.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -13,11 +13,11 @@ extern int progress; extern unsigned char sig_org[]; -void print_progress(); -void print_hash(); +void print_progress(void); +void print_hash(void); int get_block_list_version(unsigned char *); int image_check_crc(unsigned long *, int); long get_size(unsigned long *, int); -void print_writing(); +void print_writing(void); void write_block_list(unsigned long *, int); int check_platform(unsigned long *, unsigned int, int); diff --git a/rtas/reloc.S b/rtas/reloc.S index eb54e44..e24d293 100644 --- a/rtas/reloc.S +++ b/rtas/reloc.S @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/rtas/rtas.lds b/rtas/rtas.lds index 854485b..a5ba1da 100644 --- a/rtas/rtas.lds +++ b/rtas/rtas.lds @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/rtas/rtas_call.c b/rtas/rtas_call.c index a75ab96..bf1cf89 100644 --- a/rtas/rtas_call.c +++ b/rtas/rtas_call.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/rtas/rtas_common.S b/rtas/rtas_common.S index 010c413..35cd9a9 100644 --- a/rtas/rtas_common.S +++ b/rtas/rtas_common.S @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/rtas/rtas_entry.S b/rtas/rtas_entry.S index 35421d8..74693aa 100644 --- a/rtas/rtas_entry.S +++ b/rtas/rtas_entry.S @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/slof/Makefile.inc b/slof/Makefile.inc index 2bc6dad..a8b3a37 100644 --- a/slof/Makefile.inc +++ b/slof/Makefile.inc @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -69,7 +69,7 @@ OF.o: OF.fsi dict.xt: $(DICT) $(SLOFCMNDIR)/ref.pl - cat $(DICT) | perl $(SLOFCMNDIR)/ref.pl > dict.xt + cat $(DICT) | perl $(SLOFCMNDIR)/ref.pl -s $(CELLSIZE) > dict.xt ifdef BOARD_SLOF_CODE board.code: $(BOARD_SLOF_CODE) diff --git a/slof/OF.lds b/slof/OF.lds index 61ddd1c..3e4a8f6 100644 --- a/slof/OF.lds +++ b/slof/OF.lds @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -17,20 +17,17 @@ ENTRY(_start_OF) SECTIONS { - . = 0xE100000; - _slof_start = .; - . = 0x0E10C000; + . = 0x0E100100; _start_OF = .; .slof.loader : { *(.slof.loader) } - . = 0x0E110000; /* + SIZEOF_HEADERS; */ + . = ALIGN(0x100); _slof_text = .; -/* .rela : { *(.rela.*) } */ .text : { *(.entry_text) *(.text) } = 0x60000000 _slof_text_end = .; . = ALIGN(8); _slof_text_size = (_slof_text_end - _slof_text); - . = ALIGN(0x1000); + . = ALIGN(0x100); .opd : { _slof_data = .; @@ -58,5 +55,5 @@ SECTIONS _slof_bss_size = (_slof_bss_end - _slof_bss); . = ALIGN(0x1000); - _slof_here_start = .; + the_mem = .; } diff --git a/slof/default-font.c b/slof/default-font.c index f3cfcd2..328f1b4 100644 --- a/slof/default-font.c +++ b/slof/default-font.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/slof/engine.in b/slof/engine.in index 2799c1e..af42eb6 100644 --- a/slof/engine.in +++ b/slof/engine.in @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -388,14 +388,16 @@ col(SKIPWS IB SPAN @ DUP >IN @ > 0BRANCH(14) OVER >IN @ + C@ BL <= 0BRANCH(5) 1 col(PARSE-WORD SKIPWS BL PARSE) var(WHICHPOCKET 0) // We reserved 0x1000 for the pockets. So we have 16 pockets a 0x100 -col(POCKET POCKETS WHICHPOCKET @ LIT(POCKETSIZE) * + WHICHPOCKET @ 1 + DUP LIT(16) = 0BRANCH(2) DROP 0 WHICHPOCKET !) +col(POCKET POCKETS WHICHPOCKET @ LIT(POCKETSIZE) * + WHICHPOCKET @ 1 + DUP LIT(NUMPOCKETS) = 0BRANCH(2) DROP 0 WHICHPOCKET !) col(WORD POCKET >R PARSE DUP R@ C! BOUNDS R> DUP 2SWAP DO?DO(7) CHAR+ I C@ OVER C! DOLOOP(-7) DROP) // Some simple parsing words. col(CHAR PARSE-WORD DROP C@) imm(( LIT(')') PARSE 2DROP) -imm(\ LINEFEED PARSE 2DROP) +// Removing comments out of the code, the code from the backslash to the next \n is removed. +// We need to start from cursor -1 (the backslash) to handle the case backslash+linefeed correctly 0x5c0a +imm(\ >IN @ 1- >IN ! LINEFEED PARSE 2DROP) // The compiler infrastructure. var(STATE 0) @@ -411,6 +413,7 @@ imm(; ?COMP DOTICK SEMICOLON COMPILE, REVEAL [) // Compiling strings. imm(C" ?COMP LIT('"') PARSE DOTICK SLITERAL COMPILE, DUP C, BOUNDS DO?DO(5) I C@ C, DOLOOP(-5) ALIGN) imm(S" STATE @ 0BRANCH(5) C" DOTICK COUNT COMPILE, EXIT LIT('"') PARSE DUP >R POCKET DUP >R SWAP MOVE R> R>) +imm(Z" S" 2DUP + 0 SWAP C! DROP) imm(." STATE @ 0BRANCH(5) S" DOTICK TYPE COMPILE, EXIT LIT('"') PARSE TYPE) imm(.( LIT(')') PARSE TYPE) diff --git a/slof/entry.S b/slof/entry.S index f57ddab..ce9dd83 100644 --- a/slof/entry.S +++ b/slof/entry.S @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -9,8 +9,11 @@ * Contributors: * IBM Corporation - initial implementation *****************************************************************************/ + #include <macros.h> - + +#define STACKSIZE 0x1000 + # # The generic exception code. # @@ -20,12 +23,17 @@ .section ".entry_text" the_handler: - .quad handler + .quad handler eregs: - .quad _slof_start # XXX make configurable at startup time - # should stay page aligned! - + /* the_exception_frame is a C variable which is usually + * defined in $(TARG).c + * the_exception_frame can be accessed from paflof through + * the word eregs + * in the case an excpetion is handled paflof will read + * from eregs the values of all registers and print them + * out in the exception handler */ + .quad the_exception_frame handler: mtsprg 1,1 # SPRG1 = saved GPR1 @@ -38,24 +46,20 @@ handler: std \i,\i*8(1) .endr # save GPR2..GPR31 - mr 3,0 // GPR3 = vector + li r3, 3 // GPR3 = mode (param_1, param_2) + mr 4,0 // GPR4 = vector mfsprg 0,0 std 0,0(1) # save GPR0 mfsprg 0,1 std 0,8(1) # save GPR1 - cmpwi r3, 0x900 # Decrementer interrupt + cmpwi r4, 0x900 # Decrementer interrupt bne 0f - mfdec r4 # Save old value of decrementer as reason + mfdec r5 # Save old value of decrementer as reason lis r0,0x7fff # Set decrementer to highest value mtdec r0 -0: - cmpwi r3, 0x500 # External interrupt - bne 0f - LOAD64(r4, 0x20000508408) - ld r4, 0(r4) # Read destructive interrupt reason -0: +0: mfcr 0 std 0,0x100(1) mfxer 0 @@ -73,10 +77,18 @@ handler: mfdsisr 0 std 0,0x138(1) # save special regs - addi 1,1,0x7000 - li 0,0 - stdu 0,-0x10(1) - stdu 1,-0x100(1) # set up stack + bcl 20, 31, over +base: + .align 3 +.the_system_stack: + .quad the_system_stack+STACKSIZE-base +over: + mflr r2 /* gpr 2 is the base */ + ld r1, .the_system_stack-base(r2) /* load stack pointer */ + add r1, r1, r2 /* add base */ + li r0, 0 + stdu r0, -0x10(r1) + stdu r1, -0x100(r1) lis 2,engine@ha ld 0,engine@l(2) # set up entry @@ -94,8 +106,20 @@ handler: # swap_ci_regs: - lis 8,_slof_start@ha - addi 8,8,0x0400 + /* save lr */ + mflr r0 + /* let's find out where our client stack is */ + bcl 20, 31, client_over +client_base: + .align 3 +.the_client_frame: + .quad the_client_frame-client_base +client_over: + mflr r8 /* gpr 2 is the client_base */ + mtlr r0 /* restore the original lr */ + ld r0, .the_client_frame-client_base(r8) + add r8, r0, r8 /* add the client_base */ + /* r8 now contains the address of the_client_frame */ .irp i, 1,2,3,4,5,6,7, \ 13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 @@ -159,3 +183,5 @@ call_client: mtlr 4 li 3, -1 # client app return blr + + .lcomm the_system_stack, STACKSIZE, 16 diff --git a/slof/fs/accept.fs b/slof/fs/accept.fs index b700f4a..7e8e271 100644 --- a/slof/fs/accept.fs +++ b/slof/fs/accept.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -26,32 +26,49 @@ : esc 1b emit ; : csi esc 5b emit ; -: move-cursor - esc ." 8" accept-cur IF - csi base @ decimal accept-cur 0 .r base ! ." C" THEN ; -: redraw-line - accept-cur accept-len = IF EXIT THEN - move-cursor - accept-adr accept-len accept-cur /string type csi ." K" move-cursor ; -: full-redraw-line - accept-cur 0 to accept-cur move-cursor - accept-adr accept-len type csi ." K" to accept-cur move-cursor ; -: redraw-prompt - cr depth . [char] > emit ; +: move-cursor ( -- ) + esc ." 8" accept-cur IF + csi base @ decimal accept-cur 0 .r base ! ." C" + THEN +; + +: redraw-line ( -- ) + accept-cur accept-len = IF EXIT THEN + move-cursor + accept-adr accept-len accept-cur /string type + csi ." K" move-cursor +; + +: full-redraw-line ( -- ) + accept-cur 0 to accept-cur move-cursor + accept-adr accept-len type + csi ." K" to accept-cur move-cursor +; + +: redraw-prompt ( -- ) + cr depth . [char] > emit +; : insert-char ( char -- ) - accept-len accept-max = IF drop beep EXIT THEN - accept-cur accept-len <> IF csi ." @" dup emit - accept-adr accept-cur + dup 1+ accept-len accept-cur - move - ELSE dup emit THEN - accept-adr accept-cur + c! - accept-cur 1+ to accept-cur - accept-len 1+ to accept-len redraw-line ; + accept-len accept-max = IF drop beep EXIT THEN + accept-cur accept-len <> IF csi ." @" dup emit + accept-adr accept-cur + dup 1+ accept-len accept-cur - move + ELSE dup emit THEN + accept-adr accept-cur + c! + accept-cur 1+ to accept-cur + accept-len 1+ to accept-len redraw-line +; + : delete-char ( -- ) - accept-cur accept-len = IF beep EXIT THEN - accept-len 1- to accept-len - accept-adr accept-cur + dup 1+ swap accept-len accept-cur - move - csi ." P" redraw-line ; + accept-cur accept-len = IF beep EXIT THEN + accept-len 1- to accept-len + accept-adr accept-cur + dup 1+ swap accept-len accept-cur - move + csi ." P" redraw-line +; + +\ * +\ * History handling +\ * STRUCT cell FIELD his>next @@ -62,21 +79,33 @@ CONSTANT /his 0 VALUE his-head 0 VALUE his-tail 0 VALUE his-cur -: add-history - /his accept-len + alloc-mem - his-tail IF dup his-tail his>next ! ELSE dup to his-head THEN - his-tail over his>prev ! 0 over his>next ! dup to his-tail - accept-len over his>len ! accept-adr swap his>buf accept-len move ; -: history - his-head BEGIN dup WHILE - cr dup his>buf over his>len @ type - his>next @ REPEAT drop ; + +: add-history ( -- ) + accept-len 0= IF EXIT THEN + /his accept-len + alloc-mem + his-tail IF dup his-tail his>next ! ELSE dup to his-head THEN + his-tail over his>prev ! 0 over his>next ! dup to his-tail + accept-len over his>len ! accept-adr swap his>buf accept-len move +; + +: history ( -- ) + his-head BEGIN dup WHILE + cr dup his>buf over his>len @ type + his>next @ REPEAT drop +; + : select-history ( his -- ) - dup to his-cur dup IF - dup his>len @ accept-max min dup to accept-len to accept-cur - his>buf accept-adr accept-len move ELSE - drop 0 to accept-len 0 to accept-cur THEN - full-redraw-line ; + dup to his-cur dup IF + dup his>len @ accept-max min dup to accept-len to accept-cur + his>buf accept-adr accept-len move ELSE + drop 0 to accept-len 0 to accept-cur THEN + full-redraw-line +; + + +\ +\ tab completion +\ \ tab completion state variables 0 value ?tab-pressed @@ -85,35 +114,35 @@ CONSTANT /his \ compares two strings and returns the longest equal substring. : $same-string ( addr-1 len-1 addr-2 len-2 -- addr-1 len-1' ) - dup 0= IF \ The second parameter is not a string. - 2drop EXIT \ bail out - THEN - rot min 0 0 -rot ( addr1 addr2 0 len' 0 ) - do ( addr1 addr2 len-1' ) - 2 pick i + c@ lcc - 2 pick i + c@ lcc - = IF 1 + ELSE leave THEN - loop - nip - ; + dup 0= IF \ The second parameter is not a string. + 2drop EXIT \ bail out + THEN + rot min 0 0 -rot ( addr1 addr2 0 len' 0 ) + DO ( addr1 addr2 len-1' ) + 2 pick i + c@ lcc + 2 pick i + c@ lcc + = IF 1 + ELSE leave THEN + LOOP + nip +; : $tab-sift-words ( text-addr text-len -- sift-count ) - sift-compl-only >r true to sift-compl-only \ save sifting mode - - last begin @ ?dup while \ loop over all words - $inner-sift IF \ any completions possible? - \ convert to lower case for user interface sanity - 2dup bounds do i c@ lcc i c! loop - ?tab-pressed IF 2dup type space THEN \ <tab><tab> prints possibilities - tab-last-adr tab-last-len $same-string \ find matching substring ... - to tab-last-len to tab-last-adr \ ... and save it - THEN - repeat - 2drop - - #sift-count 0 to #sift-count \ how many words were found? - r> to sift-compl-only \ restore sifting completion mode - ; + sift-compl-only >r true to sift-compl-only \ save sifting mode + + last BEGIN @ ?dup WHILE \ loop over all words + $inner-sift IF \ any completions possible? + \ convert to lower case for user interface sanity + 2dup bounds DO I c@ lcc I c! LOOP + ?tab-pressed IF 2dup type space THEN \ <tab><tab> prints possibilities + tab-last-adr tab-last-len $same-string \ find matching substring ... + to tab-last-len to tab-last-adr \ ... and save it + THEN + repeat + 2drop + + #sift-count 0 to #sift-count \ how many words were found? + r> to sift-compl-only \ restore sifting completion mode +; \ 8< node sifting for tab completion on device tree nodes below this line 8< @@ -127,7 +156,7 @@ CONSTANT /his dup child IF dup push child -rot EXIT THEN dup peer IF peer -rot EXIT THEN drop - BEGIN + BEGIN stack-depth WHILE pop peer ?dup IF -rot EXIT THEN @@ -182,76 +211,79 @@ create sift-node-buffer 1000 allot ; : $tab-sift ( text-addr text-len -- sift-count ) - ?tab-pressed IF beep space THEN \ cosmetical fix for <tab><tab> - - dup IF bl rsplit dup IF 2swap THEN ELSE 0 0 THEN >r >r - - 0 dup to tab-last-len to tab-last-adr \ reset last possible match - current-node @ IF \ if we are in a node? - 2dup 2>r \ save text - $tab-sift-words to #sift-count \ search in current node first - 2r> \ fetch text to complete, again - THEN - 2dup 2>r - current-node @ >r 0 set-node \ now search in global words - $tab-sift-words to #sift-count - r> set-node - 2r> $tab-sift-nodes - \ concatenate previous commands - r> r> dup IF s" " $cat THEN tab-last-adr tab-last-len $cat - to tab-last-len to tab-last-adr \ ... and save the whole string - ; + ?tab-pressed IF beep space THEN \ cosmetical fix for <tab><tab> + + dup IF bl rsplit dup IF 2swap THEN ELSE 0 0 THEN >r >r + + 0 dup to tab-last-len to tab-last-adr \ reset last possible match + current-node @ IF \ if we are in a node? + 2dup 2>r \ save text + $tab-sift-words to #sift-count \ search in current node first + 2r> \ fetch text to complete, again + THEN + 2dup 2>r + current-node @ >r 0 set-node \ now search in global words + $tab-sift-words to #sift-count + r> set-node + 2r> $tab-sift-nodes + \ concatenate previous commands + r> r> dup IF s" " $cat THEN tab-last-adr tab-last-len $cat + to tab-last-len to tab-last-adr \ ... and save the whole string +; \ 8< node sifting for tab completion on device tree nodes above this line 8< : handle-^A - 0 to accept-cur move-cursor ; + 0 to accept-cur move-cursor ; : handle-^B - accept-cur ?dup IF 1- to accept-cur ( csi ." D" ) move-cursor THEN ; + accept-cur ?dup IF 1- to accept-cur ( csi ." D" ) move-cursor THEN ; : handle-^D - delete-char ( redraw-line ) ; + delete-char ( redraw-line ) ; : handle-^E - accept-len to accept-cur move-cursor ; + accept-len to accept-cur move-cursor ; : handle-^F - accept-cur accept-len <> IF accept-cur 1+ to accept-cur csi ." C" THEN ; + accept-cur accept-len <> IF accept-cur 1+ to accept-cur csi ." C" THEN ; : handle-^H - accept-cur 0= IF beep EXIT THEN - handle-^B delete-char ; - + accept-cur 0= IF beep EXIT THEN + handle-^B delete-char +; : handle-^I - accept-adr accept-len - $tab-sift 0 > IF - ?tab-pressed IF - redraw-prompt full-redraw-line - false to ?tab-pressed - ELSE - tab-last-adr accept-adr tab-last-len move \ copy matching substring - tab-last-len dup to accept-len to accept-cur \ len and cursor position - full-redraw-line \ redraw new string - true to ?tab-pressed \ second tab will print possible matches - THEN - THEN - ; + accept-adr accept-len + $tab-sift 0 > IF + ?tab-pressed IF + redraw-prompt full-redraw-line + false to ?tab-pressed + ELSE + tab-last-adr accept-adr tab-last-len move \ copy matching substring + tab-last-len dup to accept-len to accept-cur \ len and cursor position + full-redraw-line \ redraw new string + true to ?tab-pressed \ second tab will print possible matches + THEN + THEN +; : handle-^K - BEGIN accept-cur accept-len <> WHILE delete-char REPEAT ; + BEGIN accept-cur accept-len <> WHILE delete-char REPEAT ; : handle-^L - history redraw-prompt full-redraw-line ; + history redraw-prompt full-redraw-line ; : handle-^N - his-cur IF his-cur his>next @ ELSE his-head THEN - dup to his-cur select-history ; + his-cur IF his-cur his>next @ ELSE his-head THEN + dup to his-cur select-history +; : handle-^P - his-cur IF his-cur his>prev @ ELSE his-tail THEN - dup to his-cur select-history ; + his-cur IF his-cur his>prev @ ELSE his-tail THEN + dup to his-cur select-history +; : handle-^Q \ Does not handle terminal formatting yet. - key insert-char ; + key insert-char ; : handle-^R - full-redraw-line ; + full-redraw-line ; : handle-^U - 0 to accept-len 0 to accept-cur full-redraw-line ; + 0 to accept-len 0 to accept-cur full-redraw-line ; : handle-fn - key drop beep ; + key drop beep +; TABLE-EXECUTE handle-CSI 0 , ' handle-^P , ' handle-^N , ' handle-^F , @@ -273,15 +305,46 @@ TABLE-EXECUTE handle-meta 0 , 0 , 0 , ' handle-CSI , 0 , 0 , 0 , 0 , +: handle-ESC-O + key + dup 48 = IF + handle-^A + ELSE + dup 46 = IF + handle-^E + THEN + THEN drop +; + +: handle-ESC-5b + key + dup 31 = IF \ HOME + key drop ( drops closing 7e ) handle-^A + ELSE + dup 33 = IF \ DEL + key drop handle-^D + ELSE + dup 34 = IF \ END + key drop handle-^E + ELSE + dup 1f and handle-CSI + THEN + THEN + THEN drop +; + : handle-ESC - key dup 5b = IF drop key - dup 33 = IF \ DEL - drop key drop ( drops closing 7e ) handle-^D - ELSE - 1f and handle-CSI - THEN - ELSE 1f and handle-meta THEN - ; + key + dup 5b = IF + handle-ESC-5b + ELSE + dup 4f = IF + handle-ESC-O + ELSE + dup 1f and handle-meta + THEN + THEN drop +; TABLE-EXECUTE handle-control 0 , \ ^@: @@ -318,21 +381,30 @@ TABLE-EXECUTE handle-control 0 , \ ^_: : (accept) ( adr len -- len' ) - cursor-on - to accept-max to accept-adr - 0 to accept-len 0 to accept-cur - 0 to his-cur - 1b emit 37 emit - BEGIN key - dup 0d <> WHILE - dup 9 <> IF 0 to ?tab-pressed THEN \ reset state machine - dup 7f = IF drop 8 THEN \ Handle DEL as if it was BS. ??? bogus - dup bl < IF handle-control ELSE - dup 80 and IF dup a0 < IF 7f and handle-meta ELSE drop beep THEN ELSE - insert-char THEN THEN - REPEAT drop add-history - accept-len to accept-cur move-cursor space accept-len - cursor-off + cursor-on + to accept-max to accept-adr + 0 to accept-len 0 to accept-cur + 0 to his-cur + 1b emit 37 emit + BEGIN + key dup 0d <> + WHILE + dup 9 <> IF 0 to ?tab-pressed THEN \ reset state machine + dup 7f = IF drop 8 THEN \ Handle DEL as if it was BS. ??? bogus + dup bl < IF handle-control ELSE + dup 80 and IF + dup a0 < IF 7f and handle-meta ELSE drop beep THEN + ELSE + insert-char + THEN + THEN + REPEAT + drop add-history + accept-len to accept-cur + move-cursor space + accept-len + cursor-off ; ' (accept) to accept + diff --git a/slof/fs/alloc-mem.fs b/slof/fs/alloc-mem.fs index 89c6a61..59381a7 100644 --- a/slof/fs/alloc-mem.fs +++ b/slof/fs/alloc-mem.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/available.fs b/slof/fs/available.fs index da80c79..5eb8fa9 100644 --- a/slof/fs/available.fs +++ b/slof/fs/available.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -53,7 +53,7 @@ VARIABLE chosen-memory-ih 0 chosen-memory-ih ! \ \\\\\\\\\\\\\\ Exported Interface: \ + \ IEEE 1275 implementation: -\ claim +\ claim \ Claim the region with given start address and size (if align parameter is 0); \ alternatively claim any region of given alignment \ + @@ -63,7 +63,7 @@ VARIABLE chosen-memory-ih 0 chosen-memory-ih ! \ + \ IEEE 1275 implementation: -\ release +\ release \ Free the region with given start address and size \ + : release ( addr len -- ) release update-available-property ; diff --git a/slof/fs/banner.fs b/slof/fs/banner.fs index 15527c6..efdba0c 100644 --- a/slof/fs/banner.fs +++ b/slof/fs/banner.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/base.fs b/slof/fs/base.fs index ab8cf39..f05ffab 100644 --- a/slof/fs/base.fs +++ b/slof/fs/base.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -10,11 +10,20 @@ \ * IBM Corporation - initial implementation \ ****************************************************************************/ +: >name ( xt -- nfa ) \ note: still has the "immediate" field! + BEGIN char- dup c@ UNTIL ( @lastchar ) + dup dup aligned - cell+ char- ( @lastchar lenmodcell ) + dup >r - + BEGIN dup c@ r@ <> WHILE + cell- r> cell+ >r + REPEAT + r> drop char- +; \ Words missing in *.in files VARIABLE mask -1 mask ! -VARIABLE huge-tftp-load 0 huge-tftp-load ! +VARIABLE huge-tftp-load 1 huge-tftp-load ! : default-hw-exception s" Exception #" type . ; @@ -94,7 +103,6 @@ CREATE $catpad 100 allot : (is-user-word) ( name-str name-len xt -- ) -rot $CREATE , DOES> @ execute ; -: zcount ( zstr -- str len ) dup BEGIN dup c@ WHILE char+ REPEAT over - ; : zplace ( str len buf -- ) 2dup + 0 swap c! swap move ; : strdup ( str len -- dupstr len ) here over allot swap 2dup 2>r move 2r> ; @@ -190,6 +198,13 @@ CREATE $catpad 100 allot +LOOP ; +\ Add special character to string + +: add-specialchar ( dst-adr special -- dst-adr' ) + over c! 1+ ( dst-adr' ) + 1 >in +! \ advance input-index +; + \ Parse upto next " : parse-" ( dst-adr -- dst-adr' ) @@ -200,11 +215,17 @@ CREATE $catpad 100 allot : (") ( dst-adr -- dst-adr' ) begin ( dst-adr ) parse-" ( dst-adr' ) - ib >in @ + c@ [char] ( = IF - parse-hexstring - ELSE - EXIT + >in @ dup span @ >= IF ( dst-adr' >in-@ ) + drop + EXIT THEN + + ib + c@ + CASE + [char] ( OF parse-hexstring ENDOF + [char] " OF [char] " add-specialchar ENDOF + dup OF EXIT ENDOF + ENDCASE again ; @@ -248,18 +269,18 @@ CREATE "pad 100 allot #include <search.fs> -\ The following constants are required in some parts -\ of the code, mainly instance variables and see. Having to reverse +\ The following constants are required in some parts +\ of the code, mainly instance variables and see. Having to reverse \ engineer our own CFAs seems somewhat weird, but we gained a bit speed. \ Each colon definition is surrounded by colon and semicolon \ constant below contain address of their xt : (function) ; -defer (defer) -0 value (value) +defer (defer) +0 value (value) 0 constant (constant) -variable (variable) +variable (variable) create (create) alias (alias) (function) cell buffer: (buffer:) @@ -268,7 +289,7 @@ cell buffer: (buffer:) ' (function) cell + @ \ ( ... <semicolon> ) ' (defer) @ \ ( ... <defer> ) ' (value) @ \ ( ... <value> ) -' (constant) @ \ ( ... <constant> ) +' (constant) @ \ ( ... <constant> ) ' (variable) @ \ ( ... <variable> ) ' (create) @ \ ( ... <create> ) ' (alias) @ \ ( ... <alias> ) @@ -299,6 +320,8 @@ constant <colon> ' do+loop constant <do+loop> ' do constant <do> ' exit constant <exit> +' doleave constant <doleave> +' do?leave constant <do?leave> \ provide the memory management words @@ -463,7 +486,7 @@ defer cursor-off ( -- ) : nop-get-flashside ( -- side ) ." Cannot get flashside" cr ABORT ; : nop-set-flashside ( side -- status ) ." Cannot set flashside" cr ABORT ; : nop-read-bootlist ( -- ) ; -: nop-furnish-bootfile ( -- adr len ) s" :NONE" ; +: nop-furnish-bootfile ( -- adr len ) s" net:" ; : nop-set-boot-file ( adr len -- ) 2drop ; : nop-mfg-mode? ( -- flag ) false ; : nop-of-prompt? ( -- flag ) false ; @@ -504,3 +527,29 @@ defer cursor-off ( -- ) #include "rmove.fs" \ provide a simple run time preprocessor #include <preprocessor.fs> + +: $dnumber base @ >r decimal $number r> base ! ; +: (.d) base @ >r decimal (.) r> base ! ; + +\ IP address conversion + +: (ipaddr) ( "a.b.c.d" -- FALSE | n1 n2 n3 n4 TRUE ) + base @ >r decimal + over s" 000.000.000.000" comp 0= IF 2drop false r> base ! EXIT THEN + [char] . left-parse-string $number IF 2drop false r> base ! EXIT THEN -rot + [char] . left-parse-string $number IF 2drop false r> base ! EXIT THEN -rot + [char] . left-parse-string $number IF 2drop false r> base ! EXIT THEN -rot + $number IF false r> base ! EXIT THEN + true r> base ! +; + +: (ipformat) ( n1 n2 n3 n4 -- str len ) + base @ >r decimal + 0 <# # # # [char] . hold drop # # # [char] . hold + drop # # # [char] . hold drop # # #s #> + r> base ! +; + +: ipformat ( n1 n2 n3 n4 -- ) (ipformat) type ; + + diff --git a/slof/fs/boot.fs b/slof/fs/boot.fs index 6c20c5f..3980563 100644 --- a/slof/fs/boot.fs +++ b/slof/fs/boot.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -10,13 +10,6 @@ \ * IBM Corporation - initial implementation \ ****************************************************************************/ -\ \\\\\\\\\\\\\\ Global Data -CREATE (bootdevice) 2 cells allot (bootdevice) 2 cells erase -CREATE bootargs 2 cells allot bootargs 2 cells erase -CREATE load-list 2 cells allot load-list 2 cells erase - -' (bootdevice) to bootdevice - 0 VALUE load-size 0 VALUE go-entry VARIABLE state-valid false state-valid ! @@ -25,19 +18,20 @@ CREATE go-args 2 cells allot go-args 2 cells erase \ \\\\\\\\\\\\\\ Structure/Implementation Dependent Methods : $bootargs - bootargs 2@ ?dup IF - ELSE s" diagnostic-mode?" evaluate and IF s" diag-file" evaluate - ELSE s" boot-file" evaluate THEN THEN + bootargs 2@ ?dup IF + ELSE s" diagnostic-mode?" evaluate and IF s" diag-file" evaluate + ELSE s" boot-file" evaluate THEN THEN ; : $bootdev - bootdevice 2@ ?dup IF - ELSE s" diagnostic-mode?" evaluate and IF - s" diag-device" evaluate - ELSE - s" boot-device" evaluate - THEN + bootdevice 2@ dup IF s" " $cat THEN + s" diagnostic-mode?" evaluate IF + s" diag-device" evaluate + ELSE + s" boot-device" evaluate THEN + $cat \ prepend bootdevice setting from vpd-bootlist + strdup ?dup 0= IF disable-watchdog drop ABORT" No boot device!" @@ -51,12 +45,14 @@ CREATE go-args 2 cells allot go-args 2 cells erase : set-boot-args ( str len -- ) dup IF strdup ELSE nip dup THEN bootargs 2! ; : (set-boot-device) ( str len -- ) - ?dup IF 1+ strdup 1- ELSE drop 0 0 THEN bootdevice 2! ; + ?dup IF 1+ strdup 1- ELSE drop 0 0 THEN bootdevice 2! +; ' (set-boot-device) to set-boot-device : (add-boot-device) ( str len -- ) \ Concatenate " str" to "bootdevice" - bootdevice 2@ ?dup IF $cat-space ELSE drop THEN set-boot-device ; + bootdevice 2@ ?dup IF $cat-space ELSE drop THEN set-boot-device +; ' (add-boot-device) to add-boot-device @@ -90,9 +86,9 @@ defer go ( -- ) THEN dup ['] elf-check-file CATCH IF - ( -64 THROW ) \ Not now, let the 'go' (i.e. no-go) whine about it - drop 0 - THEN + ( -64 THROW ) \ Not now, let the 'go' (i.e. no-go) whine about it + drop 0 + THEN CASE 1 OF true swap ['] load-elf32-claim CATCH IF 2drop drop -66 THROW @@ -117,26 +113,28 @@ defer go ( -- ) ; : init-program ( -- ) - $bootargs LOAD-BASE ['] load-elf-init CATCH ?dup IF - boot-exception-handler - 2drop 2drop false \ Could not claim - ELSE IF - 0 ciregs 2dup >r3 ! >r4 ! \ Valid (ELF ) Image - THEN - THEN + $bootargs LOAD-BASE ['] load-elf-init CATCH ?dup IF + boot-exception-handler + 2drop 2drop false \ Could not claim + ELSE IF + 0 ciregs 2dup >r3 ! >r4 ! \ Valid (ELF ) Image + THEN + THEN ; + \ \\\\\\\\\\\\\\ Exported Interface: \ * \ Generic device load method: \ * - : do-load ( devstr len -- img-size ) \ Device method wrapper - \ Set watchdog timer to 10 minutes, mul. - \ multiply with 2 because DHCP needs 1 - \ sec. per try and add 1 min to avoid - 4ec set-watchdog \ race conditions with watchdog timeout + use-load-watchdog? IF + \ Set watchdog timer to 10 minutes, multiply with 2 because DHCP + \ needs 1 second per try and add 1 min to avoid race conditions + \ with watchdog timeout. + 4ec set-watchdog + THEN my-self >r current-node @ >r \ Save my-self ." Trying to load: " $bootargs type ." from: " 2dup type ." ... " 2dup open-dev dup IF @@ -168,7 +166,7 @@ defer go ( -- ) : parse-load ( "{devlist}" -- success ) \ Parse-execute boot-device list cr BEGIN parse-word dup WHILE ( de-alias ) do-load dup 0< IF drop 0 THEN IF - state-valid @ IF ." Successfully loaded" cr THEN + state-valid @ IF ." Successfully loaded" cr THEN true 0d parse strdup load-list 2! EXIT THEN REPEAT 2drop 0 0 load-list 2! false @@ -177,11 +175,7 @@ defer go ( -- ) : load ( "{params}<eol>"} -- success ) \ Client interface to load parse-word 0d parse -leading 2swap ?dup IF de-alias - over c@ [char] / = IF - set-boot-device - ELSE - s" " 2swap $cat $cat - THEN + set-boot-device ELSE drop THEN @@ -189,14 +183,13 @@ defer go ( -- ) ; : load-next ( -- success ) \ Continue after go failed - load-list 2@ ?dup IF s" parse-load " 2swap $cat strdup evaluate - ELSE drop false THEN + load-list 2@ ?dup IF s" parse-load " 2swap $cat strdup evaluate + ELSE drop false THEN ; \ \\\\\\\\\\\\\\\\\\\\\\\\\\ \ load/go utilities \ -> Should be in loaders.fs -\ * : noload false ; @@ -217,28 +210,27 @@ read-bootlist \ IEEE 1275 : load (user interface) \ * : boot - load IF - disable-watchdog (go-and-catch) - BEGIN load-next WHILE - (go-and-catch) - REPEAT - - \ When we return from boot print the banner again. - .banner - ELSE - -65 boot-exception-handler - THEN + load 0= IF -65 boot-exception-handler EXIT THEN + disable-watchdog (go-and-catch) + BEGIN load-next WHILE + (go-and-catch) + REPEAT + + \ When we return from boot print the banner again. + .banner ; : load load 0= IF -65 boot-exception-handler THEN ; \ \\\\ Temporary hacks for backwards compatibility -: yaboot ." use 'boot disk' instead " ; +: yaboot ." Use 'boot disk' instead " ; : netboot ( -- rc ) ." Use 'boot net' instead " ; -: netboot-arg ( arg-string -- rc ) s" boot net " 2swap $cat (parse-line) $cat - evaluate ; +: netboot-arg ( arg-string -- rc ) + s" boot net " 2swap $cat (parse-line) $cat + evaluate +; : netload ( -- rc ) (parse-line) load-base >r FLASH-LOAD-BASE to load-base @@ -246,5 +238,6 @@ read-bootlist r> to load-base load-size ; + : neteval ( -- ) FLASH-LOAD-BASE netload evaluate ; diff --git a/slof/fs/bootmsg.fs b/slof/fs/bootmsg.fs index 7d1e9f7..524d469 100644 --- a/slof/fs/bootmsg.fs +++ b/slof/fs/bootmsg.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/claim.fs b/slof/fs/claim.fs index cba0312..f12e37c 100644 --- a/slof/fs/claim.fs +++ b/slof/fs/claim.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/client.fs b/slof/fs/client.fs index ffd4cdb..78ccfdf 100644 --- a/slof/fs/client.fs +++ b/slof/fs/client.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/debug.fs b/slof/fs/debug.fs index b2593dc..bfdc9fc 100644 --- a/slof/fs/debug.fs +++ b/slof/fs/debug.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -12,12 +12,12 @@ false constant <debug-dummy> -12 34 2constant (2constant) ' (2constant) cell+ @ +12 34 2constant (2constant) ' (2constant) cell+ @ \ fake device node here 0 -dup , dup , dup , dup , dup , -over 7 cells + , -dup , dup , dup , dup , dup , +dup , dup , dup , dup , dup , +over 7 cells + , +dup , dup , dup , dup , dup , dup , drop current-node ! \ FAKE! 12 instance value (instancevalue) ' (instancevalue) cell+ @ @@ -46,7 +46,7 @@ constant <2constant> cell -1 * CONSTANT -cell : cell- ( n -- n-cell-size ) [ cell -1 * ] LITERAL + -; +; \ Search for xt of given address : find-xt-addr ( addr -- xt ) @@ -56,7 +56,7 @@ cell -1 * CONSTANT -cell THEN cell- AGAIN -; +; : (.immediate) ( xt -- ) \ is it immediate? @@ -76,36 +76,89 @@ cell -1 * CONSTANT -cell : trace-back ( ) 1 BEGIN - cr dup dup . ." : " rpick dup . ." : " - ['] tib here within IF + cr dup dup . ." : " rpick dup . ." : " + ['] tib here within IF dup rpick find-xt-addr (.xt) - THEN - 1+ dup rdepth 5 - >= IF cr drop EXIT THEN + THEN + 1+ dup rdepth 5 - >= IF cr drop EXIT THEN AGAIN -; +; -: (see-colon) ( xt -- ) - ." : " dup (.xt) cr 3 spaces - BEGIN - cell + dup @ - dup <semicolon> <> - WHILE - dup (.xt) ." " +VARIABLE see-my-type-column + +: (see-my-type) ( indent limit xt str len -- indent limit xt ) + dup see-my-type-column @ + dup 50 >= IF + -rot over " " comp 0= IF + \ blank causes overflow: just enforce new line with next call + 2drop see-my-type-column ! + ELSE + rot drop ( indent limit xt str len ) + 2 pick (u.) dup -rot cr type ( indent limit xt str len xt-len ) + " :" type 1+ ( indent limit xt str len prefix-len ) + 5 pick dup spaces + ( indent limit xt str len prefix-len ) + over + see-my-type-column ! ( indent limit xt str len ) + type + THEN ( indent limit xt ) + ELSE + see-my-type-column ! type ( indent limit xt ) + THEN +; + +: (see-my-type-init) ( -- ) + ffff see-my-type-column ! \ just enforce a new line +; + +: (see-colon-body) ( indent limit xt -- indent limit xt ) + (see-my-type-init) \ enforce new line + BEGIN ( indent limit xt ) + cell+ 2dup <> + over @ + dup <semicolon> <> + rot and ( indent limit xt @xt flag ) + WHILE ( indent limit xt @xt ) + xt>name (see-my-type) " " (see-my-type) + dup @ ( indent limit xt @xt) CASE - <0branch> OF cell+ dup @ . ENDOF - <branch> OF cell+ dup @ . ENDOF - <do?do> OF cell+ dup @ . ENDOF - <lit> OF cell+ dup @ . ENDOF - <dotick> OF cell+ dup @ (.xt) ." " ENDOF - <doloop> OF cell+ dup @ . ENDOF - <do+loop> OF cell+ dup @ . ENDOF - <sliteral> OF cell+ dup count dup >r type ." " - r> -cell and + .s ENDOF - dup OF ." " ENDOF + <0branch> OF cell+ dup @ + over + cell+ dup >r + (u.) (see-my-type) r> ( indent limit xt target) + 2dup < IF + over 4 pick 3 + -rot recurse + nip nip nip cell- ( indent limit xt ) + ELSE + drop ( indent limit xt ) + THEN + (see-my-type-init) ENDOF \ enforce new line + <branch> OF cell+ dup @ over + cell+ (u.) + (see-my-type) " " (see-my-type) ENDOF + <do?do> OF cell+ dup @ (u.) (see-my-type) + " " (see-my-type) ENDOF + <lit> OF cell+ dup @ (u.) (see-my-type) + " " (see-my-type) ENDOF + <dotick> OF cell+ dup @ xt>name (see-my-type) + " " (see-my-type) ENDOF + <doloop> OF cell+ dup @ (u.) (see-my-type) + " " (see-my-type) ENDOF + <doleave> OF cell+ dup @ over + cell+ (u.) + (see-my-type) " " (see-my-type) ENDOF + <do?leave> OF cell+ dup @ over + cell+ (u.) + (see-my-type) " " (see-my-type) ENDOF + <sliteral> OF cell+ " """ (see-my-type) dup count dup >r + (see-my-type) " """ (see-my-type) + " " (see-my-type) + r> -cell and + ENDOF ENDCASE REPEAT - 2drop - cr ." ;" + drop +; + +: (see-colon) ( xt -- ) + (see-my-type-init) + 1 swap 0 swap ( indent limit xt ) + " : " (see-my-type) dup xt>name (see-my-type) + rot drop 4 -rot (see-colon-body) ( indent limit xt ) + rot drop 1 -rot (see-my-type-init) " ;" (see-my-type) + 3drop ; \ Create words are a bit tricky. We find out where their code points. @@ -115,11 +168,11 @@ cell -1 * CONSTANT -cell dup cell+ @ CASE <2constant> OF - dup cell+ cell+ dup @ swap cell+ @ . . ." 2CONSTANT " + dup cell+ cell+ dup @ swap cell+ @ . . ." 2CONSTANT " ENDOF <instancevalue> OF - dup cell+ cell+ @ . ." INSTANCE VALUE " + dup cell+ cell+ @ . ." INSTANCE VALUE " ENDOF <instancevariable> OF @@ -136,8 +189,8 @@ cell -1 * CONSTANT -cell \ Decompile Forth command whose execution token is xt : (see) ( xt -- ) - cr dup dup @ - CASE + cr dup dup @ + CASE <variable> OF ." VARIABLE " (.xt) ENDOF <value> OF dup execute . ." VALUE " (.xt) ENDOF <constant> OF dup execute . ." CONSTANT " (.xt) ENDOF @@ -155,7 +208,7 @@ cell -1 * CONSTANT -cell : see ( "old-name<>" -- ) ' (see) -; +; \ Work in progress... @@ -165,6 +218,7 @@ true value trace>print? true value trace>up? 0 value trace>depth 0 value trace>rdepth +0 value trace>recurse : trace-depth+ ( -- ) trace>depth 1+ to trace>depth ; : trace-depth- ( -- ) trace>depth 1- to trace>depth ; @@ -178,24 +232,31 @@ true value trace>up? : trace-print-on ( -- ) true to trace>print? -; +; : trace-print-off ( -- ) false to trace>print? -; +; \ Add n to ip : fip-add ( n -- ) forth-ip + to forth-ip -; +; + +\ Save execution token address and content + +0 value debug-last-xt +0 value debug-last-xt-content : trace-print ( -- ) - forth-ip cr u. ." : " - forth-ip @ xt>name type ." " + forth-ip cr u. ." : " + forth-ip @ + dup ['] breakpoint = IF drop debug-last-xt-content THEN + xt>name type ." " ." ( " .s ." ) | " -; +; : trace-interpret ( -- ) rdepth 1- to trace>rdepth @@ -203,37 +264,47 @@ true value trace>up? depth . [char] > dup emit emit space source expect ( str len ) ['] interpret catch print-status - AGAIN + AGAIN ; -\ Save execution token address and content - -0 value debug-last-xt -0 value debug-last-xt-content - \ Main trace routine, trace a colon definition : trace-xt ( xt -- ) - debug-last-xt ['] breakpoint @ swap ! \ Re-arm break point - r> drop \ Drop return of 'trace-xt call - cell + to forth-ip \ Step over ":" - true to trace>print? + trace>recurse IF + r> drop \ Drop return of 'trace-xt call + cell+ \ Step over ":" + ELSE + debug-last-xt-content <colon> = IF + \ debug colon-definition + ['] breakpoint @ debug-last-xt ! \ Re-arm break point + r> drop \ Drop return of 'trace-xt call + cell+ \ Step over ":" + ELSE + ['] breakpoint debug-last-xt ! \ Re-arm break point + 2r> 2drop + THEN + THEN + + to forth-ip + true to trace>print? BEGIN trace>print? IF trace-print THEN - forth-ip ( ip ) + forth-ip ( ip ) trace>stepping? IF - BEGIN - key + BEGIN + key CASE - [char] d OF dup @ @ <colon> = IF \ recurse only into colon definitions - trace-depth+ dup >r @ recurse + [char] d OF dup @ @ <colon> = IF \ recurse only into colon definitions + trace-depth+ + 1 to trace>recurse + dup >r @ recurse THEN true ENDOF [char] u OF trace>depth IF tracing trace-print-off true ELSE false THEN ENDOF [char] f OF drop cr trace-interpret ENDOF \ quit trace and start interpreter FIXME rstack - [char] c OF tracing true ENDOF + [char] c OF tracing true ENDOF [char] t OF trace-back false ENDOF - [char] q OF drop cr quit ENDOF + [char] q OF drop cr quit ENDOF 20 OF true ENDOF dup OF cr ." Press d: Down into current word" cr ." Press u: Up to caller" cr @@ -243,15 +314,17 @@ true value trace>up? ." Press q: Abort execution, switch to interpreter" cr false ENDOF ENDCASE - UNTIL - THEN ( ip' ) - dup to forth-ip @ dup ( xt xt ) + UNTIL + THEN ( ip' ) + dup to forth-ip @ ( xt ) + dup ['] breakpoint = IF drop debug-last-xt-content THEN + dup ( xt xt ) CASE - <sliteral> OF drop forth-ip cell+ dup dup c@ + -cell and to forth-ip ENDOF - <dotick> OF drop forth-ip cell+ @ cell fip-add ENDOF + <sliteral> OF drop forth-ip cell+ dup dup c@ + -cell and to forth-ip ENDOF + <dotick> OF drop forth-ip cell+ @ cell fip-add ENDOF <lit> OF drop forth-ip cell+ @ cell fip-add ENDOF - <doto> OF drop forth-ip cell+ @ cell+ ! cell fip-add ENDOF + <doto> OF drop forth-ip cell+ @ cell+ ! cell fip-add ENDOF <0branch> OF drop IF cell fip-add ELSE @@ -261,21 +334,29 @@ true value trace>up? swap >r >r cell fip-add ELSE forth-ip cell+ @ cell+ fip-add 2drop THEN - ENDOF + ENDOF <branch> OF drop forth-ip cell+ @ cell+ fip-add ENDOF + <doleave> OF drop r> r> 2drop forth-ip cell+ @ cell+ fip-add ENDOF + <do?leave> OF drop IF + r> r> 2drop forth-ip cell+ @ cell+ fip-add + ELSE + cell fip-add + THEN + ENDOF <doloop> OF drop r> 1+ r> 2dup = IF 2drop cell fip-add - ELSE >r >r + ELSE >r >r forth-ip cell+ @ cell+ fip-add THEN - ENDOF - <do+loop> OF drop r> + r> 2dup = IF + ENDOF + <do+loop> OF drop r> + r> 2dup >= IF 2drop cell fip-add - ELSE >r >r + ELSE >r >r forth-ip cell+ @ cell+ fip-add THEN ENDOF - + <semicolon> OF trace>depth 0> IF - trace-depth- stepping drop r> recurse + trace-depth- 1 to trace>recurse + stepping drop r> recurse ELSE drop exit THEN ENDOF @@ -283,26 +364,26 @@ true value trace>up? trace-depth- stepping drop r> recurse ELSE drop exit THEN - ENDOF + ENDOF dup OF execute ENDOF ENDCASE - forth-ip cell+ to forth-ip + forth-ip cell+ to forth-ip AGAIN -; +; \ Resume execution from tracer : resume ( -- ) trace>rdepth rdepth! forth-ip cell - trace-xt -; - +; + \ Turn debug off, by erasing breakpoint : debug-off ( -- ) - debug-last-xt IF + debug-last-xt IF debug-last-xt-content debug-last-xt ! \ Restore overwriten token 0 to debug-last-xt - THEN + THEN ; @@ -310,30 +391,40 @@ true value trace>up? \ Entry point for debug : (break-entry) ( -- ) - debug-last-xt-content debug-last-xt ! \ Restore overwriten token + debug-last-xt dup @ ['] breakpoint <> swap ( debug-addr? debug-last-xt ) + debug-last-xt-content swap ! \ Restore overwriten token r> drop \ Don't return to bp, but to caller - debug-last-xt-content <colon> <> IF \ Execute non colon definition - debug-last-xt cr u. ." : " - debug-last-xt xt>name type ." " + debug-last-xt-content <colon> <> and IF \ Execute non colon definition + debug-last-xt cr u. ." : " + debug-last-xt xt>name type ." " ." ( " .s ." ) | " - key drop + key drop debug-last-xt execute - ELSE - debug-last-xt 0 to trace>depth trace-xt \ Trace colon definition + ELSE + debug-last-xt 0 to trace>depth 0 to trace>recurse trace-xt \ Trace colon definition THEN -; +; \ Put entry point bp defer ' (break-entry) to BP +\ Mark an address for debugging + +: debug-address ( addr -- ) + debug-off ( xt ) \ Remove active breakpoint + dup to debug-last-xt ( xt ) \ Save token for later debug + dup @ to debug-last-xt-content ( xt ) \ Save old value + ['] breakpoint swap ! +; + \ Mark the command indicated by xt for debugging : (debug ( xt -- ) - debug-off ( xt ) \ Remove active breakpoint + debug-off ( xt ) \ Remove active breakpoint dup to debug-last-xt ( xt ) \ Save token for later debug - dup @ to debug-last-xt-content ( xt ) \ Save old value + dup @ to debug-last-xt-content ( xt ) \ Save old value ['] breakpoint @ swap ! -; +; \ Mark the command indicated by xt for debugging @@ -343,4 +434,4 @@ true value trace>up? ELSE ." undefined word " type cr THEN -; +; diff --git a/slof/fs/devices/pci-class_02.fs b/slof/fs/devices/pci-class_02.fs index 7cf3493..ff78496 100644 --- a/slof/fs/devices/pci-class_02.fs +++ b/slof/fs/devices/pci-class_02.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/devices/pci-class_0c.fs b/slof/fs/devices/pci-class_0c.fs index 8c3d43c..53e1e19 100644 --- a/slof/fs/devices/pci-class_0c.fs +++ b/slof/fs/devices/pci-class_0c.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/devices/pci-device_10de_0141.fs b/slof/fs/devices/pci-device_10de_0141.fs index ab9f2a5..507c383 100644 --- a/slof/fs/devices/pci-device_10de_0141.fs +++ b/slof/fs/devices/pci-device_10de_0141.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/dictionary.fs b/slof/fs/dictionary.fs index 15cc2cb..5d1dae7 100644 --- a/slof/fs/dictionary.fs +++ b/slof/fs/dictionary.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -11,64 +11,64 @@ \ ****************************************************************************/ : words - last @ - begin ?dup while - dup cell+ char+ count type space @ - repeat + last @ + BEGIN ?dup WHILE + dup cell+ char+ count type space @ + REPEAT ; : .calls ( xt -- ) - current-node @ >r 0 set-node \ only search commands, according too IEEE1275 + current-node @ >r 0 set-node \ only search commands, according too IEEE1275 - last begin @ ?dup while ( xt currxt ) - dup cell+ char+ ( xt currxt name* ) - dup dup c@ + 1+ aligned ( xt currxt name* CFA ) - dup @ <colon> = IF ( xt currxt name* CFA ) - begin - cell+ dup @ ['] semicolon <> - while ( xt currxt *name pos ) - dup @ 4 pick = IF ( xt currxt *name pos ) - over count type space - begin cell+ dup @ ['] semicolon = until cell - \ eat up other occurences - THEN - repeat - THEN - 2drop ( xt currxt ) - repeat - drop + last BEGIN @ ?dup WHILE ( xt currxt ) + dup cell+ char+ ( xt currxt name* ) + dup dup c@ + 1+ aligned ( xt currxt name* CFA ) + dup @ <colon> = IF ( xt currxt name* CFA ) + BEGIN + cell+ dup @ ['] semicolon <> + WHILE ( xt currxt *name pos ) + dup @ 4 pick = IF ( xt currxt *name pos ) + over count type space + BEGIN cell+ dup @ ['] semicolon = UNTIL cell - \ eat up other occurences + THEN + REPEAT + THEN + 2drop ( xt currxt ) + REPEAT + drop - r> set-node \ restore node - ; + r> set-node \ restore node +; 0 value #sift-count false value sift-compl-only : $inner-sift ( text-addr text-len LFA -- ... word-addr word-len true | false ) - dup cell+ char+ count \ get word name - 2dup 6 pick 6 pick find-isubstr \ is there a partly match? - \ in tab completion mode the substring has to be at the beginning - sift-compl-only IF 0= ELSE over < THEN - IF - #sift-count 1+ to #sift-count \ count completions - true - ELSE - 2drop false - THEN - ; + dup cell+ char+ count \ get word name + 2dup 6 pick 6 pick find-isubstr \ is there a partly match? + \ in tab completion mode the substring has to be at the beginning + sift-compl-only IF 0= ELSE over < THEN + IF + #sift-count 1+ to #sift-count \ count completions + true + ELSE + 2drop false + THEN +; : $sift ( text-addr text-len -- ) - current-node @ >r 0 set-node \ only search commands, according too IEEE1275 - sift-compl-only >r false to sift-compl-only \ all substrings, not only compl. - last begin @ ?dup while \ walk the whole dictionary - $inner-sift IF type space THEN - repeat - 2drop - 0 to #sift-count \ we don't need completions here. - r> to sift-compl-only \ restore previous sifting mode - r> set-node \ restore node - ; + current-node @ >r 0 set-node \ only search commands, according too IEEE1275 + sift-compl-only >r false to sift-compl-only \ all substrings, not only compl. + last BEGIN @ ?dup WHILE \ walk the whole dictionary + $inner-sift IF type space THEN + REPEAT + 2drop + 0 to #sift-count \ we don't need completions here. + r> to sift-compl-only \ restore previous sifting mode + r> set-node \ restore node +; : sifting ( "text< >" -- ) - parse-word $sift - ; + parse-word $sift +; diff --git a/slof/fs/display.fs b/slof/fs/display.fs index f0ffae0..5bb8797 100644 --- a/slof/fs/display.fs +++ b/slof/fs/display.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -75,12 +75,12 @@ CREATE default-font-ctrblk /font allot default-font-ctrblk : display-default-font ( str len -- ) romfs-lookup dup 0= IF drop EXIT THEN - 600 <> IF ." Only support 60x8x16 fonts ! " drop EXIT THEN + 600 <> IF ." Only support 60x8x16 fonts ! " drop EXIT THEN default-font-ctrblk font>addr ! ; s" default-font.bin" display-default-font - + \ \\\\\\\\\\\\\\ Implementation Independent Methods (Depend on Previous) \ * \ * @@ -121,4 +121,3 @@ s" default-font.bin" display-default-font default-font-ctrblk /font 0 DO dup cell+ >r @ r> 1 cells +LOOP drop ; - diff --git a/slof/fs/dump.fs b/slof/fs/dump.fs index a7c17fd..90d60c4 100644 --- a/slof/fs/dump.fs +++ b/slof/fs/dump.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/elf.fs b/slof/fs/elf.fs index d60df34..8f1c7b7 100644 --- a/slof/fs/elf.fs +++ b/slof/fs/elf.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -49,6 +49,14 @@ STRUCT /l field phdr>p_align END-STRUCT +\ Provide word to load image to an offset of vaddr +0 value elf-segment-offset + +: xlate-vaddr32 ( programm-header-addr -- addr ) + phdr>p_vaddr l@ elf-segment-offset + +; + + \ ELF 64 bit header STRUCT @@ -121,16 +129,16 @@ false value elf-claim? >r ( file-addr R: program-header-addr ) \ Copy into storage - r@ phdr>p_offset l@ + r@ phdr>p_vaddr l@ r@ phdr>p_filesz l@ move + r@ phdr>p_offset l@ + r@ xlate-vaddr32 r@ phdr>p_filesz l@ move ( R: programm-header-addr ) \ Clear BSS - r@ phdr>p_vaddr l@ r@ phdr>p_filesz l@ + + r@ xlate-vaddr32 r@ phdr>p_filesz l@ + r@ phdr>p_memsz l@ r@ phdr>p_filesz l@ - erase ( R: programm-header-addr ) \ Flush cache - r@ phdr>p_vaddr l@ r> phdr>p_memsz l@ dup 0= IF 2drop ELSE flushcache THEN + r@ xlate-vaddr32 r> phdr>p_memsz l@ dup 0= IF 2drop ELSE flushcache THEN ; : load-segments ( file-addr -- ) @@ -201,7 +209,12 @@ false value elf-claim? nip nip \ cleanup ; -: elf-check-file ( file-addr -- 1 : 32, 2 : 64, else bad ) +\ Return type of ELF image, abort if not valid +\ 1: 32 Bit PPC image +\ 2: 64 Bit PPC image +\ 5: 32 Bit SPU image + +: elf-check-file ( file-addr -- image-type ) ( file-addr ) dup ehdr>e_ident l@-be 7f454c46 <> IF ABORT" Not an ELF executable" @@ -219,10 +232,13 @@ false value elf-claim? dup ehdr>e_type w@ 2 <> ABORT" Not an ELF executable" ( file-addr ) - dup ehdr>e_machine w@ dup 14 <> swap 15 <> and ABORT" Not a PPC ELF executable" - - ( file-addr) - ehdr>e_class c@ + dup ehdr>e_machine w@ + CASE + 14 OF ehdr>e_class c@ ENDOF \ PPC 32 bit executable + 15 OF ehdr>e_class c@ ENDOF \ PPC 64 bit executable + 17 OF ehdr>e_class c@ 4 or ENDOF \ SPU 32 bit executable + dup OF drop ABORT" Not a PPC / SPU ELF executable" ENDOF + ENDCASE ; : load-elf32 ( file-addr -- entry ) @@ -262,12 +278,20 @@ false value elf-claim? ( file-addr 1|2|x ) CASE - 1 OF load-elf32 true ENDOF - 2 OF load-elf64 false ENDOF - dup OF true ABORT" Neither 32- nor 64-bit ELF file" ENDOF + 1 OF 0 to elf-segment-offset load-elf32 true ENDOF + 2 OF 0 to elf-segment-offset load-elf64 false ENDOF + 5 OF load-elf32 true ENDOF + dup OF true ABORT" load-elf-file: Not valid image" ENDOF ENDCASE ; +\ Method to load SPU image + +: elf-spu-load ( ls-start-addr file-addr -- entry ) + swap to elf-segment-offset + load-elf-file drop +; + \ Release memory claimed before : elf-release ( claim-list -- ) diff --git a/slof/fs/envvar.fs b/slof/fs/envvar.fs index 9542bed..8a2932d 100644 --- a/slof/fs/envvar.fs +++ b/slof/fs/envvar.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -16,7 +16,9 @@ wordlist CONSTANT envvars \ list the names in envvars -: listenv get-current envvars set-current words set-current ; +: listenv ( -- ) + get-current envvars set-current words set-current +; \ create a definition in envvars : create-env ( "name" -- ) @@ -24,21 +26,21 @@ wordlist CONSTANT envvars ; \ lay out the data for the separate envvar types -: env-int ( n -- ) 1 c, align , DOES> char+ aligned @ ; -: env-bytes ( a len -- ) +: env-int ( n -- ) 1 c, align , DOES> char+ aligned @ ; +: env-bytes ( a len -- ) 2 c, align dup , here swap dup allot move DOES> char+ aligned dup @ >r cell+ r> ; -: env-string ( str len -- ) 3 c, string, DOES> char+ count ; -: env-flag ( f -- ) 4 c, c, DOES> char+ c@ 0<> ; +: env-string ( str len -- ) 3 c, string, DOES> char+ count ; +: env-flag ( f -- ) 4 c, c, DOES> char+ c@ 0<> ; : env-secmode ( sm -- ) 5 c, c, DOES> char+ c@ ; \ create default envvars -: default-int ( n "name" -- ) create-env env-int ; -: default-bytes ( a len "name" -- ) create-env env-bytes ; -: default-string ( a len "name" -- ) create-env env-string ; -: default-flag ( f "name" -- ) create-env env-flag ; -: default-secmode ( sm "name" -- ) create-env env-secmode ; +: default-int ( n "name" -- ) create-env env-int ; +: default-bytes ( a len "name" -- ) create-env env-bytes ; +: default-string ( a len "name" -- ) create-env env-string ; +: default-flag ( f "name" -- ) create-env env-flag ; +: default-secmode ( sm "name" -- ) create-env env-secmode ; : set-option ( option-name len option len -- ) 2swap encode-string @@ -54,6 +56,7 @@ wordlist CONSTANT envvars THEN ; + : test-flag ( param len -- true | false ) 2dup s" true" string=ci -rot s" false" string=ci or ; @@ -129,9 +132,6 @@ wordlist CONSTANT envvars THEN ; -\ : setenv parse-word skipws 0 parse 2swap $setenv ; -: setenv parse-word ( skipws ) 0d parse -leading 2swap $setenv ; - \ print an envvar : (printenv) ( adr type -- ) CASE @@ -203,91 +203,70 @@ DEFER old-emit 5 OF env-secmode ENDOF ENDCASE ; -: set-default - parse-word envvars voc-find - dup 0= ABORT" not a configuration variable" link> (set-default) -; +\ Enviroment variables might be board specific -: set-defaults - envvars cell+ - BEGIN @ dup WHILE dup link> (set-default) REPEAT - drop -; +#include <envvar_defaults.fs> + +VARIABLE nvoff \ offset in envvar partition -\ the defaults -\ some of those are platform dependent, and should e.g. be -\ created from VPD values -true default-flag auto-boot? -s" " default-string boot-device -s" " default-string boot-file -s" boot" default-string boot-command -s" " default-string diag-device -s" " default-string diag-file -false default-flag diag-switch? -true default-flag fcode-debug? -s" " default-string input-device -s" " default-string nvramrc -s" " default-string oem-banner -false default-flag oem-banner? -0 0 default-bytes oem-logo -false default-flag oem-logo? -s" " default-string output-device -200 default-int screen-#columns -200 default-int screen-#rows -0 default-int security-#badlogins -0 default-secmode security-mode -s" " default-string security-password -0 default-int selftest-#megs -false default-flag use-nvramrc? -false default-flag direct-serial? -true default-flag real-mode? -true default-flag use-axon-ddr? - - -set-defaults - -VARIABLE nvoff \ 70 get-header 2drop nvoff ! - -: (nvupdate-one) ( adr type -- ) +: (nvupdate-one) ( adr type -- "value" ) CASE - 1 OF aligned @ . ENDOF - 2 OF drop ." 0 0" ENDOF - 3 OF count type ENDOF - 4 OF c@ IF ." true" ELSE ." false" THEN ENDOF - 5 OF c@ . ENDOF \ XXX: print symbolically + 1 OF aligned @ (.) ENDOF + 2 OF drop s" 0 0" ENDOF + 3 OF count ENDOF + 4 OF c@ IF s" true" ELSE s" false" THEN ENDOF + 5 OF c@ (.) ENDOF \ XXX: print symbolically ENDCASE ; : nvupdate-one ( def-xt -- ) - >name name>string - ( ." setenv " 2dup type space ) \ Old Implementation - 2dup type s" =" type - findenv nip (nvupdate-one) - ( cr ) \ Old Implementation - 0 emit + >r nvram-partition-type-common get-nvram-partition ( part.addr part.len FALSE|TRUE R: def-xt ) + ABORT" No valid NVRAM." r> ( part.addr part.len def-xt ) + >name name>string ( part.addr part.len var.a var.l ) + 2dup findenv nip (nvupdate-one) + ( part.addr part.len var.addr var.len val.addr val.len ) + internal-add-env + drop ; -: (nvupdate) +: (nvupdate) ( -- ) + nvram-partition-type-common get-nvram-partition ABORT" No valid NVRAM." + erase-nvram-partition drop envvars cell+ BEGIN @ dup WHILE dup link> nvupdate-one REPEAT drop ; -: nvemit nvoff @ rb! 1 nvoff +! 0 nvoff @ rb! ; +: nvupdate ( -- ) + ." nvupdate is obsolete." cr +; + +: set-default + parse-word envvars voc-find + dup 0= ABORT" not a configuration variable" link> (set-default) +; -: nvupdate - 70 get-header 2drop nvoff ! - ['] emit behavior ['] nvemit to emit (nvupdate) to emit +: (set-defaults) + envvars cell+ + BEGIN @ dup WHILE dup link> (set-default) REPEAT + drop ; +\ Preset nvram variables in RAM, but do not overwrite them in NVRAM +(set-defaults) + +: set-defaults + (set-defaults) (nvupdate) +; +: setenv parse-word ( skipws ) 0d parse -leading 2swap $setenv (nvupdate) ; : get-nv ( -- ) - 70 get-header ( addr offset not-found | not-found ) \ find partition header + nvram-partition-type-common get-nvram-partition ( addr offset not-found | not-found ) \ find partition header IF - create-default-headers \ partition header not found: set default values - nvupdate - 70 get-header IF ." NVRAM seems to be broken." cr EXIT THEN + internal-reset-nvram + (nvupdate) + nvram-partition-type-common get-nvram-partition IF ." NVRAM seems to be broken." cr EXIT THEN THEN \ partition header found: read data from nvram drop ( addr ) \ throw away offset @@ -304,10 +283,8 @@ VARIABLE nvoff \ 70 get-header 2drop nvoff ! 2drop drop \ cleanup ; - get-nv - : check-for-nvramrc ( -- ) use-nvramrc? IF s" Executing following code from nvramrc: " @@ -416,16 +393,23 @@ get-nv 4dup ['] (nv-build-real-entry) (nv-build-nvramrc) set-alias s" true" s" use-nvramrc?" $setenv - nvupdate + (nvupdate) ; : nvalias ( "alias-name< >device-specifier<eol>" -- ) - parse-word parse-word $nvalias + parse-word parse-word dup 0<> IF + $nvalias + ELSE + 2drop 2drop + cr + " Usage: nvalias (""alias-name< >device-specifier<eol>"" -- )" type + cr + THEN ; : $nvunalias ( name-str name-len -- ) s" " ['] (nv-build-null-entry) (nv-build-nvramrc) - nvupdate + (nvupdate) ; : nvunalias ( "alias-name< >" -- ) diff --git a/slof/fs/envvar_defaults.fs b/slof/fs/envvar_defaults.fs new file mode 100644 index 0000000..a88d91b --- /dev/null +++ b/slof/fs/envvar_defaults.fs @@ -0,0 +1,40 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2008 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ * IBM Corporation - initial implementation +\ ****************************************************************************/ + +\ the defaults +\ some of those are platform dependent, and should e.g. be +\ created from VPD values +true default-flag auto-boot? +s" " default-string boot-device +s" " default-string boot-file +s" boot" default-string boot-command +s" " default-string diag-device +s" " default-string diag-file +false default-flag diag-switch? +true default-flag fcode-debug? +s" " default-string input-device +s" " default-string nvramrc +s" " default-string oem-banner +false default-flag oem-banner? +0 0 default-bytes oem-logo +false default-flag oem-logo? +s" " default-string output-device +200 default-int screen-#columns +200 default-int screen-#rows +0 default-int security-#badlogins +0 default-secmode security-mode +s" " default-string security-password +0 default-int selftest-#megs +false default-flag use-nvramrc? +false default-flag direct-serial? +true default-flag real-mode? +true default-flag use-axon-ddr? diff --git a/slof/fs/exception.fs b/slof/fs/exception.fs index d243eb9..91e39be 100644 --- a/slof/fs/exception.fs +++ b/slof/fs/exception.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/fbuffer.fs b/slof/fs/fbuffer.fs index 3167ca5..d19c330 100644 --- a/slof/fs/fbuffer.fs +++ b/slof/fs/fbuffer.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -55,7 +55,7 @@ CREATE bitmap-buffer 400 allot : fb8-char2bitmap ( font-height font-addr -- bitmap-buffer ) bitmap-buffer >r char-height rot 0> IF r> char-width 2dup fb8-erase-block + >r 1- THEN - + r> -rot char-width to .ab ( fb-addr font-addr font-height ) fontbytes * bounds ?DO diff --git a/slof/fs/fcode/1275.fs b/slof/fs/fcode/1275.fs index 39ee3ed..ace0933 100644 --- a/slof/fs/fcode/1275.fs +++ b/slof/fs/fcode/1275.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/fcode/big.fs b/slof/fs/fcode/big.fs index c2cb8d9..00eb570 100644 --- a/slof/fs/fcode/big.fs +++ b/slof/fs/fcode/big.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/fcode/core.fs b/slof/fs/fcode/core.fs index 8cfadeb..79d47c3 100644 --- a/slof/fs/fcode/core.fs +++ b/slof/fs/fcode/core.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/fcode/evaluator.fs b/slof/fs/fcode/evaluator.fs index a0249ab..1434098 100644 --- a/slof/fs/fcode/evaluator.fs +++ b/slof/fs/fcode/evaluator.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/fcode/tokens.fs b/slof/fs/fcode/tokens.fs index bf76b8b..ad6c52b 100644 --- a/slof/fs/fcode/tokens.fs +++ b/slof/fs/fcode/tokens.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/find-hash.fs b/slof/fs/find-hash.fs index 2d6facf..3769673 100644 --- a/slof/fs/find-hash.fs +++ b/slof/fs/find-hash.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -21,11 +21,12 @@ clean-hash ; : hash-find ( str len head -- 0 | link ) - >r 2dup 2dup hash - dup >r @ dup IF link>name name>string string=ci ELSE nip nip THEN - IF 2drop r> @ r> drop exit THEN - r> r> swap >r ((find)) - dup IF dup r> ! ELSE r> drop THEN ; + >r 2dup 2dup hash + dup >r @ dup IF link>name name>string string=ci ELSE nip nip THEN + IF 2drop r> @ r> drop exit THEN + r> r> swap >r ((find)) + dup IF dup r> ! ELSE r> drop THEN +; : hash-reveal hash off ; diff --git a/slof/fs/generic-disk.fs b/slof/fs/generic-disk.fs index bfbcb15..0543c89 100644 --- a/slof/fs/generic-disk.fs +++ b/slof/fs/generic-disk.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/history.fs b/slof/fs/history.fs new file mode 100644 index 0000000..2c2c70f --- /dev/null +++ b/slof/fs/history.fs @@ -0,0 +1,107 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2008 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ * IBM Corporation - initial implementation +\ ****************************************************************************/ + +\ Create debug section in NVRAM +: debug-init-nvram ( -- ) + nvram-partition-type-debug get-nvram-partition IF + cr ." Could not find debug partition in NVRAM - " + nvram-partition-type-debug s" debug" d# 1024 new-nvram-partition + ABORT" Failed to create DEBUG NVRAM partition" + 2dup erase-nvram-partition drop + ." created." cr + THEN + s" debug-nvram-partition" $2constant +; + +debug-init-nvram + +: debug-add-env ( "name" "value" -- ) debug-nvram-partition 2rot 2rot internal-add-env drop ; +: debug-set-env ( "name" "value" -- ) debug-nvram-partition 2rot 2rot internal-set-env drop ; +: debug-get-env ( "name" -- "value" TRUE | FALSE) debug-nvram-partition 2swap internal-get-env ; + +: debug-get-history-enabled ( -- n ) s" history-enabled?" debug-get-env IF $number IF 0 THEN ELSE 0 THEN ; +: debug-set-history-enabled ( n -- ) (.) s" history-enabled?" 2swap debug-set-env ; + + +debug-get-history-enabled constant nvram-history? + +nvram-history? [IF] + +: history-init-nvram ( -- ) + nvram-partition-type-history get-nvram-partition IF + cr ." Could not find history partition in NVRAM - " + nvram-partition-type-history s" history" d# 2048 new-nvram-partition + ABORT" Failed to create SMS NVRAM partition" + 2dup erase-nvram-partition drop + ." created" cr + THEN + s" history-nvram-partition" $2constant +; + +history-init-nvram + +0 value (history-len) +0 value (history-adr) + +: (history-load-one) ( str len -- len ) + \ 2dup ." loading " type cr + to (history-len) to (history-adr) + /his (history-len) + alloc-mem ( his ) + his-tail 0= IF dup to his-tail THEN + his-head over his>next ! to his-head + his-head his>next @ his>prev his-head swap ! + (history-len) his-head his>len ! + (history-adr) his-head his>buf (history-len) move + (history-len) 1+ +; + +: history-load ( -- ) + history-nvram-partition drop BEGIN dup WHILE + dup rzcount ( part str len ) + dup IF + (history-load-one) + + ELSE + 3drop 0 + THEN + REPEAT + drop +; + +: (history-store-one) ( pos len saddr slen -- FALSE | npos nlen TRUE ) + dup 3 pick < IF \ enough space + dup >r rot >r + \ 2dup ." storing " type cr + bounds DO dup i c@ swap nvram-c! 1+ LOOP + dup 0 swap nvram-c! 1+ + r> r> - 1- true + ELSE + 2drop false + THEN +; + +: history-store ( -- ) + history-nvram-partition erase-nvram-partition drop + history-nvram-partition his-tail BEGIN dup WHILE + dup his>buf over his>len @ + ( position len link saddr slen ) + rot >r (history-store-one) r> + swap IF his>prev @ ELSE drop 0 THEN + REPEAT + 2drop drop +; + +\ redefine "end of SLOF" words to safe history +: reset-all history-store reset-all ; +: reboot history-store reboot ; +: boot history-store boot ; + +[THEN] diff --git a/slof/fs/ide.fs b/slof/fs/ide.fs index 59c8438..93ca766 100644 --- a/slof/fs/ide.fs +++ b/slof/fs/ide.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -9,20 +9,23 @@ \ * Contributors: \ * IBM Corporation - initial implementation \ ****************************************************************************/ +\ \ 26.06.2007 added: two devices (Master/Slave) per channel - + 1 encode-int s" #address-cells" property 0 encode-int s" #size-cells" property : decode-unit 1 hex-decode-unit ; : encode-unit 1 hex-encode-unit ; -0 VALUE >ata \ base address for command-block -0 VALUE >ata1 \ base address for control block +0 VALUE >ata \ base address for command-block +0 VALUE >ata1 \ base address for control block -true VALUE no-timeout \ flag that no timeout occured +true VALUE no-timeout \ flag that no timeout occured -0c CONSTANT #cdb-bytes \ command descriptor block (12 bytes) +0c CONSTANT #cdb-bytes \ command descriptor block (12 bytes) +800 CONSTANT atapi-size +200 CONSTANT ata-size \ ***************************** \ Some register access helpers. @@ -67,11 +70,11 @@ ec CONSTANT cmd#identify-device \ ATA and ATAPI \ BAR 2 & 3 : Device 1 \ ***************************** : set-regs ( n -- ) -\ dup ." < Set #" . \ *** DEBUG LINE **** dup - 01 and \ only Chan 0 or Chan 1 allowed + 01 and \ only Chan 0 or Chan 1 allowed 3 lshift dup 10 + config-l@ -4 and to >ata 14 + config-l@ -4 and to >ata1 + 02 ata-ctrl! \ disable interrupts 02 and IF 10 @@ -79,15 +82,16 @@ ec CONSTANT cmd#identify-device \ ATA and ATAPI 00 THEN ata-dev! -\ >ata ." /" . ata-astat@ ." /" . ." > " \ *** DEBUG LINE *** ; - 200 VALUE block-size -80000 VALUE max-transfer \ Arbitrary, really +ata-size VALUE block-size +80000 VALUE max-transfer \ Arbitrary, really CREATE sector d# 512 allot -CREATE packet-cb #cdb-bytes allot -CREATE packet-buffer 800 allot +CREATE packet-cdb #cdb-bytes allot +CREATE return-buffer atapi-size allot + +scsi-open \ add scsi functions \ ******************************** \ show all ATAPI-registers @@ -123,7 +127,11 @@ CREATE packet-buffer 800 allot ." ( media changed or reset )" \ 'unit attention' drop \ drop err-reg content ELSE - ." (Err : " . ." )" \ show err-reg content + dup + ." (Err : " . \ show err-reg content + space + rshift 4 .sense-text \ show text string + 29 emit THEN cr ELSE @@ -265,21 +273,11 @@ CREATE packet-buffer 800 allot c@ 80 AND 0= IF \ is this an ATA drive ? sector d# 120 + \ get word 60 + 61 - rl@-le \ read 32-bit as little endian value - d# 1000 / \ bytes -> kbytes (avoid 32-bit overflow) - d# 512 * \ LBA = 512 Bytes - d# 500 + \ round +- 0.5 - d# 1000 / \ kB -> MB - dup - d# 1000 > - IF - d# 500 + - d# 1000 / - ." (" .d ." GB)" - ELSE - ." (" .d ." MB)" - THEN - THEN + rl@-le \ read 32-bit as little endian value + d# 512 \ standard ATA block-size + swap + .capacity-text ( block-size #blocks -- ) + THEN sector d# 98 + \ goto word 49 w@ @@ -336,8 +334,8 @@ CREATE packet-buffer 800 allot \ preset LBA register with maximum \ allowed block-size (16-bits) \ ******************************* -: set-lba ( block-length -- ) - lbsplit ( quad -- b1.lo b2 b3 b4.hi ) +: set-lba ( block-length -- ) + lbsplit ( quad -- b1.lo b2 b3 b4.hi ) drop \ skip upper two bytes drop ata-lbah! @@ -348,7 +346,7 @@ CREATE packet-buffer 800 allot \ gets byte-count and reads a block of words \ from data-register to a buffer \ ******************************************* -: read-pio-block ( buff-addr -- buff-addr-new) +: read-pio-block ( buff-addr -- buff-addr-new ) ata-lbah@ 8 lshift \ get block length High ata-lbam@ or \ get block length Low 1 rshift \ bcount -> wcount @@ -370,132 +368,117 @@ CREATE packet-buffer 800 allot \ Send a command block (12 bytes) in PIO mode \ read data if requested \ ******************************************** -: send-atapi-packet ( req-buffer req-len -- ) - >r ( req-len R: req-buffer ) - 800 set-lba \ set regs to length limit +: send-atapi-packet ( req-buffer -- ) + >r ( R: req-buffer ) + atapi-size set-lba \ set regs to length limit 00 ata-feat! cmd#packet ata-cmd! \ A0 = ATAPI packet command 48 C8 wait-for-status ( val mask -- ) \ BSY:0 DRDY:1 DRQ:1 6 0 do - packet-cb i 2 * + \ transfer command block (12 bytes) + packet-cdb i 2 * + \ transfer command block (12 bytes) w@ ata-data! \ 6 doublets PIO transfer to device loop \ copy packet to data-reg - status-check \ status err bit set ? -> display - wait-for-ready \ busy released ? + status-check ( -- ) \ status err bit set ? -> display + wait-for-ready ( -- ) \ busy released ? BEGIN ata-stat@ 08 and 08 = WHILE \ Data-Request-Bit set ? - r> \ get target buffer address + r> \ get last target buffer address read-pio-block \ only if from device requested >r \ start of next block REPEAT - r> - drop + r> \ original value + drop \ return clean ; +: atapi-packet-io ( -- ) + return-buffer atapi-size erase \ clear return buffer + return-buffer send-atapi-packet \ send 'packet-cdb' , get 'return-buffer' +; + + + \ ******************************** \ ATAPI packet commands \ ******************************** -03 CONSTANT scsi-cmd#request-sense -12 CONSTANT scsi-cmd#inquiry -28 CONSTANT scsi-cmd#read10 -A8 CONSTANT scsi-cmd#read12 -25 CONSTANT scsi-cmd#read-capacity -2B CONSTANT scsi-cmd#seek \ Methods to access atapi disk : atapi-test ( -- true|false ) - packet-cb #cdb-bytes erase \ command-code 0 - packet-buffer send-atapi-packet + packet-cdb scsi-build-test-unit-ready \ command-code: 00 + atapi-packet-io ( ) \ send CDB, get return-buffer ata-stat@ 1 and IF false ELSE true THEN ; -: atapi-sense ( -- ASC sense-key ) - packet-cb #cdb-bytes erase - scsi-cmd#request-sense packet-cb c! \ set command-code 03h - 12 packet-cb 4 + c! \ allocation length = 18 - packet-buffer send-atapi-packet - packet-buffer d# 12 + c@ \ additional sense code (ASC) - packet-buffer 2 + c@ f and \ sense key +: atapi-sense ( -- ascq asc sense-key ) + d# 252 packet-cdb scsi-build-request-sense ( alloc-len cdb -- ) + atapi-packet-io ( ) \ send CDB, get return-buffer + return-buffer scsi-get-sense-data ( cdb-addr -- ascq asc sense-key ) ; -: atapi-inquiry ( -- ) - packet-cb #cdb-bytes erase \ set command-code 12h - scsi-cmd#inquiry packet-cb c! - 24 packet-cb 4 + c! - packet-buffer send-atapi-packet +: atapi-read-blocks ( address block# #blocks dev# -- #read-blocks ) + set-regs ( address block# #blocks ) + dup >r ( address block# #blocks ) + packet-cdb scsi-build-read-10 ( address block# #blocks cdb -- ) + send-atapi-packet ( address -- ) + r> \ return requested number of blocks ; -: atapi-capacity ( -- ) - packet-cb #cdb-bytes erase - scsi-cmd#read-capacity packet-cb c! \ set command-code 25h - packet-buffer send-atapi-packet +\ *************************************** +\ read capacity of drive medium +\ use SCSI-Support Package +\ *************************************** +: atapi-read-capacity ( -- ) + packet-cdb scsi-build-read-cap-10 \ fill block with command + atapi-packet-io ( ) \ send CDB, get return-buffer + return-buffer scsi-get-capacity-10 ( cdb -- block-size #blocks ) + .capacity-text ( block-size #blocks -- ) + status-check ( -- ) ; -: atapi-seek ( offset -- ) - packet-cb #cdb-bytes erase - scsi-cmd#seek packet-cb c! \ set command code 2bh - packet-cb 4 + l! - packet-buffer send-atapi-packet +\ *************************************** +\ read capacity of drive medium +\ use SCSI-Support Package +\ *************************************** +: atapi-read-capacity-ext ( -- ) + packet-cdb scsi-build-read-cap-16 \ fill block with command + atapi-packet-io ( ) \ send CDB, get return-buffer + return-buffer scsi-get-capacity-16 ( cdb -- block-size #blocks ) + .capacity-text ( block-size #blocks -- ) + status-check ( -- ) ; -: atapi-start ( cmd -- ) - packet-cb #cdb-bytes erase - 1b packet-cb c! - packet-cb 4 + c! - packet-buffer send-atapi-packet -; - -: atapi-toc ( -- ) - packet-cb #cdb-bytes erase - 43 packet-cb c! - 200 packet-cb 7 + w! - packet-buffer send-atapi-packet -; - -: atapi-read ( offset cnt -- ) - packet-cb #cdb-bytes erase - scsi-cmd#read10 packet-cb c! \ set command code 28h - packet-cb 7 + w! \ 2 bytes: Transfer Length - packet-cb 2 + l! \ 4 bytes: Block-Address - packet-buffer send-atapi-packet -; - -: atapi-read-blocks ( address block# #blocks dev# -- #read-blocks ) - set-regs ( dev# -- ) - dup >r - packet-cb #cdb-bytes erase - scsi-cmd#read10 packet-cb c! \ set command code 28h - packet-cb 7 + w! \ 2 bytes: Transfer Length - packet-cb 2 + l! \ 4 bytes: Block-Address - send-atapi-packet - r> -; \ *********************************************** \ wait until media in drive is ready ( max 5 sec) \ *********************************************** -: wait-for-media-ready ( -- true|false ) - get-msecs \ initial timer value (start) +: wait-for-media-ready ( -- true|false ) + get-msecs \ initial timer value (start) >r BEGIN - atapi-test \ unit ready? false if not + atapi-test \ unit ready? false if not not no-timeout and WHILE - atapi-sense ( -- asc sensekey ) - 02 = \ sense key 2 = media error - IF \ check add. sense code - 3A = IF false to no-timeout ." empty" THEN \ medium not present, abort waiting + atapi-sense ( -- ascq asc sense-key ) + 02 = \ sense key 2 = media error + IF \ check add. sense code + 3A = \ asc: device not ready ? + IF + false to no-timeout + ." empty (" . 29 emit \ show asc qualifier + ELSE + drop \ discard asc qualifier + THEN \ medium not present, abort waiting ELSE - drop \ discard add. sense code - THEN - get-msecs r@ - \ calculate timer difference - FFFF AND \ mask-off overflow bits - d# 5000 > \ 5 seconds exceeded ? + drop \ discard asc + drop \ discard ascq + THEN + get-msecs r@ - \ calculate timer difference + FFFF AND \ mask-off overflow bits + d# 5000 > \ 5 seconds exceeded ? IF - false to no-timeout \ set global flag + false to no-timeout \ set global flag THEN REPEAT r> @@ -511,7 +494,7 @@ A8 CONSTANT scsi-cmd#read12 \ 2 channels (primary/secondary) per controller 2 CONSTANT #chan -\ 2 devices (master/slacve) per channel +\ 2 devices (master/slave) per channel 2 CONSTANT #dev \ results in a total of devices @@ -522,8 +505,8 @@ A8 CONSTANT scsi-cmd#read12 CREATE read-blocks-xt #totaldev cells allot read-blocks-xt #totaldev cells erase \ Execute read-blocks of device -: dev-read-blocks ( address block# #blocks dev# -- #read-blocks ) - dup cells read-blocks-xt + @ execute +: dev-read-blocks ( address block# #blocks dev# -- #read-blocks ) + dup cells read-blocks-xt + @ execute ; \ ********************************************************** @@ -538,12 +521,12 @@ CREATE read-blocks-xt #totaldev cells allot read-blocks-xt #totaldev cells erase \ see also ATA/ATAPI errata at: \ http://suif.stanford.edu/~csapuntz/blackmagic.html \ ********************************************************** -: read-ident ( -- true|false ) +: read-ident ( -- true|false ) false - 00 ata-lbal! \ clear previous signature + 00 ata-lbal! \ clear previous signature 00 ata-lbam! 00 ata-lbah! - cmd#identify-device ata-cmd! wait-for-ready \ first try ATA, ATAPI aborts command + cmd#identify-device ata-cmd! wait-for-ready \ first try ATA, ATAPI aborts command ata-stat@ CF and 48 = IF drop true \ cmd accepted, this is a ATA @@ -574,6 +557,9 @@ CREATE read-blocks-xt #totaldev cells allot read-blocks-xt #totaldev cells erase THEN ; +scsi-close \ remove scsi commands from word list + + \ ************************************************* \ Init controller ( chan 0 and 1 ) \ device 0 (= master) and device 1 ( = slave) @@ -584,12 +570,11 @@ CREATE read-blocks-xt #totaldev cells allot read-blocks-xt #totaldev cells erase \ 1 0 2 Slave of Channel 0 \ 1 1 3 Slave of Channel 1 \ ************************************************* - : find-disks ( -- ) #chan 0 DO \ check 2 channels (primary & secondary) #dev 0 DO \ check 2 devices per channel (master / slave) - i 2 * j + set-regs \ set base address and dev-register for register access - 02 ata-ctrl! \ disable interrupts + i 2 * j + + set-regs \ set base address and dev-register for register access ata-stat@ 7f and 7f <> \ Check, if device is connected IF true to no-timeout \ preset timeout-flag @@ -601,15 +586,16 @@ CREATE read-blocks-xt #totaldev cells allot read-blocks-xt #totaldev cells erase wait-for-media-ready \ wait up to 5 sec if not ready no-timeout and IF - 800 to block-size \ ATAPI: 2048 bytes + atapi-read-capacity + atapi-size to block-size \ ATAPI: 2048 bytes 80000 to max-transfer - ['] atapi-read-blocks i 2 * j + cells read-blocks-xt + ! + ['] atapi-read-blocks i 2 * j + cells read-blocks-xt + ! s" cdrom" strdup i 2 * j + s" generic-disk.fs" included ELSE ." -" \ show hint for not registered THEN ELSE - 200 to block-size \ ATA: 512 bytes + ata-size to block-size \ ATA: 512 bytes 80000 to max-transfer ['] ata-read-blocks i 2 * j + cells read-blocks-xt + ! s" disk" strdup i 2 * j + s" generic-disk.fs" included @@ -617,9 +603,10 @@ CREATE read-blocks-xt #totaldev cells allot read-blocks-xt #totaldev cells erase cr THEN THEN + i 2 * j + 200 + cp LOOP LOOP -; +; find-disks diff --git a/slof/fs/instance.fs b/slof/fs/instance.fs index 22be971..67c5b06 100644 --- a/slof/fs/instance.fs +++ b/slof/fs/instance.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/little-endian.fs b/slof/fs/little-endian.fs index 76ce370..cc9e7f2 100644 --- a/slof/fs/little-endian.fs +++ b/slof/fs/little-endian.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/loaders.fs b/slof/fs/loaders.fs index b799692..8bf8163 100644 --- a/slof/fs/loaders.fs +++ b/slof/fs/loaders.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -10,47 +10,63 @@ \ * IBM Corporation - initial implementation \ ****************************************************************************/ +\ \\\\\\\\\\\\\\ Global Data +CREATE bootdevice 2 cells allot bootdevice 2 cells erase +CREATE bootargs 2 cells allot bootargs 2 cells erase +CREATE load-list 2 cells allot load-list 2 cells erase : start-elf ( arg len entry -- ) - msr@ 7fffffffffffffff and 2000 or ciregs >srr1 ! call-client ; + msr@ 7fffffffffffffff and 2000 or ciregs >srr1 ! call-client +; : start-elf64 ( arg len entry -- ) - msr@ 2000 or ciregs >srr1 ! - dup 8 + @ ciregs >r2 ! @ call-client ; \ entry point is pointer to .opd + msr@ 2000 or ciregs >srr1 ! + dup 8 + @ ciregs >r2 ! @ call-client \ entry point is pointer to .opd +; 10000000 VALUE LOAD-BASE 2000000 VALUE FLASH-LOAD-BASE -: set-bootpath s" disk" find-alias - dup IF ELSE drop s" boot-device" evaluate find-alias THEN - dup IF strdup ELSE 0 THEN - encode-string s" bootpath" set-chosen ; +: set-bootpath + s" disk" find-alias + dup IF ELSE drop s" boot-device" evaluate find-alias THEN + dup IF strdup ELSE 0 THEN + encode-string s" bootpath" set-chosen +; -: set-netbootpath s" net" find-alias - ?dup IF strdup encode-string s" bootpath" set-chosen THEN ; +: set-netbootpath + s" net" find-alias + ?dup IF strdup encode-string s" bootpath" set-chosen THEN +; -: set-bootargs skipws 0 parse dup 0= IF 2drop s" boot-file" - evaluate THEN encode-string s" bootargs" set-chosen ; +: set-bootargs + skipws 0 parse dup 0= IF + 2drop s" boot-file" evaluate + THEN + encode-string s" bootargs" set-chosen +; : .(client-exec) ( arg len -- rc ) - s" snk" romfs-lookup 0<> IF load-elf-file drop start-elf64 client-data - ELSE 2drop false THEN ; + s" snk" romfs-lookup 0<> IF load-elf-file drop start-elf64 client-data + ELSE 2drop false THEN +; ' .(client-exec) to (client-exec) : .client-exec ( arg len -- rc ) set-bootargs (client-exec) ; ' .client-exec to client-exec : netflash ( -- rc ) s" netflash 2000000 " (parse-line) $cat set-netbootpath - client-exec ; + client-exec +; : netsave ( "addr len {filename}[,params]" -- rc ) - (parse-line) dup 0> IF - s" netsave " 2swap $cat set-netbootpath client-exec - ELSE - cr - ." Usage: netsave addr len [bootp|dhcp,]filename[,siaddr][,ciaddr][,giaddr][,bootp-retries][,tftp-retries][,use_ci]" - cr 2drop - THEN + (parse-line) dup 0> IF + s" netsave " 2swap $cat set-netbootpath client-exec + ELSE + cr + ." Usage: netsave addr len [bootp|dhcp,]filename[,siaddr][,ciaddr][,giaddr][,bootp-retries][,tftp-retries][,use_ci]" + cr 2drop + THEN ; : ping ( "{device-path:[device-args,]server-ip,[client-ip],[gateway-ip][,timeout]}" -- ) @@ -69,3 +85,8 @@ THEN r> set-node r> to my-self \ Restore my-self ; + +: modforth ( -- rc ) + romfs-base eregs 80 + ! + s" forth" (client-exec) +; diff --git a/slof/fs/logging.fs b/slof/fs/logging.fs index 293a013..4a31b50 100644 --- a/slof/fs/logging.fs +++ b/slof/fs/logging.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -25,8 +25,12 @@ defer nvramlog-write-byte ' .nvramlog-write-byte to nvramlog-write-byte : nvramlog-write-string ( str len -- ) - 0 DO dup c@ - nvramlog-write-byte char+ LOOP drop ; + dup 0> IF + 0 DO dup c@ + nvramlog-write-byte char+ LOOP + ELSE + drop + THEN drop ; : nvramlog-write-number ( number format -- ) 0 swap <# 0 ?DO # LOOP #> diff --git a/slof/fs/node.fs b/slof/fs/node.fs index b632d65..8f587b2 100644 --- a/slof/fs/node.fs +++ b/slof/fs/node.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -85,13 +85,50 @@ CREATE $indent 100 allot VARIABLE indent 0 indent ! \ Unit address. : #address-cells s" #address-cells" rot parent get-property - ABORT" parent doesn't have a #address-cells property!" - decode-int nip nip ; -: my-#address-cells get-node #address-cells ; \ bit of a misnomer... "my-" + ABORT" parent doesn't have a #address-cells property!" + decode-int nip nip +; + +\ my-#address-cells returns the #address-cells property of the parent node. +\ child-#address-cells returns the #address-cells property of the current node. + +\ This is confusing in several ways: Remember that a node's address is always +\ described in the parent's address space, thus the parent's property is taken +\ into regard, rather than the own. + +\ Also, an address-cell here is always a 32bit cell, no matter whether the +\ "real" cell size is 32bit or 64bit. + +: my-#address-cells ( -- #address-cells ) + get-node #address-cells +; + +: child-#address-cells ( -- #address-cells ) + s" #address-cells" get-node get-property + ABORT" node doesn't have a #address-cells property!" + decode-int nip nip +; -: encode-phys ( phys.hi ... phys.low -- str len ) +: child-#size-cells ( -- #address-cells ) + s" #size-cells" get-node get-property + ABORT" node doesn't have a #size-cells property!" + decode-int nip nip +; + +: encode-phys ( phys.hi ... phys.low -- prop len ) + encode-first? IF encode-start ELSE here 0 THEN + my-#address-cells 0 ?DO rot encode-int+ LOOP +; + +: encode-child-phys ( phys.hi ... phys.low -- prop len ) encode-first? IF encode-start ELSE here 0 THEN - my-#address-cells 0 ?DO rot encode-int+ LOOP ; + child-#address-cells 0 ?DO rot encode-int+ LOOP +; + +: encode-child-size ( size.hi ... size.low -- prop len ) + encode-first? IF encode-start ELSE here 0 THEN + child-#size-cells 0 ?DO rot encode-int+ LOOP +; : decode-phys my-#address-cells BEGIN dup WHILE 1- >r decode-int r> swap >r REPEAT drop diff --git a/slof/fs/nvram.fs b/slof/fs/nvram.fs index 5d8344b..322d858 100644 --- a/slof/fs/nvram.fs +++ b/slof/fs/nvram.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -10,65 +10,79 @@ \ * IBM Corporation - initial implementation \ ****************************************************************************/ -: rztype ( str len -- ) \ stop at zero byte, read with rb@ - BEGIN dup WHILE swap dup rb@ dup WHILE - emit char+ swap 1- REPEAT drop THEN 2drop ; - -: rtype ( str len -- ) - 0 DO dup rb@ emit char+ LOOP drop ; - -: mrzplace ( str len buf -- ) 2dup + 0 swap rb! swap mrmove ; +51 CONSTANT nvram-partition-type-cpulog +\ types 53-55 are omitted because they have been used for +\ storing binary tables in the past +60 CONSTANT nvram-partition-type-sas +61 CONSTANT nvram-partition-type-sms +6e CONSTANT nvram-partition-type-debug +6f CONSTANT nvram-partition-type-history +70 CONSTANT nvram-partition-type-common +7f CONSTANT nvram-partition-type-freespace +a0 CONSTANT nvram-partition-type-linux + +: rztype ( str len -- ) \ stop at zero byte, read with nvram-c@ + 0 DO + dup i + nvram-c@ ?dup IF ( str char ) + emit + ELSE ( str ) + drop UNLOOP EXIT + THEN + LOOP +; create tmpStr 500 allot : rzcount ( zstr -- str len ) - dup tmpStr >r BEGIN dup rb@ dup r> dup 1+ >r c! WHILE char+ REPEAT - r> drop over - swap drop tmpStr swap ; - -: >nvram nvram-base + ; + dup tmpStr >r BEGIN + dup nvram-c@ dup r> dup 1+ >r c! + WHILE + char+ + REPEAT + r> drop over - swap drop tmpStr swap +; : calc-header-cksum ( offset -- cksum ) - >nvram dup rb@ + dup nvram-c@ 10 2 DO - over i + rb@ + + over I + nvram-c@ + LOOP wbsplit + nip ; : bad-header? ( offset -- flag ) - dup >nvram 2+ rw@ ( offset length ) + dup 2+ nvram-w@ ( offset length ) 0= IF ( offset ) drop true EXIT ( ) THEN dup calc-header-cksum ( offset checksum' ) - swap >nvram 1+ rb@ ( checksum ' checksum ) + swap 1+ nvram-c@ ( checksum ' checksum ) <> ( flag ) ; : .header ( offset -- ) - cr ( offset ) - dup bad-header? IF ( offset ) + cr ( offset ) + dup bad-header? IF ( offset ) ." BAD HEADER -- trying to print it anyway" cr THEN - space >nvram ( adr ) + space ( offset ) \ print type - dup rb@ 2 0.r ( adr ) - space space ( adr ) + dup nvram-c@ 2 0.r ( offset ) + space space ( offset ) \ print length - dup 2+ rw@ 10 * 5 .r ( adr ) - space space ( adr ) + dup 2+ nvram-w@ 10 * 5 .r ( offset ) + space space ( offset ) \ print name - 4 + 0c rztype ( ) + 4 + 0c rztype ( ) ; : .headers ( -- ) cr cr ." Type Size Name" cr ." ========================" 0 BEGIN ( offset ) - dup >nvram ( offset adr ) - rb@ ( offset type ) + dup nvram-c@ ( offset type ) WHILE dup .header ( offset ) - dup >nvram 2+ rw@ 10 * + ( offset offset' ) + dup 2+ nvram-w@ 10 * + ( offset offset' ) dup nvram-size < IF ( offset ) ELSE drop EXIT ( ) @@ -78,182 +92,98 @@ create tmpStr 500 allot cr cr ; -: find-header ( type -- offset false | true ) - 0 >r ( type R: offset ) - BEGIN - r@ >nvram ( type adr ) ( R: offset ) - rb@ 2dup ( type sig type sig ) ( R: offset ) - = IF ( type sig ) ( R: offset ) - 2drop r> false EXIT ( offset false ) - THEN - WHILE - r> dup ( type offset offset ) - bad-header? IF ( type offset ) - 2drop true EXIT ( true ) - THEN - dup >nvram 2+ rw@ 10 * ( tyoe offset length ) - + >r ( type ) ( R: offset' ) - REPEAT - r> 2drop true ( true ) +: reset-nvram ( -- ) + internal-reset-nvram ; -: get-header ( type -- data len false | true ) - find-header ?dup IF ( offset false | true ) - EXIT ( true ) - THEN - dup ( offset offset ) - bad-header? ?dup IF ( offset true | offset ) - nip EXIT ( true ) - THEN - >nvram ( adr ) - dup 10 + swap ( adr' adr ) - 2+ rw@ 1- 10 * ( adr length ) - false ( adr length true ) -; +: dump-partition ['] nvram-c@ 1 (dump) ; -\ FIXME: This function should return if it succeeded! -: add-header ( type size name len -- ) - rot dup >r 10 / ( type name len size/10 R:size ) - 7f get-header IF ( type name len size/10 R:size ) - r> drop 4drop - ." couldn't find free partition" \ FIXME this should be a warning!!! - EXIT - THEN - r> 2dup <= IF - 2drop 2drop 3drop - ." couldn't find space in free partition" - EXIT - THEN - - 10 + 10 / >r dup e - r> swap rw! \ write new free size - 10 - dup dup nvram-base - calc-header-cksum swap 1+ rb! - dup 2+ rw@ 10 * + \ now we are on next header offset - dup >r 2+ rw! \ write new size - rot r@ rb! \ write type - r@ 4 + mrzplace \ write name - r@ nvram-base - calc-header-cksum r> 1+ rb! +: type-no-zero ( addr len -- ) + 0 DO + dup I + dup nvram-c@ 0= IF drop ELSE nvram-c@ emit THEN + LOOP + drop ; -: create-header ( type size name len -- ) - 0 find-header ABORT" couldn't find space for new NVRAM partition" - \ write name - dup >r >nvram 4 + mrzplace ( type size ) ( R: offset ) - \ adr of first byte behind partition - r@ >nvram over + ( type size adr' ) ( R: offset ) - \ clear first byte behind new partition - dup nvram-size >nvram < IF ( type size adr' ) ( R: offset ) - 0 swap rb! ( type size ) ( R: offset ) - ELSE - drop ( type size ) ( R: offset ) - THEN - \ write size - 10 / r@ >nvram 2+ rw! ( type ) ( R: offset ) - \ write type - dup r@ >nvram rb! ( type ) ( R: offset ) - \ write checksum - r@ calc-header-cksum ( type cksum ) ( R: offset) - r> >nvram 1+ rb! ( type ) - \ zero out partition - get-header drop 0 rfill ( ) +: type-no-zero-part ( from-str cnt-str addr len ) + 0 DO + dup i + dup nvram-c@ 0= IF + drop + ELSE + ( from-str cnt-str addr addr+i ) + ( from-str==0 AND cnt-str > 0 ) + 3 pick 0= 3 pick 0 > AND IF + dup 1 type-no-zero + THEN + + nvram-c@ a = IF + 2 pick 0= IF + over 1- 0 max + rot drop swap + THEN + 2 pick 1- 0 max + 3 roll drop rot rot + ( from-str-- cnt-str-- addr addr+i ) + THEN + THEN + LOOP + drop ; -: calc-used-nvram-space ( -- used ) - 0 dup >r BEGIN ( offset ) ( R: used ) - dup >nvram rb@ ( offset sig ) ( R: used ) - WHILE - dup >nvram 2+ rw@ 10 * ( offset length ) ( R: used ) - r> + >r ( offset ) ( R: used ) - dup >nvram 2+ rw@ 10 * ( offset length ) ( R: used ) - + ( offset' ) ( R: used ) - REPEAT - drop r> ( used ) +: (dmesg-prepare) ( base-addr -- base-addr' addr len act-off ) + 10 - \ go back to header + dup 14 + nvram-l@ dup >r + ( base-addr act-off ) ( R: act-off ) + over over over + swap 10 + nvram-w@ + >r + ( base-addr act-off ) ( R: act-off nvram-act-addr ) + over 2 + nvram-w@ 10 * swap - over swap + ( base-addr base-addr start-size ) ( R: act-off nvram-act-addr ) + r> swap rot 10 + nvram-w@ - r> ; -: create-default-headers - s" Creating common NVRAM partition" nvramlog-write-string-cr - 70 1000 s" common" create-header ( ) - \ calculate free partition - nvram-size calc-used-nvram-space - ( free ) - dup 1 < IF ( free ) - drop ( ) - ELSE - s" Creating free space NVRAM partition with 0x" nvramlog-write-string - dup 6 nvramlog-write-number ( free ) - s" bytes" nvramlog-write-string-cr - 7f swap ( 7f type ) - here 10 allot ( 7f type adr ) - 10 0 DO - dup i + FF swap c! ( 7f type adr ) - LOOP - e create-header ( ) - THEN +: .dmesg ( base-addr -- ) + (dmesg-prepare) >r + ( base-addr addr len ) + cr type-no-zero + ( base-addr ) ( R: act-off ) + dup 10 + nvram-w@ + r> type-no-zero ; -: reset-nvram ( -- ) - nvram-base nvram-size 0 rfill ( ) - 51 20000 s" ibm,BE0log" create-header ( ) - 51 5000 s" ibm,BE1log" create-header ( ) - nvram-base 10 + dup ( adr adr ) - 1 swap x! ( adr ) - 40 swap w! ( ) - 20000 nvram-base + 10 + dup ( adr adr ) - 1 swap x! ( adr ) - 40 swap w! ( ) - create-default-headers ( ) +: .dmesg-part ( from-str cnt-str base-addr -- ) + (dmesg-prepare) >r + ( from-str cnt-str base-addr addr len ) + >r >r -rot r> r> + ( base-addr from-str cnt-str addr len ) + cr type-no-zero-part rot + ( base-addr ) ( R: act-off ) + dup 10 + nvram-w@ + r> type-no-zero-part ; -: type-no-zero ( addr len -- ) - 0 do dup i + dup rb@ 0= IF drop ELSE 1 rtype THEN loop drop ; - -: .dmesg ( base-addr -- ) dup 14 + rl@ dup >r - ( base-addr act-off ) ( R: act-off ) - over over over + swap 10 + rw@ + >r - ( base-addr act-off ) ( R: act-off nvram-act-addr ) - over 2 + rw@ 10 * swap - over swap - ( base-addr base-addr start-size ) ( R: act-off nvram-act-addr ) - r> swap rot 10 + rw@ - cr type-no-zero - ( base-addr ) ( R: act-off ) - dup 10 + rw@ + r> type-no-zero ; - - -: type-no-zero-part ( from-str cnt-str addr len ) - 0 do - dup i + dup c@ 0= IF - drop - ELSE - ( from-str cnt-str addr addr+i ) - ( from-str==0 AND cnt-str > 0 ) - 3 pick 0= 3 pick 0 > AND IF - dup 1 type +: dmesg-part ( from-str cnt-str -- left-from-str left-cnt-str ) + 2dup + s" ibm,BE0log" get-named-nvram-partition IF + s" ibm,CPU0log" get-named-nvram-partition IF + 2drop EXIT THEN + THEN + drop .dmesg-part nip nip +; - c@ a = IF - 2 pick 0= IF - over 1- 0 max - rot drop swap - THEN - 2 pick 1- 0 max - 3 roll drop rot rot - ( from-str-- cnt-str-- addr addr+i ) +: dmesg2 ( -- ) + s" ibm,BE1log" get-named-nvram-partition IF + s" ibm,CPU1log" get-named-nvram-partition IF + ." No log partition." cr EXIT THEN - THEN - loop drop ; - -: .dmesg-part ( from-str cnt-str base-addr -- ) dup 14 + l@ dup >r - ( base-addr act-off ) ( R: act-off ) - over over over + swap 10 + w@ + >r - ( base-addr act-off ) ( R: act-off nvram-act-addr ) - over 2 + w@ 10 * swap - over swap - ( base-addr base-addr start-size ) ( R: act-off nvram-act-addr ) - r> swap rot 10 + w@ - cr - rot 4 roll 4 roll 4 roll 4 roll - ( base-addr from-str cnt-str addr len ) - type-no-zero-part rot - ( base-addr ) ( R: act-off ) - dup 10 + w@ + r> type-no-zero-part ; - -: dmesg-part ( from-str cnt-str -- from-str cnt-str ) - 2dup nvram-base .dmesg-part nip nip ; + THEN + drop .dmesg +; -: dmesg ( -- ) nvram-base .dmesg ; +: dmesg ( -- ) + s" ibm,BE0log" get-named-nvram-partition IF + s" ibm,CPU0log" get-named-nvram-partition IF + ." No log partition." cr EXIT + THEN + THEN + drop .dmesg +; -: dmesg2 ( -- ) nvram-log-be1-base .dmesg ; diff --git a/slof/fs/packages.fs b/slof/fs/packages.fs index 3b222be..a31be2e 100644 --- a/slof/fs/packages.fs +++ b/slof/fs/packages.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -51,9 +51,9 @@ new-device #include "packages/iso-9660.fs" finish-device -new-device -#include "packages/scsi.fs" -finish-device +\ new-device +\ #include "packages/scsi.fs" +\ finish-device new-device #include "packages/bulk.fs" diff --git a/slof/fs/packages/bulk.fs b/slof/fs/packages/bulk.fs index 3ee48a0..06d7eae 100644 --- a/slof/fs/packages/bulk.fs +++ b/slof/fs/packages/bulk.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/packages/deblocker.fs b/slof/fs/packages/deblocker.fs index 92b4862..0b29079 100644 --- a/slof/fs/packages/deblocker.fs +++ b/slof/fs/packages/deblocker.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/packages/disk-label.fs b/slof/fs/packages/disk-label.fs index 6079555..ca4b5b4 100644 --- a/slof/fs/packages/disk-label.fs +++ b/slof/fs/packages/disk-label.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/packages/ext2-files.fs b/slof/fs/packages/ext2-files.fs index d33f0e6..454e919 100644 --- a/slof/fs/packages/ext2-files.fs +++ b/slof/fs/packages/ext2-files.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/packages/fat-files.fs b/slof/fs/packages/fat-files.fs index 07c0f7e..76d9f51 100644 --- a/slof/fs/packages/fat-files.fs +++ b/slof/fs/packages/fat-files.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/packages/filler.fs b/slof/fs/packages/filler.fs index c32c84c..bd5c17a 100644 --- a/slof/fs/packages/filler.fs +++ b/slof/fs/packages/filler.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/packages/iso-9660.fs b/slof/fs/packages/iso-9660.fs index 7927381..6db3d8d 100644 --- a/slof/fs/packages/iso-9660.fs +++ b/slof/fs/packages/iso-9660.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/packages/obp-tftp.fs b/slof/fs/packages/obp-tftp.fs index affbe5c..6bb43c9 100644 --- a/slof/fs/packages/obp-tftp.fs +++ b/slof/fs/packages/obp-tftp.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -38,6 +38,9 @@ INSTANCE VARIABLE ciregs-buffer \ Allocate 1720 bytes to store the BOOTP-REPLY packet 6B8 alloc-mem dup >r (u.) $cat s" " $cat huge-tftp-load @ IF s" 1 " ELSE s" 0 " THEN $cat + \ Add desired TFTP-Blocksize as additional argument + s" 1432 " $cat + \ Add OBP-TFTP Bootstring argument, e.g. "10.128.0.1,bootrom.bin,10.128.40.1" my-args $cat \ Call SNK netboot loadr diff --git a/slof/fs/packages/rom-files.fs b/slof/fs/packages/rom-files.fs index 2a93e0a..418cf4e 100644 --- a/slof/fs/packages/rom-files.fs +++ b/slof/fs/packages/rom-files.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/packages/sms.fs b/slof/fs/packages/sms.fs index 7df46c0..d8c672f 100644 --- a/slof/fs/packages/sms.fs +++ b/slof/fs/packages/sms.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -11,24 +11,19 @@ \ ****************************************************************************/ -s" sms.fs" romfs-lookup [IF] - drop +s" /packages" find-device - s" /packages" find-device +new-device + s" sms" device-name - new-device + : open true ; - s" sms" device-name + : close ; - : open true ; + \ The rest of methods is loaded dynamically from the romfs + \ on a first call to sms-start - : close ; +finish-device - \ The rest of methods is loaded dynamically from the romfs - \ on a first call to sms-start - - finish-device - - device-end -[THEN] +device-end \ leave /packages diff --git a/slof/fs/pci-bridge.fs b/slof/fs/pci-bridge.fs index 140f37a..81bfca1 100644 --- a/slof/fs/pci-bridge.fs +++ b/slof/fs/pci-bridge.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/pci-class-code-names.fs b/slof/fs/pci-class-code-names.fs index a511c41..4156fba 100644 --- a/slof/fs/pci-class-code-names.fs +++ b/slof/fs/pci-class-code-names.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/pci-config-bridge.fs b/slof/fs/pci-config-bridge.fs index e8d1f49..f813431 100644 --- a/slof/fs/pci-config-bridge.fs +++ b/slof/fs/pci-config-bridge.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/pci-device.fs b/slof/fs/pci-device.fs index c8b445e..fbb4c61 100644 --- a/slof/fs/pci-device.fs +++ b/slof/fs/pci-device.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/pci-properties.fs b/slof/fs/pci-properties.fs index aab8f13..312f431 100644 --- a/slof/fs/pci-properties.fs +++ b/slof/fs/pci-properties.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/pci-scan.fs b/slof/fs/pci-scan.fs index 5096e68..454631e 100644 --- a/slof/fs/pci-scan.fs +++ b/slof/fs/pci-scan.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -493,7 +493,3 @@ DEFER func-pci-probe-bus \ provide all words needed to generate the properties and/or assign BAR values #include "pci-properties.fs" -\ provide all words implementing lspci functionality -#if defined(ELBA) || defined(MALTA) -#include "pci-lspci.fs" -#endif diff --git a/slof/fs/preprocessor.fs b/slof/fs/preprocessor.fs index 5bab531..a13fb30 100644 --- a/slof/fs/preprocessor.fs +++ b/slof/fs/preprocessor.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/property.fs b/slof/fs/property.fs index d8b97ac..c02a07d 100644 --- a/slof/fs/property.fs +++ b/slof/fs/property.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/quiesce.fs b/slof/fs/quiesce.fs index 7521d1c..3b2dee9 100644 --- a/slof/fs/quiesce.fs +++ b/slof/fs/quiesce.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -22,12 +22,18 @@ quiesce-xts quiesce-xt# cells erase : add-quiesce-xt ( xt -- ) quiesce-xt# 0 DO quiesce-xts I cells + ( xt arrayptr ) - dup @ 0= IF ( xt arrayptr ) + dup @ 0= ( xt arrayptr true|false ) + IF ! UNLOOP EXIT - ELSE - drop ( xt ) + ELSE ( xt arrayptr ) + over swap ( xt xt arrayptr ) + @ = \ xt already stored ? + IF + drop UNLOOP EXIT + THEN ( xt ) THEN LOOP + drop ( xt -- ) ." Warning: quiesce xt list is full." cr ; diff --git a/slof/fs/rmove.fs b/slof/fs/rmove.fs index aafc2f6..c28dba9 100644 --- a/slof/fs/rmove.fs +++ b/slof/fs/rmove.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/romfs.fs b/slof/fs/romfs.fs index 29fa80d..b5210fe 100644 --- a/slof/fs/romfs.fs +++ b/slof/fs/romfs.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -10,8 +10,6 @@ \ * IBM Corporation - initial implementation \ ****************************************************************************/ -eregs 10 8 * + @ CONSTANT romfs-base - STRUCT cell field romfs>file-header cell field romfs>data @@ -77,11 +75,11 @@ CREATE bdate-str 10 allot dup 6 + bdate-str 3 + 2 move dup 8 + bdate-str b + 2 move a + bdate-str e + 2 move - 2d bdate-str 2 + c! + 2d bdate-str 2 + c! 2d bdate-str 5 + c! 20 bdate-str a + c! 3a bdate-str d + c! - bdate-str 10 + bdate-str 10 ; diff --git a/slof/fs/root.fs b/slof/fs/root.fs index 67df811..429b77e 100644 --- a/slof/fs/root.fs +++ b/slof/fs/root.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/rtas/rtas-cpu.fs b/slof/fs/rtas/rtas-cpu.fs index 54aac7b..c133abc 100644 --- a/slof/fs/rtas/rtas-cpu.fs +++ b/slof/fs/rtas/rtas-cpu.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -21,19 +21,3 @@ enter-rtas rtas-cb rtas>args3 l@ ; - -: rtas-freeze-timebase ( -- status ) - [ s" freeze-time-base" rtas-get-token ] LITERAL rtas-cb rtas>token l! - 0 rtas-cb rtas>nargs l! - 1 rtas-cb rtas>nret l! - enter-rtas - rtas-cb rtas>args0 l@ -; - -: rtas-thaw-timebase ( -- status ) - [ s" thaw-time-base" rtas-get-token ] LITERAL rtas-cb rtas>token l! - 0 rtas-cb rtas>nargs l! - 1 rtas-cb rtas>nret l! - enter-rtas - rtas-cb rtas>args0 l@ -; diff --git a/slof/fs/rtas/rtas-flash.fs b/slof/fs/rtas/rtas-flash.fs index fb4bc6e..f8abeaa 100644 --- a/slof/fs/rtas/rtas-flash.fs +++ b/slof/fs/rtas/rtas-flash.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/rtas/rtas-init.fs b/slof/fs/rtas/rtas-init.fs index c98fe6d..8451cfd 100644 --- a/slof/fs/rtas/rtas-init.fs +++ b/slof/fs/rtas/rtas-init.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -25,7 +25,7 @@ dup rtas-size erase s" rtas" romfs-lookup 0= ABORT" romfs-lookup for rtas failed" - hsprg1 swap start-rtas ; + rtas-config swap start-rtas ; here fff + fffffffffffff000 and here - allot here rtas-size allot CONSTANT rtas-start-addr diff --git a/slof/fs/rtas/rtas-reboot.fs b/slof/fs/rtas/rtas-reboot.fs index c20f80e..a9539ec 100644 --- a/slof/fs/rtas/rtas-reboot.fs +++ b/slof/fs/rtas/rtas-reboot.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/rtas/rtas-vpd.fs b/slof/fs/rtas/rtas-vpd.fs index 2191ee9..7fb4b54 100644 --- a/slof/fs/rtas/rtas-vpd.fs +++ b/slof/fs/rtas/rtas-vpd.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/scsi-loader.fs b/slof/fs/scsi-loader.fs new file mode 100644 index 0000000..406c184 --- /dev/null +++ b/slof/fs/scsi-loader.fs @@ -0,0 +1,77 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2008 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ * IBM Corporation - initial implementation +\ ****************************************************************************/ + +\ ************************************** +\ Last change: MiR 13.11.2007 10:55:57 +\ ************************************** + +: .ansi-attr-off 1b emit ." [0m" ; \ ESC Sequence: all terminal atributes off +: .ansi-blue 1b emit ." [34m" ; \ ESC Sequence: foreground-color = blue +: .ansi-green 1b emit ." [32m" ; \ ESC Sequence: foreground-color = green +: .ansi-red 1b emit ." [31m" ; \ ESC Sequence: foreground-color = green +: .ansi-bold 1b emit ." [1m" ; \ ESC Sequence: foreground-color bold + +false VALUE scsi-supp-present? + +: scsi-xt-err ." SCSI-ERROR (Intern) " ; +' scsi-xt-err VALUE scsi-open-xt \ preset with an invalid token + +\ ************************************* +\ utility to show all active word-lists +\ ************************************* +: .wordlists ( -- ) + .ansi-red + get-order ( -- wid1 .. widn n ) + dup space 28 emit .d ." word lists : " + 0 DO + . 08 emit 2c emit + LOOP + 08 emit \ 'bs' + 29 emit \ ')' + cr space 28 emit + ." Context: " context dup . + @ 5b emit . 8 emit 5d emit + space + ." / Current: " current . + .ansi-attr-off + cr +; + +\ ************************************* +\ utility to show first word-lists +\ ************************************* +: .context ( num -- ) + .ansi-red + space + 5b emit + 23 emit . 3a emit + context @ + . 8 emit 5d emit space + .ansi-attr-off +; + +\ **************************************************************************** +\ open scsi-support by adding a new word list on top of search path +\ first check if scsi-support.fs must be included (first call) +\ when open use execution pointer to access version in new word list +\ **************************************************************************** +: scsi-open ( -- ) + scsi-supp-present? NOT + IF + s" scsi-support.fs" included ( xt-open ) + to scsi-open-xt ( ) + true to scsi-supp-present? + THEN + scsi-open-xt execute +; + + diff --git a/slof/fs/scsi-support.fs b/slof/fs/scsi-support.fs new file mode 100644 index 0000000..7e4fd05 --- /dev/null +++ b/slof/fs/scsi-support.fs @@ -0,0 +1,781 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2008 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ * IBM Corporation - initial implementation +\ ****************************************************************************/ + +\ ************************************************ +\ create a new scsi word-list named 'scsi-words' +\ ************************************************ +vocabulary scsi-words \ create new word list named 'scsi-words' +also scsi-words definitions \ place next definitions into new list + +\ for some commands specific parameters are used, which normally +\ need not to be altered. These values are preset at include time +\ or explicit by a call of 'scsi-supp-init' +false value scsi-param-debug \ common debugging flag +d# 0 value scsi-param-size \ length of CDB processed last +h# 0 value scsi-param-control \ control word for CDBs as defined in SAM-4 +d# 0 value scsi-param-errors \ counter for detected errors + +\ utility to increment error counter +: scsi-inc-errors + scsi-param-errors 1 + to scsi-param-errors +; + +\ *************************************************************************** +\ SCSI-Command: TEST UNIT READY +\ Type: Primary Command (SPC-3 clause 6.33) +\ *************************************************************************** +\ Forth Word: scsi-build-test-unit-ready ( cdb -- ) +\ *************************************************************************** +\ checks if a device is ready to receive commands +\ *************************************************************************** +\ command code: +00 CONSTANT scsi-cmd-test-unit-ready +\ CDB structure: +STRUCT + /c FIELD test-unit-ready>operation-code \ 00h + 4 FIELD test-unit-ready>reserved \ unused + /c FIELD test-unit-ready>control \ control byte as specified in SAM-4 +CONSTANT scsi-length-test-unit-ready + +\ cdb build: +\ all fields are zeroed +: scsi-build-test-unit-ready ( cdb -- ) + dup scsi-length-test-unit-ready erase ( cdb ) + scsi-param-control swap test-unit-ready>control c! ( ) + scsi-length-test-unit-ready to scsi-param-size \ update CDB length +; + +\ *************************************************************************** +\ SCSI-Command: REQUEST SENSE +\ Type: Primary Command (SPC-3 clause 6.27) +\ *************************************************************************** +\ Forth Word: scsi-build-request-sense ( cdb -- ) +\ *************************************************************************** +\ for return data a buffer of at least 252 bytes must be present! +\ see spec: SPC-3 (r23) / clauses 4.5 and 6.27 +\ *************************************************************************** +\ command code: +03 CONSTANT scsi-cmd-request-sense +\ CDB structure: +STRUCT + /c FIELD request-sense>operation-code \ 03h + 3 FIELD request-sense>reserved \ unused + /c FIELD request-sense>allocation-length \ buffer-length for data response + /c FIELD request-sense>control \ control byte as specified in SAM-4 +CONSTANT scsi-length-request-sense + +\ cdb build: +: scsi-build-request-sense ( alloc-len cdb -- ) + >r ( alloc-len ) ( R: -- cdb ) + r@ scsi-length-request-sense erase ( alloc-len ) + scsi-cmd-request-sense r@ ( alloc-len cmd cdb ) + request-sense>operation-code c! ( alloc-len ) + dup d# 252 > \ buffer length too big ? + IF + scsi-inc-errors + drop d# 252 \ replace with 252 + ELSE + dup d# 18 < \ allocated buffer too small ? + IF + scsi-inc-errors + drop 0 \ reject return data + THEN + THEN ( alloclen ) + r@ request-sense>allocation-length c! ( ) + scsi-param-control r> request-sense>control c! ( alloc-len cdb ) ( R: cdb -- ) + scsi-length-request-sense to scsi-param-size \ update CDB length +; + +\ ---------------------------------------- +\ SCSI-Response: SENSE_DATA +\ ---------------------------------------- +70 CONSTANT scsi-response(request-sense-0) +71 CONSTANT scsi-response(request-sense-1) + +STRUCT + /c FIELD sense-data>response-code \ 70h (current errors) or 71h (deferred errors) + /c FIELD sense-data>obsolete + /c FIELD sense-data>sense-key \ D3..D0 = sense key, D7 = EndOfMedium + /l FIELD sense-data>info + /c FIELD sense-data>alloc-length \ <= 244 (for max size) + /l FIELD sense-data>command-info + /c FIELD sense-data>asc \ additional sense key + /c FIELD sense-data>ascq \ additional sense key qualifier + /c FIELD sense-data>unit-code + 3 FIELD sense-data>key-specific + /c FIELD sense-data>add-sense-bytes \ start of appended extra bytes +CONSTANT scsi-length-sense-data + +\ ---------------------------------------- +\ get from SCSI response block: +\ - Additional Sense Code Qualifier +\ - Additional Sense Code +\ - sense-key +\ ---------------------------------------- +\ Forth Word: scsi-get-sense-data ( addr -- ascq asc sense-key ) +\ ---------------------------------------- +: scsi-get-sense-data ( addr -- ascq asc sense-key ) + >r ( R: -- addr ) + r@ sense-data>ASCQ c@ ( ascq ) + r@ sense-data>ASC c@ ( ascq asc ) + r> sense-data>sense-key c@ 0f and ( ascq asc sense-key ) ( R: addr -- ) +; + +\ -------------------------------------------------------------------------- +\ Forth Word: scsi-get-sense-data? ( addr -- false | ascq asc sense-key true ) +\ -------------------------------------------------------------------------- +: scsi-get-sense-data? ( addr -- false | ascq asc sense-key true ) + dup + sense-data>response-code c@ + 7e AND 70 = \ Response code (some devices have MSB set) + IF + scsi-get-sense-data TRUE + ELSE + drop FALSE \ drop addr + THEN + +; + +\ -------------------------------------------------------------------------- +\ Forth Word: scsi-get-sense-ID? ( addr -- false | sense-ID true ) +\ same as scsi-get-sense-data? but returns +\ a single word composed of: sense-key<<16 | asc<<8 | ascq +\ -------------------------------------------------------------------------- +: scsi-get-sense-ID? ( addr -- false | ascq asc sense-key true ) + dup + sense-data>response-code c@ + 7e AND 70 = \ Response code (some devices have MSB set) + IF + scsi-get-sense-data ( ascq asc sense-key ) + 10 lshift ( ascq asc sense-key16 ) + swap 8 lshift or ( ascq sense-key+asc ) + swap or \ 24-bit sense-ID ( sense-key+asc+ascq ) + TRUE + ELSE + drop FALSE \ drop addr + THEN +; + +\ *************************************************************************** +\ SCSI-Command: INQUIRY +\ Type: Primary Command (SPC-3 clause 6.4) +\ *************************************************************************** +\ Forth Word: scsi-build-inquiry ( alloc-len cdb -- ) +\ *************************************************************************** +\ command code: +12 CONSTANT scsi-cmd-inquiry + +\ CDB structure +STRUCT + /c FIELD inquiry>operation-code \ 0x12 + /c FIELD inquiry>reserved \ + EVPD-Bit (vital product data) + /c FIELD inquiry>page-code \ page code for vital product data (if used) + /w FIELD inquiry>allocation-length \ length of Data-In-Buffer + /c FIELD inquiry>control \ control byte as specified in SAM-4 +CONSTANT scsi-length-inquiry + +\ Setup command INQUIRY +: scsi-build-inquiry ( alloc-len cdb -- ) + dup scsi-length-inquiry erase \ 6 bytes CDB + scsi-cmd-inquiry over ( alloc-len cdb cmd cdb ) + inquiry>operation-code c! ( alloc-len cdb ) + scsi-param-control over inquiry>control c! ( alloc-len cdb ) + inquiry>allocation-length w! \ size of Data-In Buffer + scsi-length-inquiry to scsi-param-size \ update CDB length +; + +\ ---------------------------------------- +\ block structure of inquiry return data: +\ ---------------------------------------- +STRUCT + /c FIELD inquiry-data>peripheral \ qualifier and device type + /c FIELD inquiry-data>reserved1 + /c FIELD inquiry-data>version \ supported SCSI version (1,2,3) + /c FIELD inquiry-data>data-format + /c FIELD inquiry-data>add-length \ total block length - 4 + /c FIELD inquiry-data>flags1 + /c FIELD inquiry-data>flags2 + /c FIELD inquiry-data>flags3 + d# 8 FIELD inquiry-data>vendor-ident \ vendor string + d# 16 FIELD inquiry-data>product-ident \ device string + /l FIELD inquiry-data>product-revision \ revision string + d# 20 FIELD inquiry-data>vendor-specific \ optional params +\ can be increased by vendor specific fields +CONSTANT scsi-length-inquiry-data + +\ *************************************************************************** +\ SCSI-Command: READ CAPACITY (10) +\ Type: Block Command (SBC-3 clause 5.12) +\ *************************************************************************** +\ Forth Word: scsi-build-read-capacity-10 ( cdb -- ) +\ *************************************************************************** +25 CONSTANT scsi-cmd-read-capacity-10 \ command code + +STRUCT \ SCSI 10-byte CDB structure + /c FIELD read-cap-10>operation-code + /c FIELD read-cap-10>reserved1 + /l FIELD read-cap-10>lba + /w FIELD read-cap-10>reserved2 + /c FIELD read-cap-10>reserved3 + /c FIELD read-cap-10>control +CONSTANT scsi-length-read-cap-10 + +\ Setup READ CAPACITY (10) command +: scsi-build-read-cap-10 ( cdb -- ) + dup scsi-length-read-cap-10 erase ( cdb ) + scsi-cmd-read-capacity-10 over ( cdb cmd cdb ) + read-cap-10>operation-code c! ( cdb ) + scsi-param-control swap read-cap-10>control c! ( ) + scsi-length-read-cap-10 to scsi-param-size \ update CDB length +; + +\ ---------------------------------------- +\ get from SCSI response block: +\ - Additional Sense Code Qualifier +\ - Additional Sense Code +\ - sense-key +\ ---------------------------------------- +\ Forth Word: scsi-get-capacity-10 ( addr -- block-size #blocks ) +\ ---------------------------------------- +\ Block structure +STRUCT + /l FIELD read-cap-10-data>max-lba + /l FIELD read-cap-10-data>block-size +CONSTANT scsi-length-read-cap-10-data + +\ get data-block +: scsi-get-capacity-10 ( addr -- block-size #blocks ) + >r ( addr -- ) ( R: -- addr ) + r@ read-cap-10-data>block-size l@ ( block-size ) + r> read-cap-10-data>max-lba l@ ( block-size #blocks ) ( R: addr -- ) +; + +\ *************************************************************************** +\ SCSI-Command: READ CAPACITY (16) +\ Type: Block Command (SBC-3 clause 5.13) +\ *************************************************************************** +\ Forth Word: scsi-build-read-capacity-16 ( cdb -- ) +\ *************************************************************************** +9e CONSTANT scsi-cmd-read-capacity-16 \ command code + +STRUCT \ SCSI 16-byte CDB structure + /c FIELD read-cap-16>operation-code + /c FIELD read-cap-16>service-action + /l FIELD read-cap-16>lba-high + /l FIELD read-cap-16>lba-low + /l FIELD read-cap-16>allocation-length \ should be 32 + /c FIELD read-cap-16>reserved + /c FIELD read-cap-16>control +CONSTANT scsi-length-read-cap-16 + +\ Setup READ CAPACITY (16) command +: scsi-build-read-cap-16 ( cdb -- ) + >r r@ ( R: -- cdb ) + scsi-length-read-cap-16 erase ( ) + scsi-cmd-read-capacity-16 ( code ) + r@ read-cap-16>operation-code c! ( ) + 10 r@ read-cap-16>service-action c! + d# 32 \ response size 32 bytes + r@ read-cap-16>allocation-length l! ( ) + scsi-param-control r> read-cap-16>control c! ( R: cdb -- ) + scsi-length-read-cap-16 to scsi-param-size \ update CDB length +; + +\ ---------------------------------------- +\ get from SCSI response block: +\ - Block Size (in Bytes) +\ - Number of Blocks +\ ---------------------------------------- +\ Forth Word: scsi-get-capacity-16 ( addr -- block-size #blocks ) +\ ---------------------------------------- +\ Block structure for return data +STRUCT + /l FIELD read-cap-16-data>max-lba-high \ upper quadlet of Max-LBA + /l FIELD read-cap-16-data>max-lba-low \ lower quadlet of Max-LBA + /l FIELD read-cap-16-data>block-size \ logical block length in bytes + /c FIELD read-cap-16-data>protect \ type of protection (4 bits) + /c FIELD read-cap-16-data>exponent \ logical blocks per physical blocks + /w FIELD read-cap-16-data>lowest-aligned \ first LBA of a phsy. block + 10 FIELD read-cap-16-data>reserved \ 16 reserved bytes +CONSTANT scsi-length-read-cap-16-data \ results in 32 + +\ get data-block +: scsi-get-capacity-16 ( addr -- block-size #blocks ) + >r ( R: -- addr ) + r@ read-cap-16-data>block-size l@ ( block-size ) + r@ read-cap-16-data>max-lba-high l@ ( block-size #blocks-high ) + d# 32 lshift ( block-size #blocks-upper ) + r> read-cap-16-data>max-lba-low l@ + ( block-size #blocks ) ( R: addr -- ) +; + +\ *************************************************************************** +\ SCSI-Command: MODE SENSE (10) +\ Type: Primary Command (SPC-3 clause 6.10) +\ *************************************************************************** +\ Forth Word: scsi-build-mode-sense-10 ( alloc-len subpage page cdb -- ) +\ *************************************************************************** +5a CONSTANT scsi-cmd-mode-sense-10 + +\ CDB structure +STRUCT + /c FIELD mode-sense-10>operation-code + /c FIELD mode-sense-10>res-llbaa-dbd-res + /c FIELD mode-sense-10>pc-page-code \ page code + page control + /c FIELD mode-sense-10>sub-page-code + 3 FIELD mode-sense-10>reserved2 + /w FIELD mode-sense-10>allocation-length + /c FIELD mode-sense-10>control +CONSTANT scsi-length-mode-sense-10 + +: scsi-build-mode-sense-10 ( alloc-len subpage page cdb -- ) + >r ( alloc-len subpage page ) ( R: -- cdb ) + r@ scsi-length-mode-sense-10 erase \ 10 bytes CDB + scsi-cmd-mode-sense-10 ( alloc-len subpage page cmd ) + r@ mode-sense-10>operation-code c! ( alloc-len subpage page ) + 10 r@ mode-sense-10>res-llbaa-dbd-res c! \ long LBAs accepted + r@ mode-sense-10>pc-page-code c! ( alloc-len subpage ) + r@ mode-sense-10>sub-page-code c! ( alloc-len ) + r@ mode-sense-10>allocation-length w! ( ) + + scsi-param-control r> mode-sense-10>control c! ( R: cdb -- ) + scsi-length-mode-sense-10 to scsi-param-size \ update CDB length +; + +\ return data processing +\ (see spec: SPC-3 clause 7.4.3) + +STRUCT + /w FIELD mode-sense-10-data>head-length + /c FIELD mode-sense-10-data>head-medium + /c FIELD mode-sense-10-data>head-param + /c FIELD mode-sense-10-data>head-longlba + /c FIELD mode-sense-10-data>head-reserved + /w FIELD mode-sense-10-data>head-descr-len +CONSTANT scsi-length-mode-sense-10-data + +\ **************************************** +\ This function shows the mode page header +\ helpful for further analysis +\ **************************************** +: .mode-sense-data ( addr -- ) + cr + dup mode-sense-10-data>head-length + w@ ." Mode Length: " .d space + dup mode-sense-10-data>head-medium + c@ ." / Medium Type: " .d space + dup mode-sense-10-data>head-longlba + c@ ." / Long LBA: " .d space + mode-sense-10-data>head-descr-len + w@ ." / Descr. Length: " .d +; + +\ *************************************************************************** +\ SCSI-Command: READ (6) +\ Type: Block Command (SBC-3 clause 5.7) +\ *************************************************************************** +\ Forth Word: scsi-build-read-6 ( block# #blocks cdb -- ) +\ *************************************************************************** +\ this SCSI command uses 21 bits to represent start LBA +\ and 8 bits to specify the numbers of blocks to read +\ The value of 0 blocks is interpreted as 256 blocks +\ +\ command code +08 CONSTANT scsi-cmd-read-6 + +\ CDB structure +STRUCT + /c FIELD read-6>operation-code \ 08h + /c FIELD read-6>block-address-msb \ upper 5 bits + /w FIELD read-6>block-address \ lower 16 bits + /c FIELD read-6>length \ number of blocks to read + /c FIELD read-6>control \ CDB control +CONSTANT scsi-length-read-6 + +: scsi-build-read-6 ( block# #blocks cdb -- ) + >r ( block# #blocks ) ( R: -- cdb ) + r@ scsi-length-read-6 erase \ 6 bytes CDB + scsi-cmd-read-6 r@ read-6>operation-code c! ( block# #blocks ) + + \ check block count to read (#blocks) + dup d# 255 > \ #blocks exceeded limit ? + IF + scsi-inc-errors + drop 1 \ replace with any valid number + THEN + r@ read-6>length c! \ set #blocks to read + + \ check starting block number (block#) + dup 1fffff > \ check address upper limit + IF + scsi-inc-errors + drop \ remove original block# + 1fffff \ replace with any valid address + THEN + dup d# 16 rshift + r@ read-6>block-address-msb c! \ set upper 5 bits + ffff and + r@ read-6>block-address w! \ set lower 16 bits + scsi-param-control r> read-6>control c! ( R: cdb -- ) + scsi-length-read-6 to scsi-param-size \ update CDB length +; + +\ *************************************************************************** +\ SCSI-Command: READ (10) +\ Type: Block Command (SBC-3 clause 5.8) +\ *************************************************************************** +\ Forth Word: scsi-build-read-10 ( block# #blocks cdb -- ) +\ *************************************************************************** +\ command code +28 CONSTANT scsi-cmd-read-10 + +\ CDB structure +STRUCT + /c FIELD read-10>operation-code + /c FIELD read-10>protect + /l FIELD read-10>block-address \ logical block address (32bits) + /c FIELD read-10>group + /w FIELD read-10>length \ transfer length (16-bits) + /c FIELD read-10>control +CONSTANT scsi-length-read-10 + +: scsi-build-read-10 ( block# #blocks cdb -- ) + >r ( block# #blocks ) ( R: -- cdb ) + r@ scsi-length-read-10 erase \ 10 bytes CDB + scsi-cmd-read-10 r@ read-10>operation-code c! ( block# #blocks ) + r@ read-10>length w! ( block# ) + r@ read-10>block-address l! ( ) + scsi-param-control r> read-10>control c! ( R: cdb -- ) + scsi-length-read-10 to scsi-param-size \ update CDB length +; + +\ *************************************************************************** +\ SCSI-Command: READ (12) +\ Type: Block Command (SBC-3 clause 5.9) +\ *************************************************************************** +\ Forth Word: scsi-build-read-12 ( block# #blocks cdb -- ) +\ *************************************************************************** +\ command code +a8 CONSTANT scsi-cmd-read-12 + +\ CDB structure +STRUCT + /c FIELD read-12>operation-code \ code: a8 + /c FIELD read-12>protect \ RDPROTECT, DPO, FUA, FUA_NV + /l FIELD read-12>block-address \ lba + /l FIELD read-12>length \ transfer length (32bits) + /c FIELD read-12>group \ group number + /c FIELD read-12>control +CONSTANT scsi-length-read-12 + +: scsi-build-read-12 ( block# #blocks cdb -- ) + >r ( block# #blocks ) ( R: -- cdb ) + r@ scsi-length-read-12 erase \ 12 bytes CDB + scsi-cmd-read-12 r@ read-12>operation-code c! ( block# #blocks ) + r@ read-12>length l! ( block# ) + r@ read-12>block-address l! ( ) + scsi-param-control r> read-12>control c! ( R: cdb -- ) + scsi-length-read-12 to scsi-param-size \ update CDB length +; + +\ *************************************************************************** +\ SCSI-Command: READ with autodetection of required command +\ read(10) or read(12) depending on parameter size +\ (read(6) removed because obsolete in some cases (USB)) +\ Type: Block Command +\ *************************************************************************** +\ Forth Word: scsi-build-read? ( block# #blocks cdb -- ) +\ +\ +----------------+---------------------------| +\ | block# (lba) | #block (transfer-length) | +\ +-----------+----------------+---------------------------| +\ | read-6 | 16-Bits | 8 Bits | +\ | read-10 | 32-Bits | 16 Bits | +\ | read-12 | 32-Bits | 32 Bits | +\ *************************************************************************** +: scsi-build-read? ( block# #blocks cdb -- length ) + over ( block# #blocks cdb #blocks ) + fffe > \ tx-length (#blocks) exceeds 16-bit limit ? + IF + scsi-build-read-12 ( block# #blocks cdb -- ) + scsi-length-read-12 ( length ) + ELSE ( block# #blocks cdb ) + scsi-build-read-10 ( block# #blocks cdb -- ) + scsi-length-read-10 ( length ) + THEN +; + +\ *************************************************************************** +\ SCSI-Command: START STOP UNIT +\ Type: Block Command (SBC-3 clause 5.19) +\ *************************************************************************** +\ Forth Word: scsi-build-start-stop-unit ( state# cdb -- ) +\ *************************************************************************** +\ command code +1b CONSTANT scsi-cmd-start-stop-unit + +\ CDB structure +STRUCT + /c FIELD start-stop-unit>operation-code + /c FIELD start-stop-unit>immed + /w FIELD start-stop-unit>reserved + /c FIELD start-stop-unit>pow-condition + /c FIELD start-stop-unit>control +CONSTANT scsi-length-start-stop-unit + +\ START/STOP constants +\ (see spec: SBC-3 clause 5.19) +f1 CONSTANT scsi-const-active-power \ param used for start-stop-unit +f2 CONSTANT scsi-const-idle-power \ param used for start-stop-unit +f3 CONSTANT scsi-const-standby-power \ param used for start-stop-unit +3 CONSTANT scsi-const-load \ param used for start-stop-unit +2 CONSTANT scsi-const-eject \ param used for start-stop-unit +1 CONSTANT scsi-const-start +0 CONSTANT scsi-const-stop + +: scsi-build-start-stop-unit ( state# cdb -- ) + >r ( state# ) ( R: -- cdb ) + r@ scsi-length-start-stop-unit erase \ 6 bytes CDB + scsi-cmd-start-stop-unit r@ start-stop-unit>operation-code c! + dup 3 > + IF + 4 lshift \ shift to upper nibble + THEN ( state ) + r@ start-stop-unit>pow-condition c! ( ) + scsi-param-control r> start-stop-unit>control c! ( R: cdb -- ) + scsi-length-start-stop-unit to scsi-param-size \ update CDB length +; + +\ *************************************************************************** +\ SCSI-Command: SEEK(10) +\ Type: Block Command (obsolete) +\ *************************************************************************** +\ Forth Word: scsi-build-seek ( state# cdb -- ) +\ Obsolete function (last listed in spec SBC / Nov. 1997) +\ implemented only for the sake of completeness +\ *************************************************************************** +\ command code +2b CONSTANT scsi-cmd-seek + +\ CDB structure +STRUCT + /c FIELD seek>operation-code + /c FIELD seek>reserved1 + /l FIELD seek>lba + 3 FIELD seek>reserved2 + /c FIELD seek>control +CONSTANT scsi-length-seek + +: scsi-build-seek ( lba cdb -- ) + >r ( lba ) ( R: -- cdb ) + r@ scsi-length-seek erase \ 10 bytes CDB + scsi-cmd-seek r@ seek>operation-code c! + r> seek>lba l! ( ) ( R: cdb -- ) + scsi-length-seek to scsi-param-size \ update CDB length +; + +\ *************************************************************************** +\ SCSI-Utility: .sense-code +\ *************************************************************************** +\ this utility prints a string associated to the sense code +\ see specs: SPC-3/r23 clause 4.5.6 +\ *************************************************************************** +: .sense-text ( scode -- ) + case + 0 OF s" OK" ENDOF + 1 OF s" RECOVERED ERR" ENDOF + 2 OF s" NOT READY" ENDOF + 3 OF s" MEDIUM ERROR" ENDOF + 4 OF s" HARDWARE ERR" ENDOF + 5 OF s" ILLEGAL REQUEST" ENDOF + 6 OF s" UNIT ATTENTION" ENDOF + 7 OF s" DATA PROTECT" ENDOF + 8 OF s" BLANK CHECK" ENDOF + 9 OF s" VENDOR SPECIFIC" ENDOF + a OF s" COPY ABORTED" ENDOF + b OF s" ABORTED COMMAND" ENDOF + d OF s" VOLUME OVERFLOW" ENDOF + e OF s" MISCOMPARE" ENDOF + dup OF s" UNKNOWN" ENDOF + endcase + 5b emit type 5d emit +; + +\ *************************************************************************** +\ SCSI-Utility: .status-code +\ *************************************************************************** +\ this utility prints a string associated to the status code +\ see specs: SAM-3/r14 clause 5.3 +\ *************************************************************************** +: .status-text ( stat -- ) + case + 00 OF s" GOOD" ENDOF + 02 OF s" CHECK CONDITION" ENDOF + 04 OF s" CONDITION MET" ENDOF + 08 OF s" BUSY" ENDOF + 18 OF s" RESERVATION CONFLICT" ENDOF + 28 OF s" TASK SET FULL" ENDOF + 30 OF s" ACA ACTIVE" ENDOF + 40 OF s" TASK ABORTED" ENDOF + dup OF s" UNKNOWN" ENDOF + endcase + 5b emit type 5d emit +; + +\ *************************************************************************** +\ SCSI-Utility: .capacity-text +\ *************************************************************************** +\ utility that shows total capacity on screen by use of the return data +\ from read-capacity calculation is SI conform (base 10) +\ *************************************************************************** +\ sub function to print a 3 digit decimal +\ number with 2 post decimal positions xxx.yy +: .dec3-2 ( prenum postnum -- ) + swap + base @ >r \ save actual base setting + decimal \ show decimal values + 4 .r 2e emit + dup 9 <= IF 30 emit THEN .d \ 3 pre-decimal, right aligned + r> base ! \ restore base +; + +: .capacity-text ( block-size #blocks -- ) + scsi-param-debug \ debugging flag set ? + IF \ show additional info + 2dup + cr + ." LBAs: " .d \ highest logical block number + ." / Block-Size: " .d + ." / Total Capacity: " + THEN + * \ calculate total capacity + dup d# 1000000000000 >= \ check terabyte limit + IF + d# 1000000000000 /mod + swap + d# 10000000000 / \ limit remainder to two digits + .dec3-2 ." TB" \ show terabytes as xxx.yy + ELSE + dup d# 1000000000 >= \ check gigabyte limit + IF + d# 1000000000 /mod + swap + d# 10000000 / + .dec3-2 ." GB" \ show gigabytes as xxx.yy + ELSE + dup d# 1000000 >= + IF + d# 1000000 /mod \ check mega byte limit + swap + d# 10000 / + .dec3-2 ." MB" \ show megabytes as xxx.yy + ELSE + dup d# 1000 >= \ check kilo byte limit + IF + d# 1000 /mod + swap + d# 10 / + .dec3-2 ." kB" + ELSE + .d ." Bytes" + THEN + THEN + THEN + THEN +; + +\ *************************************************************************** +\ SCSI-Utility: .inquiry-text ( addr -- ) +\ *************************************************************************** +\ utility that shows: +\ vendor-ident product-ident and revision +\ from an inquiry return data block (addr) +\ *************************************************************************** +: .inquiry-text ( addr -- ) + 22 emit \ enclose text with " + dup inquiry-data>vendor-ident 8 type space + dup inquiry-data>product-ident 10 type space + inquiry-data>product-revision 4 type + 22 emit +; + +\ *************************************************************************** +\ SCSI-Utility: scsi-supp-init ( -- ) +\ *************************************************************************** +\ utility that helps to ensure that parameters are set to valid values +: scsi-supp-init ( -- ) + false to scsi-param-debug \ no debug strings + h# 0 to scsi-param-size + h# 0 to scsi-param-control \ common CDB control byte + d# 0 to scsi-param-errors \ local errors (param limits) +; + + +\ *************************************************************************** +\ scsi loader +\ *************************************************************************** +0 VALUE scsi-context \ addr of word list on top + + +\ **************************************************************************** +\ open scsi-support by adding a new word list on top of search path +\ precondition: scsi-support.fs must have been included +\ **************************************************************************** +: scsi-init ( -- ) + also scsi-words \ append scsi word-list + context to scsi-context \ save for close process + scsi-supp-init \ preset all scsi-param-xxx values + scsi-param-debug + IF + space ." SCSI-SUPPORT OPENED" cr + .wordlists + THEN +; + +\ **************************************************************************** +\ close scsi-session and remove scsi word list (if exists) +\ **************************************************************************** +\ if 'previous' is used without a preceeding 'also' all forth words are lost ! +\ **************************************************************************** +: scsi-close ( -- ) +\ FIXME This only works if scsi-words is the last vocabulary on the stack +\ Instead we could use get-order to find us on the "wordlist stack", +\ remove us and write the wordlist stack back with set-order. +\ BUT: Is this worth the effort? + + scsi-param-debug + IF + space ." Closing SCSI-SUPPORT .. " cr + THEN + context scsi-context = \ scsi word list still active ? + IF + scsi-param-errors 0<> \ any errors occured ? + IF + cr ." ** WARNING: " scsi-param-errors .d + ." SCSI Errors occured ** " cr + THEN + previous \ remove scsi word list on top + 0 to scsi-context \ prevent from being misinterpreted + ELSE + cr ." ** WARNING: Trying to close non-open SCSI-SUPPORT (1) ** " cr + THEN + scsi-param-debug + IF + .wordlists + THEN +; + + +s" scsi-init" $find drop \ return execution pointer, when included + +previous \ remove scsi word list from search path +definitions \ place next definitions into previous list + diff --git a/slof/fs/search.fs b/slof/fs/search.fs index 4016233..3acca2f 100644 --- a/slof/fs/search.fs +++ b/slof/fs/search.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -9,6 +9,10 @@ \ * Contributors: \ * IBM Corporation - initial implementation \ ****************************************************************************/ +\ +\ Copyright 2002,2003,2004 Segher Boessenkool <segher@kernel.crashing.org> +\ + \ stuff we should already have: @@ -68,12 +72,6 @@ VARIABLE wordlists forth-wordlist wordlists ! \ XXX we'd like to swap forth and forth-wordlist around (for .voc 's sake) : FORTH ( -- ) clean-hash forth-wordlist context ! ; -\ XXX this one needs to be elsewhere -: >name ( xt -- nfa ) \ note: still has the "immediate" field! - BEGIN char- dup c@ UNTIL ( @lastchar ) - dup dup aligned - cell+ char- ( @lastchar lenmodcell ) - dup >r - BEGIN dup c@ r@ <> WHILE - cell- r> cell+ >r REPEAT r> drop char- ; : .voc ( wid -- ) \ display name for wid \ needs work ( body> or something like that ) dup cell- @ ['] vocabulary ['] forth within IF 2 cells - >name name>string type ELSE u. THEN space ; diff --git a/slof/fs/slof-logo.fs b/slof/fs/slof-logo.fs new file mode 100644 index 0000000..53d3184 --- /dev/null +++ b/slof/fs/slof-logo.fs @@ -0,0 +1,20 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2008 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ * IBM Corporation - initial implementation +\ ****************************************************************************/ + +: .slof-logo + cr ." ..`. .. ....... .. ...... ......." + cr ." ..`...`''.`'. .''``````..''. .`''```''`. `''``````" + cr ." .`` .:' ': `''..... .''. ''` .''..''......." + cr ." ``.':.';. ``````''`.''. .''. ''``''`````'`" + cr ." ``.':':` .....`''.`'`...... `'`.....`''.`'` " + cr ." .`.`'`` .'`'`````. ``'''''' ``''`'''`. `'` " +; diff --git a/slof/fs/sms/sms-load.fs b/slof/fs/sms/sms-load.fs index a5b2541..8e4db80 100644 --- a/slof/fs/sms/sms-load.fs +++ b/slof/fs/sms/sms-load.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -10,10 +10,19 @@ \ * IBM Corporation - initial implementation \ ****************************************************************************/ -false VALUE sms-loaded +false VALUE (sms-loaded?) + +false value (sms-available?) + +s" sms.fs" romfs-lookup IF true to (sms-available?) drop THEN + +(sms-available?) [IF] #include "packages/sms.fs" +\ Initialize SMS NVRAM handling. +#include "sms-nvram.fs" + \ Dynamically load sms code from the romfs file \ Assumption is that skeleton sms package already exists \ but aside of open & close, all other methods are in a romfs file (sms.fs) @@ -25,17 +34,17 @@ false VALUE sms-loaded : $sms-node s" /packages/sms" ; : (sms-init-package) ( -- true|false ) - sms-loaded ?dup IF EXIT THEN + (sms-loaded?) ?dup IF EXIT THEN $sms-node ['] find-device catch IF 2drop false EXIT THEN s" sms.fs" [COMPILE] included device-end - true dup to sms-loaded + true dup to (sms-loaded?) ; \ External wrapper for sms package method -: sms-start ( -- ) +: (sms-evaluate) ( addr len -- ) (sms-init-package) not IF - cr ." SMS is not available." cr exit + cr ." SMS is not available." cr 2drop exit THEN s" Entering SMS ..." type @@ -43,8 +52,19 @@ false VALUE sms-loaded reset-dual-emit \ if we only had execute-device-method... - $sms-node find-device - s" sms-start" evaluate + 2>r $sms-node find-device + 2r> evaluate device-end + vpd-boot-import ; +: sms-start ( -- ) s" sms-start" (sms-evaluate) ; +: sms-fru-replacement ( -- ) s" sms-fru-replacement" (sms-evaluate) ; + +[ELSE] + +: sms-start ( -- ) cr ." SMS is not available." cr ; +: sms-fru-replacement ( -- ) cr ." SMS FRU replacement is not available." cr ; + +[THEN] + diff --git a/slof/fs/sms/sms-nvram.fs b/slof/fs/sms/sms-nvram.fs new file mode 100644 index 0000000..4f5d6dd --- /dev/null +++ b/slof/fs/sms/sms-nvram.fs @@ -0,0 +1,124 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2008 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ * IBM Corporation - initial implementation +\ ****************************************************************************/ + +\ Initialize SMS NVRAM handling. + +: sms-init-nvram ( -- ) + nvram-partition-type-sms get-nvram-partition IF + cr ." Could not find SMS partition in NVRAM - " + nvram-partition-type-sms s" SMS" d# 1024 new-nvram-partition + ABORT" Failed to create SMS NVRAM partition" + 2dup erase-nvram-partition drop + + 2dup s" lang" s" 1" internal-set-env drop + + 2dup s" tftp-retries" s" 5" internal-set-env drop + 2dup s" tftp-blocksize" s" 512" internal-set-env drop + 2dup s" bootp-retries" s" 255" internal-set-env drop + 2dup s" client" s" 000.000.000.000" internal-set-env drop + 2dup s" server" s" 000.000.000.000" internal-set-env drop + 2dup s" gateway" s" 000.000.000.000" internal-set-env drop + 2dup s" netmask" s" 255.255.255.000" internal-set-env drop + 2dup s" net-protocol" s" 0" internal-set-env drop + 2dup s" net-flags" s" 0" internal-set-env drop + 2dup s" net-device" s" 0" internal-set-env drop + 2dup s" net-client-name" s" " internal-set-env drop + + 2dup s" scsi-spinup" s" 6" internal-set-env drop + 2dup s" scsi-id-0" s" 7" internal-set-env drop + 2dup s" scsi-id-1" s" 7" internal-set-env drop + 2dup s" scsi-id-2" s" 7" internal-set-env drop + 2dup s" scsi-id-3" s" 7" internal-set-env drop + ." created" cr + THEN + s" sms-nvram-partition" $2constant +; + +sms-init-nvram + +: sms-add-env ( "name" "value" -- ) sms-nvram-partition 2rot 2rot internal-add-env drop ; +: sms-set-env ( "name" "value" -- ) sms-nvram-partition 2rot 2rot internal-set-env drop ; +: sms-get-env ( "name" -- "value" TRUE | FALSE) sms-nvram-partition 2swap internal-get-env ; + +: sms-get-net-device ( -- n ) s" net-device" sms-get-env IF $dnumber IF 0 THEN ELSE 0 THEN ; +: sms-set-net-device ( n -- ) (.d) s" net-device" 2swap sms-set-env ; + +: sms-get-net-flags ( -- n ) s" net-flags" sms-get-env IF $dnumber IF 0 THEN ELSE 0 THEN ; +: sms-set-net-flags ( n -- ) (.d) s" net-flags" 2swap sms-set-env ; + +: sms-get-net-protocol ( -- n ) s" net-protocol" sms-get-env IF $dnumber IF 0 THEN ELSE 0 THEN ; +: sms-set-net-protocol ( n -- ) (.d) s" net-protocol" 2swap sms-set-env ; + +: sms-get-lang ( -- n ) s" lang" sms-get-env IF $dnumber IF 1 THEN ELSE 1 THEN ; +: sms-set-lang ( n -- ) (.d) s" lang" 2swap sms-set-env ; + +: sms-get-bootp-retries ( -- n ) s" bootp-retries" sms-get-env IF $dnumber IF 255 THEN ELSE 255 THEN ; +: sms-set-bootp-retries ( n -- ) (.d) s" bootp-retries" 2swap sms-set-env ; + +: sms-get-tftp-retries ( -- n ) s" tftp-retries" sms-get-env IF $dnumber IF 5 THEN ELSE 5 THEN ; +: sms-set-tftp-retries ( n -- ) (.d) s" tftp-retries" 2swap sms-set-env ; + +: sms-get-tftp-blocksize ( -- n ) s" tftp-blocksize" sms-get-env IF $dnumber IF 5 THEN ELSE 5 THEN ; +: sms-set-tftp-blocksize ( n -- ) (.d) s" tftp-blocksize" 2swap sms-set-env ; + +: sms-get-client ( -- FALSE | n1 n2 n3 n4 TRUE ) s" client" sms-get-env IF (ipaddr) ELSE false THEN ; +: sms-set-client ( n1 n2 n3 n4 -- ) (ipformat) s" client" 2swap sms-set-env ; + +: sms-get-server ( -- FALSE | n1 n2 n3 n4 TRUE ) s" server" sms-get-env IF (ipaddr) ELSE false THEN ; +: sms-set-server ( n1 n2 n3 n4 -- ) (ipformat) s" server" 2swap sms-set-env ; + +: sms-get-gateway ( -- FALSE | n1 n2 n3 n4 TRUE ) s" gateway" sms-get-env IF (ipaddr) ELSE false THEN ; +: sms-set-gateway ( n1 n2 n3 n4 -- ) (ipformat) s" gateway" 2swap sms-set-env ; + +: sms-get-subnet ( -- FALSE | n1 n2 n3 n4 TRUE ) s" netmask" sms-get-env IF (ipaddr) ELSE false THEN ; +: sms-set-subnet ( n1 n2 n3 n4 -- ) (ipformat) s" netmask" 2swap sms-set-env ; + +: sms-get-client-name ( -- FALSE | addr len TRUE ) s" net-client-name" sms-get-env ; +: sms-set-client-name ( addr len -- ) s" net-client-name" 2swap sms-set-env ; + +: sms-get-scsi-spinup ( -- n ) s" scsi-spinup" sms-get-env IF $dnumber IF 6 THEN ELSE 6 THEN ; +: sms-set-scsi-spinup ( n -- ) (.d) s" scsi-spinup" 2swap sms-set-env ; + +: sms-get-scsi-id ( n -- id ) s" scsi-id-" rot (.) $cat sms-get-env IF $dnumber IF 6 THEN ELSE 6 THEN ; +: sms-set-scsi-id ( id n -- ) swap (.d) rot s" scsi-id-" rot (.) $cat sms-set-env ; + + +\ generates the boot-file part of the boot string + +: sms-get-net-boot-file ( -- addr len ) + \ the format is + \ :[bootp,]siaddr,filename,ciaddr,giaddr,bootp-retries,tftp-retries + \ we choose dhcp as a default! + s" net" sms-get-net-device (.) $cat + s" :dhcp," $cat + sms-get-server IF (ipformat) $cat THEN + s" ," $cat + sms-get-client-name IF $cat THEN + s" ," $cat + sms-get-client IF (ipformat) $cat THEN + s" ," $cat + sms-get-gateway IF (ipformat) $cat THEN + s" ," $cat + \ If the number of retries is 255 (max), assume default timeout (10min) + sms-get-bootp-retries dup ff <> IF (.) $cat ELSE drop THEN + s" ," $cat + sms-get-tftp-retries (.) $cat + \ now write the string to the boot path + dup IF + \ This could be considered a memory leak, but it is only + \ executed once for booting so it is not a problem + strdup ( s" :" 2swap $cat strdup ) + THEN +; + +' sms-get-net-boot-file to furnish-boot-file + diff --git a/slof/fs/stack.fs b/slof/fs/stack.fs index 7bbdfb8..0f7e097 100644 --- a/slof/fs/stack.fs +++ b/slof/fs/stack.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/start-up.fs b/slof/fs/start-up.fs index c36da13..0ce0f3c 100644 --- a/slof/fs/start-up.fs +++ b/slof/fs/start-up.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -61,8 +61,14 @@ THEN ; + #include "sms/sms-load.fs" + +\ Watchdog will be rearmed during load if use-load-watchdog variable is TRUE +TRUE VALUE use-load-watchdog? + + : start-it ( -- ) key? IF key CASE @@ -81,5 +87,6 @@ (boot?) THEN - disable-watchdog .banner + disable-watchdog FALSE to use-load-watchdog? + .banner ; diff --git a/slof/fs/term-io.fs b/slof/fs/term-io.fs index d352b9e..1ab9f94 100644 --- a/slof/fs/term-io.fs +++ b/slof/fs/term-io.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -54,4 +54,39 @@ ' term-io-key to key -\ TODO: Implement: ' term-io-key? to key? +\ this word will check what the current chosen input device is: +\ - if it is a serial device, it will use serial-key? to check for available input +\ - if it is a keyboard, it will check if the "key-available?" method is implemented (i.e. for usb-keyboard) and use that +\ otherwise it will always return false +: term-io-key? ( -- true|false ) + s" stdin" get-chosen IF + decode-int nip nip dup 0= IF drop 0 EXIT THEN \ return false and exit if no stdin set + >r \ store ihandle on return stack + s" device_type" r@ ihandle>phandle ( propstr len phandle ) + get-property ( true | data dlen false ) + IF + \ device_type not found, return false and exit + false + ELSE + 1 - \ remove 1 from length to ignore null-termination char + \ device_type found, check wether it is serial or keyboard + 2dup s" serial" str= IF 2drop serial-key? r> drop EXIT THEN \ call serial-key, cleanup return-stack, exit + 2dup s" keyboard" str= IF + 2drop ( ) + \ keyboard found, check for key-available? method, execute it or return false + s" key-available?" r@ ihandle>phandle find-method IF + drop s" key-available?" r@ $call-method + ELSE + false + THEN + r> drop EXIT \ cleanup return-stack, exit + THEN + 2drop r> drop false EXIT \ unknown device_type cleanup return-stack, return false + THEN + ELSE + \ stdin not set, return false + false + THEN +; + +' term-io-key? to key? diff --git a/slof/fs/terminal.fs b/slof/fs/terminal.fs index e1bf4b2..3004265 100644 --- a/slof/fs/terminal.fs +++ b/slof/fs/terminal.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/timebase.fs b/slof/fs/timebase.fs index 2184587..863f694 100644 --- a/slof/fs/timebase.fs +++ b/slof/fs/timebase.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/translate.fs b/slof/fs/translate.fs index 954acc1..e2633e5 100644 --- a/slof/fs/translate.fs +++ b/slof/fs/translate.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/update_flash.fs b/slof/fs/update_flash.fs index 7461440..495e15f 100644 --- a/slof/fs/update_flash.fs +++ b/slof/fs/update_flash.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -23,35 +23,36 @@ false value flash-new ; : flash-read-temp ( -- success? ) - get-flashside 1 = IF flash-addr load-base over flash-image-size move true - ELSE - false - THEN + get-flashside 1 = IF flash-addr load-base over flash-image-size rmove true + ELSE + false + THEN ; : flash-read-perm ( -- success? ) - get-flashside 0= IF flash-addr load-base over flash-image-size move true - ELSE - false - THEN + get-flashside 0= IF + flash-addr load-base over flash-image-size rmove true + ELSE + false + THEN ; : flash-switch-side ( side -- success? ) - set-flashside 0<> IF - s" Cannot change flashside" type cr false - ELSE - true - THEN + set-flashside 0<> IF + s" Cannot change flashside" type cr false + ELSE + true + THEN ; : flash-ensure-temp ( -- success? ) - get-flashside 0= IF - cr ." Cannot flash perm! Switching to temp side!" - 1 flash-switch-side - ELSE - true - THEN - ; + get-flashside 0= IF + cr ." Cannot flash perm! Switching to temp side!" + 1 flash-switch-side + ELSE + true + THEN +; \ update-flash -f <filename> \ -l @@ -63,39 +64,47 @@ false value flash-new parse-word ( str len ) \ Parse first string drop dup c@ ( str first-char ) [char] - <> IF - update-flash-help r> 2drop EXIT + update-flash-help r> 2drop EXIT THEN 1+ c@ ( second-char ) CASE - [char] f OF parse-word cr s" do-load" evaluate - flash-ensure-temp TO flash-new - ENDOF - [char] l OF flash-ensure-temp - ENDOF - [char] d OF flash-load-base load-base 200000 move - flash-ensure-temp - ENDOF - [char] c OF flash-read-temp 0= flash-new or IF - ." Cannot commit temp, need to boot on temp first " cr false - ELSE - 0 flash-switch-side - THEN - ENDOF - [char] r OF flash-read-perm 0= IF - ." Cannot commit perm, need to boot on perm first " cr false - ELSE - 1 flash-switch-side - THEN - ENDOF - dup OF false ENDOF - ENDCASE + [char] f OF + parse-word cr s" do-load" evaluate + flash-ensure-temp TO flash-new + ENDOF + [char] l OF + flash-ensure-temp + ENDOF + [char] d OF + flash-load-base load-base 200000 move + flash-ensure-temp + ENDOF + [char] c OF + flash-read-temp 0= flash-new or IF + ." Cannot commit temp, need to boot on temp first " cr false + ELSE + 0 flash-switch-side + THEN + ENDOF + [char] r OF + flash-read-perm 0= IF + ." Cannot commit perm, need to boot on perm first " cr false + ELSE + 1 flash-switch-side + THEN + ENDOF + dup OF + false + ENDOF + ENDCASE + + ( true| false ) - ( true| false ) - 0= IF - update-flash-help r> drop EXIT - THEN + 0= IF + update-flash-help r> drop EXIT + THEN - load-base flash-write 0= IF ." Flash write failed !! " cr THEN - r> set-flashside drop \ Restore old flashside + load-base flash-write 0= IF ." Flash write failed !! " cr THEN + r> set-flashside drop \ Restore old flashside ; diff --git a/slof/fs/usb/usb-enumerate.fs b/slof/fs/usb/usb-enumerate.fs index 5b64bed..7118f17 100644 --- a/slof/fs/usb/usb-enumerate.fs +++ b/slof/fs/usb/usb-enumerate.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -117,12 +117,47 @@ : (scsi-create) ( -- ) s" SCSI-CREATE " usb-debug-print + +\ *********************************************************************** +\ a problem was encountered on Media-Tray (REV-0): +\ The CDROM is connected to USB via an ATA/USB-Bridge (U38: CYPRESS CY7C68300) +\ The C-Revision of this chip has an malfunction which results in a +\ hanging IORD Signal at the ATA-Interface and so prevents from reading. +\ The B-Revision doesn't have this problem (populated on Media-Tray REV-5) +\ Two additional Mass-Storage-Resets are necessary to reset the ATA-Interface. +\ (see CYPRESS Application Notes to CY7C68300) +\ (see USB-Spec: 'Bulk-Only-Transport') +\ *********************************************************************** +\ a mounted ISO image (via USB) doesn't accept this bulk-reset-command! +\ *********************************************************************** + + dd-buffer @ 8 + w@-le 4b4 = \ VendorID = CYPRESS ? + IF + dd-buffer @ a + w@-le 6830 = \ Device = CY7C68300 ? + IF + \ here a Cypress ATA/USB Bridge is detected + d# 20 ms + mps new-device-address 0 0 0 ( MPS fun-addr dir data-buff data-len ) + control-bulk-reset ( TRUE|FALSE ) + d# 100 ms + mps new-device-address 0 0 0 ( TRUE|FALSE MPS fun-addr dir data-buff data-len ) + control-bulk-reset ( TRUE|FALSE TRUE|FALSE ) + and invert + IF + ." ** BULK-RESET failed **" cr + THEN + d# 20 ms + THEN + THEN + + 0 ch-buffer ! \ preset a clean response mps new-device-address 0 ch-buffer 1 control-std-get-maxlun ( TRUE|FALSE ) IF \ s" GET-MAX-LUN IS WORKING :" usb-debug-print \ ch-buffer 5 dump cr \ dump the responsed message ELSE s" ERROR in GET-MAX-LUN " usb-debug-print + 0 ch-buffer ! \ clear invalid numbers cd-buffer @ 5 + c@ to temp1 temp1 new-device-address control-std-set-configuration drop THEN @@ -133,6 +168,34 @@ \ Workaround: Devices that might report a higher number are treated \ as having exactly one LUN. Without this workaround the \ USB scan hangs during the setup of non-available LUNs. + \ + \ Concerns: "FUJITSU MHV2040AT" (VendorID: 0x984 / DeviceID: 0x70) + \ + \ MR: This Device reports an invalid MaxLUN number within the first + \ three seconds after power-on or USB-Reset. The following loop repeats + \ the MaxLUN request up to 8 times until a valid ( <15 ) value is responded. + \ This can last up to four seconds as there is a delay of 500ms in every loop + + 0 ( counter ) + begin + dup 8 < ( counter flag ) \ max 8 * 500 ms + ch-buffer c@ f > ( counter flag flag ) \ is MuxLUN above limit ? + AND ( counter flag ) + while + d# 500 ms \ this device is not yet ready + 0 ch-buffer ! \ preset a clean response + mps new-device-address 0 ch-buffer 1 control-std-get-maxlun ( TRUE|FALSE ) + not + IF + s" ** ERROR in GET-MAX-LUN ** " usb-debug-print + drop 10 \ replace counter to force loop end + THEN + 1+ ( counter+1 ) + repeat + drop + + \ here is still the workaround to handle invalid MaxLUNs as '0' + \ ch-buffer c@ dup 0= swap f > or IF s" + LUN: " ch-buffer c@ usb-debug-print-val (atapi-scsi-property-set) @@ -208,26 +271,27 @@ (classify-storage) ENDOF 03 OF - ( Interface-protocol Interface-subclass ) - s" USB: HID Found!" usb-debug-print - 01 = IF - case - 01 of - s" USB keyboard!" usb-debug-print - (keyboard-create) - endof - 02 of - s" USB mouse!" usb-debug-print - (mouse-create) - endof - dup of - s" USB: unsupported HID!" usb-debug-print - endof - endcase - ELSE - s" USB: unsupported HID!" usb-debug-print - THEN - ENDOF + ( Interface-protocol Interface-subclass ) + s" USB: HID Found!" usb-debug-print + 01 = + IF + case + 01 of + s" USB keyboard!" usb-debug-print + (keyboard-create) + endof + 02 of + s" USB mouse!" usb-debug-print + (mouse-create) + endof + dup of + s" USB: unsupported HID!" usb-debug-print + endof + endcase + ELSE + s" USB: unsupported HID!" usb-debug-print + THEN + ENDOF dup OF ( Interface-protocol Interface-subclass ) s" USB: unsupported interface type." usb-debug-print @@ -256,4 +320,5 @@ s" USB: Unknown device found." usb-debug-print ENDOF ENDCASE + uDOC-present 0f and to uDOC-present \ remove uDOC processing flag ; diff --git a/slof/fs/usb/usb-hub.fs b/slof/fs/usb/usb-hub.fs index 6701750..106b680 100644 --- a/slof/fs/usb/usb-hub.fs +++ b/slof/fs/usb/usb-hub.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -182,7 +182,7 @@ INSTANCE VARIABLE cd-buffer ; : control-std-get-maxlun - ( MPS fun-addr dir data-buff data-len -- TRUE|FALSE) + ( MPS fun-addr dir data-buff data-len -- TRUE|FALSE ) s" control-std-get-maxlun" $call-parent ; @@ -205,6 +205,11 @@ INSTANCE VARIABLE cd-buffer s" debug-td" $call-parent ; +\ *** NEW **** +: control-bulk-reset ( MPS fun-addr dir data-buff data-len -- TRUE | FALSE ) + s" control-bulk-reset" $call-parent +; + \ -------------------------------------------------------------------------- \ HUB specific methods @@ -288,55 +293,32 @@ s" usb-enumerate.fs" INCLUDED : hub-configure-port ( port# -- ) - \ Step 1: set the Port Power - usb-test-flag - IF - ." Port: " dup . cr - 150 ms \ wait for bad devices - THEN +\ this port has been powered on +\ send reset to enable port and +\ start device detection by hub +\ some devices require a long timeout here (10s) + + \ Step 1: check if reset state ended - dup control-hub-port-power-set drop ( port# ) BEGIN ( port# ) status-buffer 4 erase ( port# ) status-buffer over control-hub-port-status-get drop ( port# ) - usb-test-flag - IF - s" Port Satus: " status-buffer w@-le usb-debug-print-val - THEN - status-buffer w@-le 102 and 0= ( port# TRUE|FALSE ) WHILE ( port# ) - REPEAT ( port# ) + REPEAT ( port# ) po2pg 3 * ms \ wait for bPwrOn2PwrGood*3 ms - usb-test-flag - IF - 150 ms - THEN \ STEP 2: Reset the port. - + \ (this also enables the port) dup control-hub-port-reset-set drop ( port# ) BEGIN ( port# ) status-buffer 4 erase ( port# ) status-buffer over control-hub-port-status-get drop ( port# ) status-buffer w@-le 10 and ( port# TRUE|FALSE ) - usb-test-flag - IF - s" Port Satus: " status-buffer w@-le usb-debug-print-val - THEN WHILE ( port# ) REPEAT ( port# ) - \ after reset set port enable -important- - dup control-hub-port-enable drop ( port# ) - - usb-test-flag - IF - 10 ms - THEN - - \ STEP 3: Check if a device is connected to the - \ port. + \ STEP 3: Check if a device is connected to the port. status-buffer 4 erase ( port# ) status-buffer over control-hub-port-status-get drop ( port# ) @@ -348,19 +330,6 @@ s" usb-enumerate.fs" INCLUDED EXIT THEN - \ New addition: Sometimes the port status returns connected - \ but Set address was failing. Analysis showed that such - \ ports do not set this bit to 1. - - status-buffer 2 + w@-le 1 and 1 <> ( port# ) - IF ( port# ) - drop - s" No device connected to port- set addresss failed" usb-debug-print - EXIT - THEN - s" HUB: New device found!!!" usb-debug-print -\ s" HUB: Status buffer first word -> " usb-debug-print -\ s" HUB: Status buffer second word -> " usb-debug-print \ STEP 4: Assign an address to this device. @@ -393,8 +362,10 @@ s" usb-enumerate.fs" INCLUDED dd-buffer @ DEVICE-DESCRIPTOR-LEN mps new-device-address ( buffer descp-len mps usb-addr ) \ s" DEVICE DESCRIPTOR: " usb-debug-print - control-std-get-device-descriptor drop - \ dd-buffer usb-debug-print-val + control-std-get-device-descriptor invert + IF + s" ** reading dev-descriptor failed ** " usb-debug-print + THEN create-usb-device-tree THEN ELSE @@ -452,14 +423,27 @@ s" usb-enumerate.fs" INCLUDED \ 2. HUB descriptor size is variable. Currently we r hardcoding \ a value of 9. - hd-buffer 2 + c@ to temp2 -\ temp2 1+ to temp2 - s" HUB: Found " usb-debug-print \ temp2 . + hd-buffer 2 + c@ to temp2 \ number of downstream ports + + s" HUB: Found " usb-debug-print s" number of downstream hub ports! : " temp2 usb-debug-print-val - hd-buffer 5 + c@ to po2pg \ get bPwrOn2PwrGood + hd-buffer 5 + c@ to po2pg \ get bPwrOn2PwrGood + + \ power on all present hub ports + \ to allow slow devices to set up + + temp2 1+ 1 DO + i control-hub-port-power-set drop + d# 20 ms + LOOP + + d# 200 ms \ some devices need a long time (10s) + + \ now start detection and configuration for these ports + temp2 1+ 1 DO - s" hub-configure-port: " I usb-debug-print-val - I hub-configure-port + s" hub-configure-port: " i usb-debug-print-val + i hub-configure-port LOOP ; diff --git a/slof/fs/usb/usb-kbd-device-support.fs b/slof/fs/usb/usb-kbd-device-support.fs index ccf1b42..104a508 100644 --- a/slof/fs/usb/usb-kbd-device-support.fs +++ b/slof/fs/usb/usb-kbd-device-support.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/usb/usb-keyboard.fs b/slof/fs/usb/usb-keyboard.fs index b0c4be9..5631030 100644 --- a/slof/fs/usb/usb-keyboard.fs +++ b/slof/fs/usb/usb-keyboard.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -14,6 +14,8 @@ s" keyboard" device-name s" keyboard" device-type +." USB Keyboard" cr + 3 encode-int s" assigned-addresses" property 1 encode-int s" reg" property 1 encode-int s" configuration#" property @@ -288,16 +290,31 @@ s" usb-kbd-device-support.fs" included ret \ return char ; +: key-available? ( -- true|false ) + multi-key 0 <> IF + true \ multi scan code key was pressed... so key is available + EXIT \ done + THEN + kbd-scan 0 = IF \ if no kbd-scan code is currently available + int-get-report \ check for one using int-get-report + THEN + kbd-scan 0 <> \ if a kbd-scan is available, report true, else false +; + : usb-kread ( -- char|false ) \ usb key read for control transfer multi-key 0 <> if \ if multi scan code key is pressed multi-key ff and \ read one byte from buffer multi-key 8 rshift to multi-key \ move to next byte else \ normal key check + \ check for new scan code only, if kbd-scan is not set, e.g. + \ by a previous call to key-available? + kbd-scan 0 = IF \ if interrupt transfer int-get-report \ read report (interrupt transfer) \ else control transfer \ ctl-get-report \ read report (control transfer) \ end of interrupt/control switch + THEN kbd-scan 0 <> if \ scan code exist? begin kbd-scan ff and dup 00 = while \ get a last scancode in report buffer kbd-scan 8 rshift to kbd-scan \ This algorithm is wrong --> must be fixed! @@ -315,6 +332,7 @@ s" usb-kbd-device-support.fs" included drop false \ do nothing then then + kbd-scan 8 rshift to kbd-scan \ handled scan-code else 0 to key-old \ clear privious key false \ no scan code --> return false diff --git a/slof/fs/usb/usb-mouse.fs b/slof/fs/usb/usb-mouse.fs index 1703196..bd6fa50 100644 --- a/slof/fs/usb/usb-mouse.fs +++ b/slof/fs/usb/usb-mouse.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -14,6 +14,8 @@ s" mouse" device-name s" mouse" device-type +." USB Mouse" cr + 1 encode-int s" configuration#" property 2 encode-int s" #buttons" property 4 encode-int s" assigned-addresses" property diff --git a/slof/fs/usb/usb-ohci.fs b/slof/fs/usb/usb-ohci.fs index 1cabdc3..f4d9670 100644 --- a/slof/fs/usb/usb-ohci.fs +++ b/slof/fs/usb/usb-ohci.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -87,6 +87,7 @@ CONSTANT /hclen \ get-base-address CONSTANT baseaddrs +baseaddrs CONSTANT HcRevision baseaddrs 4 + CONSTANT hccontrol baseaddrs 8 + CONSTANT hccomstat baseaddrs 0c + CONSTANT hcintstat @@ -98,19 +99,20 @@ baseaddrs 28 + CONSTANT hcbulkhead baseaddrs 2c + CONSTANT hccurbulk baseaddrs 30 + CONSTANT hcdnehead baseaddrs 34 + CONSTANT hcintrval +baseaddrs 40 + CONSTANT HcPeriodicStart baseaddrs 48 + CONSTANT hcrhdescA +baseaddrs 4c + CONSTANT hcrhdescB +baseaddrs 50 + CONSTANT HcRhStatus baseaddrs 54 + CONSTANT hcrhpstat - -\ OHCI REGISTER SETTING FOR ELBA STEC 8GBFLASHDISK -6C903305 E0 config-l! \ setting EXT1 for 5 ports -7E020001 40 config-l! \ setting PMC for enable PME +baseaddrs 58 + CONSTANT hcrhpstat2 +baseaddrs 5c + CONSTANT hcrhpstat3 usb-debug-flag IF - 0 config-l@ ." VENID = " . cr - 40 config-l@ ." PMC = " . cr - 44 config-l@ ." PMCSR = " . cr - E0 config-l@ ." EXT1 = " . cr - E4 config-l@ ." EXT2 = " . cr + 0 config-l@ ." - VENDOR: " 8 .r cr + 40 config-l@ ." - PMC : " 8 .r + 44 config-l@ ." PMCSR : " 8 .r cr + E0 config-l@ ." - EXT1 : " 8 .r + E4 config-l@ ." EXT2 : " 8 .r cr THEN \ Constants for INTSTAT register @@ -119,11 +121,13 @@ THEN \ Constants for RH Port Status Register -1 CONSTANT RHP-CCS -2 CONSTANT RHP-PES -10 CONSTANT RHP-PRS -100 CONSTANT RHP-PPS -100000 CONSTANT RHP-PRSC +1 CONSTANT RHP-CCS \ Current Connect Status +2 CONSTANT RHP-PES \ Port Enable Status +10 CONSTANT RHP-PRS \ Port Reset Status +100 CONSTANT RHP-PPS \ Port Power Status +10000 CONSTANT RHP-CSC \ Connect Status Changed +100000 CONSTANT RHP-PRSC \ Port Reset Status Changed + \ Constants for OHCI @@ -181,6 +185,8 @@ A1FE000000000100 CONSTANT GET-MAX-LUN 0 VALUE td-freelist-head 0 VALUE td-freelist-tail 0 VALUE num-free-tds +0 VALUE max-rh-ports +0 VALUE current-stat INSTANCE VARIABLE td-list-region @@ -243,6 +249,24 @@ INSTANCE VARIABLE cd-buffer \ Debug functions for displaying ED, TD and their combo list. +: Show-OHCI-Register + ." -> OHCI-Register: " cr + ." - HcControl : " hccontrol rl@-le 8 .r + ." CmdStat : " hccomstat rl@-le 8 .r + ." HcInterr. : " hcintstat rl@-le 8 .r cr + + ." - HcFmIntval: " hcintrval rl@-le 8 .r + ." Per. Start: " HcPeriodicStart rl@-le 8 .r cr + + ." - PortStat-1: " hcrhpstat rl@-le 8 .r + ." PortStat-2: " hcrhpstat2 rl@-le 8 .r + ." PortStat-3: " hcrhpstat3 rl@-le 8 .r cr + + ." Descr-A : " hcrhdescA rl@-le 8 .r + ." Descr-B : " hcrhdescB rl@-le 8 .r + ." HcRhStat : " HcRhStatus rl@-le 8 .r cr +; + : display-ed ( ED-ADDRESS -- ) TO temp1 usb-debug-flag IF @@ -250,7 +274,7 @@ INSTANCE VARIABLE cd-buffer s" eattr : " type temp1 ed>eattr l@-le u. cr s" tdqhp : " type temp1 ed>tdqhp l@-le u. cr s" tdqtp : " type temp1 ed>tdqtp l@-le u. cr - s" ned : " type temp1 ed>ned l@-le u. cr + s" ned : " type temp1 ed>ned l@-le u. cr THEN ; @@ -738,7 +762,7 @@ THEN dup temp2 1- + temp1 td>bfrend l!-le ( dlen addr~ ) temp2 + ( dlen next-addr ) swap temp2 - swap - temp1 td>ntd l@-le TO temp1 ( dlen next-addr) + temp1 td>ntd l@-le TO temp1 ( dlen next-addr ) current-toggle ( dlen next-addr current-toggle ) CASE 0 OF 1 TO current-toggle ENDOF @@ -789,30 +813,25 @@ THEN \ Internal method \ ================================================================== - -: (wait-for-done-q) ( timeout -- TD-list TRUE | FALSE ) - BEGIN ( timeout ) - dup 0<> ( timeout TRUE|FALSE ) - WHILE ( timeout ) - (HC-CHECK-WDH) ( timeout TRUE|FALSE ) - IF ( timeout ) - drop 0 ( 0 ) - ELSE ( timeout ) - 1- ( timeout ) - 1 ms ( timeout ) - THEN ( timeout ) - - \ Wait for 1 milli-second. - \ PENDING: There should be a better way. - - REPEAT ( timeout ) +: (wait-for-done-q) ( timeout -- TD-list TRUE | FALSE ) + BEGIN ( timeout ) + dup 0<> ( timeout TRUE|FALSE ) + (HC-CHECK-WDH) NOT ( timeout TRUE|FALSE TRUE|FALSE ) + AND \ not timed out AND WDH-bit not set + WHILE + 1 ms \ wait + 1- ( timeout ) + dup ff and 0= IF show-proceed THEN + REPEAT ( timeout ) drop - hchccadneq rl@-le dup 0<> IF ( td-list ) - TRUE ( td-list TRUE ) - 0 hchccadneq rl!-le ( td-list TRUE ) - (HC-ACK-WDH) ( td-list TRUE ) - ELSE FALSE ( td-list FALSE ) - THEN ( td-list TRUE|FALSE ) + hchccadneq l@-le \ read last HcDoneHead (RAM) + (HC-CHECK-WDH) \ HcDoneHead was updated ? + IF + (HC-ACK-WDH) \ clear register bit: WDH + TRUE ( td-list TRUE ) + ELSE + FALSE + THEN ; @@ -842,23 +861,59 @@ THEN \ Arrive at the right value OF FrameInterval. Currently we are hardcoding \ it. \ ========================================================================== - - : HC-reset ( -- ) - 00 hccontrol rl!-le - hccomstat dup rl@-le 01 or swap rl!-le + + hccomstat dup rl@-le 01 or swap rl!-le \ issue HC reset BEGIN - hccomstat rl@-le 01 and 0<> - WHILE + hccomstat rl@-le 01 and 0<> \ wait for reset end + WHILE REPEAT - hchcca hchccareg rl!-le - 0000 hcctrhead rl!-le - 0ffff hcintdsbl rl!-le - 0000 hcbulkhead rl!-le - 0083 hccontrol rl!-le - 23f02fff hcintrval rl!-le \ changes from 23f02edf -; + 23f02edf hcintrval rl!-le \ frame-interval register + hchcca hchccareg rl!-le \ HC communication area + 0000 hcctrhead rl!-le \ control transfer head + 0000 hcbulkhead rl!-le \ bulk transfer head + 0ffff hcintdsbl rl!-le \ interrupt disable reg. + +\ all devices are still in reset-state +\ next command starts sending SOFs + 83 hccontrol rl!-le \ set USBOPERATIONAL + +\ these two repeated register settings are necessary for Bimini +\ Its OHCI controller (AM8111) behaves different to NEC's one + 23f02edf hcintrval rl!-le \ frame-interval register + hchcca hchccareg rl!-le \ HC communication area + + d# 50 ms + + hcrhdescA rl@-le ff and ( total-rh-ports ) + to max-rh-ports + +\ if no hardware-reset was issued (rescan) +\ switch off all ports first ! + hcrhpstat TO current-stat \ start with first port status reg + 0 \ port status default + max-rh-ports 0 \ checking all ports + DO + current-stat rl@-le or \ OR-ing all stats + 200 current-stat rl!-le \ Clear Port Power (CPP) + current-stat 4 + TO current-stat \ check next RH-Port + LOOP + 100 and 0<> \ any of the ports had power ? + IF + d# 750 wait-proceed \ wait for power discharge + THEN + +\ now power on all ports of this root-hub + hcrhpstat TO current-stat \ start with first port status reg + max-rh-ports 0 + DO + 102 current-stat rl!-le \ power on and enable + hcrhdescA 3 + rb@ 2 * ms \ startup delay 30 ms (2 * POTPGT) + current-stat 4 + TO current-stat \ check next RH-Port + LOOP + d# 500 wait-proceed \ STEC device needs 300 ms +; : error-recovery ( -- ) initialize-td-free-list @@ -918,6 +973,7 @@ s" usb-support.fs" INCLUDED : control-std-get-device-descriptor ( data-buffer data-len MPS fa -- TRUE|FALSE ) + 8006000100000000 setup-packet ! 2 pick setup-packet 6 + w!-le ( data-buffer data-len MPS fa ) @@ -943,7 +999,7 @@ s" usb-support.fs" INCLUDED 0 swap temp3 setup-packet temp2 temp1 controlxfer ; -\ Fectes num of logical units available for a device +\ Fetches num of logical units available for a device : control-std-get-maxlun ( MPS fun-addr dir data-buff data-len -- TRUE | FALSE ) GET-MAX-LUN setup-packet ! ( MPS fun-addr dir data-buff data-len ) setup-packet 5 pick 5 pick @@ -952,6 +1008,18 @@ s" usb-support.fs" INCLUDED nip nip ( TRUE | FALSE ) ; +\ Bulk-Only Mass Storage Reset +\ fixed to interface #0 +: control-bulk-reset ( MPS fun-addr dir data-buff data-len -- TRUE | FALSE ) + 21FF000000000000 setup-packet ! ( MPS fun-addr dir data-buff data-len ) + setup-packet 5 pick 5 pick + ( MPS fun-addr dir data-buff data-len setup-packet MPS fun-addr ) + controlxfer ( MPS fun-addr TRUE | FALSE ) + nip nip ( TRUE | FALSE ) +; + + + \ get the string descriptor of the usb device @@ -1056,42 +1124,50 @@ s" usb-enumerate.fs" INCLUDED \ the build OF the USB devie sub-tree so is effectively the mother OF all \ USB device nodes that are to be detected and instantiated. \ ========================================================================== +: rhport-initialize ( -- ) - -VARIABLE total-rh-ports -0 VALUE current-stat - -: rhport-initialize ( total-rh-ports -- ) - total-rh-ports ! - hcrhpstat TO current-stat - total-rh-ports @ 1+ 1 DO - hcrhdescA rl@-le 0300 and 0100 = ( TRUE|FALSE ) - IF - 100 current-stat rl!-le - hcrhdescA 3 + rb@ 2 * ms - THEN + hcrhpstat TO current-stat \ start with first port status reg + max-rh-ports 1+ 1 + DO + \ any Device connected to that port ? current-stat rl@-le RHP-CCS and 0<> ( TRUE|FALSE ) IF - s" Device at this port!" usb-debug-print - RHP-PPS current-stat rl!-le \ port power on - hcrhdescA 3 + rb@ 4 * ms \ wait for POTPGT*2 ms - RHP-PES current-stat rl!-le \ port enable - 50 ms - RHP-PRS current-stat rl!-le \ port reset - 100 ms - \ RHP-PRSC current-stat rl!-le + current-stat hcrhpstat3 = \ third port of NEC ? + IF + 81 to uDOC-present \ uDOC is present and now processed + THEN + + s" Device connected to this port!" usb-debug-print + RHP-PRS current-stat rl!-le \ issue a port reset + BEGIN + current-stat rl@-le RHP-PRS AND \ wait for reset end + WHILE + REPEAT + hcrhdescA 3 + rb@ 2 * ms \ startup delay 30 ms (POTPGT) + d# 100 ms current-stat rl@-le 200 and 4 lshift - to device-speed \ store speed bit + to device-speed \ store speed bit + + RHP-CSC RHP-PRSC or current-stat rl!-le - I ['] rhport-enumerate CATCH IF \ Scan port + I ['] rhport-enumerate CATCH IF \ Scan port s" USB scan failed on root hub port: " rot usb-debug-print-val reset-to-initial-usb-hub-address THEN + ELSE s" No device detected at this port." usb-debug-print + current-stat hcrhpstat3 = \ third port of NEC ? (=ModFD) + IF \ here a ModFD should be on ELBA + current-stat rl@-le 80000 and 0<> \ is over-current detected ? + IF + uDOC-present 08 or to uDOC-present \ set flag for uDOC-check + THEN + THEN THEN - current-stat 4 + TO current-stat + current-stat 4 + TO current-stat \ check next RH-Port + uDOC-present 0f and to uDOC-present \ remove processing flag LOOP ; @@ -1103,7 +1179,6 @@ VARIABLE total-rh-ports : enumerate ( -- ) HC-reset ['] hc-suspend add-quiesce-xt \ Assert that HC will be supsended - hcrhdescA rl@-le 000000ff and ( total-rh-ports ) store-initial-usb-hub-address rhport-initialize \ Probe all available RH ports reset-to-initial-usb-hub-address diff --git a/slof/fs/usb/usb-static.fs b/slof/fs/usb/usb-static.fs index 50c8f0e..8732957 100644 --- a/slof/fs/usb/usb-static.fs +++ b/slof/fs/usb/usb-static.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -14,10 +14,15 @@ \ Set usb-debug flag to TRUE for debugging output: 0 VALUE usb-debug-flag -0 VALUE usb-test-flag +false VALUE scan-time? VARIABLE ihandle-bulk-tran -VARIABLE ihandle-scsi-tran +\ -scsi-supp- VARIABLE ihandle-scsi-tran + +\ uDOC (Micro-Disk-On-Chip) is a FLASH-device +\ normally connected to usb-port 5 on ELBA +\ +0 VALUE uDOC-present \ device present and working? \ Print a debug message when usb-debug-flag is set : usb-debug-print ( str len -- ) @@ -29,36 +34,199 @@ VARIABLE ihandle-scsi-tran usb-debug-flag IF -ROT type . cr ELSE drop 2drop THEN ; +\ show proceeding propeller only during scan process. +\ As soon USB-keyboard can be used, this must be suppressed. +0 VALUE proceed-char +: show-proceed ( -- ) + scan-time? \ are we on usb-scan ? + IF + proceed-char + CASE + 0 OF 2d ENDOF \ show '-' + 1 OF 5c ENDOF \ show '\' + 2 OF 7c ENDOF \ show '|' + dup OF 2f ENDOF \ show '/' + ENDCASE + emit 8 emit + proceed-char 1 + 3 AND to proceed-char + THEN +; + +\ delay with proceeding signs +: wait-proceed ( nl -- ) + show-proceed + BEGIN + dup d# 100 > ( nl true|false ) + WHILE + 100 - show-proceed + 100 ms \ do it in steps of 100ms + REPEAT + ms \ rest delay +; + +\ register device alias +: do-alias-setting ( num name-str name-len ) + rot $cathex strdup \ create alias name + get-node node>path \ get path string + set-alias \ and set the alias +; + 0 VALUE ohci-alias-num \ create a new ohci device alias for the current node: : set-ohci-alias ( -- ) ohci-alias-num dup 1+ TO ohci-alias-num ( num ) - s" ohci" rot $cathex strdup \ create alias name - get-node node>path \ get path string - set-alias \ and set the alias + s" ohci" + do-alias-setting ; 0 VALUE cdrom-alias-num +0 VALUE disk-alias-num \ shall start with: pci-disk-num +FALSE VALUE ext-disk-alias \ first external disk: not yet assigned \ create a new ohci device alias for the current node: -: set-cdrom-alias ( -- ) - cdrom-alias-num dup 1+ TO cdrom-alias-num ( num ) - s" cdrom" rot $cathex strdup \ create alias name - get-node node>path \ get path string - set-alias \ and set the alias +: set-drive-alias ( -- ) + space 5b emit + s" cdrom" drop ( name-str ) + get-node node>name comp 0= ( true|false ) + IF \ is this a cdrom ? + cdrom-alias-num dup 1+ TO cdrom-alias-num ( num ) + s" cdrom" \ yes, alias = cdrom + ELSE + s" sbc-dev" drop \ is this a scsi-block-device? + get-node node>name comp 0= ( true|false ) + IF + disk-alias-num dup 1 + to disk-alias-num + s" disk" \ all block devices will be named "disk" + + \ this is a block-device. + \ check if parent is 'usb' and not 'hub' + \ if so this block-device is directly connected + \ to root-hub and must be the uDOC-device in Elba + s" usb" drop \ parent = usb controller ? (not hub) + get-node node>parent @ node>name + comp 0= \ parent node starts with 'usb' ? + IF ( true|false ) + 1 s" hdd" \ add extra alias hdd1 for IntFlash + 2dup type 2 pick . + 8 emit 2f emit + do-alias-setting + uDOC-present 1 and + IF + uDOC-present 2 or to uDOC-present \ present and ready + THEN + ELSE + ext-disk-alias not \ flag for first ext. disk already assigned + IF + TRUE to ext-disk-alias + 2 s" hdd" \ add extra alias hdd2 for first USB disk + 2dup type 2 pick . + 8 emit 2f emit + do-alias-setting + THEN + THEN + ELSE + 0 s" ??? " \ unknown device + THEN + THEN ( num name-str name-len ) + 2dup type 2 pick . + 8 emit 5d emit cr + do-alias-setting ; : usb-create-alias-name ( num -- str len ) >r s" ohciX" 2dup + 1- ( str len last-char-ptr R: num ) r> [char] 0 + swap c! ( str len R: ) ; - + + +\ ***************************************************** +\ This is a final check to see, if a uDOC-device +\ is ready for booting +\ If physically present, but not working, an +\ Error-LED must be activated (on ELBA only!) +\ ***************************************************** +\ uDOC is now replaced by ModFD (Modular-Flash-Drive) +\ due to right properties +\ 'sys-signal-modfd-fault' sends an IPMI-Message to +\ aMM for generating a log entry and to switch on +\ an error LED (call to libsystem->libipmi) +\ ***************************************************** +\ although there are IPMI-warnings defined concerning +\ detected media errors, it doesn't make sense to send +\ a warning when booting from this device is impossible. +\ The decision was made to send an error call in this +\ case as well +\ ***************************************************** +\ uDOC-present bits: +\ ***************************************************** +\ D0: any device is connected on port 3 of root-hub +\ D1: device on port 3 is directly connected (no hub) +\ D2: warnings were received (scancodes) +\ D3: OverCurrentIndicator on USB-Port was set +\ D7: flag, set while ModFD is beeing processed + +: uDOC-check ( -- ) +#ifdef ELBA + uDOC-present 7 and \ flags concerning ModFD device + CASE + 0 OF \ not present not detected + uDOC-present 8 and 0<> \ not detected due to OverCurrent? + IF + 0d emit ." * OverCurrent on ModFD *" cr + sys-signal-modfd-fault ( -- ) \ send IPMI-call to BMC + ELSE + 0d emit ." ModFD not present" cr + THEN + ENDOF + + 1 OF \ present but not detected by USB + 0d emit ." * ModFD not accessible *" cr + sys-signal-modfd-fault ( -- ) \ send IPMI-call to BMC + ENDOF + + 3 OF \ present and detected +\ 0d emit ." ModFD OK" cr + ENDOF + + 7 OF \ present and detected but with warnings + 0d emit ." * ModFD Warnings *" cr + sys-signal-modfd-fault ( -- ) \ send IPMI-call to BMC + ENDOF + + dup OF \ we have a fault in our firmware ! + s" *** ModFD detection error ***" usb-debug-print + ENDOF + ENDCASE +#endif +; + +\ ***************************************************** +\ check if actual processed device is ModFD and +\ then sets its warning bit +\ ***************************************************** +: uDOC-failure? ( -- ) + uDOC-present 80 and 0<> \ is ModFD actual beeing processed? + IF + uDOC-present 04 or to uDOC-present \ set Warning flag + THEN +; + \ Scan all USB host controllers for attached devices: : usb-scan \ Scan all OHCI chips: - ." Scan USB... " cr + space ." Scan USB... " cr + true to scan-time? \ show proceeding signs + 0 to uDOC-present \ mark as not present + 0 to disk-alias-num \ start with disk0 + s" pci-disk-num" $find \ previously detected disks ? + IF + execute to disk-alias-num \ overwrite start number + ELSE + 2drop + THEN + 0 >r \ Counter for alias BEGIN r@ usb-create-alias-name @@ -88,6 +256,8 @@ VARIABLE ihandle-scsi-tran ELSE drop ( -- ) THEN + uDOC-check \ check if uDOC-device is present and working (ELBA only) + false to scan-time? \ suppress proceeding signs ; : usb-probe @@ -112,18 +282,12 @@ VARIABLE ihandle-scsi-tran open-dev ?dup IF dup to my-self dup ihandle>phandle dup set-node -\ ihandle-bulk-tran s" bulk" open-package -\ ihandle-scsi-tran s" scsi" open-package s" bulk" $open-package ihandle-bulk-tran ! - s" scsi" $open-package ihandle-scsi-tran ! - \ make-media-ready - s" close all " usb-debug-print close-dev 0 set-node 0 to my-self ihandle-bulk-tran close-package - ihandle-scsi-tran close-package ELSE s" can't open usb hub" usb-debug-print THEN diff --git a/slof/fs/usb/usb-storage-support.fs b/slof/fs/usb/usb-storage-support.fs index 5013c2c..f5033de 100644 --- a/slof/fs/usb/usb-storage-support.fs +++ b/slof/fs/usb/usb-storage-support.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -55,73 +55,6 @@ ; -\ --------------------------------------------------------------------------- -\ SCSI support package methods -\ --------------------------------------------------------------------------- - -: build-read ( address lba #blocks -- ) - s" build-read" ihandle-scsi @ $call-method -; - -: build-inquiry ( address alloc-len -- ) - s" build-inquiry" ihandle-scsi @ $call-method -; - -: return-inquiry ( address -- version# peripheral-device-type ) - s" return-inquiry" ihandle-scsi @ $call-method - ( version# peripheral-device-type ) -; - -: build-mode-sense ( address alloc-len page-code page-control -- ) - s" build-mode-sense" ihandle-scsi @ $call-method -; - -: build-read-capacity ( address -- ) - s" build-read-capacity" ihandle-scsi @ $call-method -; - -: build-seek ( address lba -- ) - s" build-seek" ihandle-scsi @ $call-method -; - -: build-start ( address -- ) - s" build-start" ihandle-scsi @ $call-method -; - -: build-stop ( address -- ) - s" build-stop" ihandle-scsi @ $call-method -; - -\ : build-load ( address -- ) -\ s" build-load" ihandle-scsi @ $call-method -\ ; - -\ : build-unload ( address -- ) -\ s" build-unload" ihandle-scsi @ $call-method -\ ; - -: build-test-unit-ready ( address -- ) - s" build-test-unit-ready" ihandle-scsi @ $call-method -; - -: return-test-unit-ready ( address -- status ) - s" return-unit-ready" ihandle-scsi @ $call-method ( status ) -; - -: build-read-toc ( address session# alloc-len -- ) - s" build-read-toc" ihandle-scsi @ $call-method -; - -: build-request-sense ( address alloc-len -- ) - s" build-request-sense" ihandle-scsi @ $call-method -; - -: return-request-sense ( address -- FALSE | ASCQ ASC sense-key TRUE ) - s" return-request-sense" ihandle-scsi @ $call-method - ( FALSE | ASCQ ASC sense-key TRUE ) -; - - \ ======================================================= \ NATIVE METHODS USED EITHER AT PROBE TIME OR TIME \ WHEN INSTANCE IS CREATED diff --git a/slof/fs/usb/usb-storage-wrapper.fs b/slof/fs/usb/usb-storage-wrapper.fs index eb3d547..c783541 100644 --- a/slof/fs/usb/usb-storage-wrapper.fs +++ b/slof/fs/usb/usb-storage-wrapper.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License diff --git a/slof/fs/usb/usb-storage.fs b/slof/fs/usb/usb-storage.fs index bea4d64..f23c27a 100644 --- a/slof/fs/usb/usb-storage.fs +++ b/slof/fs/usb/usb-storage.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -21,8 +21,6 @@ s" block" device-type 2 encode-int s" #address-cells" property 0 encode-int s" #size-cells" property -#include <packages/scsi-support.fs> - \ ----------------------------------------------------------- \ Specific properties \ ----------------------------------------------------------- @@ -49,12 +47,12 @@ s" block" device-type 0 VALUE resp-size 0 VALUE resp-buffer INSTANCE VARIABLE ihandle-bulk -INSTANCE VARIABLE ihandle-scsi INSTANCE VARIABLE ihandle-deblocker INSTANCE VARIABLE flag INSTANCE VARIABLE count -0 VALUE max-transfer -0 VALUE block-size +0 VALUE max-transfer +200 VALUE block-size \ default (512 Bytes) +-1 VALUE max-block-num \ highest reported block-number \ ------------------------------------------------------- @@ -87,7 +85,8 @@ s" usb-storage-support.fs" INCLUDED TO resp-size TO resp-buffer \ dump buffer in debug-mode - usb-debug-flag IF + usb-debug-flag + IF command-buffer 0E + c@ TO bulk-cmd-len s" cmd-length: " bulk-cmd-len usb-debug-print-val command-buffer bulk-cmd-len 0E + dump cr @@ -95,114 +94,123 @@ s" usb-storage-support.fs" INCLUDED 6 TO bulk-cnt \ 2 old value FALSE dup - BEGIN 0= WHILE - drop - \ prepare and send bulk CBW - 1 1 bulk-out-toggle command-buffer 1f mps-bulk-out - ( pt ed-type toggle buffer length mps-bulk-out ) - my-usb-address bulk-out-ep 7 lshift or - ( pt ed-type toggle buffer length mps address ) - rw-endpoint swap ( TRUE toggle | FALSE toggle ) - to bulk-out-toggle ( TRUE | FALSE ) - IF - s" resp-size : " resp-size usb-debug-print-val - resp-size 0<> IF \ do we need a response ?! - \ read the bulk response - 0 1 bulk-in-toggle resp-buffer resp-size mps-bulk-in - ( pt ed-type toggle buffer length mps-bulk-in ) - my-usb-address bulk-in-ep 7 lshift or - ( pt ed-type toggle buffer length mps address ) - rw-endpoint swap ( TRUE toggle | FALSE toggle ) - to bulk-in-toggle ( TRUE | FALSE ) - ELSE - TRUE - THEN - + BEGIN + 0= + WHILE + drop + \ prepare and send bulk CBW + 1 1 bulk-out-toggle command-buffer 1f mps-bulk-out + ( pt ed-type toggle buffer length mps-bulk-out ) + my-usb-address bulk-out-ep 7 lshift or + ( pt ed-type toggle buffer length mps address ) + rw-endpoint swap ( TRUE toggle | FALSE toggle ) + to bulk-out-toggle ( TRUE | FALSE ) IF - \ read the bulk CSW - 0 1 bulk-in-toggle csw-buffer D mps-bulk-in - ( pt ed-type toggle buffer length mps-bulk-in ) - my-usb-address bulk-in-ep 7 lshift or - ( pt ed-type toggle buffer length mps address ) - rw-endpoint swap ( TRUE toggle | FALSE toggle ) - to bulk-in-toggle ( TRUE | FALSE ) - IF - s" Command successful." usb-debug-print - TRUE dup + s" resp-size : " resp-size usb-debug-print-val + resp-size 0<> + IF \ do we need a response ?! + \ read the bulk response + 0 1 bulk-in-toggle resp-buffer resp-size mps-bulk-in + ( pt ed-type toggle buffer length mps-bulk-in ) + my-usb-address bulk-in-ep 7 lshift or + ( pt ed-type toggle buffer length mps address ) + rw-endpoint swap ( TRUE toggle | FALSE toggle ) + to bulk-in-toggle ( TRUE | FALSE ) ELSE - s" Command failed in CSW stage" usb-debug-print - FALSE dup + TRUE + THEN + IF \ read the bulk CSW + 0 1 bulk-in-toggle csw-buffer D mps-bulk-in + ( pt ed-type toggle buffer length mps-bulk-in ) + my-usb-address bulk-in-ep 7 lshift or + ( pt ed-type toggle buffer length mps address ) + rw-endpoint swap ( TRUE toggle | FALSE toggle ) + to bulk-in-toggle ( TRUE | FALSE ) + IF + s" Command successful." usb-debug-print + TRUE dup + ELSE + s" Command failed in CSW stage" usb-debug-print + FALSE dup + THEN + ELSE + s" Command failed while receiving DATA... read CSW..." usb-debug-print + \ STALLED: Get CSW to send the CBW again + 0 1 bulk-in-toggle csw-buffer D mps-bulk-in + ( pt ed-type toggle buffer length mps-bulk-in ) + my-usb-address bulk-in-ep 7 lshift or + ( pt ed-type toggle buffer length mps address ) + rw-endpoint swap ( TRUE toggle | FALSE toggle ) + to bulk-in-toggle ( TRUE | FALSE ) + IF + s" OK evaluate the CSW ..." usb-debug-print + csw-buffer c + c@ dup TO itest + s" CSW Status: " itest usb-debug-print-val + dup + 2 = + IF \ Phase Error + s" Phase error do a bulk reset-recovery ..." usb-debug-print + bulk-out-ep bulk-in-ep my-usb-address + bulk-reset-recovery-procedure + THEN + \ ELSE + \ don't abort if the read fails. + 1 = + IF \ Command failed + s" Command Failed do a bulk-reset-recovery" usb-debug-print + bulk-out-ep bulk-in-ep my-usb-address + bulk-reset-recovery-procedure + THEN + THEN + FALSE dup THEN ELSE - s" Command failed while receiving DATA... read CSW..." usb-debug-print - \ STALLED: Get CSW to send the CBW again - 0 1 bulk-in-toggle csw-buffer D mps-bulk-in - ( pt ed-type toggle buffer length mps-bulk-in ) - my-usb-address bulk-in-ep 7 lshift or - ( pt ed-type toggle buffer length mps address ) - rw-endpoint swap ( TRUE toggle | FALSE toggle ) - to bulk-in-toggle ( TRUE | FALSE ) - IF - s" OK evaluate the CSW ..." usb-debug-print - csw-buffer c + c@ dup TO itest - s" CSW Status: " itest usb-debug-print-val - dup - 2 = IF \ Phase Error - s" Phase error do a bulk reset-recovery ..." usb-debug-print - bulk-out-ep bulk-in-ep my-usb-address - bulk-reset-recovery-procedure - THEN - \ ELSE - \ don't abort if the read fails. - 1 = IF \ Command failed - s" Command Failed do a bulk-reset-recovery" usb-debug-print - bulk-out-ep bulk-in-ep my-usb-address - bulk-reset-recovery-procedure - THEN - THEN + s" Command failed while Sending CBW ..." usb-debug-print FALSE dup THEN - ELSE - s" Command failed while Sending CBW ..." usb-debug-print - FALSE dup - THEN - bulk-cnt 1 - TO bulk-cnt - bulk-cnt 0= IF - 2drop FALSE dup - THEN + bulk-cnt 1 - TO bulk-cnt + bulk-cnt 0= + IF + 2drop FALSE dup + THEN REPEAT ; \ --------------------------------------------------------------- -\ Method to 1. Send the INQUIRY command 2. Recieve and analyse +\ Method to 1. Send the INQUIRY command 2. Receive and analyse \ (pending) INQUIRY data \ --------------------------------------------------------------- +scsi-open +usb-debug-flag to scsi-param-debug \ copy debug flag + +24 CONSTANT inquiry-length \ was 20 : inquiry ( -- ) s" usb-storage: inquiry" usb-debug-print - command-buffer 1 20 80 lun 0C + command-buffer 1 inquiry-length 80 lun scsi-length-inquiry ( address tag transfer-len direction lun command-len ) build-cbw - \ command-buffer SCSI-COMMAND-OFFSET + 20 ( address alloc-len ) - 20 command-buffer SCSI-COMMAND-OFFSET + ( alloc-len address ) + inquiry-length command-buffer SCSI-COMMAND-OFFSET + ( alloc-len address ) scsi-build-inquiry - - \ s" command buffer:" usb-debug-print - \ command-buffer 0C dump cr - \ build-inquiry - \ s" build-inquiry command buffer:" usb-debug-print - \ command-buffer 0C dump cr - response-buffer 20 do-bulk-command + response-buffer inquiry-length erase \ provide clean buffer + response-buffer inquiry-length do-bulk-command IF s" Successfully read INQUIRY data" usb-debug-print - \ response-buffer 8 + c@ 8 vendor-id-str - \ usb-debug-flag IF - response-buffer .inquiry-text cr - \ response-buffer 8 + 16 dump cr \ dump the rsponsed message - \ THEN + 0d emit space space + response-buffer c@ \ get 'Peripheral Device Type' (PDT) + CASE + 0 OF ." BLOCK-DEV: " ENDOF \ SCSI Block Device + 5 OF ." CD-ROM : " ENDOF + 7 OF ." OPTICAL : " ENDOF + e OF ." RED-BLOCK: " ENDOF \ SCSI Reduced Block Device + dup dup OF ." ? (" . 8 emit 29 emit 2 spaces ENDOF + ENDCASE + space + \ create vendor identification in device property + response-buffer 8 + 16 encode-string s" ident-str" property + response-buffer .inquiry-text ELSE - \ TRUE ABORT" USB device transaction error. (inquiry)" 5040 error" (USB) Device transaction error. (inquiry)" ABORT THEN @@ -225,13 +233,11 @@ s" usb-storage-support.fs" INCLUDED command-buffer SCSI-COMMAND-OFFSET + ( address ) read-cap-10>reserved1 c! + response-buffer 8 erase \ provide clean buffer response-buffer 8 do-bulk-command IF s" Successfully read READ CAPACITY data" usb-debug-print - \ response-buffer 8 dump cr \ dump the rsponsed message - response-buffer scsi-get-capacity-10 .capacity-text cr ELSE - \ TRUE ABORT" USB device transaction error. (capacity)" 5040 error" (USB) Device transaction error. (capacity)" ABORT THEN @@ -244,11 +250,11 @@ s" usb-storage-support.fs" INCLUDED \ ------------------------------------------------------------------- : test-unit-ready ( -- TRUE | FALSE ) - command-buffer 1 0 80 lun 0c + command-buffer 1 0 80 lun scsi-length-test-unit-ready \ was: 0c ( address tag transfer-len direction lun command-len ) build-cbw command-buffer SCSI-COMMAND-OFFSET + ( address ) - build-test-unit-ready + scsi-build-test-unit-ready ( cdb -- ) response-buffer 0 do-bulk-command IF s" Successfully read test unit ready data" usb-debug-print @@ -267,6 +273,30 @@ s" usb-storage-support.fs" INCLUDED THEN ; +\ **************************************************** +\ multiple checks of 'test-unit-ready' with timeout +\ **************************************************** +: wait-for-unit-ready ( -- TRUE|FALSE ) + s" --> WAIT: test-unit-ready ... " usb-debug-print + d# 100 ( count ) \ up to 10 seconds + BEGIN ( count ) + dup 0> ( count flag ) + test-unit-ready \ dup IF 2b ELSE 2d THEN emit + not and ( count flag ) + WHILE + 1- ( count ) + d# 100 wait-proceed \ wait 100 ms + REPEAT ( count ) + 0= + IF + s" ** Device not ready ** " usb-debug-print + FALSE + ELSE + TRUE + THEN +; + + \ ------------------------------------------------- \ Method to 1. read sense data 2. analyse sesnse \ data(pending) @@ -274,15 +304,19 @@ s" usb-storage-support.fs" INCLUDED : request-sense ( -- ) s" request-sense: Command ready." usb-debug-print - command-buffer 1 12 80 lun 0c + command-buffer 1 12 80 lun scsi-length-request-sense ( address tag transfer-len direction lun command-len ) build-cbw - command-buffer SCSI-COMMAND-OFFSET + 12 ( address alloc-len ) - build-request-sense +\ -scsi-supp- command-buffer SCSI-COMMAND-OFFSET + 12 ( address alloc-len ) +\ -scsi-supp- build-request-sense + + 12 command-buffer SCSI-COMMAND-OFFSET + ( alloc-len cdb ) + scsi-build-request-sense ( alloc-len cdb -- ) + response-buffer 12 do-bulk-command IF - s" Read Sense data successfully" usb-debug-print - \ response-buffer 12 dump cr \ dump the rsponsed message + s" Read Sense data successfully" usb-debug-print + \ response-buffer 12 dump cr \ dump the rsponsed message ELSE \ TRUE ABORT" USB device transaction error. (request-sense)" 5040 error" (USB) Device transaction error. (request-sense)" @@ -291,11 +325,15 @@ s" usb-storage-support.fs" INCLUDED ; : start ( -- ) - command-buffer 1 0 80 lun 0c + command-buffer 1 0 80 lun scsi-length-start-stop-unit ( address tag transfer-len direction lun command-len ) build-cbw - command-buffer SCSI-COMMAND-OFFSET + ( address ) - build-start +\ -scsi-supp- command-buffer SCSI-COMMAND-OFFSET + ( address ) +\ -scsi-supp- build-start + + command-buffer SCSI-COMMAND-OFFSET + ( cdb ) + scsi-const-start scsi-build-start-stop-unit ( state# cdb -- ) + response-buffer 0 do-bulk-command IF s" Start successfully" usb-debug-print @@ -310,11 +348,15 @@ s" usb-storage-support.fs" INCLUDED \ To transmit SCSI Stop command : stop ( -- ) - command-buffer 1 0 80 lun 0c + command-buffer 1 0 80 lun scsi-length-start-stop-unit ( address tag transfer-len direction lun command-len ) build-cbw - command-buffer SCSI-COMMAND-OFFSET + ( address ) - build-stop +\ -scsi-supp- command-buffer SCSI-COMMAND-OFFSET + ( address ) +\ -scsi-supp- build-stop + + command-buffer SCSI-COMMAND-OFFSET + ( cdb ) + scsi-const-stop scsi-build-start-stop-unit ( state# cdb -- ) + response-buffer 0 do-bulk-command IF s" Stop successfully" usb-debug-print @@ -334,9 +376,23 @@ s" usb-storage-support.fs" INCLUDED \ ------------------------------------------------------------- \ block device's seek \ ------------------------------------------------------------- +\ if anything is wrong in the boot device, a seek-request can +\ occur that exceeds the limits of the device in the following +\ read-command. So checking is required and the appropriate +\ return-value has to be returned +\ Spec requires -1 if operation fails and 0 or 1 if it succeeds !! +\ ------------------------------------------------------------- -: seek ( pos-hi pos-lo -- status ) - s" seek" ihandle-deblocker @ $call-method +: seek ( pos-lo pos-hi -- status ) + 2dup lxjoin max-block-num block-size * > + IF + ." ** Seek Error: pos too large (" + dup . over . ." -> " max-block-num block-size * . + ." ) ** " cr + -1 \ see spec-1275 page 183 + ELSE + s" seek" ihandle-deblocker @ $call-method + THEN ; @@ -353,22 +409,32 @@ s" usb-storage-support.fs" INCLUDED \ read-blocks to be used by deblocker \ ------------------------------------------------------------- : read-blocks ( address block# #blocks -- #read-blocks ) - block-size * command-buffer ( address block# transfer-len command-buffer ) - 1 2 pick 80 lun 0c build-cbw ( address block# transfer-len ) - dup to temp1 ( address block# transfer-len) - block-size / ( address block# #blocks ) - command-buffer ( address block# #block command-addr ) - SCSI-COMMAND-OFFSET + -rot ( address command-addr block# #blocks ) - build-read ( address ) - temp1 do-bulk-command + 2dup + max-block-num > IF - s" Read data successfully" usb-debug-print + ." ** Requested block too large " + 2dup + ." (" .d ." -> " max-block-num .d + bs emit ." ) ... read aborted **" cr + nip nip \ leave #blocks on stack ELSE - \ TRUE ABORT" USB device transaction error. (read-blocks)" - 5040 error" (USB) Device transaction error. (read-blocks)" - ABORT + block-size * command-buffer ( address block# transfer-len command-buffer ) + 1 2 pick 80 lun 0c build-cbw ( address block# transfer-len ) + dup to temp1 ( address block# transfer-len ) + block-size / ( address block# #blocks ) + command-buffer ( address block# #blocks command-addr ) + SCSI-COMMAND-OFFSET + ( address block# #blocks cdb ) + scsi-build-read? ( block# #blocks cdb -- length ) + command-buffer 0e + c! \ update bCBWCBLength-field with resulting CDB length + temp1 ( address length ) + do-bulk-command + IF + s" Read data successfully" usb-debug-print + ELSE + \ TRUE ABORT" USB device transaction error. (read-blocks)" + 5040 error" (USB) Device transaction error. (read-blocks)" + ABORT + THEN + temp1 block-size / ( #read-blocks ) THEN - temp1 block-size / ( #read-blocks ) ; \ ------------------------------------------------ @@ -376,9 +442,6 @@ s" usb-storage-support.fs" INCLUDED \ condition. \ ------------------------------------------------ -0 VALUE temp1 -0 VALUE temp2 -0 VALUE temp3 d# 800 CONSTANT media-ready-retry : make-media-ready ( -- ) @@ -399,29 +462,28 @@ d# 800 CONSTANT media-ready-retry ABORT THEN request-sense - response-buffer return-request-sense - ( FALSE | ascq asc sense-key TRUE ) + response-buffer scsi-get-sense-ID? ( addr -- false | sense-ID true ) IF - to temp1 ( ascq asc ) - to temp2 ( ascq ) - to temp3 - temp1 2 = temp2 3a = and ( TRUE | FALSE ) - IF - 5010 error" (USB) No Media found! Check for the drawer/inserted media." - ABORT - THEN - temp1 2 = temp2 06 = and ( TRUE | FALSE ) - IF - 5020 error" (USB) Unknown media format." - ABORT - THEN - temp1 0<> temp2 4 = temp3 2 = and and ( TRUE | FALSE ) - IF - start stop - THEN + ffff00 AND \ remaining: sense-key ASC + CASE + 023a00 OF \ MEDIUM NOT PRESENT (02 3a 00) + 5010 error" (USB) No Media found! Check for the drawer/inserted media." + ABORT + ENDOF + + 020400 OF \ LOGICAL DRIVE NOT READY - INITIALIZATION REQUIRED + 5010 error" (USB) No Media found! Check for the drawer/inserted media." + ABORT + ENDOF + + 033000 OF \ CANNOT READ MEDIUM - UNKNOWN FORMAT + 5020 error" (USB) Unknown media format." + ABORT + ENDOF + ENDCASE THEN THEN - d# 10 ms + d# 10 ms \ wait maximum 10ms * 800 (=8s) REPEAT usb-debug-flag IF ." make-media-ready finished after " @@ -429,6 +491,76 @@ d# 800 CONSTANT media-ready-retry THEN ; +\ ------------------------------------------------ +\ read and show devices capacity +\ ------------------------------------------------ +: .showcap + space + test-unit-ready drop \ initial command + request-sense + response-buffer scsi-get-sense-ID? ( addr -- false | sense-ID true ) + IF + dup FFFF00 and 023a00 = ( sense-id flag ) + IF + uDOC-failure? + 023a02 = \ see sense-codes SPC-3 clause 4.5.6 + IF + ." Tray Open!" + ELSE + ." No Media" + THEN + ELSE ( sense-id ) + drop + wait-for-unit-ready + IF + read-capacity + response-buffer scsi-get-capacity-10 space .capacity-text + ELSE + request-sense + response-buffer scsi-get-sense-ID? ( addr -- false | sense-ID true ) + IF + dup ff0000 and 040000 = \ sense-code = 4 ? + IF + ." *HW-ERROR*" + uDOC-failure? + ELSE + dup FFFF00 and 023a00 = IF uDOC-failure? THEN + CASE ( sense-ID ) + \ see SPC-3 clause 4.5.6 + 023a00 OF ." No Media " ENDOF + 023a02 OF ." Tray Open! " ENDOF + dup OF ." ? " ENDOF + ENDCASE + THEN + THEN + THEN + THEN + ELSE + ." ?? " + THEN +; + + + +: init-dev-ready + test-unit-ready drop + 4 >r \ loop-counter + 0 0 + BEGIN + 2drop + request-sense + response-buffer scsi-get-sense-data ( ascq asc sense-key ) + 0<> r> 1- dup >r 0<> AND \ loop-counter or sense-key + WHILE + REPEAT + 2drop + r> drop +; + + + +scsi-close \ no further scsi words required + \ Set up the block-size of the device, using the READ CAPACITY command. \ Note: Media must be ready (=> make-media-ready) or READ CAPACITY @@ -436,6 +568,12 @@ d# 800 CONSTANT media-ready-retry : (init-block-size) read-capacity + response-buffer l@ dup 0<> + IF + to max-block-num \ highest block-number + ELSE + -1 to max-block-num \ indeterminate + THEN response-buffer 4 + l@ to block-size s" usb-storage: block-size=" block-size usb-debug-print-val @@ -447,7 +585,6 @@ d# 800 CONSTANT media-ready-retry : open ( -- TRUE ) s" usb-storage: open" usb-debug-print ihandle-bulk s" bulk" (open-package) - ihandle-scsi s" scsi" (open-package) make-media-ready (init-block-size) \ Init block-size before opening the deblocker @@ -464,7 +601,6 @@ d# 800 CONSTANT media-ready-retry : close ( -- ) ihandle-deblocker (close-package) - ihandle-scsi (close-package) ihandle-bulk (close-package) ; @@ -472,15 +608,15 @@ d# 800 CONSTANT media-ready-retry \ Set device name according to type : (init-device-name) ( -- ) + init-dev-ready inquiry response-buffer c@ CASE - 1 OF s" tape" device-name ENDOF - 5 OF s" cdrom" device-name s" CDROM found" usb-debug-print ENDOF - 0 OF s" sbc-dev" device-name s" SBC Direct acces device" usb-debug-print ENDOF - \ make-media-redy ENDOF \ read-capacity ENDOF - 7 OF s" optical" device-name s" Optical memory found" usb-debug-print ENDOF - 0E OF s" rbc-dev" device-name s" RBC direct acces device found" usb-debug-print ENDOF + 1 OF .showcap s" tape" device-name ENDOF + 5 OF .showcap s" cdrom" device-name s" CDROM found" usb-debug-print ENDOF + 0 OF .showcap s" sbc-dev" device-name s" SBC Direct access device" usb-debug-print ENDOF + 7 OF .showcap s" optical" device-name s" Optical memory found" usb-debug-print ENDOF + 0E OF .showcap s" rbc-dev" device-name s" RBC direct acces device found" usb-debug-print ENDOF \ dup OF s" storage" device-name ENDOF ENDCASE ; @@ -490,16 +626,14 @@ d# 800 CONSTANT media-ready-retry : (initial-setup) ihandle-bulk s" bulk" (open-package) - ihandle-scsi s" scsi" (open-package) - device-init (init-device-name) - set-cdrom-alias + set-drive-alias 200 to block-size \ Default block-size, will be overwritten in "open" 10000 to max-transfer - + ihandle-bulk (close-package) - ihandle-scsi (close-package) ; (initial-setup) + diff --git a/slof/fs/usb/usb-support.fs b/slof/fs/usb/usb-support.fs index 9fa2f02..08ff9bd 100644 --- a/slof/fs/usb/usb-support.fs +++ b/slof/fs/usb/usb-support.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -26,9 +26,6 @@ VARIABLE controlxfer-cmd drop 3drop 2drop FALSE EXIT ( FALSE ) THEN TO temp1 ( dir addr dlen setup-packet MPS ep-fun ) - usb-test-flag IF - s" controlxfer: Allocated ED: " temp1 usb-debug-print-val - THEN temp1 zero-out-an-ed-except-link ( dir addr dlen setup-packet MPS ep-fun ) temp1 ed>eattr l@-le or temp1 ed>eattr l!-le ( dir addr dlen setup-ptr MPS ) dup TO temp2 10 lshift temp1 ed>eattr l@-le or temp1 ed>eattr l!-le @@ -141,37 +138,43 @@ VARIABLE controlxfer-cmd \ Free the ED and TDs associated with it. \ PENDING: Above said. -20 CONSTANT max-retire-td +10 CONSTANT max-retire-td : (transfer-wait-for-doneq) ( ed-ptr -- TRUE | FALSE ) dup ( ed-ptr ed-ptr ) hcctrhead rl!-le ( ed-ptr ) HC-enable-control-list-processing ( ed-ptr ) 0 TO td-retire-count ( ed-ptr ) - 0 TO poll-timer BEGIN ( ed-ptr ) + 0 TO poll-timer ( ed-ptr ) + BEGIN td-retire-count num-tds <> ( ed-ptr TRUE | FALSE ) poll-timer max-retire-td < and ( ed-ptr TRUE | FALSE ) - WHILE - (HC-CHECK-WDH) IF ( ed-ptr ) - hchccadneq rl@-le find-td-list-tail-and-size nip ( ed-ptr n ) + WHILE + (HC-CHECK-WDH) ( ed-ptr ) + IF + hchccadneq l@-le find-td-list-tail-and-size nip ( ed-ptr n ) td-retire-count + TO td-retire-count ( ed-ptr ) - hchccadneq rl@-le dup ( ed-ptr done-td done-td ) - (td-list-status) IF ( ed-ptr done-td failed-td CCcode ) + hchccadneq l@-le dup ( ed-ptr done-td done-td ) + (td-list-status) ( ed-ptr done-td failed-td CCcode ) + IF \ keep condition code of TD on return stack dup >r s" (transfer-wait-for-doneq: USB device communication error." usb-debug-print ( ed-ptr done-td failed-td CCcode R: CCcode ) - dup 4 = swap dup 5 = rot or IF ( ed-ptr done-td failed-td CCcode R: CCcode ) + dup 4 = swap dup 5 = rot or ( ed-ptr done-td failed-td CCcode R: CCcode ) + IF max-retire-td TO poll-timer ( ed-ptr done-td failed-td CCcode R: CCcode ) THEN - ( ed-ptr done-td failed-td CCcode R: CCcode) - usb-debug-flag IF + ( ed-ptr done-td failed-td CCcode R: CCcode ) + usb-debug-flag + IF s" CC code ->" type . cr s" Failing TD contents:" type cr display-td ELSE 2drop - THEN ( ed-ptr done-td R: CCcode) - controlxfer-cmd @ GET-MAX-LUN = r> 4 = and IF + THEN ( ed-ptr done-td R: CCcode ) + controlxfer-cmd @ GET-MAX-LUN = r> 4 = and + IF s" (transfer-wait-for-doneq): GET-MAX-LUN ControlXfer STALLed" usb-debug-print \ Condition Code = 4 means that the device does not support multiple LUNS @@ -186,26 +189,21 @@ VARIABLE controlxfer-cmd THEN THEN ( ed-ptr done-td ) (free-td-list) ( ed-ptr ) - 0 hchccadneq rl!-le ( ed-ptr ) + 0 hchccadneq l!-le ( ed-ptr ) (HC-ACK-WDH) \ TDs were written to DOne queue. ACK the HC. - usb-test-flag IF - s" Retired = " td-retire-count usb-debug-print-val - s" Total = " num-tds usb-debug-print-val - THEN THEN poll-timer 1+ TO poll-timer - 4 ms \ longer 1 ms - usb-test-flag IF - s" poll-timer: " poll-timer usb-debug-print-val - THEN + 4 ms \ longer 1 ms REPEAT ( ed-ptr ) disable-control-list-processing ( ed-ptr ) - td-retire-count num-tds <> IF ( ed-ptr ) + td-retire-count num-tds <> ( ed-ptr ) + IF dup display-descriptors ( ed-ptr ) s" maximum of retire " usb-debug-print THEN free-ed - td-retire-count num-tds <> IF + td-retire-count num-tds <> + IF FALSE ( FALSE ) ELSE TRUE ( TRUE ) @@ -434,59 +432,61 @@ VARIABLE controlxfer-cmd : (wait-td-retire) ( -- ) 0 TO num-rw-retired-tds - FALSE TO while-failed BEGIN - num-rw-retired-tds num-rw-tds < ( TRUE | FALSE ) - while-failed FALSE = and ( TRUE | FALSE ) - WHILE - d# 800 (wait-for-DOne-q) IF ( TD-list ) + FALSE TO while-failed + BEGIN + num-rw-retired-tds num-rw-tds < ( TRUE | FALSE ) + while-failed FALSE = and ( TRUE | FALSE ) + WHILE + d# 5000 (wait-for-done-q) ( TD-list TRUE|FALSE ) + IF dup find-td-list-tail-and-size nip ( td-list size ) num-rw-retired-tds + TO num-rw-retired-tds ( td-list ) - dup (td-list-status) IF ( td-list failed-TD CC ) - dup 4 = IF - saved-list-type CASE - 0 OF - 0 0 control-std-clear-feature - s" clear feature " usb-debug-print - ENDOF - 1 OF \ clean bulk stalled - s" clear bulk when stalled " usb-debug-print - disable-bulk-list-processing \ disable procesing - saved-rw-ed ed>eattr l@-le dup \ extract - 780 and 7 rshift 80 or \ endpoint and - swap 7f and \ usb addr - control-std-clear-feature - ENDOF - 2 OF - 0 saved-rw-ed ed>eattr l@-le - control-std-clear-feature - ENDOF - dup OF - s" default case von Michael" usb-debug-print - ENDOF - ENDCASE - ELSE - usb-debug-flag IF - s" TD failed with CC code: " type . cr - THEN - drop drop - \ TRUE ABORT" USB device transaction error." - 5040 error" (USB) device transaction error (wait-td-retrire)." - ABORT + dup (td-list-status) ( td-list failed-TD CC ) + IF + dup 4 = + IF + saved-list-type + CASE + 0 OF + 0 0 control-std-clear-feature + s" clear feature " usb-debug-print + ENDOF + 1 OF \ clean bulk stalled + s" clear bulk when stalled " usb-debug-print + disable-bulk-list-processing \ disable procesing + saved-rw-ed ed>eattr l@-le dup \ extract + 780 and 7 rshift 80 or \ endpoint and + swap 7f and \ usb addr + control-std-clear-feature + ENDOF + 2 OF + 0 saved-rw-ed ed>eattr l@-le + control-std-clear-feature + ENDOF + dup OF + s" unknown status " usb-debug-print + ENDOF + ENDCASE + ELSE ( td-list failed-TD CC ) + ." TD failed " 5b emit .s 5d emit cr + 5040 error" (USB) device transaction error (wait-td-retire)." + ABORT THEN - 2drop drop - TRUE TO while-failed \ transaction failed - NEXT-TD 0<> IF \ clean the TD if we - NEXT-TD (free-td-list) \ had a stalled - THEN + 2drop drop + TRUE TO while-failed \ transaction failed + NEXT-TD 0<> \ clean the TD if we + IF + NEXT-TD (free-td-list) \ had a stalled + THEN THEN - (free-td-list) + (free-td-list) ELSE - drop \ drop td-list pointer + drop \ drop td-list pointer + scan-time? IF 2e emit THEN \ show proceeding dots TRUE TO while-failed - s" time out wait for done" usb-debug-print - 5 ms \ wait for bad device + s" time out wait for done" usb-debug-print + 20 ms \ wait for bad device THEN - REPEAT ; @@ -544,7 +544,7 @@ VARIABLE controlxfer-cmd : (do-rw-endpoint) ( pt ed-type toggle buffer length mps address -- toggle TRUE|toggle FALSE ) 4 pick ( pt ed-type toggle buffer length mps address toggle ) - TO saved-rw-start-toggle ( pt ed-type toggle buffer length mps address) + TO saved-rw-start-toggle ( pt ed-type toggle buffer length mps address ) (ed-prepare-rw) ( FALSE | pt ed-type toggle buffer length mps ) invert IF FALSE EXIT THEN (td-prepare-rw) ( FALSE | pt ed-type toggle buffer length mps head ) diff --git a/slof/fs/vpd-bootlist.fs b/slof/fs/vpd-bootlist.fs index 50c3cac..5a08215 100644 --- a/slof/fs/vpd-bootlist.fs +++ b/slof/fs/vpd-bootlist.fs @@ -1,5 +1,5 @@ \ ***************************************************************************** -\ * Copyright (c) 2004, 2007 IBM Corporation +\ * Copyright (c) 2004, 2008 IBM Corporation \ * All rights reserved. \ * This program and the accompanying materials \ * are made available under the terms of the BSD License @@ -10,28 +10,64 @@ \ * IBM Corporation - initial implementation \ ****************************************************************************/ +4 CONSTANT vpd-bootlist-size + +\ Bootable devices +00 CONSTANT FLOPPY +01 CONSTANT USB +02 CONSTANT SAS +03 CONSTANT SATA +04 CONSTANT ISCSI +05 CONSTANT ISCSICRITICAL +06 CONSTANT NET +07 CONSTANT NOTSPECIFIED +08 CONSTANT HDD0 +09 CONSTANT HDD1 +0a CONSTANT HDD2 +0b CONSTANT HDD3 +0c CONSTANT CDROM +0e CONSTANT HDD4 +10 CONSTANT SCSI + : check-bootlist ( -- true | false ) - vpd-bootlist l@ - dup 0= IF - ( bootlist == 0 means that probably nothing from vpd has been received ) - s" Boot list could not be read from VPD" log-string cr - s" Boot watchdog has been rearmed" log-string cr - 2 set-watchdog - exit THEN - FFFFFFFF = IF - ( bootlist all FFs means that the vpd has no useful information ) - .banner - -6b boot-exception-handler - \ The next message is duplicate, but sent w. log-string - s" Boot list successfully read from VPD but no useful information received" log-string cr - s" Please specify the boot device in the management module" log-string cr - s" Specified Boot Sequence not valid" mm-log-warning - false ELSE true THEN ; + vpd-bootlist l@ + dup 0= IF + ( bootlist == 0 means that probably nothing from vpd has been received ) + s" Boot list could not be read from VPD" log-string cr + s" Boot watchdog has been rearmed" log-string cr + 2 set-watchdog + EXIT + THEN + + FFFFFFFF = IF + ( bootlist all FFs means that the vpd has no useful information ) + .banner + -6b boot-exception-handler + \ The next message is duplicate, but sent w. log-string + s" Boot list successfully read from VPD but no useful information received" log-string cr + s" Please specify the boot device in the management module" log-string cr + s" Specified Boot Sequence not valid" mm-log-warning + false + EXIT + THEN + + true +; \ the following words are necessary for vpd-boot-import defer set-boot-device defer add-boot-device -defer bootdevice + +\ select-install? is a flag which is used in the SMS panel #20 +\ "Select/Install Boot Devices". +\ This panel can be used to temporarily override the boot device. +false VALUE select-install? + +\ select/install-path stores string address and string length of the +\ device node chosen in the SMS panel #20 "Select/Install Boot Devices" +\ This device node is prepended to the boot path if select-install? is +\ true. +CREATE select/install-path 2 cells allot \ Import boot device list from VPD \ If none, keep the existing list in NVRAM @@ -39,45 +75,60 @@ defer bootdevice : vpd-boot-import ( -- ) 0 0 set-boot-device + + select-install? IF + select/install-path 2@ add-boot-device + THEN + vpd-read-bootlist check-bootlist IF 4 0 DO vpd-bootlist i + c@ CASE 6 OF \ cr s" 2B Booting from Network" log-string cr - s" net" furnish-boot-file $cat strdup add-boot-device + furnish-boot-file strdup add-boot-device ENDOF - \ 7 OF cr s" Booting from no device not supported" 2dup mm-log-warning log-string cr - \ 7 OF cr s" 2B Booting from NVRAM boot-device list: " boot-device $cat - \ log-string cr - \ boot-device add-boot-device ENDOF - - 8 OF \ cr s" 2B Booting from disk0" log-string cr - s" disk disk0" add-boot-device ENDOF + HDD0 OF \ cr s" 2B Booting from hdd0" log-string cr + s" disk hdd0" add-boot-device ENDOF - 9 OF \ cr s" 2B Booting from disk1" log-string cr - s" disk1" add-boot-device ENDOF + HDD1 OF \ cr s" 2B Booting from hdd1" log-string cr + s" hdd1" add-boot-device ENDOF - A OF \ cr s" 2B Booting from disk2" log-string cr - s" disk2" add-boot-device ENDOF + HDD2 OF \ cr s" 2B Booting from hdd2" log-string cr + s" hdd2" add-boot-device ENDOF - B OF \ cr s" 2B Booting from disk3" log-string cr - s" disk3" add-boot-device ENDOF + HDD3 OF \ cr s" 2B Booting from hdd3" log-string cr + s" hdd3" add-boot-device ENDOF - C OF \ cr s" 2B Booting from CDROM" log-string cr + CDROM OF \ cr s" 2B Booting from CDROM" log-string cr s" cdrom" add-boot-device ENDOF - E OF \ cr s" 2B Booting from disk4" log-string cr - s" disk4" add-boot-device ENDOF + HDD4 OF \ cr s" 2B Booting from hdd4" log-string cr + s" hdd4" add-boot-device ENDOF F OF \ cr s" 2B Booting from SAS - w. Timeout" log-string cr - s" sas" add-boot-device ENDOF - 10 OF \ cr s" 2B Booting from SAS - Continuous Retry" log-string cr - s" sas" add-boot-device ENDOF + s" sas" add-boot-device ENDOF + + SCSI OF \ cr s" 2B Booting from SAS - Continuous Retry" log-string cr + s" sas" add-boot-device ENDOF + ENDCASE LOOP - bootdevice 2@ dup >r s" boot-device" $setenv - r> IF 0 ELSE -6b THEN + bootdevice 2@ nip + IF 0 + ELSE + \ Check for all no device -> use boot-device + vpd-bootlist l@ 07070707 = IF 0 ELSE -6b THEN + THEN ELSE -6a THEN boot-exception-handler ; + +: vpd-bootlist-restore-default ( -- ) + NOTSPECIFIED vpd-bootlist 0 + c! + NOTSPECIFIED vpd-bootlist 1 + c! + NOTSPECIFIED vpd-bootlist 2 + c! + HDD0 vpd-bootlist 3 + c! + vpd-write-bootlist +; + diff --git a/slof/fs/xmodem.fs b/slof/fs/xmodem.fs new file mode 100644 index 0000000..a111708 --- /dev/null +++ b/slof/fs/xmodem.fs @@ -0,0 +1,120 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2008 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ * IBM Corporation - initial implementation +\ ****************************************************************************/ + + +01 CONSTANT XM-SOH \ Start of header +04 CONSTANT XM-EOT \ End-of-transmission +06 CONSTANT XM-ACK \ Acknowledge +15 CONSTANT XM-NAK \ Neg. acknowledge + +0 VALUE xm-retries \ Retry count +0 VALUE xm-block# + + +\ * +\ * Internal function: +\ * wait <timeout> seconds for a new character +\ * +: xmodem-get-byte ( timeout -- byte|-1 ) + d# 1000 * + 0 DO + key? IF key UNLOOP EXIT THEN + 1 ms + LOOP + -1 +; + + +\ * +\ * Internal function: +\ * Receive one XMODEM packet, check block number and check sum. +\ * +: xmodem-rx-packet ( address -- success? ) + 1 xmodem-get-byte \ Get block number + dup 0 < IF + 2drop false EXIT \ Timeout + THEN + 1 xmodem-get-byte \ Get neg. block number + dup 0 < IF + 3drop false EXIT \ Timeout + THEN + rot 0 ( blk# ~blk# address chksum ) + 80 0 DO + 1 xmodem-get-byte dup 0 < IF ( blk# ~blk# address chksum byte ) + 3drop 2drop UNLOOP FALSE EXIT + THEN + dup 3 pick c! ( blk# ~blk# address chksum byte ) + + swap 1+ swap ( blk# ~blk# address+1 chksum' ) + LOOP + ( blk# ~blk# address chksum ) + \ Check sum: + 0ff and + 1 xmodem-get-byte <> IF + \ CRC failed! + 3drop FALSE EXIT + THEN + drop ( blk# ~blk# ) + \ finally check if block numbers are ok: + over xm-block# <> IF + \ Wrong block number! + 2drop FALSE EXIT + THEN ( blk# ~blk# ) + ff xor = +; + + +\ * +\ * Internal function: +\ * Load file to given address via XMODEM protocol +\ * +: (xmodem-load) ( address -- bytes ) + 1 to xm-block# + 0 to xm-retries + dup + BEGIN + d# 10 xmodem-get-byte dup >r + CASE + XM-SOH OF + dup xmodem-rx-packet IF + \ A packet has been received successfully + XM-ACK emit + 80 + ( start-addr next-addr R: rx-byte ) + 0 to xm-retries \ Reset retry count + xm-block# 1+ ff and to xm-block# \ Increase current block# + ELSE + \ Error while receiving packet + XM-NAK emit + xm-retries 1+ to xm-retries \ Increase retry count + THEN + ENDOF + XM-EOT OF + XM-ACK emit + ENDOF + dup OF + XM-NAK emit + xm-retries 1+ to xm-retries \ Increase retry count + ENDOF + ENDCASE + r> XM-EOT = + xm-retries d# 10 >= OR + UNTIL ( start-address end-address ) + swap - ( bytes received ) +; + + +\ * +\ * Load file to load-base via XMODEM protocol +\ * +: xmodem-load ( -- bytes ) + cr ." Waiting for start of XMODEM upload..." cr + load-base (xmodem-load) +; diff --git a/slof/lowmem.S b/slof/lowmem.S index 024e78f..3f99320 100644 --- a/slof/lowmem.S +++ b/slof/lowmem.S @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -15,15 +15,28 @@ .section ".slof.loader","ax" - mr r16, r4 # ROM Base - mfspr r17, HSPRG1 # Fixme, will be done in pcd + /* this only works if paflof is running below 4GB */ + lis r31, fdt_start@h /* save address of */ + ori r31, r31, fdt_start@l /* flattened device */ + std r3, 0(r31) /* tree */ - # fill in handler address + /* this only works if paflof is running below 4GB */ + lis r31, romfs_base@h /* save address of */ + ori r31, r31, romfs_base@l /* the romfs */ + std r4, 0(r31) + /* this only works if paflof is running below 4GB */ + lis r31, epapr_magic@h /* if it is an epapr compliant */ + ori r31, r31, epapr_magic@l /* low level firmware; then r6 */ + std r6, 0(r31) /* contains the epapr magic */ + + /* fill in handler address */ + + /* this only works if paflof is running below 4GB */ lis r3, _slof_text@h ori r3, r3, _slof_text@l ld r3, 0(r3) std r3, XVECT_M_HANDLER(0) - # GO! + /* GO! */ ba 0x100 diff --git a/slof/paflof.c b/slof/paflof.c index 423ed8a..895a18f 100644 --- a/slof/paflof.c +++ b/slof/paflof.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -20,40 +20,86 @@ #include "paflof.h" #include <string.h> +#include <stdint.h> #include ISTR(TARG,h) #define LAST_ELEMENT(x) x[sizeof x / sizeof x[0] - 1] #include ISTR(TARG,c) +unsigned long fdt_start; +unsigned long romfs_base; +unsigned long epapr_magic; -void engine(long error, long reason) + +// the actual engine +long engine(int mode, long param_1, long param_2) { - cell *restrict dp; - cell *restrict rp; + // For Exceptions: + // mode = ENGINE_MODE_PARAM_1 | MODE_PARAM_2 + // (param_1 = error, param_2 = reason) + // + // For Push: + // mode = ENGINE_MODE_PARAM_1 | ENGINE_MODE_NOP + // + // For Pop: + // mode = ENGINE_MODE_NOP | ENGINE_MODE_POP + // + // For Evaluate: + // mode = ENGINE_MODE_PARAM_1 | MODE_PARAM_2 | ENGINE_MODE_EVAL + // (param_1 = strlen(string), param_2 = string) + cell *restrict ip; cell *restrict cfa; - cell handler_stack[160]; + static cell handler_stack[160]; + static cell c_return[2]; + static cell dummy; #include "prep.h" #include "dict.xt" - static int init_lw = 0; - if (init_lw == 0) { - init_lw = 1; + static int init_engine = 0; + if (init_engine == 0) { + // one-time initialisation + init_engine = 1; LAST_ELEMENT(xt_FORTH_X2d_WORDLIST).a = xt_LASTWORD; + + // stack-pointers + dp = the_data_stack - 1; + rp = handler_stack - 1; + + // return-address for "evaluate" personality + dummy.a = &&over; + c_return[1].a = &dummy; } - dp = the_data_stack; - rp = handler_stack - 1; - if (error != 0x100) { - dp->n = reason; - dp++; + if (mode & ENGINE_MODE_PARAM_2) { + (++dp)->n = param_2; + } + if (mode & ENGINE_MODE_PARAM_1) { + (++dp)->n = param_1; } - dp->n = error; - ip = xt_SYSTHROW; + + if (mode & ENGINE_MODE_NOP ) { + goto over; + } + + if (mode & ENGINE_MODE_EVAL) { + (++rp)->a = c_return; + ip = xt_EVALUATE + 2 + ((10 + CELLSIZE - 1) / CELLSIZE); + } else { + ip = xt_SYSTHROW; + } #include "prim.code" #include "board.code" #include ISTR(TARG,code) + + + // Only reached in case of non-exception call +over: if (mode & ENGINE_MODE_POP) { + return ((dp--)->n); + } else { + return 0; + } } diff --git a/slof/paflof.h b/slof/paflof.h index cf2f07f..81182cb 100644 --- a/slof/paflof.h +++ b/slof/paflof.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -15,4 +15,23 @@ #define TIBSIZE 256 + #define POCKETSIZE 256 +#define NUMPOCKETS 16 + +// engine mode bits +#define ENGINE_MODE_PARAM_1 0x0001 +#define ENGINE_MODE_PARAM_2 0x0002 +#define ENGINE_MODE_NOP 0x0004 +#define ENGINE_MODE_EVAL 0x0008 +#define ENGINE_MODE_POP 0x0010 + +// engine calls +#define forth_eval(s) engine(ENGINE_MODE_PARAM_1|ENGINE_MODE_PARAM_2|ENGINE_MODE_EVAL, \ + strlen((s)), (long)(s)) +#define forth_eval_pop(s) engine(ENGINE_MODE_PARAM_1|ENGINE_MODE_PARAM_2|ENGINE_MODE_EVAL|ENGINE_MODE_POP, \ + strlen((s)), (long)(s)) + +#define forth_push(v) engine(ENGINE_MODE_PARAM_1|ENGINE_MODE_NOP, v, 0) + +#define forth_pop() engine(ENGINE_MODE_NOP|ENGINE_MODE_POP, 0, 0) diff --git a/slof/ppc64.c b/slof/ppc64.c index 6fdad05..ff94d3d 100644 --- a/slof/ppc64.c +++ b/slof/ppc64.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -12,6 +12,38 @@ #include <cpu.h> +/* the exception frame should be page aligned + * the_exception_frame is used by the handler to store a copy of all + * registers after an exception; this copy can then be used by paflof's + * exception handler to printout a register dump */ +cell the_exception_frame[0x400/CELLSIZE] __attribute__ ((aligned(PAGE_SIZE)));; + +/* the_client_frame is the register save area when starting a client */ +cell the_client_frame[0x1000/CELLSIZE] __attribute__ ((aligned(0x100))); +cell the_client_stack[0x2000/CELLSIZE] __attribute__ ((aligned(0x100))); +/* THE forth stack */ +cell the_data_stack[0x2000/CELLSIZE] __attribute__ ((aligned(0x100))); +/* the forth return stack */ +cell the_return_stack[0x2000/CELLSIZE] __attribute__ ((aligned(0x100))); + +/* forth stack and return-stack pointers */ +cell *restrict dp; +cell *restrict rp; + +/* terminal input buffer */ +cell the_tib[0x1000/CELLSIZE] __attribute__ ((aligned(0x100))); +/* temporary string buffers */ +char the_pockets[NUMPOCKETS*POCKETSIZE] __attribute__ ((aligned(0x100))); + +cell the_comp_buffer[0x1000/CELLSIZE] __attribute__ ((aligned(0x100))); + +cell the_heap[HEAP_SIZE/CELLSIZE] __attribute__ ((aligned(0x1000))); +cell *the_heap_start = &the_heap[0]; +cell *the_heap_end = &the_heap[HEAP_SIZE/CELLSIZE]; + +extern void io_putchar(unsigned char); + + static unsigned long __attribute__((noinline)) call_c(cell arg0, cell arg1, cell arg2, cell entry) { @@ -37,3 +69,36 @@ writeLogByte_wrapper(long x, long y) clr_ci(); return result; } + + +/** + * Standard write function for the libc. + * + * @param fd file descriptor (should always be 1 or 2) + * @param buf pointer to the array with the output characters + * @param count number of bytes to be written + * @return the number of bytes that have been written successfully + */ +int write(int fd, const void *buf, int count) +{ + int i; + char *ptr = (char *)buf; + + if (fd != 1 && fd != 2) + return 0; + + for (i = 0; i < count; i++) { + if (*ptr == '\n') + io_putchar('\r'); + io_putchar(*ptr++); + } + + return i; +} + +/* This should probably be temporary until a better solution is fount */ +void asm_cout(long Character,long UART,long NVRAM __attribute__((unused))) +{ + if(UART) + io_putchar(Character); +} diff --git a/slof/ppc64.code b/slof/ppc64.code index e2866fb..620446c 100644 --- a/slof/ppc64.code +++ b/slof/ppc64.code @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/slof/ppc64.h b/slof/ppc64.h index eff7383..2e9d90c 100644 --- a/slof/ppc64.h +++ b/slof/ppc64.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -13,38 +13,22 @@ #include <cpu.h> #include "types.h" +#define PAGE_SIZE 4096 +#define HEAP_SIZE 0x800000 + #define SET_CI set_ci() #define CLR_CI clr_ci() // The big Forth source file that contains everything but the core engine. // We include it as a hunk of data into the C part of SLOF; at startup // time, this will be EVALUATE'd. +extern char _binary_OF_fsi_start[], _binary_OF_fsi_end[]; -extern char _slof_start[]; -extern char _slof_here_start[]; - -#define the_exception_frame ((cell *) (_slof_start)) -#define the_client_frame ((cell *) (_slof_start+0x400)) -#define the_data_stack ((cell *) (_slof_start+0x2000)) -#define the_return_stack ((cell *) (_slof_start+0x4000)) -#define the_system_stack ((cell *) (_slof_start+0x6000)) - -// these two really need to be implemented as a plain -// normal BUFFER: in the data space -#define the_tib ((cell *) (_slof_start+0x8000)) -#define the_pockets ((cell *) (_slof_start+0x9000)) -#define the_comp_buffer ((cell *) (_slof_start+0xA000)) -#define the_client_stack ((cell *) (_slof_start+0xBf00)) - -// wasteful, but who cares. 14MB should be enough. -#define the_mem ((cell *) (_slof_here_start)) - -#define the_heap_start ((cell *) (_slof_start+0x700000)) -#define the_heap_end ((cell *) (_slof_start+0x700000+0x800000)) +extern cell the_mem[]; /* Space for the dictionary / the HERE pointer */ +extern cell *restrict dp; +extern cell *restrict rp; -extern char _binary_OF_fsi_start[], _binary_OF_fsi_end[]; -//extern char _binary_vmlinux_start[], _binary_vmlinux_end[]; void client_entry_point(); extern unsigned long call_client(cell); diff --git a/slof/ppc64.in b/slof/ppc64.in index d7da086..56ab66d 100644 --- a/slof/ppc64.in +++ b/slof/ppc64.in @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -96,7 +96,7 @@ dfr(BOOT-EXCEPTION-HANDLER) col(NICEINIT DOTICK DROP DOTO EMIT DOTICK ((FIND)) DOTO (FIND) DOTICK 2DROP DOTO (REVEAL) LIT((type_u)_binary_OF_fsi_start) LIT((type_u)_binary_OF_fsi_end) OVER - DOTICK EVALUATE CATCH BOOT-EXCEPTION-HANDLER) -static cell xt_SYSTHROW[] = { _0 RDEPTH_X21 DUP LIT(0x100) _X3d _0BRANCH(3) NICEINIT BRANCH(7) DUP LIT(0x3800) _X3d _0BRANCH(1) CLIENTINTERFACE PRINT_X2d_STATUS QUIT }; +static cell xt_SYSTHROW[] = { _0 RDEPTH_X21 DUP LIT(0x100) _X3d _0BRANCH(5) SWAP DROP NICEINIT BRANCH(7) DUP LIT(0x3800) _X3d _0BRANCH(1) CLIENTINTERFACE PRINT_X2d_STATUS QUIT }; // sentinel, leave it here! col(LASTWORD ) diff --git a/slof/prep.h b/slof/prep.h index e020b6b..03950ba 100644 --- a/slof/prep.h +++ b/slof/prep.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/slof/prim.code b/slof/prim.code index af4601c..0b9603e 100644 --- a/slof/prim.code +++ b/slof/prim.code @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -9,8 +9,6 @@ * Contributors: * IBM Corporation - initial implementation *****************************************************************************/ -// ============================================================================ -// ============================================================================ // @@ -70,7 +68,16 @@ PRIM(COMP_X2d_BUFFER) PUSH; TOS.a = the_comp_buffer; MIRP PRIM(HEAP_X2d_START) PUSH; TOS.a = the_heap_start; MIRP PRIM(HEAP_X2d_END) PUSH; TOS.a = the_heap_end; MIRP +// FDT pointer +PRIM(FDT_X2d_START) PUSH; TOS.u = fdt_start; MIRP +// romfs-base +PRIM(ROMFS_X2d_BASE) PUSH; TOS.u = romfs_base; MIRP + +// if the low level firmware is epapr compliant it will put the +// epapr magic into r6 before starting paflof +// epapr-magic is a copy of r6 +PRIM(EPAPR_X2d_MAGIC) PUSH; TOS.u = epapr_magic; MIRP // Codefields. code_DOCOL: @@ -421,7 +428,7 @@ code_FILL: switch (((type_u)d | (type_u)size) & (sizeof(type_u)-1)) { case 0: { type_u *up = (type_u *)d; -#ifndef UNIX +#if (__LONG_MAX__ > 2147483647L) fill_v |= fill_v << 32; #endif while ((size-=sizeof(type_u)) >= 0) @@ -534,3 +541,9 @@ PRIM(_X3f_PICK) if (b) { NOS = TOS; } POP; MIRP + +/* zcount ( zstr -- str len ) */ +PRIM(ZCOUNT) + type_u len = strlen(TOS.a); + PUSH; TOS.u = len; +MIRP diff --git a/slof/prim.in b/slof/prim.in index 6da069f..47c09ed 100644 --- a/slof/prim.in +++ b/slof/prim.in @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -9,9 +9,6 @@ * Contributors: * IBM Corporation - initial implementation *****************************************************************************/ -// ============================================================================ -// ============================================================================ - // // Copyright 2002,2003,2004 Segher Boessenkool <segher@kernel.crashing.org> @@ -27,6 +24,14 @@ cod(COMP-BUFFER) cod(HEAP-START) cod(HEAP-END) +// flattened device tree start address +cod(FDT-START) +// romfs start address +cod(ROMFS-BASE) +// if the low level firmware is epapr compliant it will put the +// epapr magic into r6 before starting paflof +// epapr-magic is a copy of r6 +cod(EPAPR-MAGIC) cod(BRANCH) _ADDING _O cod(0BRANCH) _ADDING _O @@ -93,7 +98,4 @@ cod(EXECUTE) cod(MOVE) // cod(RMOVE64) cod(RMOVE) - - - - +cod(ZCOUNT) diff --git a/slof/ref.pl b/slof/ref.pl index 61f7a88..b21f139 100644 --- a/slof/ref.pl +++ b/slof/ref.pl @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License diff --git a/slof/types.h b/slof/types.h index 6f5d146..e347cc3 100644 --- a/slof/types.h +++ b/slof/types.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License diff --git a/tools/Makefile b/tools/Makefile index 9c31a9d..6de8fe6 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License diff --git a/tools/create_reloc_table.sh b/tools/create_reloc_table.sh index b7ebb5f..8cacb74 100755 --- a/tools/create_reloc_table.sh +++ b/tools/create_reloc_table.sh @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * Copyright (c) 2004, 2008 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License diff --git a/tools/gen_reloc_table.c b/tools/gen_reloc_table.c index 17c06f9..b2e2176 100644 --- a/tools/gen_reloc_table.c +++ b/tools/gen_reloc_table.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License |