diff options
| author | fishsoupisgood <github@madingley.org> | 2019-04-29 01:17:54 +0100 | 
|---|---|---|
| committer | fishsoupisgood <github@madingley.org> | 2019-05-27 03:43:43 +0100 | 
| commit | 3f2546b2ef55b661fd8dd69682b38992225e86f6 (patch) | |
| tree | 65ca85f13617aee1dce474596800950f266a456c /roms/SLOF/board-qemu/slof | |
| download | qemu-master.tar.gz qemu-master.tar.bz2 qemu-master.zip  | |
Diffstat (limited to 'roms/SLOF/board-qemu/slof')
34 files changed, 3963 insertions, 0 deletions
diff --git a/roms/SLOF/board-qemu/slof/.gitignore b/roms/SLOF/board-qemu/slof/.gitignore new file mode 100644 index 00000000..55268aa6 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/.gitignore @@ -0,0 +1 @@ +OF.ffs diff --git a/roms/SLOF/board-qemu/slof/Makefile b/roms/SLOF/board-qemu/slof/Makefile new file mode 100644 index 00000000..283f77d3 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/Makefile @@ -0,0 +1,126 @@ +# ***************************************************************************** +# * Copyright (c) 2004, 2011 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 ../Makefile.dirs + +include $(TOPBRDDIR)/config +include $(TOPCMNDIR)/make.rules + +all: version.o Makefile.dep OF.ffs paflof $(SLOFCMNDIR)/xvect.bin + +CPPFLAGS = -I$(LIBCMNDIR)/libbootmsg -I$(LIBCMNDIR)/libhvcall \ +	   -I$(LIBCMNDIR)/libvirtio -I$(LIBCMNDIR)/libnvram \ +	   -I$(LIBCMNDIR)/libusb -I$(LIBCMNDIR)/libveth \ +	   -I$(LIBCMNDIR)/libe1k +SLOF_LIBS = \ +	$(LIBCMNDIR)/libbootmsg.a \ +	$(LIBCMNDIR)/libelf.a \ +	$(LIBCMNDIR)/libhvcall.a \ +	$(LIBCMNDIR)/libvirtio.a \ +	$(LIBCMNDIR)/libusb.a \ +	$(LIBCMNDIR)/libnvram.a \ +	$(LIBCMNDIR)/libveth.a \ +	$(LIBCMNDIR)/libe1k.a +BOARD_SLOF_IN = \ +	$(LIBCMNDIR)/libhvcall/hvcall.in \ +	$(LIBCMNDIR)/libvirtio/virtio.in \ +	$(LIBCMNDIR)/libusb/usb.in \ +	$(LIBCMNDIR)/libbootmsg/bootmsg.in \ +	$(LIBCMNDIR)/libelf/libelf.in \ +	$(LIBCMNDIR)/libnvram/libnvram.in \ +	$(LIBCMNDIR)/libbases/libbases.in \ +	$(LIBCMNDIR)/libveth/veth.in \ +	$(LIBCMNDIR)/libe1k/e1k.in +BOARD_SLOF_CODE = $(BOARD_SLOF_IN:%.in=%.code) + +include $(SLOFCMNDIR)/Makefile.inc + +AS1FLAGS  = $(CPPFLAGS) $(RELEASE) $(FLAG) $(CPUARCHDEF)  -Wa,-mregnames + +%.o: %.S +	$(CC) $(AS1FLAGS) -o $@ -c $^ + +FPPINCLUDES = -I. -I$(SLOFCMNDIR)/fs -I$(SLOFCMNDIR) + +USB_FFS_FILES = \ +	$(SLOFCMNDIR)/fs/devices/pci-class_02.fs \ +	$(SLOFCMNDIR)/fs/devices/pci-class_0c.fs \ +	$(SLOFCMNDIR)/fs/usb/dev-hci.fs \ +	$(SLOFCMNDIR)/fs/usb/slofdev.fs \ +	$(SLOFCMNDIR)/fs/usb/dev-parent-calls.fs \ +	$(SLOFCMNDIR)/fs/usb/dev-keyb.fs \ +	$(SLOFCMNDIR)/fs/usb/dev-mouse.fs \ +	$(SLOFCMNDIR)/fs/usb/dev-storage.fs \ +	$(SLOFCMNDIR)/fs/usb/dev-hub.fs + + +VIO_FFS_FILES = \ +	$(SLOFBRDDIR)/pci-device_1af4_1000.fs \ +	$(SLOFBRDDIR)/pci-device_1af4_1001.fs \ +	$(SLOFBRDDIR)/pci-device_1af4_1004.fs \ +	$(SLOFBRDDIR)/pci-device_1af4_1009.fs \ +	$(SLOFBRDDIR)/vio-hvterm.fs \ +	$(SLOFBRDDIR)/vio-vscsi.fs \ +	$(SLOFBRDDIR)/vio-veth.fs \ +	$(SLOFBRDDIR)/rtas-nvram.fs \ +	$(SLOFBRDDIR)/virtio-net.fs \ +	$(SLOFBRDDIR)/virtio-block.fs \ +	$(SLOFBRDDIR)/virtio-fs.fs \ +	$(SLOFBRDDIR)/dev-null.fs \ +	$(SLOFBRDDIR)/virtio-scsi.fs + +# Files that should go into the ROM fs (and so have to be listed in OF.ffs): +OF_FFS_FILES = \ +	$(SLOFCMNDIR)/fs/ide.fs \ +	$(SLOFCMNDIR)/fs/fbuffer.fs \ +	$(SLOFCMNDIR)/fs/graphics.fs \ +	$(SLOFCMNDIR)/fs/generic-disk.fs \ +	$(SLOFCMNDIR)/fs/dma-function.fs \ +	$(SLOFCMNDIR)/fs/pci-device.fs \ +	$(SLOFCMNDIR)/fs/pci-bridge.fs \ +	$(SLOFCMNDIR)/fs/pci-properties.fs \ +	$(SLOFCMNDIR)/fs/pci-config-bridge.fs \ +	$(SLOFCMNDIR)/fs/update_flash.fs \ +	$(SLOFCMNDIR)/fs/xmodem.fs \ +	$(SLOFCMNDIR)/fs/scsi-disk.fs \ +	$(SLOFCMNDIR)/fs/scsi-host-helpers.fs \ +	$(SLOFCMNDIR)/fs/scsi-probe-helpers.fs \ +	$(SLOFCMNDIR)/fs/scsi-support.fs \ +	$(SLOFBRDDIR)/default-font.bin \ +	$(SLOFBRDDIR)/pci-phb.fs \ +	$(SLOFBRDDIR)/rtas.fs \ +	$(SLOFBRDDIR)/pci-device_1234_1111.fs \ +	$(SLOFBRDDIR)/pci-device_1013_00b8.fs \ +	$(SLOFBRDDIR)/pci-device_8086_100e.fs \ +	$(SLOFBRDDIR)/e1k.fs \ +	$(FCODE_FFS_FILES) + +# Uncomment the following line to enable the USB code: +OF_FFS_FILES += $(USB_FFS_FILES) + +OF_FFS_FILES += $(VIO_FFS_FILES) + +OF_FFS_FILES := $(OF_FFS_FILES:%.fs=%.fsi) + +OF.ffs: Makefile $(SLOFCMNDIR)/Makefile.inc $(OF_FFS_FILES) +	$(MAKE) create_OF_ffs + +# Rules for cleaning up: +.PHONY: clean_here clean distclean + +clean_here: +	rm -f *.o OF.fsi OF.ffs + +clean: clean_here clean_slof + +distclean: clean_here distclean_slof diff --git a/roms/SLOF/board-qemu/slof/OF.fs b/roms/SLOF/board-qemu/slof/OF.fs new file mode 100644 index 00000000..561d8922 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/OF.fs @@ -0,0 +1,306 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2011 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 master file.  Everything else is included into here. + +hex + +' ll-cr to cr + +#include "header.fs" + +#include "hvterm.fs" + +#include "base.fs" + +\ Set default load-base to 0x4000 +4000 to default-load-base + +\ Little-endian accesses.  Also known as `wrong-endian'. +#include <little-endian.fs> + +: #join  ( lo hi #bits -- x )  lshift or ; +: #split ( x #bits -- lo hi )  2dup rshift dup >r swap lshift xor r> ; + +: blink ; +: reset-dual-emit ; +: console-clean-fifo ; +: bootmsg-nvupdate ; +: asm-cout 2drop drop ; + +#include "logging.fs" + +: log-string 2drop ; + +#include "bootmsg.fs" + +000 cp + +#include "exception.fs" + +: mm-log-warning 2drop ; + +: write-mm-log ( data length type -- status ) +	3drop 0 +; + +100 cp + +\ Input line editing. +#include "accept.fs" + +120 cp + +#include "dump.fs" + +cistack ciregs >r1 ! \ kernel wants a stack :-) + +140 cp + +#include "romfs.fs" + +200 cp + +#include <slof-logo.fs> + +201 cp + +#include <banner.fs> + +: .banner .slof-logo .banner ; + +220 cp + +DEFER find-boot-sector ( -- ) + +240 cp +\ Timebase frequency, in Hz. Start with a good default +\ Use device-tree later to fix it up +d# 512000000 VALUE tb-frequency   \ default value - needed for "ms" to work +-1 VALUE cpu-frequency + +#include "helper.fs" +260 cp + +#include <timebase.fs> + +270 cp + +#include <fcode/evaluator.fs> + +2e0 cp + +#include <quiesce.fs> + +300 cp + +#include <usb/usb-static.fs> + +320 cp + +#include <scsi-loader.fs> + +340 cp + +#include "fdt.fs" + +360 cp + +#include <root.fs> + +370 cp + +: check-boot-menu +   s" qemu,boot-menu" get-chosen IF +      decode-int 1 = IF +         ." Press F12 for boot menu." cr cr +      THEN +      2drop +   THEN +; +check-boot-menu + +380 cp + +\ Grab rtas from qemu +#include "rtas.fs" + +390 cp + +#include "virtio.fs" + +3f0 cp + +#include "tree.fs" + +800 cp + +#include "nvram.fs" + +880 cp + +#include "envvar.fs" +check-for-nvramrc + +890 cp + +#include "qemu-bootlist.fs" + +8a0 cp + +\ The client interface. +#include "client.fs" +\ ELF binary file format. +#include "elf.fs" +#include <loaders.fs> + +8a8 cp +CREATE version-str 10 ALLOT +0 value temp-ptr + +: dump-display-buffer +    disp-ptr to temp-ptr +    " SLOF **********************************************************************" terminal-write drop +    cr +    version-str get-print-version +    version-str @                   \ start +    version-str 8 + @               \ end +    over - terminal-write drop +    " Press 's' to enter Open Firmware." terminal-write drop +    cr cr +    temp-ptr disp-size > IF +	temp-ptr disp-size MOD +	dup +	prevga-disp-buf + swap disp-size swap - terminal-write drop +	temp-ptr disp-size MOD +	prevga-disp-buf swap 1 - terminal-write drop +    ELSE +	prevga-disp-buf temp-ptr terminal-write drop +    THEN +; + +: enable-framebuffer-output  ( -- ) +\ enable output on framebuffer +   s" screen" find-alias ?dup  IF +      \ we need to open/close the screen device once +      \ before "ticking" display-emit to emit +      open-dev close-node +      false to store-prevga? +      s" display-emit" $find  IF  +         to emit  +	 dump-display-buffer +      ELSE +         2drop +      THEN +   THEN +; + +enable-framebuffer-output + +8b0 cp + +\ Scan USB devices +usb-scan + +8c0 cp + +\ Claim remaining memory that is used by firmware: +romfs-base 400000 0 ' claim CATCH IF ." claim failed!" cr 2drop THEN drop + +8d0 cp + +: set-default-console +    s" linux,stdout-path" get-chosen IF +        decode-string +        ." Using default console: " 2dup type cr +        io +        2drop +    ELSE +        ." No console specified " +        " screen" find-alias dup IF nip THEN +        " keyboard" find-alias dup IF nip THEN +	AND IF +	  ." using screen & keyboard" cr +	  " screen" output +	  " keyboard" input +        ELSE +          " hvterm" find-alias IF +	    drop +	    ." using hvterm" cr +            " hvterm" io +	  ELSE +	    " /openprom" find-node ?dup IF +		set-node +		." and no default found, creating dev-null" cr +		" dev-null.fs" included +		" devnull-console" io +		0 set-node +	    THEN +	  THEN +        THEN +    THEN +; +set-default-console + +8e0 cp + +\ Check if we are booting a kernel passed by qemu, in which case +\ we skip initializing some devices + +0 VALUE direct-ram-boot-base +0 VALUE direct-ram-boot-size + +: (boot-ram) +    direct-ram-boot-size 0<> IF +        ." Booting from memory..." cr +	s" go-args 2@ " evaluate +	direct-ram-boot-base 0 +	s" true state-valid ! " evaluate +	s" disable-watchdog go-64" evaluate +    THEN +; + +8e8 cp + +: check-boot-from-ram +    s" qemu,boot-kernel" get-chosen IF +        decode-int -rot decode-int -rot ( n1 n2 p s ) +	decode-int -rot decode-int -rot ( n1 n2 n3 n4 p s ) +	2drop +	swap 20 << or to direct-ram-boot-size +	swap 20 << or to direct-ram-boot-base +	." Detected RAM kernel at " direct-ram-boot-base . +	." (" direct-ram-boot-size . ." bytes) " +	\ Override the boot-command word without touching the +	\ nvram environment +	s" boot-command" $create " (boot-ram)" env-string +    THEN +; +check-boot-from-ram + +8ff cp + +#include <start-up.fs> + +."      "   \ Clear last checkpoint + +#include <boot.fs> + +cr .(   Welcome to Open Firmware) +cr +#include "copyright-oss.fs" +cr cr + +\ this CATCH is to ensure the code bellow always executes:  boot may ABORT! +' start-it CATCH drop + +cr ." Ready!" diff --git a/roms/SLOF/board-qemu/slof/copyright-oss.fs b/roms/SLOF/board-qemu/slof/copyright-oss.fs new file mode 100644 index 00000000..e45b1940 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/copyright-oss.fs @@ -0,0 +1,16 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2011 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 +\ ****************************************************************************/ + +cr .(   Copyright (c) char ) emit .(  2004, 2011 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/roms/SLOF/board-qemu/slof/dev-null.fs b/roms/SLOF/board-qemu/slof/dev-null.fs new file mode 100644 index 00000000..d0ffad6b --- /dev/null +++ b/roms/SLOF/board-qemu/slof/dev-null.fs @@ -0,0 +1,35 @@ +\ Introduce a dummy console that will eat away all chars and make all +\ the components dependent on stdout happy. + +new-device +" devnull-console" device-name + +: open true ; +: close ; + +: write ( adr len -- actual ) +  nip +; + +: read  ( adr len -- actual ) +  nip +; + +: setup-alias +    " devnull-console" find-alias 0= IF +        " devnull-console" get-node node>path set-alias +    ELSE +        drop +    THEN +; + +: dummy-term-emit drop ; +: dummy-term-key  0 ; +: dummy-term-key? FALSE ; + +' dummy-term-emit to emit +' dummy-term-key  to key +' dummy-term-key? to key? + +setup-alias +finish-device diff --git a/roms/SLOF/board-qemu/slof/e1k.fs b/roms/SLOF/board-qemu/slof/e1k.fs new file mode 100644 index 00000000..51855be8 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/e1k.fs @@ -0,0 +1,98 @@ +\ ***************************************************************************** +\ * Copyright (c) 2013 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 +\ ****************************************************************************/ + +\ Handle e1000 device + +s" network" device-type + +INSTANCE VARIABLE obp-tftp-package +get-node CONSTANT my-phandle +10 config-l@ translate-my-address 3 not AND CONSTANT baseaddr + +0 VALUE e1k-priv +0 VALUE open-count + +: open  ( -- okay? ) +   open-count 0= IF +       open IF +	 baseaddr +         e1k-open dup not IF ." e1k-open failed" EXIT THEN +         drop TO e1k-priv +         true +      ELSE +         false +      THEN +   ELSE +      true +   THEN +   my-args s" obp-tftp" $open-package obp-tftp-package ! +   open-count 1 + to open-count +; + + +: close  ( -- ) +   my-phandle set-node +   open-count 0> IF +      open-count 1 - dup to open-count +      0= IF +         e1k-priv e1k-close +         close +      THEN +   THEN +   s" close" obp-tftp-package @ $call-method +; + +: read ( buf len -- actual ) +   dup IF +      e1k-read +   ELSE   +      nip +   THEN +; + +: write ( buf len -- actual ) +   dup IF +      e1k-write +   ELSE +      nip +   THEN +; + +: load  ( addr -- len ) +   s" load" obp-tftp-package @ $call-method +; + +: ping  ( -- ) +   s" ping" obp-tftp-package @ $call-method +; + +6 BUFFER: local-mac +: setup-mac ( -- ) +   pci-mem-enable +   " vendor-id" get-node get-property IF EXIT THEN +   decode-int nip nip +   " device-id" get-node get-property IF EXIT THEN +   decode-int nip nip +   baseaddr +   local-mac e1k-mac-setup IF +      encode-bytes  " local-mac-address"  property +   THEN +; + +setup-mac + +: setup-alias  ( -- ) +   " net" get-next-alias ?dup IF +      get-node node>path set-alias +   THEN +; +setup-alias diff --git a/roms/SLOF/board-qemu/slof/fdt.fs b/roms/SLOF/board-qemu/slof/fdt.fs new file mode 100644 index 00000000..8d4635f3 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/fdt.fs @@ -0,0 +1,435 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 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 +\ ****************************************************************************/ + +0 VALUE fdt-debug +TRUE VALUE fdt-cas-fix? + +\ Bail out if no fdt +fdt-start 0 = IF -1 throw THEN + +struct +  4 field >fdth_magic +  4 field >fdth_tsize +  4 field >fdth_struct_off +  4 field >fdth_string_off +  4 field >fdth_rsvmap_off +  4 field >fdth_version +  4 field >fdth_compat_vers +  4 field >fdth_boot_cpu +  4 field >fdth_string_size +  4 field >fdth_struct_size +drop + +h# d00dfeed constant OF_DT_HEADER +h#        1 constant OF_DT_BEGIN_NODE +h#        2 constant OF_DT_END_NODE +h#        3 constant OF_DT_PROP +h#        4 constant OF_DT_NOP +h#        9 constant OF_DT_END + +\ Create some variables early +0 value fdt-start-addr +0 value fdt-struct +0 value fdt-strings + +: fdt-init ( fdt-start -- ) +    dup to fdt-start-addr +    dup dup >fdth_struct_off l@ + to fdt-struct +    dup dup >fdth_string_off l@ + to fdt-strings +    drop +; +fdt-start fdt-init + +\ Dump fdt header for all to see and check FDT validity +: fdt-check-header ( -- ) +    fdt-start-addr dup 0 = IF +        ." No flat device tree !" cr drop -1 throw EXIT THEN +    hex +    fdt-debug IF +        ." Flat device tree header at 0x" dup . s" :" type cr +        ."  magic            : 0x" dup >fdth_magic l@ . cr +        ."  total size       : 0x" dup >fdth_tsize l@ . cr +        ."  offset to struct : 0x" dup >fdth_struct_off l@ . cr +        ."  offset to strings: 0x" dup >fdth_string_off l@ . cr +        ."  offset to rsvmap : 0x" dup >fdth_rsvmap_off l@ . cr +        ."  version          : " dup >fdth_version l@ decimal . hex cr +        ."  last compat vers : " dup >fdth_compat_vers l@ decimal . hex cr +        dup >fdth_version l@ 2 >= IF +            ."  boot CPU         : 0x" dup >fdth_boot_cpu l@ . cr +        THEN +        dup >fdth_version l@ 3 >= IF +            ."  strings size     : 0x" dup >fdth_string_size l@ . cr +        THEN +        dup >fdth_version l@ 17 >= IF +            ."  struct size      : 0x" dup >fdth_struct_size l@ . cr +        THEN +    THEN +    dup >fdth_magic l@ OF_DT_HEADER <> IF +        ." Flat device tree has incorrect magic value !" cr +	drop -1 throw EXIT +    THEN +    dup >fdth_version l@ 10 < IF +        ." Flat device tree has usupported version !" cr +	drop -1 throw EXIT +    THEN + +    drop +; +fdt-check-header + +\ Fetch next tag, skip nops and increment address +: fdt-next-tag ( addr -- nextaddr tag ) +  0	       	      	 	( dummy tag on stack for loop ) +  BEGIN +    drop			( drop previous tag ) +    dup l@			( read new tag ) +    swap 4 + swap		( increment addr ) +  dup OF_DT_NOP <> UNTIL 	( loop until not nop ) +; + +\ Parse unit name and advance addr +: fdt-fetch-unit ( addr -- addr $name ) +  dup from-cstring	       \  get string size +  2dup + 1 + 3 + fffffffc and -rot +; + +\ Update unit with information from the reg property... +\ ... this is required for the PCI nodes for example. +: fdt-reg-unit ( prop-addr prop-len -- ) +      decode-phys               ( prop-addr' prop-len' phys.lo ... phys.hi ) +      set-unit                  ( prop-addr' prop-len' ) +      2drop +; + +\ Lookup a string by index +: fdt-fetch-string ( index -- str-addr str-len )   +  fdt-strings + dup from-cstring +; + +: fdt-create-dec  s" decode-unit" $CREATE , DOES> @ hex64-decode-unit ; +: fdt-create-enc  s" encode-unit" $CREATE , DOES> @ hex64-encode-unit ; + +\ Check whether array contains an zero-terminated ASCII string: +: fdt-prop-is-string?  ( addr len -- string? ) +   dup 1 < IF 2drop FALSE EXIT THEN                \ Check for valid length +   1- +   2dup + c@ 0<> IF 2drop FALSE EXIT THEN          \ Check zero-termination +   test-string +; + +\ Encode fdt property to OF property +: fdt-encode-prop  ( addr len -- ) +   2dup fdt-prop-is-string? IF +      1- encode-string +   ELSE +      encode-bytes +   THEN +; + +\ Method to unflatten a node +: fdt-unflatten-node ( start -- end ) +  \ this can and will recurse +  recursive + +  \ Get & check first tag of node ( addr -- addr) +  fdt-next-tag dup OF_DT_BEGIN_NODE <> IF +    s" Weird tag 0x" type . " at start of node" type cr +    -1 throw +  THEN drop + +  new-device + +  \ Parse name, split unit address +  fdt-fetch-unit +  dup 0 = IF drop drop " /" THEN +  40 left-parse-string +  \ Set name +  device-name + +  \ Set preliminary unit address - might get overwritten by reg property +  dup IF +     " #address-cells" get-parent get-package-property IF +        2drop +     ELSE +        decode-int nip nip +	hex-decode-unit +	set-unit +     THEN +  ELSE 2drop THEN + +  \ Iterate sub tags +  BEGIN +    fdt-next-tag dup OF_DT_END_NODE <> +  WHILE +    dup OF_DT_PROP = IF +      \ Found property +      drop dup			( drop tag, dup addr     : a1 a1 ) +      dup l@ dup rot 4 +	( fetch size, stack is   : a1 s s a2) +      dup l@ swap 4 +		( fetch nameid, stack is : a1 s s i a3 ) +      rot			( we now have: a1 s i a3 s ) +      fdt-encode-prop rot	( a1 s pa ps i) +      fdt-fetch-string		( a1 s pa ps na ns ) +      2dup s" reg" str= IF +          2swap 2dup fdt-reg-unit 2swap +      THEN +      property +      + 8 + 3 + fffffffc and +    ELSE dup OF_DT_BEGIN_NODE = IF +      drop			( drop tag ) +      4 - +      fdt-unflatten-node +    ELSE +      drop -1 throw +    THEN THEN +  REPEAT drop \ drop tag + +  \ Create encode/decode unit +  " #address-cells" get-node get-package-property IF ELSE +    decode-int dup fdt-create-dec fdt-create-enc 2drop +  THEN + +  finish-device   +; + +\ Start unflattening +: fdt-unflatten-tree +    fdt-debug IF +        ." Unflattening device tree..." cr THEN +    fdt-struct fdt-unflatten-node drop +    fdt-debug IF +        ." Done !" cr THEN +; +fdt-unflatten-tree + +\ Find memory size +: fdt-parse-memory +    \ XXX FIXME Handle more than one memory node, and deal +    \     with RMA vs. full access +    " /memory@0" find-device +    " reg" get-node get-package-property IF throw -1 THEN + +    \ XXX FIXME Assume one entry only in "reg" property for now +    decode-phys 2drop decode-phys +    my-#address-cells 1 > IF 20 << or THEN +     +    fdt-debug IF +        dup ." Memory size: " . cr +    THEN +    \ claim.fs already released the memory between 0 and MIN-RAM-SIZE, +    \ so we've got only to release the remaining memory now: +    MIN-RAM-SIZE swap MIN-RAM-SIZE - release +    2drop device-end +; +fdt-parse-memory + + +\ Claim fdt memory and reserve map +: fdt-claim-reserve +    fdt-start-addr +    dup dup >fdth_tsize l@ 0 claim drop +    dup >fdth_rsvmap_off l@ + +    BEGIN +        dup dup x@ swap 8 + x@ +	dup 0 <> +    WHILE +	fdt-debug IF +	    2dup swap ." Reserve map entry: " . ." : " . cr +	THEN +	0 claim drop +	10 + +    REPEAT drop drop drop +; +fdt-claim-reserve  + + +\ The following functions are use to replace the FDT phandle and +\ linux,phandle properties with our own OF1275 phandles... + +\ This is used to check whether we successfully replaced a phandle value +0 VALUE (fdt-phandle-replaced) + +\ Replace phandle value in "interrupt-map" property +: fdt-replace-interrupt-map  ( old new prop-addr prop-len -- old new ) +   BEGIN +      dup                    ( old new prop-addr prop-len prop-len ) +   WHILE +      \ This is a little bit ugly ... we're accessing the property at +      \ hard-coded offsets instead of analyzing it completely... +      swap dup 10 +          ( old new prop-len prop-addr prop-addr+10 ) +      dup l@ 5 pick = IF +          \ it matches the old phandle value! +          3 pick swap l! +          TRUE TO (fdt-phandle-replaced) +      ELSE +          drop +      THEN +      ( old new prop-len prop-addr ) +      1c + swap 1c - +      ( old new new-prop-addr new-prop-len ) +   REPEAT +   2drop +; + +\ Replace one FDT phandle "old" with a OF1275 phandle "new" in the +\ whole tree: +: fdt-replace-all-phandles ( old new node -- ) +   \ ." Replacing in " dup node>path type cr +   >r +   s" interrupt-map" r@ get-property 0= IF +      ( old new prop-addr prop-len  R: node ) +      fdt-replace-interrupt-map +   THEN +   s" interrupt-parent" r@ get-property 0= IF +      ( old new prop-addr prop-len  R: node ) +      decode-int -rot 2drop                  ( old new val  R: node ) +      2 pick = IF                            ( old new      R: node ) +         dup encode-int s" interrupt-parent" r@ set-property +         TRUE TO (fdt-phandle-replaced) +      THEN +   THEN +   \ ... add more properties that have to be fixed here ... +   r> +   \ Now recurse over all child nodes:       ( old new node ) +   child BEGIN +      dup +   WHILE +      3dup RECURSE +      PEER +   REPEAT +   3drop +; + +\ Check whether a node has "phandle" or "linux,phandle" properties +\ and replace them: +: fdt-fix-node-phandle  ( node -- ) +   >r +   FALSE TO (fdt-phandle-replaced) +   s" phandle" r@ get-property 0= IF +      decode-int                       ( p-addr2 p-len2 val ) +      \ ." found phandle: " dup . cr +      r@ s" /" find-node               ( p-addr2 p-len2 val node root )   +      fdt-replace-all-phandles         ( p-addr2 p-len2 ) +      2drop +      (fdt-phandle-replaced) IF +         r@ set-node +         s" phandle" delete-property +         s" linux,phandle" delete-property +      ELSE +         diagnostic-mode? IF +            cr ." Warning: Did not replace phandle in " r@ node>path type cr +         THEN +      THEN +   THEN +   r> drop +; + +\ Recursively walk through all nodes to fix their phandles: +: fdt-fix-phandles  ( node -- ) +   \ ." fixing phandles of " dup node>path type cr +   dup fdt-fix-node-phandle +   child BEGIN +      dup +   WHILE +      dup RECURSE +      PEER +   REPEAT +   drop +   device-end +; + +: fdt-create-cas-node ( name  -- ) +    2dup +    2dup " memory@" find-substr 0 = IF +	fdt-debug IF ." Creating memory@ " cr THEN +	new-device +	2dup " @" find-substr nip device-name       \ Parse the node name +	2dup +	2dup " @" find-substr rot over + 1 + -rot - 1 - \ Jump to addr afte "@" +	parse-2int nip xlsplit set-unit                 \ Parse and set unit +	finish-device +    ELSE +	2dup " ibm,dynamic-reconfiguration-memory" find-substr 0 = IF +	    fdt-debug IF  ." Creating ibm,dynamic-reconfiguration-memory " cr THEN +	    new-device +	    device-name +	    finish-device +	ELSE +	    2drop 2drop +	    false to fdt-cas-fix? +	    ." Node not supported " cr +	    EXIT +	THEN +    THEN + +    find-node ?dup 0 <> IF set-node THEN +; + +: fdt-fix-cas-node ( start -- end ) +    recursive +    fdt-next-tag dup OF_DT_BEGIN_NODE <> IF +	." Error " cr +	false to fdt-cas-fix? +	EXIT +    THEN drop +    fdt-fetch-unit +    dup 0 = IF drop drop " /" THEN +    40 left-parse-string +    2swap ?dup 0 <> IF +	nip +	1 + + \ Add the string len +@ +    ELSE +	drop +    THEN +    fdt-debug IF ." Setting node: " 2dup type cr THEN +    2dup find-node ?dup 0 <> IF +	set-node 2drop +    ELSE +	fdt-debug IF ." Node not found, creating " 2dup type cr THEN +	fdt-create-cas-node +    THEN +    fdt-debug IF ." Current  now: " pwd cr THEN +    BEGIN +	fdt-next-tag dup OF_DT_END_NODE <> +    WHILE +	dup OF_DT_PROP = IF +	    fdt-debug IF ." Found property " cr THEN +	    drop dup		( drop tag, dup addr     : a1 a1 ) +	    dup l@ dup rot 4 +	( fetch size, stack is   : a1 s s a2) +	    dup l@ swap 4 +	( fetch nameid, stack is : a1 s s i a3 ) +	    rot			( we now have: a1 s i a3 s ) +	    fdt-encode-prop rot	( a1 s pa ps i) +	    fdt-fetch-string		( a1 s pa ps na ns ) +	    property +	    fdt-debug IF ." Setting property done " cr THEN +	    + 8 + 3 + fffffffc and +	ELSE dup OF_DT_BEGIN_NODE = IF +		drop			( drop tag ) +		4 - +		fdt-fix-cas-node +		get-parent set-node +		fdt-debug IF ." Returning back " pwd cr THEN +	    ELSE +		." Error " cr +		drop +		false to fdt-cas-fix? +		EXIT +	    THEN +	THEN +    REPEAT +    drop \ drop tag +; + +: fdt-fix-cas-success +    fdt-cas-fix? +; + +s" /" find-node fdt-fix-phandles diff --git a/roms/SLOF/board-qemu/slof/header.fs b/roms/SLOF/board-qemu/slof/header.fs new file mode 100644 index 00000000..8bc17a18 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/header.fs @@ -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 +\ ****************************************************************************/ + +\ XXXFIXME: Old Bimini/JX2x crap to remove + +get-flash-base VALUE flash-addr + +get-nvram-base CONSTANT nvram-base +get-nvram-size CONSTANT nvram-size diff --git a/roms/SLOF/board-qemu/slof/helper.fs b/roms/SLOF/board-qemu/slof/helper.fs new file mode 100644 index 00000000..96da4989 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/helper.fs @@ -0,0 +1,35 @@ +\ ***************************************************************************** +\ * Copyright (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-build-id  ( -- str len ) +   flash-header 10 + a +; + +: slof-revision s" 001" ; + +: read-version-and-date +   flash-header 0= IF +   s"  " encode-string +   ELSE +   flash-header 10 + 10 +   here swap rmove +   here 10 +   s" , " $cat +   bdate2human $cat encode-string THEN +; + +\ Fetch C string +: from-cstring ( addr - len )   +  dup dup BEGIN c@ 0 <> WHILE 1 + dup REPEAT +  swap - +; + diff --git a/roms/SLOF/board-qemu/slof/hvterm.fs b/roms/SLOF/board-qemu/slof/hvterm.fs new file mode 100644 index 00000000..98c14458 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/hvterm.fs @@ -0,0 +1,43 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 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 +\ ****************************************************************************/ + +\ PAPR hvterm console.  Enabled very early. + +0 CONSTANT default-hvtermno +\ Buffer for pre-display +4096 CONSTANT disp-size +CREATE prevga-disp-buf 4096 allot +0 value disp-ptr +true value store-prevga? + +: store-to-disp-buffer         ( ch  --  ) +    prevga-disp-buf disp-ptr disp-size MOD + c! +    disp-ptr 1 + to disp-ptr +; + +: hvterm-emit +    store-prevga? IF +	dup store-to-disp-buffer +    THEN +    default-hvtermno SWAP hv-putchar +; +: hvterm-key?  default-hvtermno hv-haschar ; +: hvterm-key   BEGIN hvterm-key? UNTIL default-hvtermno hv-getchar ; + +' hvterm-emit to emit +' hvterm-key  to key +' hvterm-key? to key? + +\ Override serial methods to make term-io.fs happy +: serial-emit hvterm-emit ; +: serial-key? hvterm-key? ; +: serial-key  hvterm-key  ; diff --git a/roms/SLOF/board-qemu/slof/pci-aliases.fs b/roms/SLOF/board-qemu/slof/pci-aliases.fs new file mode 100644 index 00000000..9ce519da --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-aliases.fs @@ -0,0 +1,58 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2011 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 +\ ****************************************************************************/ + +\ Starting alias number for net devices after the onboard devices. +0 VALUE pci-net-num +\ Starting alias number for disks after the onboard devices. +0 VALUE pci-disk-num +\ Starting alias number for cdroms after the onboard devices. +0 VALUE pci-cdrom-num + +\ define a new alias for this device +: pci-set-alias ( str-addr str-len num -- ) +        $cathex strdup       \ create alias name +        get-node node>path   \ get path string +        set-alias            \ and set the alias +; + +\ define a new net alias +: unknown-enet ( -- pci-net-num ) +	pci-net-num dup 1+ TO pci-net-num +; +: pci-alias-net ( config-addr -- ) +        drop                                   \ forget the config address +        pci-net-num dup 1+ TO pci-net-num      \ increase the pci-net-num +        s" net" rot pci-set-alias              \ create the alias +; + +\ define a new disk alias +: pci-alias-disk ( config-addr -- ) +        drop                                    \ forget the config address +        pci-disk-num dup 1+ TO pci-disk-num     \ increase the pci-disk-num +        s" disk" rot pci-set-alias              \ create the alias +; +\ define a new cdrom alias +: pci-alias-cdrom ( config-addr -- ) +        drop                                    \ forget the config address +        pci-cdrom-num dup 1+ TO pci-cdrom-num     \ increase the pci-cdrom-num +        s" cdrom" rot pci-set-alias              \ create the alias +; + +\ define the alias for the calling device +: pci-alias ( config-addr -- ) +        dup pci-class@  +        10 rshift CASE +                01 OF   pci-alias-disk ENDOF +                02 OF   pci-alias-net  ENDOF +               dup OF   drop           ENDOF +        ENDCASE +; diff --git a/roms/SLOF/board-qemu/slof/pci-capabilities.fs b/roms/SLOF/board-qemu/slof/pci-capabilities.fs new file mode 100644 index 00000000..ef8c7b0d --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-capabilities.fs @@ -0,0 +1,34 @@ +\ Set up all known capabilities for this board to the plugged devices + +: pci-msi-prop ( addr -- ) +    5 pci-cap-find          ( capaddr ) +    ?dup IF +        2+ rtas-config-w@   ( msi-control ) +        1 rshift 7 and      ( msi-control:3:1 ) + +        dup 6 < IF +            1 swap lshift   ( vectors# ) +            encode-int " ibm,req#msi" property +        ELSE +            ." Invalid MSI vectors number " . cr +        THEN +    THEN +; + +: pci-msix-prop ( addr -- ) +    11 pci-cap-find         ( capaddr ) +    ?dup IF +        2+ rtas-config-w@   ( msix-control ) +        7ff and             ( msix-control:10:0 ) +        1+                  ( vectors# ) +        ?dup IF +            encode-int " ibm,req#msi-x" property +        THEN +    THEN +; + +: pci-set-capabilities ( config-addr -- ) +    dup pci-msi-prop +    dup pci-msix-prop +    drop +; diff --git a/roms/SLOF/board-qemu/slof/pci-device_1013_00b8.fs b/roms/SLOF/board-qemu/slof/pci-device_1013_00b8.fs new file mode 100644 index 00000000..c3ac2ec4 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-device_1013_00b8.fs @@ -0,0 +1,265 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 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 +\ ****************************************************************************/ + +my-space pci-device-generic-setup + +\ Defaults, overriden from qemu +d# 800 VALUE disp-width +d# 600 VALUE disp-height +d#   8 VALUE disp-depth + +\ Determine base address +10 config-l@ translate-my-address f not AND  VALUE fb-base + +\ Fixed up later +-1 VALUE io-base + +\ We support only one instance +false VALUE is-installed? + +: vga-io-xlate ( port -- addr ) +  io-base -1 = IF +    dup translate-my-address fff not and to io-base +  THEN +  io-base + +; + +: vga-w! ( value port -- ) +  vga-io-xlate rw!-le +; + +: vga-w@ ( port -- value ) +  vga-io-xlate rw@-le +; + +: vga-b! ( value port -- ) +  vga-io-xlate rb! +; + +: vga-b@ ( port -- value ) +  vga-io-xlate rb@ +; + +: vga-crt@ ( index -- value ) +  3d4 vga-b! +  3d5 vga-b@ +; + +: vga-crt! ( value index -- ) +  3d4 vga-b! +  3d5 vga-b! +; + +: vga-seq@ ( index -- value ) +  3c4 vga-b! +  3c5 vga-b@ +; + +: vga-seq! ( value index -- ) +  3c4 vga-b! +  3c5 vga-b! +; + +: vga-att@ ( index -- value ) +  3c0 vga-b! +  3c1 vga-b@ +; + +: vga-att! ( value index -- ) +  3c0 vga-b! +  3c0 vga-b! +; + +: vga-gfx@ ( index -- value ) +  3ce vga-b! +  3cf vga-b@ +; + +: vga-gfx! ( value index -- ) +  3ce vga-b! +  3cf vga-b! +; + +: color! ( r g b number -- )  +   3c8 vga-b! +   rot 2 >> 3c9 vga-b! +   swap 2 >> 3c9 vga-b! +   2 >> 3c9 vga-b! +; + +: color@ ( number -- r g b )  +   3c8 vga-b! +   3c9 vga-b@ 2 << +   3c9 vga-b@ 2 << +   3c9 vga-b@ 2 << +; + +: set-colors ( adr number #numbers -- ) +   over 3c8 vga-b! +   swap DO +     rb@ 2 >> 3c9 vga-b! +     rb@ 2 >> 3c9 vga-b! +     rb@ 2 >> 3c9 vga-b! +   LOOP +   3drop +; + +: get-colors ( adr number #numbers -- ) +   3drop +; + +include graphics.fs + +: init-mode +  3da vga-b@ drop \ reset flip flop +  0f 3c2 vga-b!   \ color mode, ram enable, ... +  12 06 vga-seq!  \ unlock extensions +  05 06 vga-gfx!  \ graphic mode   +  \ set bit depth. Note: we should set the hidden +  \ dac register to differenciate 15 and 16bpp, but +  \ it's annoying and in practice we don't care as +  \ we are only displaying in black & white atm +  disp-depth CASE \ set depth +     8 OF 01 07 vga-seq! ENDOF +     f OF 07 07 vga-seq! ENDOF +    10 OF 07 07 vga-seq! ENDOF +    20 OF 09 07 vga-seq! ENDOF +  ENDCASE +  ff 02 vga-seq!  \ enable plane write +  0a 04 vga-seq!  \ memory mode +  03 17 vga-crt!  \ disable display +  \ calculate line offset & split +  disp-width disp-depth 7 + 8 / * 3 >> +  dup ff and 13 vga-crt!  \ bottom bits +  4 >> 10 and 1b vga-crt! \ top bit +  disp-width 3 >> 1 -                  01 vga-crt! \ H_DISP +  disp-height 1 - ff and               12 vga-crt! \ V_DISP +  disp-height 1 - 7 >> 2 and +  disp-height 1 - 3 >> 40 and +  or 10 or                             07 vga-crt! \ OFLOW +  ff 18 vga-crt! \ LINE_COMPARE +  40 09 vga-crt! \ MAX_SCAN +  08 04 vga-crt! \ SYNC_START +  0f 02 vga-crt! \ BLANK_START +  00 0c vga-crt! +  00 0d vga-crt! +  40 05 vga-gfx! \ gfx mode +  83 17 vga-crt! \ enable display +  33 3c0 vga-b!  \ gfx in ar index +  00 3c0 vga-b! +  01 01 vga-seq! \ enable seq +; + +: clear-screen +  fb-base disp-width disp-height disp-depth 7 + 8 / * * 0 rfill +; + +: read-settings +  s" qemu,graphic-width" get-chosen IF +     decode-int to disp-width 2drop +  THEN +  s" qemu,graphic-height" get-chosen IF +     decode-int to disp-height 2drop +  THEN +  s" qemu,graphic-depth" get-chosen IF +     decode-int nip nip      +       dup 8 = +       over f = or +       over 10 = or +       over 20 = or IF +         to disp-depth +       ELSE +         ." Unsupported bit depth, using 8bpp " drop cr +       THEN +  THEN +; + +: add-legacy-reg +  \ add legacy I/O Ports / Memory regions to assigned-addresses +  \ see PCI Bus Binding Revision 2.1 Section 7. +  s" reg" get-node get-property IF +    \ "reg" does not exist, create new +    encode-start +  ELSE +    \ "reg" does exist, copy it  +    encode-bytes +  THEN +  \ I/O Range 0x1ce-0x1d2 +  my-space a1000000 or encode-int+ \ non-relocatable, aliased I/O space +  1ce encode-64+ 4 encode-64+ \ addr size +  \ I/O Range 0x3B0-0x3BB +  my-space a1000000 or encode-int+ \ non-relocatable, aliased I/O space +  3b0 encode-64+ c encode-64+ \ addr size +  \ I/O Range 0x3C0-0x3DF +  my-space a1000000 or encode-int+ \ non-relocatable, aliased I/O space +  3c0 encode-64+ 20 encode-64+ \ addr size +  \ Memory Range 0xA0000-0xBFFFF +  my-space a2000000 or encode-int+ \ non-relocatable, <1MB Memory space +  a0000 encode-64+ 20000 encode-64+ \ addr size +  s" reg" property \ store "reg" property +; + +: setup-properties +   \ Shouldn't this be done from open ? +   disp-width encode-int s" width" property +   disp-height encode-int s" height" property +   disp-width disp-depth 7 + 8 / * encode-int s" linebytes" property +   disp-depth encode-int s" depth" property +   s" ISO8859-1" encode-string s" character-set" property \ i hope this is ok... +   \ add "device_type" property +   s" display" device-type +   \ XXX We don't create an "address" property because Linux doesn't know what +   \ to do with it for >32-bit +; + +\ words for installation/removal, needed by is-install/is-remove, see display.fs +: display-remove ( -- )  +; + +: display-install ( -- ) +    is-installed? NOT IF +        ." Installing QEMU fb" cr +        fb-base to frame-buffer-adr +        default-font  +        set-font +        disp-width disp-height +        disp-width char-width / disp-height char-height / +        disp-depth 7 + 8 /                      ( width height #lines #cols depth ) +        fb-install +        true to is-installed? +    THEN +; + +: set-alias +    s" screen" find-alias 0= IF +      \ no previous screen alias defined, define it... +      s" screen" get-node node>path set-alias +    ELSE +       drop +    THEN  +; + + +." cirrus vga" cr + +pci-master-enable +pci-mem-enable +pci-io-enable +add-legacy-reg +read-settings +init-mode +clear-screen +init-default-palette +setup-properties +' display-install is-install +' display-remove is-remove +set-alias diff --git a/roms/SLOF/board-qemu/slof/pci-device_1234_1111.fs b/roms/SLOF/board-qemu/slof/pci-device_1234_1111.fs new file mode 100644 index 00000000..a5c3584f --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-device_1234_1111.fs @@ -0,0 +1,242 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 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 +\ ****************************************************************************/ + +my-space pci-device-generic-setup + +\ Defaults, overriden from qemu +d# 800 VALUE disp-width +d# 600 VALUE disp-height +d#   8 VALUE disp-depth + +\ Determine base address +10 config-l@ translate-my-address f not AND VALUE fb-base + +\ Fixed up later +-1 VALUE io-base + +\ We support only one instance +false VALUE is-installed? + +: vga-io-xlate ( port -- addr ) +  io-base -1 = IF +    dup translate-my-address fff not and to io-base +  THEN +  io-base + +; + +: vga-w! ( value port -- ) +  vga-io-xlate rw!-le +; + +: vga-w@ ( port -- value ) +  vga-io-xlate rw@-le +; + +: vga-b! ( value port -- ) +  vga-io-xlate rb! +; + +: vga-b@ ( port -- value ) +  vga-io-xlate rb@ +; + +: vbe!	( value index -- ) +  1ce vga-w! 1d0 vga-w! +; + +: vbe@	( index -- value ) +  1ce vga-w! 1d0 vga-w@ +; + +: color! ( r g b number -- )  +   3c8 vga-b! +   rot 3c9 vga-b! +   swap 3c9 vga-b! +   3c9 vga-b! +; + +: color@ ( number -- r g b )  +   3c8 vga-b! +   3c9 vga-b@ +   3c9 vga-b@ +   3c9 vga-b@ +; + +: set-colors ( adr number #numbers -- ) +   over 3c8 vga-b! +   swap DO +     rb@ 3c9 vga-b! +     rb@ 3c9 vga-b! +     rb@ 3c9 vga-b! +   LOOP +   3drop +; + +: get-colors ( adr number #numbers -- ) +   3drop +; + +include graphics.fs + +\ qemu fake VBE IO registers +0 CONSTANT VBE_DISPI_INDEX_ID +1 CONSTANT VBE_DISPI_INDEX_XRES +2 CONSTANT VBE_DISPI_INDEX_YRES +3 CONSTANT VBE_DISPI_INDEX_BPP +4 CONSTANT VBE_DISPI_INDEX_ENABLE +5 CONSTANT VBE_DISPI_INDEX_BANK +6 CONSTANT VBE_DISPI_INDEX_VIRT_WIDTH +7 CONSTANT VBE_DISPI_INDEX_VIRT_HEIGHT +8 CONSTANT VBE_DISPI_INDEX_X_OFFSET +9 CONSTANT VBE_DISPI_INDEX_Y_OFFSET +a CONSTANT VBE_DISPI_INDEX_NB + +\ ENABLE register +00 CONSTANT VBE_DISPI_DISABLED +01 CONSTANT VBE_DISPI_ENABLED +02 CONSTANT VBE_DISPI_GETCAPS +20 CONSTANT VBE_DISPI_8BIT_DAC +40 CONSTANT VBE_DISPI_LFB_ENABLED +80 CONSTANT VBE_DISPI_NOCLEARMEM + +: init-mode +  0 3c0 vga-b! +  VBE_DISPI_DISABLED VBE_DISPI_INDEX_ENABLE vbe! +  0 VBE_DISPI_INDEX_X_OFFSET vbe! +  0 VBE_DISPI_INDEX_Y_OFFSET vbe! +  disp-width VBE_DISPI_INDEX_XRES vbe! +  disp-height VBE_DISPI_INDEX_YRES vbe! +  disp-depth VBE_DISPI_INDEX_BPP vbe! +  VBE_DISPI_ENABLED VBE_DISPI_8BIT_DAC or VBE_DISPI_INDEX_ENABLE vbe! +  0 3c0 vga-b! +  20 3c0 vga-b! +; + +: clear-screen +  fb-base disp-width disp-height disp-depth 7 + 8 / * * 0 rfill +; + +: read-settings +  s" qemu,graphic-width" get-chosen IF +     decode-int to disp-width 2drop +  THEN +  s" qemu,graphic-height" get-chosen IF +     decode-int to disp-height 2drop +  THEN +  s" qemu,graphic-depth" get-chosen IF +     decode-int nip nip      +       dup 8 = +       over f = or +       over 10 = or +       over 20 = or IF +         to disp-depth +       ELSE +         ." Unsupported bit depth, using 8bpp " drop cr +       THEN +  THEN +; + +: add-legacy-reg +  \ add legacy I/O Ports / Memory regions to assigned-addresses +  \ see PCI Bus Binding Revision 2.1 Section 7. +  s" reg" get-node get-property IF +    \ "reg" does not exist, create new +    encode-start +  ELSE +    \ "reg" does exist, copy it  +    encode-bytes +  THEN +  \ I/O Range 0x1ce-0x1d2 +  my-space a1000000 or encode-int+ \ non-relocatable, aliased I/O space +  1ce encode-64+ 4 encode-64+ \ addr size +  \ I/O Range 0x3B0-0x3BB +  my-space a1000000 or encode-int+ \ non-relocatable, aliased I/O space +  3b0 encode-64+ c encode-64+ \ addr size +  \ I/O Range 0x3C0-0x3DF +  my-space a1000000 or encode-int+ \ non-relocatable, aliased I/O space +  3c0 encode-64+ 20 encode-64+ \ addr size +  \ Memory Range 0xA0000-0xBFFFF +  my-space a2000000 or encode-int+ \ non-relocatable, <1MB Memory space +  a0000 encode-64+ 20000 encode-64+ \ addr size +  s" reg" property \ store "reg" property +; + +: setup-properties +   \ Shouldn't this be done from open ? +   disp-width encode-int s" width" property +   disp-height encode-int s" height" property +   disp-width disp-depth 7 + 8 / * encode-int s" linebytes" property +   disp-depth encode-int s" depth" property +   s" ISO8859-1" encode-string s" character-set" property \ i hope this is ok... +   \ add "device_type" property +   s" display" device-type +   s" qemu,std-vga" encode-string s" compatible" property +   \ XXX We don't create an "address" property because Linux doesn't know what +   \ to do with it for >32-bit +; + +\ words for installation/removal, needed by is-install/is-remove, see display.fs +: display-remove ( -- )  +; + +: hcall-invert-screen ( -- ) +    frame-buffer-adr frame-buffer-adr 3 +    screen-height screen-width * screen-depth * /x / +    1 hv-logical-memop +    drop +; + +: hcall-blink-screen ( -- ) +    \ 32 msec delay for visually noticing the blink +    hcall-invert-screen 20 ms hcall-invert-screen +; + +: display-install ( -- ) +    is-installed? NOT IF +        ." Installing QEMU fb" cr +        fb-base to frame-buffer-adr +        clear-screen +        default-font  +        set-font +        disp-width disp-height +        disp-width char-width / disp-height char-height / +        disp-depth 7 + 8 /                      ( width height #lines #cols depth ) +        fb-install +	['] hcall-invert-screen to invert-screen +	['] hcall-blink-screen to blink-screen +         true to is-installed? +    THEN +; + +: set-alias +    s" screen" find-alias 0= IF +      \ no previous screen alias defined, define it... +      s" screen" get-node node>path set-alias +    ELSE +       drop +    THEN  +; + + +." qemu vga" cr + +pci-master-enable +pci-mem-enable +pci-io-enable +add-legacy-reg +read-settings +init-mode +init-default-palette +setup-properties +' display-install is-install +' display-remove is-remove +set-alias diff --git a/roms/SLOF/board-qemu/slof/pci-device_1af4_1000.fs b/roms/SLOF/board-qemu/slof/pci-device_1af4_1000.fs new file mode 100644 index 00000000..ac18e0ef --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-device_1af4_1000.fs @@ -0,0 +1,23 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 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 +\ ****************************************************************************/ + +\ Handle virtio-net device + +s" virtio [ net ]" type cr + +my-space pci-device-generic-setup + +pci-io-enable + +s" virtio-net.fs" included + +pci-device-disable diff --git a/roms/SLOF/board-qemu/slof/pci-device_1af4_1001.fs b/roms/SLOF/board-qemu/slof/pci-device_1af4_1001.fs new file mode 100644 index 00000000..fb246346 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-device_1af4_1001.fs @@ -0,0 +1,34 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 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 +\ ****************************************************************************/ + +\ Handle virtio-blk device + +s" virtio [ block ]" type cr + +my-space pci-device-generic-setup + +pci-master-enable +pci-mem-enable +pci-io-enable + +s" virtio-block.fs" included + +\ Allocate memory for virtio queue: +virtiodev 0 virtio-get-qsize virtio-vring-size +1000 CLAIM VALUE queue-addr + +\ Write queue address into device: +queue-addr c rshift +virtiodev vd>base @ 8 + +rl!-le + +pci-device-disable diff --git a/roms/SLOF/board-qemu/slof/pci-device_1af4_1004.fs b/roms/SLOF/board-qemu/slof/pci-device_1af4_1004.fs new file mode 100644 index 00000000..9c1089ac --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-device_1af4_1004.fs @@ -0,0 +1,24 @@ +\ ***************************************************************************** +\ * Copyright (c) 2012 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 +\ ****************************************************************************/ + +\ Handle virtio-net device + +s" virtio [ scsi ]" type cr + +my-space pci-device-generic-setup +pci-master-enable +pci-mem-enable +pci-io-enable + +s" virtio-scsi.fs" included + +pci-device-disable diff --git a/roms/SLOF/board-qemu/slof/pci-device_1af4_1009.fs b/roms/SLOF/board-qemu/slof/pci-device_1af4_1009.fs new file mode 100644 index 00000000..03964a6d --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-device_1af4_1009.fs @@ -0,0 +1,34 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 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 +\ ****************************************************************************/ + +\ Handle virtio-fs device + +s" virtio [ network ]" type cr + +my-space pci-device-generic-setup + +pci-master-enable +pci-mem-enable +pci-io-enable + +s" virtio-fs.fs" included + +\ Allocate memory for virtio queue: +virtiodev 0 virtio-get-qsize virtio-vring-size +1000 CLAIM VALUE queue-addr + +\ Write queue address into device: +queue-addr c rshift +virtiodev vd>base @ 8 + +rl!-le + +pci-device-disable diff --git a/roms/SLOF/board-qemu/slof/pci-device_8086_100e.fs b/roms/SLOF/board-qemu/slof/pci-device_8086_100e.fs new file mode 100644 index 00000000..8f279a25 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-device_8086_100e.fs @@ -0,0 +1,23 @@ +\ ***************************************************************************** +\ * Copyright (c) 2013 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 +\ ****************************************************************************/ + +\ Handle e1000 device + +s" e1000 [ net ]" type cr + +my-space pci-device-generic-setup + +pci-io-enable + +s" e1k.fs" included + +pci-device-disable diff --git a/roms/SLOF/board-qemu/slof/pci-interrupts.fs b/roms/SLOF/board-qemu/slof/pci-interrupts.fs new file mode 100644 index 00000000..e11b7793 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-interrupts.fs @@ -0,0 +1,38 @@ + +: pci-gen-irq-map-one ( prop-addr prop-len slot pin -- prop-addr prop-len ) +        2dup + 4 mod                ( prop-addr prop-len slot pin parentpin ) +        >r >r                       ( prop-addr prop-len slot R: swizzledpin pin ) + +        \ Child slot# +        B lshift encode-int+        ( prop-addr prop-len R: swizzledpin pin ) +        \ Child 64bit BAR (not really used) +        0 encode-64+ +        \ Chile pin# +        r> encode-int+              ( prop-addr prop-len R: swizzledpin ) + +        \ Parent phandle +        get-parent encode-int+ + +        \ Parent slot# +        get-node >space +        pci-addr2dev B lshift       ( prop-addr prop-len parent-slot R: swizzledpin ) +        encode-int+ +        \ Parent 64bit BAR (not really used) +        0 encode-64+ +        \ Parent pin +        r> encode-int+              ( prop-addr prop-len R: ) +; + +: pci-gen-irq-entry ( prop-addr prop-len config-addr -- prop-addr prop-len ) +        pci-addr2dev 4 mod          ( prop-addr prop-len slot ) +        -rot                        ( slot prop-addr prop-len ) +        5 1 DO +                2 pick i            ( slot prop-addr prop-len slot pin ) +                pci-gen-irq-map-one +        LOOP +        rot drop +; + +: pci-set-irq-line ( config-addr -- ) +  drop +; diff --git a/roms/SLOF/board-qemu/slof/pci-phb.fs b/roms/SLOF/board-qemu/slof/pci-phb.fs new file mode 100644 index 00000000..a8fb7ca5 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/pci-phb.fs @@ -0,0 +1,337 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2011 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 +\ ****************************************************************************/ + +\ PAPR PCI host bridge. + +0 VALUE phb-debug? + + +." Populating " pwd cr + +\ needed to find the right path in the device tree +: decode-unit ( addr len -- phys.lo ... phys.hi ) +   2 hex-decode-unit       \ decode string +   b lshift swap           \ shift the devicenumber to the right spot +   8 lshift or             \ add the functionnumber +   \ my-bus 10 lshift or   \ add the busnumber (assume always bus 0) +   0 0 rot                 \ make phys.lo = 0 = phys.mid +; + +\ needed to have the right unit address in the device tree listing +\ phys.lo=phys.mid=0 , phys.hi=config-address +: encode-unit ( phys.lo phys-mid phys.hi -- unit-str unit-len ) +   nip nip                     \ forget the phys.lo and phys.mid +   dup 8 rshift 7 and swap     \ calculate function number +   B rshift 1F and             \ calculate device number +   over IF 2 ELSE nip 1 THEN   \ create string with dev#,fn# or dev# only? +   hex-encode-unit +; + + +0 VALUE my-puid + +: setup-puid +  s" reg" get-node get-property 0= IF +    decode-64 to my-puid 2drop +  THEN +; + +setup-puid + +: config-b@  puid >r my-puid TO puid rtas-config-b@ r> TO puid ; +: config-w@  puid >r my-puid TO puid rtas-config-w@ r> TO puid ; +: config-l@  puid >r my-puid TO puid rtas-config-l@ r> TO puid ; + +\ define the config writes +: config-b!  puid >r my-puid TO puid rtas-config-b! r> TO puid ; +: config-w!  puid >r my-puid TO puid rtas-config-w! r> TO puid ; +: config-l!  puid >r my-puid TO puid rtas-config-l! r> TO puid ; + + +: map-in ( phys.lo phys.mid phys.hi size -- virt ) +   phb-debug? IF cr ." map-in called: " .s cr THEN +   \ Ignore the size, phys.lo and phys.mid, get BAR from config space +   drop nip nip                         ( phys.hi ) +   \ Sanity check whether config address is in expected range: +   dup FF AND dup 10 28 WITHIN NOT swap 30 <> AND IF +      cr ." phys.hi = " . cr +      ABORT" map-in with illegal config space address" +   THEN +   00FFFFFF AND                         \ Need only bus-dev-fn+register bits +   dup config-l@                        ( phys.hi' bar.lo ) +   dup 7 AND 4 = IF                     \ Is it a 64-bit BAR? +      swap 4 + config-l@ lxjoin         \ Add upper part of 64-bit BAR +   ELSE +      nip +   THEN +   F NOT AND                            \ Clear indicator bits +   translate-my-address +   phb-debug? IF ." map-in done: " .s cr THEN +; + +: map-out ( virt size -- ) +   phb-debug? IF ." map-out called: " .s cr THEN +   2drop  +; + + +: dma-alloc ( size -- virt ) +   phb-debug? IF cr ." dma-alloc called: " .s cr THEN +   fff + fff not and                  \ Align size to next 4k boundary +   alloc-mem +   \ alloc-mem always returns aligned memory - double check just to be sure +   dup fff and IF +      ." Warning: dma-alloc got unaligned memory!" cr +   THEN +; + +: dma-free ( virt size -- ) +   phb-debug? IF cr ." dma-free called: " .s cr THEN +   fff + fff not and                  \ Align size to next 4k boundary +   free-mem +; + + +\ Helper variables for dma-map-in and dma-map-out +0 VALUE dma-window-liobn        \ Logical I/O bus number +0 VALUE dma-window-base         \ Start address of window +0 VALUE dma-window-size         \ Size of the window + +0 VALUE bm-handle               \ Bitmap allocator handle +0 VALUE my-virt +0 VALUE my-size +0 VALUE dev-addr +0 VALUE tmp-dev-addr + +\ Read helper variables (LIOBN, DMA window base and size) from the +\ "ibm,dma-window" property. This property can be either located +\ in the PCI device node or in the bus node, so we've got to use the +\ "calling-child" variable here to get to the node that initiated the call. +\ XXX We should search all the way up the tree to the PHB ... +: (init-dma-window-vars)  ( -- ) +\   ." Foo called in " pwd cr +\   ." calling child is " calling-child .node cr +\   ." parent is " calling-child parent .node cr +   s" ibm,dma-window" calling-child get-property IF +       s" ibm,dma-window" calling-child parent get-property  +       ABORT" no dma-window property available" +   THEN +   decode-int TO dma-window-liobn +   decode-64 TO dma-window-base +   decode-64 TO dma-window-size +   2drop +   bm-handle 0= IF +       dma-window-base dma-window-size 1000 bm-allocator-init to bm-handle +       \ Sometimes the window-base appears as zero, that does not +       \ go well with NULL pointers. So block this address +       dma-window-base 0= IF +          bm-handle 1000 bm-alloc drop +       THEN +   THEN +; + +: (clear-dma-window-vars)  ( -- ) +    0 TO dma-window-liobn +    0 TO dma-window-base +    0 TO dma-window-size +; + +\ We assume that firmware never maps more than the whole dma-window-size +\ so we cheat by calculating the remainder of addr/windowsize instead +\ of taking care to maintain a list of assigned device addresses +: dma-virt2dev  ( virt -- devaddr ) +   dma-window-size mod dma-window-base + +; + +: dma-map-in  ( virt size cachable? -- devaddr ) +   phb-debug? IF cr ." dma-map-in called: " .s cr THEN +   (init-dma-window-vars) +   drop                               ( virt size ) + +   to my-size +   to my-virt +   bm-handle my-size bm-alloc +   to dev-addr +   dev-addr 0 < IF +       ." Bitmap allocation Failed " dev-addr . +       FALSE EXIT +   THEN +   dev-addr to tmp-dev-addr + +   my-virt my-size +   bounds dup >r                      ( v+s virt  R: virt ) +   swap fff + fff not and             \ Align end to next 4k boundary +   swap fff not and                   ( v+s' virt'  R: virt ) +   ?DO +       \ ." mapping " i . cr +       dma-window-liobn                \ liobn +       tmp-dev-addr                    \ ioba +       i 3 OR                          \ Make a read- & writeable TCE +       ( liobn ioba tce  R: virt ) +       hv-put-tce ABORT" H_PUT_TCE failed" +       tmp-dev-addr 1000 + to tmp-dev-addr +   1000 +LOOP +   r> drop +   my-virt FFF and dev-addr or +   (clear-dma-window-vars) +; + +: dma-map-out  ( virt devaddr size -- ) +   phb-debug? IF cr ." dma-map-out called: " .s cr THEN +   (init-dma-window-vars) +   to my-size +   to dev-addr +   to my-virt +   dev-addr fff not and to dev-addr +   dev-addr to tmp-dev-addr + +   my-virt my-size                    ( virt size ) +   bounds                             ( v+s virt ) +   swap fff + fff not and             \ Align end to next 4k boundary +   swap fff not and                   ( v+s' virt' ) +   ?DO +       \ ." unmapping " i . cr +       dma-window-liobn                \ liobn +       tmp-dev-addr                    \ ioba +       i                               \ Lowest bits not set => invalid TCE +       ( liobn ioba tce ) +       hv-put-tce ABORT" H_PUT_TCE failed" +       tmp-dev-addr 1000 + to tmp-dev-addr +   1000 +LOOP +   bm-handle dev-addr my-size bm-free +   (clear-dma-window-vars) +; + +: dma-sync  ( virt devaddr size -- ) +   phb-debug? IF cr ." dma-sync called: " .s cr THEN +   \ TODO: Call flush-cache or sync here? +   3drop +; + + +: open  true ; +: close ; + +\ Parse the "ranges" property of the root pci node to decode the available +\ memory ranges. See "PCI Bus Binding to IEEE Std 1275-1994" for details. +\ The memory ranges are then used for setting up the device bars (if necessary) +: phb-parse-ranges ( -- ) +   \ First clear everything, in case there is something missing in the ranges +   0  pci-next-io ! +   0  pci-max-io ! +   0  pci-next-mem ! +   0  pci-max-mem ! +   0  pci-next-mmio ! +   0  pci-max-mmio ! +   0  pci-next-mem64 ! +   0  pci-max-mem64 ! + +   \ Now get the "ranges" property +   s" ranges" get-node get-property 0<> ABORT" ranges property not found" +   ( prop-addr prop-len ) +   BEGIN +      dup +   WHILE +      decode-int                      \ Decode phys.hi +      3000000 AND                     \ Filter out address space in phys.hi +      CASE +         1000000 OF                             \ I/O space? +            decode-64 dup >r pci-next-io !      \ Decode PCI base address +            decode-64 drop                      \ Forget the parent address +            decode-64 r> + pci-max-io !         \ Decode size & calc max address +            pci-next-io @ 0= IF +               pci-next-io @ 10 + pci-next-io ! \ BARs must not be set to zero +            THEN +         ENDOF +         2000000 OF                             \ 32-bit memory space? +            decode-64 pci-next-mem !            \ Decode mem base address +            decode-64 drop                      \ Forget the parent address +            decode-64 2 / dup >r                \ Decode and calc size/2 +            pci-next-mem @ + dup pci-max-mem !  \ and calc max mem address +            dup pci-next-mmio !                 \ which is the same as MMIO base +            r> + pci-max-mmio !                 \ calc max MMIO address +         ENDOF +         3000000 OF                             \ 64-bit memory space? +	    decode-64 pci-next-mem64 ! +	    decode-64 drop                      \ Forget the parent address +	    decode-64 pci-max-mem64 ! +         ENDOF +      ENDCASE +   REPEAT +   ( prop-addr prop-len ) +   2drop + +   phb-debug? IF +     ." pci-next-io   = " pci-next-io @ . cr +     ." pci-max-io    = " pci-max-io  @ . cr +     ." pci-next-mem  = " pci-next-mem @ . cr +     ." pci-max-mem   = " pci-max-mem  @ . cr +     ." pci-next-mmio = " pci-next-mmio @ . cr +     ." pci-max-mmio  = " pci-max-mmio @ . cr +     ." pci-next-mem64  = " pci-next-mem64 @ . cr +     ." pci-max-mem64   = " pci-max-mem64  @ . cr +   THEN +; + +: phb-pci-walk-bridge ( -- ) +    phb-debug? IF ."   Calling pci-walk-bridge " pwd cr THEN + +    get-node child ?dup 0= IF EXIT THEN    \ get and check if we have children +    0 to pci-device-slots                  \ reset slot array to unpoppulated +    BEGIN +        dup                                \ Continue as long as there are children +    WHILE +        dup set-node                       \ Set child node as current node +        my-space pci-set-slot              \ set the slot bit +        my-space pci-htype@                \ read HEADER-Type +        7f and                             \ Mask bit 7 - multifunction device +        CASE +            0 OF my-space pci-device-setup ENDOF  \ | set up the device +            1 OF my-space pci-bridge-setup ENDOF  \ | set up the bridge +            dup OF my-space pci-htype@ pci-out ENDOF +        ENDCASE +        peer +    REPEAT drop +    get-parent set-node +; + +\ Landing routing to probe the popuated device tree +: phb-pci-probe-bus ( busnr -- ) +    drop phb-pci-walk-bridge +; + +\ Stub routine, as qemu has enumerated, we already have the device +\ properties set. +: phb-pci-device-props ( addr -- ) +    dup pci-class-name device-name +    dup pci-device-assigned-addresses-prop +    drop +; + +\ Scan the child nodes of the pci root node to assign bars, fixup +\ properties etc. +: phb-setup-children +   puid >r                          \ Save old value of puid +   my-puid TO puid                  \ Set current puid +   phb-parse-ranges +   1 TO pci-hotplug-enabled +   s" qemu,phb-enumerated" get-node get-property 0<> IF +       1 0 (probe-pci-host-bridge) +   ELSE +       2drop +       ['] phb-pci-probe-bus TO func-pci-probe-bus +       ['] phb-pci-device-props TO func-pci-device-props +       phb-pci-walk-bridge          \ PHB device tree is already populated. +   THEN +   r> TO puid                       \ Restore previous puid +; +phb-setup-children diff --git a/roms/SLOF/board-qemu/slof/qemu-bootlist.fs b/roms/SLOF/board-qemu/slof/qemu-bootlist.fs new file mode 100644 index 00000000..4778e162 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/qemu-bootlist.fs @@ -0,0 +1,61 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 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 +\ ****************************************************************************/ + +defer set-boot-device +defer add-boot-device + +8 CONSTANT MAX-ALIAS +: add-boot-aliases ( str -- ) +    2dup add-boot-device               ( $str ) +    MAX-ALIAS 1 DO +	2dup i $cathex 2dup              ( $str $strN $strN ) +	find-alias 0 > IF                ( $str $strN false | $result ) +	    drop strdup add-boot-device  ( $str ) +	ELSE 2drop THEN +    LOOP +    2drop +; + +: qemu-read-bootlist ( -- ) +   \ See if QEMU has set exact boot device list +   " qemu,boot-list" get-chosen IF +        s" boot-device" $setenv +        EXIT +   THEN + +   0 0 set-boot-device + +   " qemu,boot-device" get-chosen not IF +      \ No boot list set from qemu, so check nvram +      " boot-device" evaluate swap drop 0= IF +         \ Not set in nvram too, set default disk/cdrom alias +         " disk" add-boot-aliases +         " cdrom" add-boot-aliases +         " net" add-boot-aliases +      THEN +      EXIT +   THEN + +   0 ?DO +       dup i + c@ CASE +           0        OF ENDOF +           [char] a OF ENDOF +           [char] b OF ENDOF +           [char] c OF " disk"  add-boot-aliases ENDOF +           [char] d OF " cdrom" add-boot-aliases ENDOF +           [char] n OF " net"   add-boot-aliases ENDOF +       ENDCASE cr +   LOOP +   drop +; + +' qemu-read-bootlist to read-bootlist diff --git a/roms/SLOF/board-qemu/slof/rtas-nvram.fs b/roms/SLOF/board-qemu/slof/rtas-nvram.fs new file mode 100644 index 00000000..fdebfb23 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/rtas-nvram.fs @@ -0,0 +1,48 @@ +\ ***************************************************************************** +\ * Copyright (c) 2012 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 +\ ****************************************************************************/ + +." Populating " pwd cr + +0 VALUE my-nvram-fetch +0 VALUE my-nvram-store +0 VALUE my-nvram-size +0 VALUE nvram-addr + +: open true ; +: close ; + +: write ( adr len -- actual ) +  nip +; + +: read  ( adr len -- actual ) +  nip +; + +: setup-alias +    " nvram" find-alias 0= IF +        " nvram" get-node node>path set-alias +    ELSE +        drop +    THEN +; + +" #bytes" get-node get-package-property 0= IF +    decode-int to my-nvram-size 2drop +    " nvram-fetch" rtas-get-token to my-nvram-fetch +    " nvram-store" rtas-get-token to my-nvram-store +    my-nvram-size to nvram-size +    nvram-size alloc-mem to nvram-addr +    my-nvram-fetch my-nvram-store nvram-size nvram-addr internal-nvram-init +THEN + +setup-alias diff --git a/roms/SLOF/board-qemu/slof/rtas.fs b/roms/SLOF/board-qemu/slof/rtas.fs new file mode 100644 index 00000000..2e10b0a5 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/rtas.fs @@ -0,0 +1,189 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 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 +\ ****************************************************************************/ + +\ KVM/qemu RTAS + +\ rtas control block + +371 cp + +STRUCT +    /l field rtas>token +    /l field rtas>nargs +    /l field rtas>nret +    /l field rtas>args0 +    /l field rtas>args1 +    /l field rtas>args2 +    /l field rtas>args3 +    /l field rtas>args4 +    /l field rtas>args5 +    /l field rtas>args6 +    /l field rtas>args7 +    /l C * field rtas>args +    /l field rtas>bla +CONSTANT /rtas-control-block + +CREATE rtas-cb /rtas-control-block allot +rtas-cb /rtas-control-block erase + +0 VALUE rtas-base +0 VALUE rtas-size +0 VALUE rtas-entry +0 VALUE rtas-node + +\ Locate qemu RTAS, remove the linux,... properties we really don't +\ want them to stick around + +372 cp + +: find-qemu-rtas ( -- ) +    " /rtas" find-device get-node to rtas-node + +    " linux,rtas-base" rtas-node get-package-property IF +         device-end EXIT THEN +    drop l@ to rtas-base +    " linux,rtas-base" delete-property + +    " rtas-size" rtas-node get-package-property IF +         device-end EXIT THEN +    drop l@ to rtas-size + +    " linux,rtas-entry" rtas-node get-package-property IF +        rtas-base to rtas-entry +    ELSE +        drop l@ to rtas-entry +        " linux,rtas-entry" delete-property +    THEN + +\    ." RTAS found, base=" rtas-base . ."  size=" rtas-size . cr + +    \ Patch the RTAS blob with our sc1 patcher if necessary +    0 +    rtas-base +    dup rtas-size + +    check-and-patch-sc1 + +    device-end +; +find-qemu-rtas +373 cp + +: enter-rtas ( -- ) +    rtas-cb rtas-base 0 rtas-entry call-c drop +; + +: rtas-get-token ( str len -- token | 0 ) +    rtas-node get-package-property IF 0 ELSE drop l@ THEN +; + +#include <rtas/rtas-reboot.fs> +#include <rtas/rtas-cpu.fs> + +: rtas-set-tce-bypass ( unit enable -- ) +    " ibm,set-tce-bypass" rtas-get-token rtas-cb rtas>token l! +    2 rtas-cb rtas>nargs l! +    0 rtas-cb rtas>nret l! +    rtas-cb rtas>args1 l! +    rtas-cb rtas>args0 l! +    enter-rtas +; + +: rtas-quiesce ( -- ) +    " quiesce" rtas-get-token rtas-cb rtas>token l! +    0 rtas-cb rtas>nargs l! +    0 rtas-cb rtas>nret l! +    enter-rtas +; + + +0 value puid + +: rtas-do-config-@ ( config-addr size -- value) +    \ We really want to cache this ! +    " ibm,read-pci-config" rtas-get-token rtas-cb rtas>token l! +    4 rtas-cb rtas>nargs l! +    2 rtas-cb rtas>nret l! +    ( addr size ) rtas-cb rtas>args3 l! +    puid ffffffff and rtas-cb rtas>args2 l! +    puid 20 rshift rtas-cb rtas>args1 l! +    ( addr ) rtas-cb rtas>args0 l! +    enter-rtas +    rtas-cb rtas>args4 l@ dup IF +        \ Do not warn on error as this is part of the +	\ normal PCI probing pass +	drop ffffffff +    ELSE +	drop rtas-cb rtas>args5 l@ +    THEN +; + +: rtas-do-config-! ( value config-addr size ) +    \ We really want to cache this ! +    " ibm,write-pci-config" rtas-get-token rtas-cb rtas>token l! +    5 rtas-cb rtas>nargs l! +    1 rtas-cb rtas>nret l! +    ( value addr size ) rtas-cb rtas>args3 l! +    puid ffffffff and rtas-cb rtas>args2 l! +    puid 20 rshift rtas-cb rtas>args1 l! +    ( value addr ) rtas-cb rtas>args0 l! +    ( value ) rtas-cb rtas>args4 l! +    enter-rtas +    rtas-cb rtas>args5 l@ dup IF +    	    ." RTAS write config err " . cr +    ELSE drop THEN +; + +: rtas-config-b@ ( config-addr -- value ) +  1 rtas-do-config-@ ff and +; +: rtas-config-b! ( value config-addr -- ) +  1 rtas-do-config-! +; +: rtas-config-w@ ( config-addr -- value ) +  2 rtas-do-config-@ ffff and +; +: rtas-config-w! ( value config-addr -- ) +  2 rtas-do-config-! +; +: rtas-config-l@ ( config-addr -- value ) +  4 rtas-do-config-@ ffffffff and +; +: rtas-config-l! ( value config-addr -- ) +  4 rtas-do-config-! +; + +: of-start-cpu rtas-start-cpu ; + +' power-off to halt +' rtas-system-reboot to reboot + +\ Methods of the rtas node proper +rtas-node set-node + +: open true ; +: close ; + +: instantiate-rtas ( adr -- entry ) +    dup rtas-base swap rtas-size move +    dup rtas-entry rtas-base - + +    2dup hv-rtas-update dup 0 <> IF +	\ Ignore hcall not implemented error, print error otherwise +	dup -2 <> IF ." HV-RTAS-UPDATE error: " . cr ELSE drop THEN +    ELSE +	drop +    THEN +    nip +; + +device-end + +374 cp diff --git a/roms/SLOF/board-qemu/slof/tree.fs b/roms/SLOF/board-qemu/slof/tree.fs new file mode 100644 index 00000000..4aba4c53 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/tree.fs @@ -0,0 +1,193 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2011 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 +\ ****************************************************************************/ + +: strequal ( str1 len1 str2 len2 -- flag ) +  rot dup rot = IF comp 0= ELSE 2drop drop 0 THEN ;  + +400 cp + +\ The root of the device tree and some of its kids. +" /" find-device + +\ The following properties have been provided by the FDT from QEMU already, +\ so we do not have to create them on our own: + +\ " QEMU" encode-string s" model" property +\ 2 encode-int s" #address-cells" property +\ 2 encode-int s" #size-cells" property +\ s" chrp" device-type + +480 cp + +\ See 3.6.5, and the PowerPC OF binding document. +new-device +s" mmu" 2dup device-name device-type +0 0 s" translations" property + +: open  true ; +: close ; + +finish-device +device-end + +4c0 cp + +\ Fixup timebase frequency from device-tree +: fixup-tbfreq +    " /cpus/@0" find-device +    " timebase-frequency" get-node get-package-property IF +        2drop +    ELSE +        decode-int to tb-frequency 2drop +    THEN +    device-end +; +fixup-tbfreq + +4d0 cp + +include fbuffer.fs + +500 cp + +: populate-vios ( -- ) +    \ Populate the /vdevice children with their methods +    \ WARNING: Quite a few SLOFisms here like get-node, set-node, ... + +    ." Populating /vdevice methods" cr +    " /vdevice" find-device get-node child +    BEGIN +        dup 0 <> +    WHILE +        dup set-node +        dup " compatible" rot get-package-property 0 = IF +            drop dup from-cstring +            2dup " hvterm1" strequal IF +                " vio-hvterm.fs" included +            THEN +            2dup " IBM,v-scsi" strequal IF +                " vio-vscsi.fs" included +            THEN +            2dup " IBM,l-lan" strequal IF +                " vio-veth.fs" included +            THEN +	    2dup " qemu,spapr-nvram" strequal IF +	    	" rtas-nvram.fs" included +	    THEN +            2drop +       THEN +       peer +    REPEAT drop + +    device-end +; + +\ Now do it +populate-vios + +580 cp + +5a0 cp + +#include "pci-scan.fs" + +: populate-pci-busses ( -- ) +    \ Populate the /pci* children with their methods +    " /" find-device get-node child +    BEGIN +        dup 0 <> +    WHILE +        dup set-node +        dup " name" rot get-package-property 0 = IF +            drop dup from-cstring +            2dup s" pci" strequal IF +                s" pci-phb.fs" included +            THEN +            2drop +       THEN +       peer +    REPEAT drop + +    device-end +; + +populate-pci-busses + +600 cp + +: check-patch-kernel-sc1 ( -- ) +    \ At this point we can try our best to patch the kernel. This function +    \ gets called from the "quiesce" call that kernels execute before they +    \ take over the system. +    \ +    \ Here we know that ciregs->r4 contains the return address that gets us +    \ back into enter_prom inside the guest kernel. +    \ We assume that within a range of +- 16MB of that pointer all sc 1 +    \ instructions inside of that kernel reside. + +    \ test_ins (instruction that tells us the kernel's endianness; we use the +    \           return address back into the kernel here.) +    ciregs >r4 @ +    \ test_ins + 16MB (end of search range) +    dup 1000000 + +    \ MAX(test_ins - 16MB, 0) (start of search range) +    dup 2000000 < IF 0 ELSE dup 2000000 - THEN +    swap +    check-and-patch-sc1 +; + +\ Add sc 1 patching +' check-patch-kernel-sc1 add-quiesce-xt + +\ Add rtas cleanup last +' rtas-quiesce add-quiesce-xt + +640 cp + +690 cp + +6a0 cp + +6a8 cp + +6b0 cp + +6b8 cp + +6c0 cp + +s" /cpus/@0" open-dev encode-int s" cpu" set-chosen +s" /memory@0" open-dev encode-int s" memory" set-chosen + +6e0 cp + +700 cp + +\ See 3.5. +s" /openprom" find-device +   s" SLOF," slof-build-id here swap rmove here slof-build-id nip $cat encode-string s" model" property +   0 0 s" relative-addressing" property +device-end + +s" /aliases" find-device +   : open  true ; +   : close ; +device-end + +s" /mmu" open-dev encode-int s" mmu" set-chosen + +#include "available.fs" + +\ Setup terminal IO + +#include <term-io.fs> + diff --git a/roms/SLOF/board-qemu/slof/version.S b/roms/SLOF/board-qemu/slof/version.S new file mode 100644 index 00000000..9aa2a94f --- /dev/null +++ b/roms/SLOF/board-qemu/slof/version.S @@ -0,0 +1,36 @@ +/****************************************************************************** + * Copyright (c) 2010, 2011 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 + *****************************************************************************/ + +/* + * Print version information - in SLOF + * This code is in a separate file so that it can be easily compiled during + * each new build (for refreshing the build date). + */ + +#include "termctrl.h" +#include <product.h> + +.global print_version +print_version: +	.ascii	TERM_CTRL_RESET +	.ascii	TERM_CTRL_CRSOFF +	.ascii	TERM_CTRL_BRIGHT +	.ascii	PRODUCT_NAME +	.ascii  " Starting\r\n" +	.ascii  TERM_CTRL_RESET +	.ascii  " Build Date = ", __DATE__, " ", __TIME__ +	.ascii	"\r\n" +	.ascii  " FW Version = " , RELEASE +	.ascii	"\r\n\0" +	.align	2 +.global print_version_end +print_version_end: diff --git a/roms/SLOF/board-qemu/slof/vio-hvterm.fs b/roms/SLOF/board-qemu/slof/vio-hvterm.fs new file mode 100644 index 00000000..3519751e --- /dev/null +++ b/roms/SLOF/board-qemu/slof/vio-hvterm.fs @@ -0,0 +1,41 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 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 +\ ****************************************************************************/ + +." Populating " pwd cr + +: open true ; +: close ; + +: write ( adr len -- actual ) +   tuck +   0 ?DO +       dup c@ my-unit SWAP hv-putchar +       1 + +   LOOP +   drop +; + +: read  ( adr len -- actual ) +   0= IF drop 0 EXIT THEN +   my-unit hv-haschar 0= IF 0 swap c! -2 EXIT THEN +   my-unit hv-getchar swap c! 1 +; + +: setup-alias +    " hvterm" find-alias 0= IF +        " hvterm" get-node node>path set-alias +    ELSE +        drop +    THEN +; + +setup-alias diff --git a/roms/SLOF/board-qemu/slof/vio-veth.fs b/roms/SLOF/board-qemu/slof/vio-veth.fs new file mode 100644 index 00000000..3c8f489f --- /dev/null +++ b/roms/SLOF/board-qemu/slof/vio-veth.fs @@ -0,0 +1,76 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 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 +\ ****************************************************************************/ + +." Populating " pwd cr + +" network" device-type + +INSTANCE VARIABLE obp-tftp-package +0 VALUE veth-priv +0 VALUE open-count + +: open  ( -- okay? ) +   open-count 0= IF +      my-unit 1 rtas-set-tce-bypass +      s" local-mac-address" get-node get-property not +      s" reg" get-node get-property not 3 pick and IF +         >r nip r> +         libveth-open dup not IF ." libveth-open failed" EXIT THEN +         drop TO veth-priv +      THEN +   THEN +   my-args s" obp-tftp" $open-package obp-tftp-package ! +   open-count 1 + to open-count +   true +; + +: close  ( -- ) +   open-count 0> IF +      open-count 1 - dup to open-count +      0= IF +         veth-priv libveth-close +         my-unit 0 rtas-set-tce-bypass +      THEN +   THEN +   s" close" obp-tftp-package @ $call-method +; + +: read ( buf len -- actual ) +   dup IF +      veth-priv libveth-read +   ELSE +      nip +   THEN +; + +: write ( buf len -- actual ) +   dup IF +      veth-priv libveth-write +   ELSE +      nip +   THEN +; + +: load  ( addr -- len ) +    s" load" obp-tftp-package @ $call-method  +; + +: ping  ( -- ) +    s" ping" obp-tftp-package @ $call-method +; + +: setup-alias +    " net" get-next-alias ?dup IF +        get-node node>path set-alias +    THEN +; +setup-alias diff --git a/roms/SLOF/board-qemu/slof/vio-vscsi.fs b/roms/SLOF/board-qemu/slof/vio-vscsi.fs new file mode 100644 index 00000000..f2d4c6fc --- /dev/null +++ b/roms/SLOF/board-qemu/slof/vio-vscsi.fs @@ -0,0 +1,546 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 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 +\ ****************************************************************************/ + +." Populating " pwd + +false VALUE vscsi-debug? +0 VALUE vscsi-unit + +\ ----------------------------------------------------------- +\ Direct DMA conversion hack +\ ----------------------------------------------------------- +: l2dma ( laddr - dma_addr)       +; + +\ ----------------------------------------------------------- +\ CRQ related functions +\ ----------------------------------------------------------- + +0    VALUE     crq-real-base +0    VALUE     crq-base +0    VALUE     crq-dma +0    VALUE     crq-offset +1000 CONSTANT  CRQ-SIZE + +CREATE crq 10 allot + +: crq-alloc ( -- ) +    \ Allocate enough to align to a page +    CRQ-SIZE fff + alloc-mem to crq-real-base +    \ align the result +    crq-real-base fff + fffff000 AND to crq-base 0 to crq-offset +    crq-base l2dma to crq-dma +; + +: crq-free ( -- ) +    vscsi-unit hv-free-crq +    crq-real-base CRQ-SIZE fff + free-mem 0 to crq-base 0 to crq-real-base +; + +: crq-init ( -- res ) +    \ Allocate CRQ. XXX deal with fail +    crq-alloc + +    vscsi-debug? IF +        ." VSCSI: allocated crq at " crq-base . cr +    THEN + +    \ Clear buffer +    crq-base CRQ-SIZE erase + +    \ Register with HV +    vscsi-unit crq-dma CRQ-SIZE hv-reg-crq + +    \ Fail case +    dup 0 <> IF +        ." VSCSI: Error " . ."  registering CRQ !" cr +	crq-free +    THEN +; + +: crq-cleanup ( -- ) +    crq-base 0 = IF EXIT THEN + +    vscsi-debug? IF +        ." VSCSI: freeing crq at " crq-base . cr +    THEN +    crq-free +; + +: crq-send ( msgaddr -- true | false ) +    vscsi-unit swap hv-send-crq 0 = +; + +: crq-poll ( -- true | false) +    crq-offset crq-base + dup +    vscsi-debug? IF +        ." VSCSI: crq poll " dup . +    THEN +    c@ +    vscsi-debug? IF +        ."  value=" dup . cr +    THEN +    80 and 0 <> IF +        dup crq 10 move +	0 swap c! +	crq-offset 10 + dup CRQ-SIZE >= IF drop 0 THEN to crq-offset +	true +    ELSE drop false THEN +; + +: crq-wait ( -- true | false) +    \ FIXME: Add timeout +    0 BEGIN drop crq-poll dup not WHILE d# 1 ms REPEAT +    dup not IF +        ." VSCSI: Timeout waiting response !" cr EXIT +    ELSE +        vscsi-debug? IF +            ." VSCSI: got crq: " crq dup l@ . ."  " 4 + dup l@ . ."  " +	    4 + dup l@ . ."  " 4 + l@ . cr +        THEN +    THEN +; + +\ ----------------------------------------------------------- +\ CRQ encapsulated SRP definitions +\ ----------------------------------------------------------- + +01 CONSTANT VIOSRP_SRP_FORMAT +02 CONSTANT VIOSRP_MAD_FORMAT +03 CONSTANT VIOSRP_OS400_FORMAT +04 CONSTANT VIOSRP_AIX_FORMAT +06 CONSTANT VIOSRP_LINUX_FORMAT +07 CONSTANT VIOSRP_INLINE_FORMAT + +struct +   1 field >crq-valid +   1 field >crq-format +   1 field >crq-reserved +   1 field >crq-status +   2 field >crq-timeout +   2 field >crq-iu-len +   8 field >crq-iu-data-ptr +constant /crq + +: srp-send-crq ( addr len -- ) +    80                crq >crq-valid c! +    VIOSRP_SRP_FORMAT crq >crq-format c! +    0                 crq >crq-reserved c! +    0                 crq >crq-status c! +    0                 crq >crq-timeout w! +    ( len )           crq >crq-iu-len w! +    ( addr ) l2dma    crq >crq-iu-data-ptr x! +    crq crq-send +    not IF +        ." VSCSI: Error sending CRQ !" cr +    THEN +; + +: srp-wait-crq ( -- [tag true] | false ) +    crq-wait not IF false EXIT THEN + +    crq >crq-format c@ VIOSRP_SRP_FORMAT <> IF +    	." VSCSI: Unsupported SRP response: " +	crq >crq-format c@ . cr +	false EXIT +    THEN + +    crq >crq-iu-data-ptr x@ true +; + +\ Add scsi functions to dictionary +scsi-open + + +\ ----------------------------------------------------------- +\ SRP definitions +\ ----------------------------------------------------------- + +0 VALUE >srp_opcode + +00 CONSTANT SRP_LOGIN_REQ +01 CONSTANT SRP_TSK_MGMT +02 CONSTANT SRP_CMD +03 CONSTANT SRP_I_LOGOUT +c0 CONSTANT SRP_LOGIN_RSP +c1 CONSTANT SRP_RSP +c2 CONSTANT SRP_LOGIN_REJ +80 CONSTANT SRP_T_LOGOUT +81 CONSTANT SRP_CRED_REQ +82 CONSTANT SRP_AER_REQ +41 CONSTANT SRP_CRED_RSP +42 CONSTANT SRP_AER_RSP + +02 CONSTANT SRP_BUF_FORMAT_DIRECT +04 CONSTANT SRP_BUF_FORMAT_INDIRECT + +struct +   1 field >srp-login-opcode +   3 + +   8 field >srp-login-tag +   4 field >srp-login-req-it-iu-len +   4 + +   2 field >srp-login-req-buf-fmt +   1 field >srp-login-req-flags +   5 + +  10 field >srp-login-init-port-ids +  10 field >srp-login-trgt-port-ids +constant /srp-login + +struct +   1 field >srp-lresp-opcode +   3 + +   4 field >srp-lresp-req-lim-delta +   8 field >srp-lresp-tag +   4 field >srp-lresp-max-it-iu-len +   4 field >srp-lresp-max-ti-iu-len +   2 field >srp-lresp-buf-fmt +   1 field >srp-lresp-flags +constant /srp-login-resp + +struct +   1 field >srp-lrej-opcode +   3 + +   4 field >srp-lrej-reason +   8 field >srp-lrej-tag +   8 + +   2 field >srp-lrej-buf-fmt +constant /srp-login-rej + +00 CONSTANT SRP_NO_DATA_DESC +01 CONSTANT SRP_DATA_DESC_DIRECT +02 CONSTANT SRP_DATA_DESC_INDIRECT + +struct +    1 field >srp-cmd-opcode +    1 field >srp-cmd-sol-not +    3 + +    1 field >srp-cmd-buf-fmt +    1 field >srp-cmd-dout-desc-cnt +    1 field >srp-cmd-din-desc-cnt +    8 field >srp-cmd-tag +    4 + +    8 field >srp-cmd-lun +    1 + +    1 field >srp-cmd-task-attr +    1 + +    1 field >srp-cmd-add-cdb-len +   10 field >srp-cmd-cdb +    0 field >srp-cmd-cdb-add +constant /srp-cmd + +struct +    1 field >srp-rsp-opcode +    1 field >srp-rsp-sol-not +    2 + +    4 field >srp-rsp-req-lim-delta +    8 field >srp-rsp-tag +    2 + +    1 field >srp-rsp-flags +    1 field >srp-rsp-status +    4 field >srp-rsp-dout-res-cnt +    4 field >srp-rsp-din-res-cnt +    4 field >srp-rsp-sense-len +    4 field >srp-rsp-resp-len +    0 field >srp-rsp-data +constant /srp-rsp + +\ Constants for srp-rsp-flags +01 CONSTANT SRP_RSP_FLAG_RSPVALID +02 CONSTANT SRP_RSP_FLAG_SNSVALID +04 CONSTANT SRP_RSP_FLAG_DOOVER +05 CONSTANT SRP_RSP_FLAG_DOUNDER +06 CONSTANT SRP_RSP_FLAG_DIOVER +07 CONSTANT SRP_RSP_FLAG_DIUNDER + +\ Storage for up to 256 bytes SRP request */ +CREATE srp 100 allot +0 VALUE srp-len + +: srp-prep-cmd-nodata ( srplun -- ) +    srp /srp-cmd erase +    SRP_CMD srp >srp-cmd-opcode c! +    1 srp >srp-cmd-tag x! +    srp >srp-cmd-lun x!         \ 8 bytes lun +    /srp-cmd to srp-len    +; + +: srp-prep-cmd-io ( addr len srplun -- ) +    srp-prep-cmd-nodata		( addr len ) +    swap l2dma			( len dmaaddr ) +    srp srp-len +    		( len dmaaddr descaddr ) +    dup >r x! r> 8 +		( len descaddr+8 ) +    dup 0 swap l! 4 +		( len descaddr+c ) +    l!     +    srp-len 10 + to srp-len +; + +: srp-prep-cmd-read ( addr len srplun -- ) +    srp-prep-cmd-io +    01 srp >srp-cmd-buf-fmt c!	\ in direct buffer +    1 srp >srp-cmd-din-desc-cnt c! +; + +: srp-prep-cmd-write ( addr len srplun -- ) +    srp-prep-cmd-io +    10 srp >srp-cmd-buf-fmt c!	\ out direct buffer +    1 srp >srp-cmd-dout-desc-cnt c! +; + +: srp-send-cmd ( -- ) +    vscsi-debug? IF +        ." VSCSI: Sending SCSI cmd " srp >srp-cmd-cdb c@ . cr +    THEN +    srp srp-len srp-send-crq +; + +: srp-rsp-find-sense ( -- addr len true | false ) +    srp >srp-rsp-flags c@ SRP_RSP_FLAG_SNSVALID and 0= IF +        false EXIT +    THEN +    \ XXX FIXME: We assume the sense data is right at response +    \            data. A different server might actually have both +    \            some response data we need to skip *and* some sense +    \            data. +    srp >srp-rsp-data srp >srp-rsp-sense-len l@ true +; + +\ Wait for a response to the last sent SRP command +\ returns a SCSI status code or -1 (HW error). +\ +: srp-wait-rsp ( -- stat ) +    srp-wait-crq not IF false EXIT THEN +    dup 1 <> IF +        ." VSCSI: Invalid CRQ response tag, want 1 got " . cr +	-1 EXIT +    THEN drop +     +    srp >srp-rsp-tag x@ dup 1 <> IF +        ." VSCSI: Invalid SRP response tag, want 1 got " . cr +	-1 EXIT +    THEN drop +     +    srp >srp-rsp-status c@ +    vscsi-debug? IF +        ." VSCSI: Got response status: " +	dup .status-text cr +    THEN +; + +\ ----------------------------------------------------------- +\ Perform SCSI commands +\ ----------------------------------------------------------- + +8000000000000000 INSTANCE VALUE current-target + +\ SCSI command. We do *NOT* implement the "standard" execute-command +\ because that doesn't have a way to return the sense buffer back, and +\ we do have auto-sense with some hosts. Instead we implement a made-up +\ do-scsi-command. +\ +\ Note: stat is -1 for "hw error" (ie, error queuing the command or +\ getting the response). +\ +\ A sense buffer is returned whenever the status is non-0 however +\ if sense-len is 0 then no sense data is actually present +\ + +: execute-scsi-command ( buf-addr buf-len dir cmd-addr cmd-len -- ... ) +                       ( ... [ sense-buf sense-len ] stat ) +    \ Stash command addr & len +    >r >r				( buf-addr buf-len dir ) +    \ Command has no data ? +    over 0= IF +        3drop current-target srp-prep-cmd-nodata +    ELSE +        \ Command is a read ? +        current-target swap IF srp-prep-cmd-read ELSE srp-prep-cmd-write THEN +    THEN +    \ Recover command and copy it to our srp buffer +    r> r> +    srp >srp-cmd-cdb swap move +    srp-send-cmd +    srp-wait-rsp + +    \ Check for HW error +    dup -1 = IF +        0 0 rot EXIT +    THEN + +    \ Other error status +    dup 0<> IF +       srp-rsp-find-sense IF +           vscsi-debug? IF +               over scsi-get-sense-data +               ." VSCSI: Sense key [ " dup . ." ] " .sense-text +	       ."  ASC,ASCQ: " . . cr +           THEN +       ELSE 0 0 +           \ This relies on auto-sense from qemu... if that isn't always the +           \ case we should request sense here +           ." VSCSI: No sense data" cr +       THEN +       rot +    THEN +; + +\ -------------------------------- +\ Include the generic host helpers +\ -------------------------------- + +" scsi-host-helpers.fs" included + +TRUE VALUE first-time-init? +0 VALUE open-count + +\ Cleanup behind us +: vscsi-cleanup +    vscsi-debug? IF ." VSCSI: Cleaning up" cr THEN +    crq-cleanup + +    \ Disable TCE bypass: +    vscsi-unit 0 rtas-set-tce-bypass +; + +\ Initialize our vscsi instance +: vscsi-init ( -- true | false ) +    vscsi-debug? IF ." VSCSI: Initializing" cr THEN + +    my-unit to vscsi-unit + +    \ Enable TCE bypass special qemu feature +    vscsi-unit 1 rtas-set-tce-bypass + +    \ Initialize CRQ +    crq-init 0 <> IF false EXIT THEN + +    \ Send init command +    " "(C0 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00)" drop +    crq-send not IF +        ." VSCSI: Error sending init command" +        crq-cleanup false EXIT +    THEN +  +    \ Wait reply +    crq-wait not IF +        crq-cleanup false EXIT +    THEN + +    \ Check init reply +    crq c@ c0 <> crq 1 + c@ 02 <> or IF +        ." VSCSI: Initial handshake failed" +	crq-cleanup false EXIT +    THEN + +    \ We should now login etc.. but we really don't need to +    \ with our qemu model + +    \ Ensure we cleanup after booting +    first-time-init? IF +        ['] vscsi-cleanup add-quiesce-xt +	false to first-time-init? +    THEN + +    true +; + +: open +    vscsi-debug? IF ." VSCSI: Opening (count is " open-count . ." )" cr THEN + +    open-count 0= IF +        vscsi-init IF +	    1 to open-count true +	ELSE ." VSCSI initialization failed !" cr false THEN +    ELSE +        open-count 1 + to open-count +        true +    THEN +; + +: close +    vscsi-debug? IF ." VSCSI: Closing (count is " open-count . ." )" cr THEN + +    open-count 0> IF +        open-count 1 - dup to open-count +	0= IF +	    vscsi-cleanup +	THEN +    THEN +; + +\ ----------------------------------------------------------- +\ SCSI scan at boot and child device support +\ ----------------------------------------------------------- + +\ We use SRP luns of the form 8000 | (bus << 8) | (id << 5) | lun +\ in the top 16 bits of the 64-bit LUN +: (set-target) +    to current-target +; + +: dev-generate-srplun ( target lun -- ) +    swap 8 << 8000 or or 30 << +; + +\ We obtain here a unit address on the stack, since our #address-cells +\ is 2, the 64-bit srplun is split in two cells that we need to join +\ +\ Note: This diverges a bit from the original OF scsi spec as the two +\ cells are the 2 words of a 64-bit SRP LUN +: set-address ( srplun.lo srplun.hi -- ) +    lxjoin (set-target) +; + +\ We set max-transfer to a fixed value for now to avoid problems +\ with some CD-ROM drives. +\ FIXME: Check max transfer coming from VSCSI +: max-transfer ( -- n ) +    10000 \ Larger value seem to have problems with some CDROMs +; + +8 CONSTANT #dev +: dev-max-target ( -- #max-target ) +    #dev +; + +" scsi-probe-helpers.fs" included + +\ Remove scsi functions from word list +scsi-close + +: setup-alias +    " scsi" find-alias 0= IF +        " scsi" get-node node>path set-alias +    ELSE +        drop +    THEN  +; + +: vscsi-init-and-scan  ( -- ) +    \ Create instance for scanning: +    0 0 get-node open-node ?dup 0= IF EXIT THEN +    my-self >r +    dup to my-self +    \ Scan the VSCSI bus: +    scsi-find-disks +    setup-alias +    \ Close the temporary instance: +    close-node +    r> to my-self +; + +: vscsi-add-disk +    " scsi-disk.fs" included +; + +vscsi-add-disk +vscsi-init-and-scan diff --git a/roms/SLOF/board-qemu/slof/virtio-block.fs b/roms/SLOF/board-qemu/slof/virtio-block.fs new file mode 100644 index 00000000..ea388fb0 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/virtio-block.fs @@ -0,0 +1,89 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 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 +\ ****************************************************************************/ + +\ ." Populating " pwd cr + +s" block" device-type + +FALSE VALUE initialized? + +\ Required interface for deblocker + +200 VALUE block-size +8000 CONSTANT max-transfer  + +INSTANCE VARIABLE deblocker + +/vd-len BUFFER: virtiodev +virtiodev virtio-setup-vd + +\ Quiesce the virtqueue of this device so that no more background +\ transactions can be pending. +: shutdown  ( -- ) +    initialized? IF +        my-phandle node>path open-dev ?dup IF +            virtiodev virtio-blk-shutdown +            close-dev +        THEN +        FALSE to initialized? +    THEN +; + +\ Basic device initialization - which has only to be done once +: init  ( -- ) +   virtiodev virtio-blk-init to block-size +   TRUE to initialized? +   ['] shutdown add-quiesce-xt +; + +\ Read multiple blocks - called by deblocker package +: read-blocks  ( addr block# #blocks -- #read ) +   virtiodev virtio-blk-read +; + +\ Standard node "open" function +: open  ( -- okay? ) +   open 0= IF false EXIT THEN +   dup initialized? 0= AND IF +      init +   THEN +   0 0 s" deblocker" $open-package dup deblocker ! dup IF +      s" disk-label" find-package IF +         my-args rot interpose +      THEN +   THEN +   0<> +; + +\ Standard node "close" function +: close  ( -- ) +   deblocker @ close-package +   close +; + +\ Standard node "seek" function +: seek  ( pos.lo pos.hi -- status ) +   s" seek" deblocker @ $call-method +; + +\ Standard node "read" function +: read  ( addr len -- actual ) +   s" read" deblocker @ $call-method +; + +\ Set disk alias if none is set yet +: (set-alias) +   s" disk" get-next-alias ?dup IF +      get-node node>path set-alias +   THEN +; +(set-alias) diff --git a/roms/SLOF/board-qemu/slof/virtio-fs.fs b/roms/SLOF/board-qemu/slof/virtio-fs.fs new file mode 100644 index 00000000..8632b465 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/virtio-fs.fs @@ -0,0 +1,96 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 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 +\ ****************************************************************************/ + +." Populating " pwd cr + +s" network" device-type + +0 VALUE virtfs-rx-buffer +0 VALUE virtfs-tx-buffer +FALSE VALUE initialized? + +2000 CONSTANT VIRTFS-BUF-SIZE \ 8k + +/vd-len BUFFER: virtiodev +virtiodev virtio-setup-vd + +\ +\ Support methods. + +: shutdown  ( -- ) +   initialized? 0= IF EXIT THEN +   virtiodev virtio-fs-shutdown +   virtfs-rx-buffer VIRTFS-BUF-SIZE free-mem +   virtfs-tx-buffer VIRTFS-BUF-SIZE free-mem +   FALSE to initialized? +; + +: init  ( -- success ) +   VIRTFS-BUF-SIZE alloc-mem to virtfs-rx-buffer +   VIRTFS-BUF-SIZE alloc-mem to virtfs-tx-buffer +    +   virtiodev			( dev ) +   virtfs-tx-buffer		( dev tx ) +   virtfs-rx-buffer		( reg tx rx ) +   VIRTFS-BUF-SIZE		( reg tx rx size )    +   virtio-fs-init		( success ) +    +   dup IF +      TRUE to initialized? +      ['] shutdown add-quiesce-xt +   THEN +; + +\ +\ Standard network interface. + +: open  ( -- okay? ) +   open 0= IF false EXIT THEN +   initialized? 0= IF +      init 0= IF false EXIT THEN +   THEN    +   true +; + +: load ( addr -- len ) +   virtiodev swap		( dev addr )    +   my-args   			( dev addr str strlen ) +   1 +		\ hack to make the following allocate 1 more byte +   \-to-/	\ convert path elements +   1 - 2dup + 0 swap c! drop +   virtio-fs-load		( length ) +; + +: close  ( -- ) +   initialized? IF +      shutdown +   THEN +   close +; + +: ping ( -- ) +   cr s" ping not supported for this device" type cr cr +; + + +: (set-alias) +    " virtfs" find-alias 0= IF +        " virtfs" get-node node>path set-alias +    ELSE +        drop +    THEN +; + +\ +\ Init the module. + +(set-alias) diff --git a/roms/SLOF/board-qemu/slof/virtio-net.fs b/roms/SLOF/board-qemu/slof/virtio-net.fs new file mode 100644 index 00000000..412b34fa --- /dev/null +++ b/roms/SLOF/board-qemu/slof/virtio-net.fs @@ -0,0 +1,96 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 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 +\ ****************************************************************************/ + +\ ." Populating " pwd cr + +s" network" device-type + +INSTANCE VARIABLE obp-tftp-package + +/vd-len BUFFER: virtiodev +virtiodev virtio-setup-vd +0 VALUE virtio-net-priv +0 VALUE open-count + +: open  ( -- okay? ) +   open-count 0= IF +      open IF +         \ my-unit 1 rtas-set-tce-bypass +         s" local-mac-address" get-node get-property not IF +            virtiodev virtio-net-open dup not IF ." virtio-net-open failed" EXIT THEN +            drop TO virtio-net-priv +         THEN +         true +      ELSE +         false +      THEN +   ELSE +      true +   THEN +   my-args s" obp-tftp" $open-package obp-tftp-package ! +   open-count 1 + to open-count +; + + +: close  ( -- ) +    open-count 0> IF +      open-count 1 - dup to open-count +      0= IF +         virtio-net-priv virtio-net-close +         \ my-unit 0 rtas-set-tce-bypass +         close +      THEN +   THEN +   s" close" obp-tftp-package @ $call-method +; + +: read ( buf len -- actual ) +   dup IF +      virtio-net-read +   ELSE +      nip +   THEN +; + +: write ( buf len -- actual ) +   dup IF +      virtio-net-write +   ELSE +      nip +   THEN +; + +: load  ( addr -- len ) +   s" load" obp-tftp-package @ $call-method  +; + +: ping  ( -- ) +   s" ping" obp-tftp-package @ $call-method +; + +\ Set up MAC address from config virtqueue +6 BUFFER: local-mac +: setup-mac  ( -- ) +   6 0 DO +      virtiodev i 1 virtio-get-config +      local-mac i + c! +   LOOP +   local-mac 6 encode-bytes  s" local-mac-address"  property +; +setup-mac + +: setup-alias  ( -- ) +   " net" get-next-alias ?dup IF +      get-node node>path set-alias +   THEN +; +setup-alias diff --git a/roms/SLOF/board-qemu/slof/virtio-scsi.fs b/roms/SLOF/board-qemu/slof/virtio-scsi.fs new file mode 100644 index 00000000..ca5fb13a --- /dev/null +++ b/roms/SLOF/board-qemu/slof/virtio-scsi.fs @@ -0,0 +1,232 @@ +\ ***************************************************************************** +\ * Copyright (c) 2012 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 +\ ****************************************************************************/ + +." Populating " pwd cr + +FALSE CONSTANT virtio-scsi-debug + +2 encode-int s" #address-cells" property +0 encode-int s" #size-cells" property + +: decode-unit 2 hex64-decode-unit ; +: encode-unit 2 hex64-encode-unit ; + +FALSE VALUE initialized? + +/vd-len BUFFER: virtiodev +virtiodev virtio-setup-vd + +STRUCT \ virtio-scsi-config +    /l FIELD vs-cfg>num-queues +    /l FIELD vs-cfg>seg-max +    /l FIELD vs-cfg>max-sectors +    /l FIELD vs-cfg>cmd-per-lun +    /l FIELD vs-cfg>event-info-size +    /l FIELD vs-cfg>sense_size +    /l FIELD vs-cfg>cdb-size +    /w FIELD vs-cfg>max-channel +    /w FIELD vs-cfg>max-target +    /l FIELD vs-cfg>max-lun +CONSTANT vs-cfg-length + +STRUCT \ virtio-scsi-req +    8  FIELD vs-req>lun +    8  FIELD vs-req>tag +    /c FIELD vs-req>task-attr +    /c FIELD vs-req>prio +    /c FIELD vs-req>crn +    20 FIELD vs-req>cdb +CONSTANT vs-req-length + +STRUCT \ virtio-scsi-resp +    /l FIELD vs-rsp>sense-len +    /l FIELD vs-rsp>residual +    /w FIELD vs-rsp>status-qualifier +    /c FIELD vs-rsp>status +    /c FIELD vs-rsp>response +    60 FIELD vs-rsp>sense +CONSTANT vs-rsp-length + +CREATE vs-req vs-req-length allot +CREATE vs-rsp vs-rsp-length allot + +scsi-open + +\ ----------------------------------------------------------- +\ Perform SCSI commands +\ ----------------------------------------------------------- + +0 INSTANCE VALUE current-target + +\ SCSI command. We do *NOT* implement the "standard" execute-command +\ because that doesn't have a way to return the sense buffer back, and +\ we do have auto-sense with some hosts. Instead we implement a made-up +\ do-scsi-command. +\ +\ Note: stat is -1 for "hw error" (ie, error queuing the command or +\ getting the response). +\ +\ A sense buffer is returned whenever the status is non-0 however +\ if sense-len is 0 then no sense data is actually present +\ + +: execute-scsi-command ( buf-addr buf-len dir cmd-addr cmd-len -- ... ) +                       ( ... [ sense-buf sense-len ] stat ) +    \ Cleanup virtio request and response +    vs-req vs-req-length erase +    vs-rsp vs-rsp-length erase + +    \ Populate the request +    current-target vs-req vs-req>lun x! +    vs-req vs-req>cdb swap move + +    \ Send it +    vs-req vs-rsp virtiodev +    virtio-scsi-send + +    0 <> IF +        ." VIRTIO-SCSI: Queuing failure !" cr +        0 0 -1 EXIT +    THEN + +    \ Check virtio response +    vs-rsp vs-rsp>response c@ CASE +        0 OF ENDOF			\ Good +        5 OF drop 0 0 8 EXIT ENDOF	\ Busy +        dup OF 0 0 -1 EXIT ENDOF	\ Anything else -> HW error +    ENDCASE + +    \ Other error status +    vs-rsp vs-rsp>status c@ dup 0<> IF +        vs-rsp vs-rsp>sense-len l@ dup 0= IF +            \ This relies on auto-sense from qemu... if that isn't always the +            \ case we should request sense here +            ." VIRTIO-SCSI: No sense data" cr +	    0 EXIT +        THEN +        vs-rsp vs-rsp>sense swap +        virtio-scsi-debug IF +            over scsi-get-sense-data +            ." VIRTIO-SCSI: Sense key [ " dup . ." ] " .sense-text +	    ."  ASC,ASCQ: " . . cr +        THEN +       rot +    THEN     +; + +\ -------------------------------- +\ Include the generic host helpers +\ -------------------------------- + +" scsi-host-helpers.fs" included + +\ FIXME: Check max transfer coming from virtio config +: max-transfer ( -- n ) +    10000 \ Larger value seem to have problems with some CDROMs +; + +\ ----------------------------------------------------------- +\ SCSI scan at boot and child device support +\ ----------------------------------------------------------- + +\ We use SRP luns of the form 01000000 | (target << 16) | lun +\ in the top 32 bits of the 64-bit LUN +: (set-target) +    to current-target +; + +: dev-generate-srplun ( target lun-id -- srplun ) +    swap 0100 or 10 << or 20 << +; + +\ We obtain here a unit address on the stack, since our #address-cells +\ is 2, the 64-bit srplun is split in two cells that we need to join +\ +\ Note: This diverges a bit from the original OF scsi spec as the two +\ cells are the 2 words of a 64-bit SRP LUN +: set-address ( srplun.lo srplun.hi -- ) +    lxjoin (set-target) +; + +100 CONSTANT #target +: dev-max-target ( -- #target ) +    #target +; + +" scsi-probe-helpers.fs" included + +scsi-close        \ no further scsi words required + +0 VALUE queue-control-addr +0 VALUE queue-event-addr +0 VALUE queue-cmd-addr + +: setup-virt-queues +    \ add 3 queues 0-controlq, 1-eventq, 2-cmdq +    \ fixme: do we need to find more than the above 3 queues if exists +    virtiodev 0 virtio-get-qsize virtio-vring-size +    alloc-mem to queue-control-addr +    virtiodev 0 queue-control-addr virtio-set-qaddr + +    virtiodev 1 virtio-get-qsize virtio-vring-size +    alloc-mem to queue-event-addr +    virtiodev 1 queue-event-addr virtio-set-qaddr + +    virtiodev 2 virtio-get-qsize virtio-vring-size +    alloc-mem to queue-cmd-addr +    virtiodev 2 queue-cmd-addr virtio-set-qaddr +; + +\ Set scsi alias if none is set yet +: setup-alias +    s" scsi" find-alias 0= IF +	s" scsi" get-node node>path set-alias +    ELSE +	drop +    THEN +; + +: shutdown ( -- ) +    initialized? IF +       my-phandle node>path open-dev ?dup IF +          virtiodev virtio-scsi-shutdown +          close-dev +       THEN +       FALSE to initialized? +    THEN +; + +: virtio-scsi-init-and-scan  ( -- ) +    \ Create instance for scanning: +    0 0 get-node open-node ?dup 0= IF ." exiting " cr EXIT THEN +    my-self >r +    dup to my-self +    \ Scan the VSCSI bus: +    virtiodev virtio-scsi-init +    0= IF +	setup-virt-queues +	scsi-find-disks +	setup-alias +	TRUE to initialized? +	['] shutdown add-quiesce-xt +    THEN +    \ Close the temporary instance: +    close-node +    r> to my-self +; + +: virtio-scsi-add-disk +    " scsi-disk.fs" included +; + +virtio-scsi-add-disk +virtio-scsi-init-and-scan diff --git a/roms/SLOF/board-qemu/slof/virtio.fs b/roms/SLOF/board-qemu/slof/virtio.fs new file mode 100644 index 00000000..818c1320 --- /dev/null +++ b/roms/SLOF/board-qemu/slof/virtio.fs @@ -0,0 +1,35 @@ +\ ***************************************************************************** +\ * Copyright (c) 2011 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 +\ ****************************************************************************/ + +\ This struct must match "struct virtio_device" in virtio.h! +STRUCT +   /n FIELD vd>base +   /l FIELD vd>type +CONSTANT /vd-len + + +\ Initialize virtiodev structure for the current node +: virtio-setup-vd  ( vdstruct -- ) +   >r +   \ Does it have a "class-code" property? If yes, assume we're a PCI device +   s" class-code" get-node get-property 0= IF +      \ Set up for PCI device interface +      2drop +      s" 10 config-l@ translate-my-address 3 not AND" evaluate +      ( io-base ) r@ vd>base ! +      0 r@ vd>type l! +   ELSE +      ." unsupported virtio interface!" cr +      1 r@ vd>type l! +   THEN +   r> drop +;  | 
