summaryrefslogtreecommitdiff
path: root/roms/SLOF
diff options
context:
space:
mode:
Diffstat (limited to 'roms/SLOF')
-rw-r--r--roms/SLOF/README14
-rw-r--r--roms/SLOF/VERSION2
-rw-r--r--roms/SLOF/board-js2x/llfw/stage2.lds3
-rw-r--r--roms/SLOF/board-js2x/llfw/stage2_head.S2
-rw-r--r--roms/SLOF/board-js2x/slof/Makefile1
-rw-r--r--roms/SLOF/board-js2x/slof/helper.fs11
-rw-r--r--roms/SLOF/board-qemu/llfw/stage2.lds3
-rw-r--r--roms/SLOF/board-qemu/llfw/stage2_head.S2
-rw-r--r--roms/SLOF/board-qemu/slof/Makefile2
-rw-r--r--roms/SLOF/board-qemu/slof/helper.fs13
-rw-r--r--roms/SLOF/board-qemu/slof/pci-device_1234_1111.fs229
-rw-r--r--roms/SLOF/board-qemu/slof/pci-device_1af4_1050.fs15
-rw-r--r--roms/SLOF/board-qemu/slof/qemu-vga.fs198
-rw-r--r--roms/SLOF/clients/net-snk/client.lds4
-rw-r--r--roms/SLOF/clients/net-snk/kernel/entry.S2
-rw-r--r--roms/SLOF/clients/takeover/client.lds4
-rw-r--r--roms/SLOF/clients/takeover/entry.S2
-rw-r--r--roms/SLOF/clients/takeover/main.c2
-rw-r--r--roms/SLOF/include/ppc970/cache.h50
-rw-r--r--roms/SLOF/include/ppcp7/cache.h22
-rw-r--r--roms/SLOF/lib/libusb/usb-hid.c85
-rw-r--r--roms/SLOF/lib/libusb/usb-xhci.c232
-rw-r--r--roms/SLOF/lib/libusb/usb-xhci.h5
-rw-r--r--roms/SLOF/make.rules12
-rw-r--r--roms/SLOF/rtas/reloc.S2
-rw-r--r--roms/SLOF/rtas/rtas.lds3
-rw-r--r--roms/SLOF/rtas/rtas_entry.S2
-rw-r--r--roms/SLOF/slof/entry.S9
-rw-r--r--roms/SLOF/slof/fs/archsupport.fs6
-rw-r--r--roms/SLOF/slof/fs/base.fs2
-rw-r--r--roms/SLOF/slof/fs/boot.fs7
-rw-r--r--roms/SLOF/slof/fs/client.fs12
-rw-r--r--roms/SLOF/slof/fs/fbuffer.fs30
-rw-r--r--roms/SLOF/slof/fs/little-endian.fs6
-rw-r--r--roms/SLOF/slof/fs/packages/disk-label.fs162
-rw-r--r--roms/SLOF/slof/fs/pci-scan.fs19
-rw-r--r--roms/SLOF/slof/fs/rmove.fs53
-rw-r--r--roms/SLOF/slof/fs/terminal.fs3
-rw-r--r--roms/SLOF/slof/ppc64.c19
-rw-r--r--roms/SLOF/slof/prim.code13
-rw-r--r--roms/SLOF/slof/prim.in3
41 files changed, 784 insertions, 482 deletions
diff --git a/roms/SLOF/README b/roms/SLOF/README
index 58e929427..789504568 100644
--- a/roms/SLOF/README
+++ b/roms/SLOF/README
@@ -11,6 +11,7 @@ Index
2.2 Overview of the source code
2.4 Extending the Forth engine
3.0 Limitations
+4.0 Submitting patches
1.0 Introduction to Slimline Open Firmware
@@ -236,6 +237,16 @@ To add primitives:
On a JS21 all memory configurations should work.
+4.0 Submitting patches
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Patches for SLOF should be made against https://github.com/aik/SLOF,
+the master branch and posted to slof@lists.ozlabs.org.
+The patches must be signed using "Signed-off-by" tag with a real name to
+confirm that you certify the Developer Certificate of Origin Version 1.1,
+see [3] for details.
+
+
Documentation
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -244,3 +255,6 @@ Documentation
[2] PAPR Standard, Power.org(TM) Standard for Power Architecture(R) Platform
Requirements (Workstation, Server), Version 2.4, December 7, 2009
+
+[3] Developer Certificate of Origin Version 1.1
+ http://developercertificate.org/
diff --git a/roms/SLOF/VERSION b/roms/SLOF/VERSION
index 20bdb2eb7..c99837873 100644
--- a/roms/SLOF/VERSION
+++ b/roms/SLOF/VERSION
@@ -1 +1 @@
-20150429
+20151103
diff --git a/roms/SLOF/board-js2x/llfw/stage2.lds b/roms/SLOF/board-js2x/llfw/stage2.lds
index f91f0658a..e6315c3c8 100644
--- a/roms/SLOF/board-js2x/llfw/stage2.lds
+++ b/roms/SLOF/board-js2x/llfw/stage2.lds
@@ -45,7 +45,8 @@ SECTIONS {
__bss_end = .;
__bss_size = (__bss_end - __bss_start);
- __toc_start = .;
+ . = ALIGN(256);
+ __toc_start = DEFINED (.TOC.) ? .TOC. : ADDR (.got) + 0x8000;
.got :
{
*(.toc .got)
diff --git a/roms/SLOF/board-js2x/llfw/stage2_head.S b/roms/SLOF/board-js2x/llfw/stage2_head.S
index 5460bfebb..f3f5e0c8c 100644
--- a/roms/SLOF/board-js2x/llfw/stage2_head.S
+++ b/roms/SLOF/board-js2x/llfw/stage2_head.S
@@ -79,8 +79,6 @@ bsscdone:
/* ------------------------------------ */
ASM_ENTRY(toc_init)
LOAD64(r2, __toc_start)
- addi r2,r2,0x4000
- addi r2,r2,0x4000
blr
/* ------------------------------------ */
diff --git a/roms/SLOF/board-js2x/slof/Makefile b/roms/SLOF/board-js2x/slof/Makefile
index ab3e683a4..fdc716fc6 100644
--- a/roms/SLOF/board-js2x/slof/Makefile
+++ b/roms/SLOF/board-js2x/slof/Makefile
@@ -82,6 +82,7 @@ OF_FFS_FILES = \
$(SLOFCMNDIR)/fs/scsi-host-helpers.fs \
$(SLOFCMNDIR)/fs/scsi-probe-helpers.fs \
$(SLOFCMNDIR)/fs/scsi-support.fs \
+ $(SLOFCMNDIR)/fs/dma-function.fs \
$(SLOFCMNDIR)/fs/pci-device.fs \
$(SLOFCMNDIR)/fs/pci-bridge.fs \
$(SLOFCMNDIR)/fs/pci-properties.fs \
diff --git a/roms/SLOF/board-js2x/slof/helper.fs b/roms/SLOF/board-js2x/slof/helper.fs
index 34d60da1f..1e2b03063 100644
--- a/roms/SLOF/board-js2x/slof/helper.fs
+++ b/roms/SLOF/board-js2x/slof/helper.fs
@@ -26,3 +26,14 @@
s" , " $cat
bdate2human $cat encode-string THEN
;
+
+: invert-region ( addr len -- )
+ 2dup or 7 and CASE
+ 0 OF 3 rshift 0 ?DO dup dup rx@ -1 xor swap rx! xa1+ LOOP ENDOF
+ 4 OF 2 rshift 0 ?DO dup dup rl@ -1 xor swap rl! la1+ LOOP ENDOF
+ 3 and
+ 2 OF 1 rshift 0 ?DO dup dup rw@ -1 xor swap rw! wa1+ LOOP ENDOF
+ dup OF 0 ?DO dup dup rb@ -1 xor swap rb! 1+ LOOP ENDOF
+ ENDCASE
+ drop
+;
diff --git a/roms/SLOF/board-qemu/llfw/stage2.lds b/roms/SLOF/board-qemu/llfw/stage2.lds
index e060dd189..28c9dca93 100644
--- a/roms/SLOF/board-qemu/llfw/stage2.lds
+++ b/roms/SLOF/board-qemu/llfw/stage2.lds
@@ -49,7 +49,8 @@ SECTIONS {
__bss_end = .;
__bss_size = (__bss_end - __bss_start);
- __toc_start = .;
+ . = ALIGN(256);
+ __toc_start = DEFINED (.TOC.) ? .TOC. : ADDR (.got) + 0x8000;
.got :
{
*(.toc .got)
diff --git a/roms/SLOF/board-qemu/llfw/stage2_head.S b/roms/SLOF/board-qemu/llfw/stage2_head.S
index c56b117ce..adf75547b 100644
--- a/roms/SLOF/board-qemu/llfw/stage2_head.S
+++ b/roms/SLOF/board-qemu/llfw/stage2_head.S
@@ -77,8 +77,6 @@ bsscdone:
/* ------------------------------------ */
ASM_ENTRY(toc_init)
LOAD64(r2, __toc_start)
- addi r2,r2,0x4000
- addi r2,r2,0x4000
blr
/* ------------------------------------ */
diff --git a/roms/SLOF/board-qemu/slof/Makefile b/roms/SLOF/board-qemu/slof/Makefile
index 283f77d32..a3fe6abd0 100644
--- a/roms/SLOF/board-qemu/slof/Makefile
+++ b/roms/SLOF/board-qemu/slof/Makefile
@@ -69,6 +69,7 @@ VIO_FFS_FILES = \
$(SLOFBRDDIR)/pci-device_1af4_1001.fs \
$(SLOFBRDDIR)/pci-device_1af4_1004.fs \
$(SLOFBRDDIR)/pci-device_1af4_1009.fs \
+ $(SLOFBRDDIR)/pci-device_1af4_1050.fs \
$(SLOFBRDDIR)/vio-hvterm.fs \
$(SLOFBRDDIR)/vio-vscsi.fs \
$(SLOFBRDDIR)/vio-veth.fs \
@@ -103,6 +104,7 @@ OF_FFS_FILES = \
$(SLOFBRDDIR)/pci-device_1013_00b8.fs \
$(SLOFBRDDIR)/pci-device_8086_100e.fs \
$(SLOFBRDDIR)/e1k.fs \
+ $(SLOFBRDDIR)/qemu-vga.fs \
$(FCODE_FFS_FILES)
# Uncomment the following line to enable the USB code:
diff --git a/roms/SLOF/board-qemu/slof/helper.fs b/roms/SLOF/board-qemu/slof/helper.fs
index 96da49894..40d4abc3a 100644
--- a/roms/SLOF/board-qemu/slof/helper.fs
+++ b/roms/SLOF/board-qemu/slof/helper.fs
@@ -33,3 +33,16 @@
swap -
;
+: invert-region-cs ( addr len cellsize -- )
+ >r over swap r@ rshift r> swap 1 hv-logical-memop drop
+;
+
+: invert-region ( addr len -- )
+ 2dup or 7 and CASE
+ 0 OF 3 invert-region-cs ENDOF
+ 4 OF 2 invert-region-cs ENDOF
+ 3 and
+ 2 OF 1 invert-region-cs ENDOF
+ dup OF 0 invert-region-cs ENDOF
+ ENDCASE
+;
diff --git a/roms/SLOF/board-qemu/slof/pci-device_1234_1111.fs b/roms/SLOF/board-qemu/slof/pci-device_1234_1111.fs
index a5c3584f9..22ea45d5c 100644
--- a/roms/SLOF/board-qemu/slof/pci-device_1234_1111.fs
+++ b/roms/SLOF/board-qemu/slof/pci-device_1234_1111.fs
@@ -10,233 +10,6 @@
\ * 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
+s" qemu-vga.fs" included
diff --git a/roms/SLOF/board-qemu/slof/pci-device_1af4_1050.fs b/roms/SLOF/board-qemu/slof/pci-device_1af4_1050.fs
new file mode 100644
index 000000000..516056aad
--- /dev/null
+++ b/roms/SLOF/board-qemu/slof/pci-device_1af4_1050.fs
@@ -0,0 +1,15 @@
+\ *****************************************************************************
+\ * Copyright (c) 2015 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
+\ ****************************************************************************/
+
+s" virtio [ vga ]" type cr
+
+s" qemu-vga.fs" included
diff --git a/roms/SLOF/board-qemu/slof/qemu-vga.fs b/roms/SLOF/board-qemu/slof/qemu-vga.fs
new file mode 100644
index 000000000..3f4c237fc
--- /dev/null
+++ b/roms/SLOF/board-qemu/slof/qemu-vga.fs
@@ -0,0 +1,198 @@
+\ *****************************************************************************
+\ * Copyright (c) 2015 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
+
+: map-in " map-in" my-phandle parent $call-static ;
+: map-out " map-out" my-phandle parent $call-static ;
+
+\ Determine base address
+0 0 my-space h# 02000010 + 1 map-in VALUE fb-base
+0 0 my-space h# 02000018 + 1 map-in VALUE reg-base
+
+\ We support only one instance
+false VALUE is-installed?
+
+: vga-w! ( value port -- )
+ 3c0 - reg-base 400 + + rw!-le
+;
+
+: vga-w@ ( port -- value )
+ 3c0 - reg-base 400 + + rw@-le
+;
+
+: vga-b! ( value port -- )
+ 3c0 - reg-base 400 + + rb!
+;
+
+: vga-b@ ( port -- value )
+ 3c0 - reg-base 400 + + rb@
+;
+
+: vbe! ( value index -- )
+ 1 << reg-base 500 + + rw!-le
+;
+
+: vbe@ ( index -- value )
+ 1 << reg-base 500 + + rw@-le
+;
+
+: 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
+;
+
+: 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 ( -- )
+;
+
+: slow-blink-screen ( -- )
+ \ 32 msec delay for visually noticing the blink
+ invert-screen 20 ms 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
+ ['] slow-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
+;
+
+pci-master-enable
+pci-mem-enable
+read-settings
+init-mode
+init-default-palette
+setup-properties
+' display-install is-install
+' display-remove is-remove
+set-alias
diff --git a/roms/SLOF/clients/net-snk/client.lds b/roms/SLOF/clients/net-snk/client.lds
index 39d04594e..c2086445b 100644
--- a/roms/SLOF/clients/net-snk/client.lds
+++ b/roms/SLOF/clients/net-snk/client.lds
@@ -44,10 +44,10 @@ SECTIONS {
*(.opd)
}
- . = ALIGN(0x10);
+ . = ALIGN(256);
.got :
{
- _got = .;
+ _got = DEFINED (.TOC.) ? .TOC. : ADDR (.got) + 0x8000;
*(.got)
*(.toc)
_got_end = .;
diff --git a/roms/SLOF/clients/net-snk/kernel/entry.S b/roms/SLOF/clients/net-snk/kernel/entry.S
index 8849fb9d1..bf10542bd 100644
--- a/roms/SLOF/clients/net-snk/kernel/entry.S
+++ b/roms/SLOF/clients/net-snk/kernel/entry.S
@@ -44,7 +44,7 @@ C_ENTRY(_entry)
bcl 20,31,over # branch after pointer table
base:
.align 3
-.LCgot: .quad _got-base+0x8000
+.LCgot: .quad _got-base
.LCstack: .quad _stack+STACKSIZE-0x80-base
over:
mflr r8 # gpr 8 is the base
diff --git a/roms/SLOF/clients/takeover/client.lds b/roms/SLOF/clients/takeover/client.lds
index 2701d8e1e..0ab428a01 100644
--- a/roms/SLOF/clients/takeover/client.lds
+++ b/roms/SLOF/clients/takeover/client.lds
@@ -43,8 +43,8 @@ SECTIONS {
.got :
{
- . = ALIGN(8);
- _got = .;
+ . = ALIGN(256);
+ _got = DEFINED (.TOC.) ? .TOC. : ADDR (.got) + 0x8000;
*(.got .toc)
_got_end = .;
}
diff --git a/roms/SLOF/clients/takeover/entry.S b/roms/SLOF/clients/takeover/entry.S
index a1030eb40..ff482732d 100644
--- a/roms/SLOF/clients/takeover/entry.S
+++ b/roms/SLOF/clients/takeover/entry.S
@@ -21,7 +21,7 @@ _wrapclient:
bcl 20,31,over # branch after pointer table
base:
.align 3
-.LCgot: .quad _got-base+0x8000
+.LCgot: .quad _got-base
over:
mflr r8 # gpr 8 is the base
ld r2, .LCgot-base(r8) # load got pointer
diff --git a/roms/SLOF/clients/takeover/main.c b/roms/SLOF/clients/takeover/main.c
index 360d8eaed..1e1b02614 100644
--- a/roms/SLOF/clients/takeover/main.c
+++ b/roms/SLOF/clients/takeover/main.c
@@ -16,7 +16,7 @@
#include <of.h>
#include <pci.h>
#include <cpu.h>
-#include <ioctl.h>
+#include <unistd.h>
#include <takeover.h>
extern void call_client_interface(of_arg_t *);
diff --git a/roms/SLOF/include/ppc970/cache.h b/roms/SLOF/include/ppc970/cache.h
index b74868986..500182ea6 100644
--- a/roms/SLOF/include/ppc970/cache.h
+++ b/roms/SLOF/include/ppc970/cache.h
@@ -55,8 +55,8 @@ cache_inhibited_access(uint64_t, 64)
#define _FASTMOVE(s, d, size) \
switch (((type_u)s | (type_u)d | size) & (sizeof(type_u)-1)) { \
case 0: _MOVE(s, d, size, type_u); break; \
- case sizeof(type_l): _MOVE(s, d, size, type_l); break; \
- case sizeof(type_w): _MOVE(s, d, size, type_w); break; \
+ case 4: _MOVE(s, d, size, type_l); break; \
+ case 2: case 6: _MOVE(s, d, size, type_w); break; \
default: _MOVE(s, d, size, type_c); break; \
}
@@ -78,9 +78,51 @@ cache_inhibited_access(uint64_t, 64)
#define _FASTRMOVE(s, d, size) \
switch (((type_u)s | (type_u)d | size) & (sizeof(type_u)-1)) { \
case 0: _RMOVE(s, d, size, type_u); break; \
- case sizeof(type_l): _RMOVE(s, d, size, type_l); break; \
- case sizeof(type_w): _RMOVE(s, d, size, type_w); break; \
+ case 4: _RMOVE(s, d, size, type_l); break; \
+ case 2: case 6: _RMOVE(s, d, size, type_w); break; \
default: _RMOVE(s, d, size, type_c); break; \
}
+/* main RAM to IO memory move */
+#define FAST_MRMOVE_TYPED(s, d, size, t) \
+{ \
+ t *s1 = (s), *d1 = (d); \
+ register t tmp; \
+ while (size > 0) { \
+ tmp = *s1++; SET_CI; *d1++ = tmp; CLR_CI; size -= sizeof(t); \
+ } \
+}
+
+#define FAST_MRMOVE(s, d, size) \
+ switch (((type_u)(s) | (type_u)(d) | (size)) & (sizeof(type_u)-1)) { \
+ case 0: FAST_MRMOVE_TYPED(s, d, size, type_u); break; \
+ case 4: FAST_MRMOVE_TYPED(s, d, size, type_l); break; \
+ case 2: case 6: FAST_MRMOVE_TYPED(s, d, size, type_w); break; \
+ default: FAST_MRMOVE_TYPED(s, d, size, type_c); break; \
+ }
+
+/* fill IO memory with pattern */
+#define FAST_RFILL_TYPED(dst, size, pat, t) \
+{ \
+ t *d1 = (dst); \
+ register t tmp = 0; \
+ int i = sizeof(t); \
+ while (i-- > 0) { \
+ tmp <<= 8; tmp |= pat & 0xff; \
+ } \
+ SET_CI; \
+ while (size > 0) { \
+ *d1++ = tmp; size -= sizeof(t); \
+ } \
+ CLR_CI; \
+}
+
+#define FAST_RFILL(dst, size, pat) \
+ switch (((type_u)dst | size) & (sizeof(type_u)-1)) { \
+ case 0: FAST_RFILL_TYPED(dst, size, pat, type_u); break; \
+ case 4: FAST_RFILL_TYPED(dst, size, pat, type_l); break; \
+ case 2: case 6: FAST_RFILL_TYPED(dst, size, pat, type_w); break; \
+ default: FAST_RFILL_TYPED(dst, size, pat, type_c); break; \
+ }
+
#endif
diff --git a/roms/SLOF/include/ppcp7/cache.h b/roms/SLOF/include/ppcp7/cache.h
index dc6837196..27975f09c 100644
--- a/roms/SLOF/include/ppcp7/cache.h
+++ b/roms/SLOF/include/ppcp7/cache.h
@@ -81,8 +81,8 @@ cache_inhibited_access(uint64_t, 64)
#define _FASTMOVE(s, d, size) \
switch (((type_u)s | (type_u)d | size) & (sizeof(type_u)-1)) { \
case 0: _MOVE(s, d, size, type_u); break; \
- case sizeof(type_l): _MOVE(s, d, size, type_l); break; \
- case sizeof(type_w): _MOVE(s, d, size, type_w); break; \
+ case 4: _MOVE(s, d, size, type_l); break; \
+ case 2: case 6: _MOVE(s, d, size, type_w); break; \
default: _MOVE(s, d, size, type_c); break; \
}
@@ -116,12 +116,26 @@ static inline void ci_rmove(void *dst, void *src, unsigned long esize,
#define _FASTRMOVE(s, d, size) do { \
switch (((type_u)s | (type_u)d | size) & (sizeof(type_u)-1)) {\
case 0: ci_rmove(d,s,3,size>>3); break; \
- case sizeof(type_l): ci_rmove(d,s,2,size>>2); break; \
- case sizeof(type_w): ci_rmove(d,s,1,size>>1); break; \
+ case 4: ci_rmove(d,s,2,size>>2); break; \
+ case 2: case 6: ci_rmove(d,s,1,size>>1); break; \
default: ci_rmove(d,s,0,size); break; \
} \
} while(0)
+#define FAST_MRMOVE(s, d, size) _FASTRMOVE(s, d, size)
+
+#define FAST_RFILL(dst, size, pat) do { \
+ type_u buf[64]; \
+ char *d = (char *)(dst); \
+ memset(buf, pat, size < sizeof(buf) ? size : sizeof(buf)); \
+ while (size > sizeof(buf)) { \
+ FAST_MRMOVE(buf, d, sizeof(buf)); \
+ d += sizeof(buf); \
+ size -= sizeof(buf); \
+ } \
+ FAST_MRMOVE(buf, d, size); \
+ } while(0)
+
static inline uint16_t bswap16_load(uint64_t addr)
{
unsigned int val;
diff --git a/roms/SLOF/lib/libusb/usb-hid.c b/roms/SLOF/lib/libusb/usb-hid.c
index f0cab8a69..ac6616aba 100644
--- a/roms/SLOF/lib/libusb/usb-hid.c
+++ b/roms/SLOF/lib/libusb/usb-hid.c
@@ -28,6 +28,10 @@
#define HID_REQ_SET_IDLE 0x0A
#define HID_REQ_SET_PROTOCOL 0x0B
+//key position for latin letters
+#define KEYP_LATIN_A 4
+#define KEYP_LATIN_Z 29
+
//#define KEY_DEBUG
/* HID SPEC - 7.2.6 Set_Protocol Request */
@@ -83,6 +87,8 @@ uint8_t set_leds;
const uint8_t *key_std = NULL;
const uint8_t *key_std_shift = NULL;
+uint8_t ctrl; /* modifiers */
+
/**
* read character from Keyboard-Buffer
*
@@ -111,6 +117,16 @@ static void write_key(uint8_t key)
}
/**
+ * Checks if keypos is a latin key
+ * @param keypos
+ * @return -
+ */
+static bool is_latin(uint8_t keypos)
+{
+ return keypos >= KEYP_LATIN_A && keypos <= KEYP_LATIN_Z;
+}
+
+/**
* Convert keyboard usage-ID to ANSI-Code
*
* @param Ctrl=Modifier Byte
@@ -120,22 +136,24 @@ static void write_key(uint8_t key)
static void get_char(uint8_t ctrl, uint8_t keypos)
{
uint8_t ch;
+ bool caps = false;
#ifdef KEY_DEBUG
printf("pos %02X\n", keypos);
#endif
if (set_leds & LED_CAPS_LOCK) /* is CAPS Lock set ? */
- ctrl |= MODIFIER_SHIFT; /* simulate shift */
+ caps = true;
- if (ctrl == 0) {
+ /* caps is a shift only for latin chars */
+ if ((!caps && ctrl == 0) || (caps && !is_latin(keypos))) {
ch = key_std[keypos];
if (ch != 0)
write_key(ch);
return;
}
- if (ctrl & MODIFIER_SHIFT) {
+ if ((ctrl & MODIFIER_SHIFT) || caps) {
ch = key_std_shift[keypos];
if (ch != 0)
write_key(ch);
@@ -187,36 +205,38 @@ static void check_key_code(uint8_t *buf)
set_leds ^= LED_CAPS_LOCK;
break;
+ case 0x36: /*Shift pressed*/
+ ctrl |= MODIFIER_SHIFT;
+ break;
+ case 0xb6: /*Shift unpressed*/
+ ctrl &= ~MODIFIER_SHIFT;
+ break;
case 0x3a: /* F1 */
write_key(0x1b);
write_key(0x5b);
- write_key(0x31);
- write_key(0x31);
- write_key(0x7e);
+ write_key(0x4f);
+ write_key(0x50);
break;
case 0x3b: /* F2 */
write_key(0x1b);
write_key(0x5b);
- write_key(0x31);
- write_key(0x32);
- write_key(0x7e);
+ write_key(0x4f);
+ write_key(0x51);
break;
case 0x3c:
write_key(0x1b); /* F3 */
write_key(0x5b);
- write_key(0x31);
- write_key(0x33);
- write_key(0x7e);
+ write_key(0x4f);
+ write_key(0x52);
break;
case 0x3d:
write_key(0x1b); /* F4 */
write_key(0x5b);
- write_key(0x31);
- write_key(0x34);
- write_key(0x7e);
+ write_key(0x4f);
+ write_key(0x53);
break;
case 0x3e:
@@ -254,7 +274,7 @@ static void check_key_code(uint8_t *buf)
case 0x42:
write_key(0x1b); /* F9 */
write_key(0x5b);
- write_key(0x31);
+ write_key(0x32);
write_key(0x30);
write_key(0x7e);
break;
@@ -262,7 +282,7 @@ static void check_key_code(uint8_t *buf)
case 0x43:
write_key(0x1b); /* F10 */
write_key(0x5b);
- write_key(0x31);
+ write_key(0x32);
write_key(0x31);
write_key(0x7e);
break;
@@ -270,7 +290,7 @@ static void check_key_code(uint8_t *buf)
case 0x44:
write_key(0x1b); /* F11 */
write_key(0x5b);
- write_key(0x31);
+ write_key(0x32);
write_key(0x33);
write_key(0x7e);
break;
@@ -278,7 +298,7 @@ static void check_key_code(uint8_t *buf)
case 0x45:
write_key(0x1b); /* F12 */
write_key(0x5b);
- write_key(0x31);
+ write_key(0x32);
write_key(0x34);
write_key(0x7e);
break;
@@ -290,36 +310,34 @@ static void check_key_code(uint8_t *buf)
case 0x49:
write_key(0x1b); /* INS */
write_key(0x5b);
- write_key(0x31);
+ write_key(0x32);
write_key(0x7e);
break;
case 0x4a:
write_key(0x1b); /* HOME */
- write_key(0x5b);
- write_key(0x32);
- write_key(0x7e);
+ write_key(0x4f);
+ write_key(0x48);
break;
case 0x4b:
write_key(0x1b); /* PgUp */
write_key(0x5b);
- write_key(0x33);
+ write_key(0x35);
write_key(0x7e);
break;
case 0x4c:
write_key(0x1b); /* DEL */
write_key(0x5b);
- write_key(0x34);
+ write_key(0x33);
write_key(0x7e);
break;
case 0x4d:
write_key(0x1b); /* END */
- write_key(0x5b);
- write_key(0x35);
- write_key(0x7e);
+ write_key(0x4f);
+ write_key(0x46);
break;
case 0x4e:
@@ -443,11 +461,8 @@ unsigned char usb_key_available(void *dev)
unsigned char usb_read_keyb(void *vdev)
{
- if (!vdev)
- return false;
-
- while (usb_poll_key(vdev)) {
- /* loop for all pending keys */
- }
- return read_key();
+ if (usb_key_available(vdev))
+ return read_key();
+ else
+ return 0;
}
diff --git a/roms/SLOF/lib/libusb/usb-xhci.c b/roms/SLOF/lib/libusb/usb-xhci.c
index 0c3d6e47f..7683c51d6 100644
--- a/roms/SLOF/lib/libusb/usb-xhci.c
+++ b/roms/SLOF/lib/libusb/usb-xhci.c
@@ -225,11 +225,11 @@ static void xhci_handle_cmd_completion(struct xhci_hcd *xhcd,
xhcd->slot_id = 0;
}
-static struct xhci_event_trb *xhci_poll_event(struct xhci_hcd *xhcd,
- uint32_t event_type)
+static uint64_t xhci_poll_event(struct xhci_hcd *xhcd,
+ uint32_t event_type)
{
struct xhci_event_trb *event;
- uint64_t val;
+ uint64_t val, retval = 0;
uint32_t flags, time;
int index;
@@ -244,7 +244,7 @@ static struct xhci_event_trb *xhci_poll_event(struct xhci_hcd *xhcd,
mb();
flags = le32_to_cpu(event->flags);
if (time < SLOF_GetTimer())
- return NULL;
+ return 0;
}
mb();
@@ -273,6 +273,7 @@ static struct xhci_event_trb *xhci_poll_event(struct xhci_hcd *xhcd,
break;
}
xhcd->ering.deq = (uint64_t) (event + 1);
+ retval = le64_to_cpu(event->addr);
event->addr = 0;
event->status = 0;
@@ -289,7 +290,11 @@ static struct xhci_event_trb *xhci_poll_event(struct xhci_hcd *xhcd,
dprintf("Update start %x deq %x index %d\n",
xhcd->ering.trbs_dma, val, index/sizeof(*event));
write_reg64(&xhcd->run_regs->irs[0].erdp, val);
- return event;
+
+ if (retval == 0)
+ return (uint64_t)event;
+ else
+ return retval;
}
static void xhci_send_cmd(struct xhci_hcd *xhcd, uint32_t field1,
@@ -388,10 +393,12 @@ static void xhci_init_seg(struct xhci_seg *seg, uint32_t size, uint32_t type)
seg->deq = (uint64_t)seg->trbs;
memset((void *)seg->trbs, 0, size);
- link =(struct xhci_link_trb *) (seg->trbs + seg->size - 1);
- link->addr = cpu_to_le64(seg->trbs_dma);
- link->field2 = 0;
- link->field3 = cpu_to_le32(0x1 | TRB_CMD_TYPE(TRB_LINK));
+ if (type != TYPE_EVENT) {
+ link =(struct xhci_link_trb *) (seg->trbs + seg->size - 1);
+ link->addr = cpu_to_le64(seg->trbs_dma);
+ link->field2 = 0;
+ link->field3 = cpu_to_le32(0x1 | TRB_CMD_TYPE(TRB_LINK));
+ }
return;
}
@@ -616,6 +623,7 @@ static void xhci_free_dev(struct xhci_dev *xdev)
{
xhci_free_seg(&xdev->bulk_in, XHCI_DATA_TRBS_SIZE);
xhci_free_seg(&xdev->bulk_out, XHCI_DATA_TRBS_SIZE);
+ xhci_free_seg(&xdev->intr, XHCI_INTR_TRBS_SIZE);
xhci_free_seg(&xdev->control, XHCI_CONTROL_TRBS_SIZE);
xhci_free_ctx(&xdev->in_ctx, XHCI_CTX_BUF_SIZE);
xhci_free_ctx(&xdev->out_ctx, XHCI_CTX_BUF_SIZE);
@@ -637,7 +645,25 @@ static bool usb3_dev_init(struct xhci_hcd *xhcd, uint32_t port)
return true;
}
-static int xhci_hub_check_ports(struct xhci_hcd *xhcd)
+static int xhci_device_present(uint32_t portsc, uint32_t usb_ver)
+{
+ if (usb_ver == USB_XHCI) {
+ /* Device present and enabled state */
+ if ((portsc & PORTSC_CCS) &&
+ (portsc & PORTSC_PP) &&
+ (portsc & PORTSC_PED)) {
+ return true;
+ }
+ } else if (usb_ver == USB_EHCI) {
+ /* Device present and in disabled state */
+ if ((portsc & PORTSC_CCS) && (portsc & PORTSC_CSC))
+ return true;
+ }
+ return false;
+}
+
+static int xhci_port_scan(struct xhci_hcd *xhcd,
+ uint32_t usb_ver)
{
uint32_t num_ports, portsc, i;
struct xhci_op_regs *op;
@@ -645,7 +671,7 @@ static int xhci_hub_check_ports(struct xhci_hcd *xhcd)
struct xhci_cap_regs *cap;
uint32_t xecp_off;
uint32_t *xecp_addr, *base;
- uint32_t port_off = 1, port_cnt;
+ uint32_t port_off = 0, port_cnt;
dprintf("enter\n");
@@ -658,14 +684,14 @@ static int xhci_hub_check_ports(struct xhci_hcd *xhcd)
base = (uint32_t *)cap;
while (xecp_off > 0) {
xecp_addr = base + xecp_off;
- dprintf(stderr, "xecp_off %d %p %p \n", xecp_off, base, xecp_addr);
+ dprintf("xecp_off %d %p %p \n", xecp_off, base, xecp_addr);
if (XHCI_XECP_CAP_ID(read_reg32(xecp_addr)) == XHCI_XECP_CAP_SP &&
- XHCI_XECP_CAP_SP_MJ(read_reg32(xecp_addr)) == 3 &&
+ XHCI_XECP_CAP_SP_MJ(read_reg32(xecp_addr)) == usb_ver &&
XHCI_XECP_CAP_SP_MN(read_reg32(xecp_addr)) == 0) {
port_cnt = XHCI_XECP_CAP_SP_PC(read_reg32(xecp_addr + 2));
port_off = XHCI_XECP_CAP_SP_PO(read_reg32(xecp_addr + 2));
- dprintf(stderr, "PortCount %d Portoffset %d\n", port_cnt, port_off);
+ dprintf("PortCount %d Portoffset %d\n", port_cnt, port_off);
}
base = xecp_addr;
xecp_off = XHCI_XECP_NEXT_PTR(read_reg32(xecp_addr));
@@ -675,10 +701,8 @@ static int xhci_hub_check_ports(struct xhci_hcd *xhcd)
for (i = (port_off - 1); i < (port_off + port_cnt - 1); i++) {
prs = &op->prs[i];
portsc = read_reg32(&prs->portsc);
- if ((portsc & PORTSC_CCS) &&
- (portsc & PORTSC_PP) &&
- (portsc & PORTSC_PED)) {
- /* Device present and enabled */
+ if (xhci_device_present(portsc, usb_ver)) {
+ /* Device present */
dprintf("Device present on port %d\n", i);
/* Reset the port */
portsc = read_reg32(&prs->portsc);
@@ -701,6 +725,11 @@ static int xhci_hub_check_ports(struct xhci_hcd *xhcd)
return true;
}
+static int xhci_hub_check_ports(struct xhci_hcd *xhcd)
+{
+ return xhci_port_scan(xhcd, USB_XHCI) | xhci_port_scan(xhcd, USB_EHCI);
+}
+
static bool xhci_hcd_init(struct xhci_hcd *xhcd)
{
struct xhci_op_regs *op;
@@ -868,6 +897,18 @@ static bool xhci_hcd_exit(struct xhci_hcd *xhcd)
SLOF_dma_map_out(xhcd->dcbaap_dma, (void *)xhcd->dcbaap, XHCI_DCBAAP_MAX_SIZE);
SLOF_dma_free((void *)xhcd->dcbaap, XHCI_DCBAAP_MAX_SIZE);
}
+
+ /*
+ * QEMU implementation of XHCI doesn't implement halt
+ * properly. It basically says that it's halted immediately
+ * but doesn't actually terminate ongoing activities and
+ * DMAs. This needs to be fixed in QEMU.
+ *
+ * For now, wait for 50ms grace time till qemu stops using
+ * this device.
+ */
+ SLOF_msleep(50);
+
return true;
}
@@ -1079,18 +1120,17 @@ static inline struct xhci_seg *xhci_pipe_get_seg(struct usb_pipe *pipe)
static inline void *xhci_get_trb(struct xhci_seg *seg)
{
uint64_t val, enq;
- uint32_t size;
+ int index;
struct xhci_link_trb *link;
enq = val = seg->enq;
val = val + XHCI_TRB_SIZE;
- size = seg->size * XHCI_TRB_SIZE;
- /* TRBs being a cyclic buffer, here we cycle back to beginning. */
- if ((val % size) == 0) {
+ index = (enq - (uint64_t)seg->trbs) / XHCI_TRB_SIZE + 1;
+ dprintf("%s: enq %llx, val %llx %x\n", __func__, enq, val, index);
+ /* TRBs being a cyclic buffer, here we cycle back to beginning. */
+ if (index == (seg->size - 1)) {
+ dprintf("%s: rounding \n", __func__);
seg->enq = (uint64_t)seg->trbs;
- enq = seg->enq;
- seg->enq = seg->enq + XHCI_TRB_SIZE;
- val = 0;
seg->cycle_state ^= seg->cycle_state;
link = (struct xhci_link_trb *) (seg->trbs + seg->size - 1);
link->addr = cpu_to_le64(seg->trbs_dma);
@@ -1105,6 +1145,12 @@ static inline void *xhci_get_trb(struct xhci_seg *seg)
return (void *)enq;
}
+static uint64_t xhci_get_trb_phys(struct xhci_seg *seg, uint64_t trb)
+{
+ return seg->trbs_dma + (trb - (uint64_t)seg->trbs);
+}
+
+static int usb_kb = false;
static int xhci_transfer_bulk(struct usb_pipe *pipe, void *td, void *td_phys,
void *data, int datalen)
{
@@ -1114,7 +1160,8 @@ static int xhci_transfer_bulk(struct usb_pipe *pipe, void *td, void *td_phys,
struct xhci_transfer_trb *trb;
struct xhci_db_regs *dbr;
int ret = true;
- uint32_t slot_id, epno;
+ uint32_t slot_id, epno, time;
+ uint64_t trb_phys, event_phys;
if (!pipe->dev || !pipe->dev->hcidev) {
dprintf(" NULL pointer\n");
@@ -1139,13 +1186,26 @@ static int xhci_transfer_bulk(struct usb_pipe *pipe, void *td, void *td_phys,
}
trb = xhci_get_trb(seg);
+ trb_phys = xhci_get_trb_phys(seg, (uint64_t)trb);
fill_normal_trb(trb, (void *)data, datalen);
epno = xhci_get_epno(pipe);
write_reg32(&dbr->db[slot_id], epno);
- if (!xhci_poll_event(xhcd, 0)) {
- dprintf("Bulk failed\n");
- ret = false;
+
+ time = SLOF_GetTimer() + USB_TIMEOUT;
+ while (1) {
+ event_phys = xhci_poll_event(xhcd, 0);
+ if (event_phys == trb_phys) {
+ break;
+ } else if (event_phys == 0) { /* polling timed out */
+ ret = false;
+ break;
+ } else
+ usb_kb = true;
+
+ /* transfer timed out */
+ if (time < SLOF_GetTimer())
+ return false;
}
trb->addr = 0;
trb->len = 0;
@@ -1214,7 +1274,8 @@ static void xhci_init_bulk_ep(struct usb_dev *dev, struct usb_pipe *pipe)
if (!seg->trbs) {
if (!xhci_alloc_seg(seg, XHCI_DATA_TRBS_SIZE, TYPE_BULK)) {
- dprintf("Failed allocating seg\n");
+ printf("usb-xhci: allocation failed for bulk endpoint\n");
+ return;
}
} else {
xhci_init_seg(seg, XHCI_DATA_TRBS_SIZE, TYPE_BULK);
@@ -1235,6 +1296,61 @@ static void xhci_init_bulk_ep(struct usb_dev *dev, struct usb_pipe *pipe)
xpipe->seg = seg;
}
+static int xhci_get_pipe_intr(struct usb_pipe *pipe,
+ struct xhci_hcd *xhcd,
+ char *buf, size_t len)
+{
+ struct xhci_dev *xdev;
+ struct xhci_seg *seg;
+ struct xhci_pipe *xpipe;
+ struct xhci_control_ctx *ctrl;
+ struct xhci_ep_ctx *ep;
+ uint32_t x_epno, val, type;
+ struct usb_dev *dev;
+ struct xhci_transfer_trb *trb;
+
+ dev = pipe->dev;
+ if (dev->class != DEV_HID_KEYB)
+ return false;
+
+ xdev = dev->priv;
+ pipe->mps = 8;
+ seg = xhci_pipe_get_seg(pipe);
+ xpipe = xhci_pipe_get_xpipe(pipe);
+ type = EP_INT_IN;
+ seg = &xdev->intr;
+
+ if (!seg->trbs) {
+ if (!xhci_alloc_seg(seg, XHCI_INTR_TRBS_SIZE, TYPE_BULK)) {
+ printf("usb-xhci: allocation failed for interrupt endpoint\n");
+ return false;
+ }
+ } else {
+ xhci_init_seg(seg, XHCI_EVENT_TRBS_SIZE, TYPE_BULK);
+ }
+
+ xpipe->buf = buf;
+ xpipe->buf_phys = SLOF_dma_map_in(buf, len, false);
+ xpipe->buflen = len;
+
+ ctrl = xhci_get_control_ctx(&xdev->in_ctx);
+ x_epno = xhci_get_epno(pipe);
+ ep = xhci_get_ep_ctx(&xdev->in_ctx, xdev->ctx_size, x_epno);
+ val = EP_TYPE(type) | MAX_BURST(0) | ERROR_COUNT(3) |
+ MAX_PACKET_SIZE(pipe->mps);
+ ep->field2 = cpu_to_le32(val);
+ ep->deq_addr = cpu_to_le64(seg->trbs_dma | seg->cycle_state);
+ ep->field4 = cpu_to_le32(8);
+ ctrl->a_flags = cpu_to_le32(BIT(x_epno) | 0x1);
+ ctrl->d_flags = 0;
+ xhci_configure_ep(xhcd, xdev->slot_id, xdev->in_ctx.dma_addr);
+ xpipe->seg = seg;
+
+ trb = xhci_get_trb(seg);
+ fill_normal_trb(trb, (void *)xpipe->buf_phys, pipe->mps);
+ return true;
+}
+
static struct usb_pipe* xhci_get_pipe(struct usb_dev *dev, struct usb_ep_descr *ep, char *buf, size_t len)
{
struct xhci_hcd *xhcd;
@@ -1264,6 +1380,12 @@ static struct usb_pipe* xhci_get_pipe(struct usb_dev *dev, struct usb_ep_descr *
new->dir = (ep->bEndpointAddress & 0x80) >> 7;
new->epno = ep->bEndpointAddress & 0x0f;
+ if (new->type == USB_EP_TYPE_INTR) {
+ if (!xhci_get_pipe_intr(new, xhcd, buf, len)) {
+ printf("usb-xhci: %s alloc_intr failed %p\n",
+ __func__, new);
+ }
+ }
if (new->type == USB_EP_TYPE_BULK)
xhci_init_bulk_ep(dev, new);
@@ -1284,6 +1406,10 @@ static void xhci_put_pipe(struct usb_pipe *pipe)
if (pipe->type == USB_EP_TYPE_BULK) {
xpipe = xhci_pipe_get_xpipe(pipe);
xpipe->seg = NULL;
+ } else if (pipe->type == USB_EP_TYPE_INTR) {
+ xpipe = xhci_pipe_get_xpipe(pipe);
+ SLOF_dma_map_out(xpipe->buf_phys, xpipe->buf, xpipe->buflen);
+ xpipe->seg = NULL;
}
if (xhcd->end)
xhcd->end->next = pipe;
@@ -1298,6 +1424,51 @@ static void xhci_put_pipe(struct usb_pipe *pipe)
dprintf("usb-xhci: %s exit\n", __func__);
}
+static int xhci_poll_intr(struct usb_pipe *pipe, uint8_t *data)
+{
+ struct xhci_transfer_trb *trb;
+ struct xhci_seg *seg;
+ struct xhci_pipe *xpipe;
+ struct xhci_dev *xdev;
+ struct xhci_hcd *xhcd;
+ struct xhci_db_regs *dbr;
+ uint32_t x_epno;
+ uint8_t *buf, ret = 1;
+
+ if (!pipe || !pipe->dev || !pipe->dev->hcidev)
+ return 0;
+ xdev = pipe->dev->priv;
+ xhcd = (struct xhci_hcd *)pipe->dev->hcidev->priv;
+ x_epno = xhci_get_epno(pipe);
+ seg = xhci_pipe_get_seg(pipe);
+ xpipe = xhci_pipe_get_xpipe(pipe);
+
+ if (usb_kb == true) {
+ /* This event was consumed by bulk transfer */
+ usb_kb = false;
+ goto skip_poll;
+ }
+ buf = xpipe->buf;
+ memset(buf, 0, 8);
+
+ mb();
+ /* Ring the doorbell - x_epno */
+ dbr = xhcd->db_regs;
+ write_reg32(&dbr->db[xdev->slot_id], x_epno);
+ if (!xhci_poll_event(xhcd, 0)) {
+ printf("poll intr failed\n");
+ return 0;
+ }
+ mb();
+ memcpy(data, buf, 8);
+
+skip_poll:
+ trb = xhci_get_trb(seg);
+ fill_normal_trb(trb, (void *)xpipe->buf_phys, pipe->mps);
+ mb();
+ return ret;
+}
+
struct usb_hcd_ops xhci_ops = {
.name = "xhci-hcd",
.init = xhci_init,
@@ -1305,6 +1476,7 @@ struct usb_hcd_ops xhci_ops = {
.usb_type = USB_XHCI,
.get_pipe = xhci_get_pipe,
.put_pipe = xhci_put_pipe,
+ .poll_intr = xhci_poll_intr,
.send_ctrl = xhci_send_ctrl,
.transfer_bulk = xhci_transfer_bulk,
.next = NULL,
diff --git a/roms/SLOF/lib/libusb/usb-xhci.h b/roms/SLOF/lib/libusb/usb-xhci.h
index faeb07ead..3fc7e7889 100644
--- a/roms/SLOF/lib/libusb/usb-xhci.h
+++ b/roms/SLOF/lib/libusb/usb-xhci.h
@@ -266,6 +266,7 @@ struct xhci_seg {
#define XHCI_EVENT_TRBS_SIZE 4096
#define XHCI_CONTROL_TRBS_SIZE 4096
#define XHCI_DATA_TRBS_SIZE 4096
+#define XHCI_INTR_TRBS_SIZE 4096
#define XHCI_ERST_NUM_SEGS 1
#define XHCI_MAX_BULK_SIZE 0xF000
@@ -349,6 +350,7 @@ struct xhci_dev {
struct xhci_ctx in_ctx;
struct xhci_ctx out_ctx;
struct xhci_seg control;
+ struct xhci_seg intr;
struct xhci_seg bulk_in;
struct xhci_seg bulk_out;
uint32_t ctx_size;
@@ -381,6 +383,9 @@ struct xhci_hcd {
struct xhci_pipe {
struct usb_pipe pipe;
struct xhci_seg *seg;
+ void *buf;
+ long buf_phys;
+ uint32_t buflen;
};
#endif /* USB_XHCI_H */
diff --git a/roms/SLOF/make.rules b/roms/SLOF/make.rules
index aebc4e360..cbc63530a 100644
--- a/roms/SLOF/make.rules
+++ b/roms/SLOF/make.rules
@@ -19,8 +19,12 @@
ARCH := $(shell uname -p)
# Auto-detect ppc64
-ifeq ($(ARCH), ppc64)
-CROSS = ""
+ifeq (ppc64,$(findstring ppc64,$(ARCH)))
+ ifeq ($(ARCH), ppc64le)
+ EXTRA_CC = -mbig -mabi=elfv1
+ EXTRA_LD = -mbig
+ endif
+CROSS ?=
else
CROSS ?= powerpc64-linux-
endif
@@ -31,8 +35,8 @@ HOSTCC ?= gcc
HOSTCFLAGS = -g -Wall -W -O2 -I. -I../include
DD = dd
-ONLY_CC = $(CROSS)gcc -m$(CELLSIZE)
-ONLY_AS = $(CROSS)as -m$(CELLSIZE)
+ONLY_CC = $(CROSS)gcc -m$(CELLSIZE) $(EXTRA_CC)
+ONLY_AS = $(CROSS)as -m$(CELLSIZE) $(EXTRA_LD)
ONLY_LD = $(CROSS)ld -melf$(CELLSIZE)ppc
# Verbose level:
diff --git a/roms/SLOF/rtas/reloc.S b/roms/SLOF/rtas/reloc.S
index e24d293d4..1b5b59a68 100644
--- a/roms/SLOF/rtas/reloc.S
+++ b/roms/SLOF/rtas/reloc.S
@@ -61,7 +61,7 @@ _rtas_start:
._rtas_entry_offset: .quad rtas_entry-_rtas_start
._rtas_config_offset: .quad rtas_config-_rtas_start
._rtas_stack: .quad .stack-_rtas_start+RTAS_STACKSIZE-0x60
-._rtas_toc: .quad _got-_rtas_start+0x8000
+._rtas_toc: .quad _got-_rtas_start
.over:
mflr r8 # gpr 8 is the base
diff --git a/roms/SLOF/rtas/rtas.lds b/roms/SLOF/rtas/rtas.lds
index a5ba1daaf..30b18dd26 100644
--- a/roms/SLOF/rtas/rtas.lds
+++ b/roms/SLOF/rtas/rtas.lds
@@ -28,7 +28,8 @@ SECTIONS {
}
.got :
{
- _got = .;
+ . = ALIGN(256);
+ _got = DEFINED (.TOC.) ? .TOC. : ADDR (.got) + 0x8000;
*(.got .toc)
}
.reloc :
diff --git a/roms/SLOF/rtas/rtas_entry.S b/roms/SLOF/rtas/rtas_entry.S
index 74693aa48..424137bf5 100644
--- a/roms/SLOF/rtas/rtas_entry.S
+++ b/roms/SLOF/rtas/rtas_entry.S
@@ -39,7 +39,7 @@ rtas_entry:
bcl 20,31,.over # branch to over
.base:
.align 3
-..got: .quad _got-.base+0x8000
+..got: .quad _got-.base
..stack: .quad .stack+RTAS_STACKSIZE-0x60-.base
.over:
mflr r8 # gpr 8 is the base
diff --git a/roms/SLOF/slof/entry.S b/roms/SLOF/slof/entry.S
index dcff57ba0..d3d29f852 100644
--- a/roms/SLOF/slof/entry.S
+++ b/roms/SLOF/slof/entry.S
@@ -207,4 +207,13 @@ call_client:
li 3, -1 # client app return
blr
+
+ # Call another function via pointer in r6
+ # (arguments can be provided in r3 to r5)
+ # Destination function should jump back to lr
+C_ENTRY(call_c)
+ mtctr r6
+ bctr
+
+
.lcomm the_system_stack, STACKSIZE, 16
diff --git a/roms/SLOF/slof/fs/archsupport.fs b/roms/SLOF/slof/fs/archsupport.fs
index cc4668769..f564ab4e0 100644
--- a/roms/SLOF/slof/fs/archsupport.fs
+++ b/roms/SLOF/slof/fs/archsupport.fs
@@ -10,9 +10,9 @@
\ * IBM Corporation - initial implementation
\ ****************************************************************************/
-\ Qemu supports max 256cpus, 32K will be able to accomodate the fdt changes if
-\ needed.
-8000 VALUE size
+\ 128KB FDT buffer size is enough to accommodate 255 CPU cores and 1TB of
+\ maxmem specification.
+20000 VALUE size
: ibm,client-architecture-support ( vec -- err? )
\ Store require parameters in nvram
\ to come back to right boot device
diff --git a/roms/SLOF/slof/fs/base.fs b/roms/SLOF/slof/fs/base.fs
index e71e087eb..03e77e54f 100644
--- a/roms/SLOF/slof/fs/base.fs
+++ b/roms/SLOF/slof/fs/base.fs
@@ -579,8 +579,6 @@ defer cursor-off ( -- )
#include "debug.fs"
\ provide 7.5.3.1 Dictionary search
#include "dictionary.fs"
-\ block data access for IO devices - ought to be implemented in engine
-#include "rmove.fs"
\ provide a simple run time preprocessor
#include <preprocessor.fs>
diff --git a/roms/SLOF/slof/fs/boot.fs b/roms/SLOF/slof/fs/boot.fs
index 9a0ded0c2..a0fe29a1b 100644
--- a/roms/SLOF/slof/fs/boot.fs
+++ b/roms/SLOF/slof/fs/boot.fs
@@ -187,11 +187,6 @@ defer go ( -- )
dup to my-self
dup ihandle>phandle set-node
-rot ( ihandle devstr len )
- my-args nip 0= IF
- 2dup 1- + c@ [char] : <> IF \ Add : to device path if missing
- 1+ strdup 2dup 1- + [char] : swap c!
- THEN
- THEN
encode-string s" bootpath" set-chosen
$bootargs encode-string s" bootargs" set-chosen
get-load-base s" load" 3 pick ['] $call-method CATCH IF
@@ -211,7 +206,7 @@ defer go ( -- )
: parse-load ( "{devlist}" -- success ) \ Parse-execute boot-device list
cr BEGIN parse-word dup WHILE
- ( de-alias ) do-load dup 0< IF drop 0 THEN IF
+ de-alias do-load dup 0< IF drop 0 THEN IF
state-valid @ IF ." Successfully loaded" cr THEN
true 0d parse strdup load-list 2! EXIT
THEN
diff --git a/roms/SLOF/slof/fs/client.fs b/roms/SLOF/slof/fs/client.fs
index 1b2bb0326..7d537a668 100644
--- a/roms/SLOF/slof/fs/client.fs
+++ b/roms/SLOF/slof/fs/client.fs
@@ -282,6 +282,18 @@ ALSO client-voc DEFINITIONS
;
\
+\ Standard for Boot, defined in 6.3.2.5:
+\
+: boot ( zstr -- )
+ zcount
+ debug-client-interface? IF
+ ." ci: boot " 2dup type cr
+ THEN
+ " boot " 2swap $cat " boot-command" $setenv (nvupdate)
+ reset-all
+;
+
+\
\ User Interface, defined in 6.3.2.6
\
: interpret ( ... zstr -- result ... )
diff --git a/roms/SLOF/slof/fs/fbuffer.fs b/roms/SLOF/slof/fs/fbuffer.fs
index 756f05a95..47046087d 100644
--- a/roms/SLOF/slof/fs/fbuffer.fs
+++ b/roms/SLOF/slof/fs/fbuffer.fs
@@ -19,6 +19,7 @@
0 VALUE screen-height
0 VALUE screen-width
0 VALUE screen-depth
+0 VALUE screen-line-bytes
0 VALUE window-top
0 VALUE window-left
@@ -54,10 +55,10 @@
: fb8-background inverse? ;
: fb8-foreground inverse? invert ;
-: fb8-lines2bytes ( #lines -- #bytes ) char-height * screen-width * screen-depth * ;
+: fb8-lines2bytes ( #lines -- #bytes ) char-height * screen-line-bytes * ;
: fb8-columns2bytes ( #columns -- #bytes ) char-width * screen-depth * ;
: fb8-line2addr ( line# -- addr )
- char-height * window-top + screen-width * screen-depth *
+ char-height * window-top + screen-line-bytes *
frame-buffer-adr + window-left screen-depth * +
;
@@ -98,9 +99,10 @@ CREATE bitmap-buffer 400 4 * allot
: fb8-toggle-cursor ( -- )
line# fb8-line2addr column# fb8-columns2bytes +
- char-height 0 ?DO
- char-width screen-depth * 0 ?DO dup dup rb@ -1 xor swap rb! 1+ LOOP
- screen-width screen-depth * + char-width screen-depth * -
+ char-height 2 - screen-line-bytes * +
+ 2 0 ?DO
+ dup char-width screen-depth * invert-region
+ screen-line-bytes +
LOOP drop
;
@@ -110,7 +112,7 @@ CREATE bitmap-buffer 400 4 * allot
line# fb8-line2addr column# fb8-columns2bytes + ( bitmap-buf fb-addr )
char-height 0 ?DO
2dup char-width screen-depth * mrmove
- screen-width screen-depth * + >r char-width screen-depth * + r>
+ screen-line-bytes + >r char-width screen-depth * + r>
LOOP 2drop
ELSE 2drop r> 3drop THEN
;
@@ -135,12 +137,12 @@ CREATE bitmap-buffer 400 4 * allot
fb8-columns2bytes swap fb8-columns2bytes tuck -
over r@ tuck + rot char-height 0 ?DO
3dup rmove
- -rot screen-width screen-depth * tuck + -rot + swap rot
+ -rot screen-line-bytes tuck + -rot + swap rot
LOOP
3drop r>
THEN
char-height 0 ?DO
- dup 2 pick fb8-erase-block screen-width screen-depth * +
+ dup 2 pick fb8-erase-block screen-line-bytes +
LOOP
2drop
;
@@ -153,12 +155,12 @@ CREATE bitmap-buffer 400 4 * allot
fb8-columns2bytes swap fb8-columns2bytes tuck -
over r@ + 2dup + r> swap >r rot char-height 0 ?DO
3dup rmove
- -rot screen-width screen-depth * tuck + -rot + swap rot
+ -rot screen-line-bytes tuck + -rot + swap rot
LOOP
3drop r> over -
THEN
char-height 0 ?DO
- dup 2 pick fb8-erase-block screen-width screen-depth * +
+ dup 2 pick fb8-erase-block screen-line-bytes +
LOOP
2drop
;
@@ -166,13 +168,11 @@ CREATE bitmap-buffer 400 4 * allot
: fb8-reset-screen ( -- ) ( Left as no-op by design ) ;
: fb8-erase-screen ( -- )
- frame-buffer-adr screen-height screen-width * screen-depth * fb8-erase-block
+ frame-buffer-adr screen-height screen-line-bytes * fb8-erase-block
;
: fb8-invert-screen ( -- )
- frame-buffer-adr screen-height screen-width * screen-depth * 2dup /x / 0 ?DO
- dup rx@ -1 xor over rx! xa1+
- LOOP 3drop
+ frame-buffer-adr screen-height screen-line-bytes * invert-region
;
: fb8-blink-screen ( -- ) fb8-invert-screen fb8-invert-screen ;
@@ -180,6 +180,7 @@ CREATE bitmap-buffer 400 4 * allot
: fb8-install ( width height #columns #lines -- )
1 to screen-depth
2swap to screen-height to screen-width
+ screen-width to screen-line-bytes
screen-#rows min to #lines
screen-#columns min to #columns
screen-height char-height #lines * - 2/ to window-top
@@ -201,6 +202,7 @@ CREATE bitmap-buffer 400 4 * allot
>r
fb8-install
r> to screen-depth
+ screen-width screen-depth * to screen-line-bytes
;
diff --git a/roms/SLOF/slof/fs/little-endian.fs b/roms/SLOF/slof/fs/little-endian.fs
index f2e4e8d42..6b4779ee0 100644
--- a/roms/SLOF/slof/fs/little-endian.fs
+++ b/roms/SLOF/slof/fs/little-endian.fs
@@ -17,6 +17,9 @@ here c@ ef = CONSTANT ?littleendian
?bigendian [IF]
+: x!-le >r xbflip r> x! ;
+: x@-le x@ xbflip ;
+
: l!-le >r lbflip r> l! ;
: l@-le l@ lbflip ;
@@ -47,6 +50,9 @@ here c@ ef = CONSTANT ?littleendian
[ELSE]
+: x!-le x! ;
+: x@-le x@ ;
+
: l!-le l! ;
: l@-le l@ ;
diff --git a/roms/SLOF/slof/fs/packages/disk-label.fs b/roms/SLOF/slof/fs/packages/disk-label.fs
index fe1c25e7a..e034d6408 100644
--- a/roms/SLOF/slof/fs/packages/disk-label.fs
+++ b/roms/SLOF/slof/fs/packages/disk-label.fs
@@ -20,6 +20,7 @@ false VALUE debug-disk-label?
\ If we ever want to put a large kernel with initramfs from a PREP partition
\ we might need to increase this value. The default value is 65536 blocks (32MB)
d# 65536 value max-prep-partition-blocks
+d# 4096 CONSTANT block-array-size
s" disk-label" device-name
@@ -152,8 +153,8 @@ CONSTANT /gpt-part-entry
: init-block ( -- )
s" block-size" ['] $call-parent CATCH IF ABORT" parent has no block-size." THEN
to block-size
- d# 4096 alloc-mem
- dup d# 4096 erase
+ block-array-size alloc-mem
+ dup block-array-size erase
to block
debug-disk-label? IF
." init-block: block-size=" block-size .d ." block=0x" block u. cr
@@ -178,7 +179,8 @@ CONSTANT /gpt-part-entry
\ This word returns true if the currently loaded block has _NO_ GPT partition id
: no-gpt? ( -- true|false )
0 read-sector
- 1 partition>part-entry part-entry>id c@ ee <>
+ 1 partition>part-entry part-entry>id c@ ee <> IF true EXIT THEN
+ block mbr>magic w@-le aa55 <>
;
: pc-extended-partition? ( part-entry-addr -- true|false )
@@ -266,7 +268,10 @@ CONSTANT /gpt-part-entry
: try-dos-partition ( -- okay? )
\ Read partition table and check magic.
- no-mbr? IF cr ." No DOS disk-label found." cr false EXIT THEN
+ no-mbr? IF
+ debug-disk-label? IF cr ." No DOS disk-label found." cr THEN
+ false EXIT
+ THEN
count-dos-logical-partitions TO dos-logical-partitions
@@ -320,6 +325,14 @@ CONSTANT /gpt-part-entry
\ Load from first active DOS boot partition.
+: fat-bootblock? ( addr -- flag )
+ \ byte 0-2 of the bootblock is a jump instruction in
+ \ all FAT filesystems.
+ \ e9 and eb are jump instructions in x86 assembler.
+ dup c@ e9 = IF drop true EXIT THEN
+ dup c@ eb = swap 2+ c@ 90 = and
+;
+
\ NOTE: block-size is always 512 bytes for DOS partition tables.
: load-from-dos-boot-partition ( addr -- size )
@@ -352,60 +365,103 @@ CONSTANT /gpt-part-entry
drop 0
;
-\ Check for GPT PReP partition GUID
-9E1A2D38 CONSTANT GPT-PREP-PARTITION-1
-C612 CONSTANT GPT-PREP-PARTITION-2
-4316 CONSTANT GPT-PREP-PARTITION-3
-AA26 CONSTANT GPT-PREP-PARTITION-4
-8B49521E5A8B CONSTANT GPT-PREP-PARTITION-5
+\ Check for GPT PReP partition GUID. Only first 3 blocks are
+\ byte-swapped treating last two blocks as contigous for simplifying
+\ comparison
+9E1A2D38 CONSTANT GPT-PREP-PARTITION-1
+C612 CONSTANT GPT-PREP-PARTITION-2
+4316 CONSTANT GPT-PREP-PARTITION-3
+AA268B49521E5A8B CONSTANT GPT-PREP-PARTITION-4
: gpt-prep-partition? ( -- true|false )
- block gpt-part-entry>part-type-guid l@-le GPT-PREP-PARTITION-1 = IF
- block gpt-part-entry>part-type-guid 4 + w@-le
- GPT-PREP-PARTITION-2 = IF
- block gpt-part-entry>part-type-guid 6 + w@-le
- GPT-PREP-PARTITION-3 = IF
- block gpt-part-entry>part-type-guid 8 + w@
- GPT-PREP-PARTITION-4 = IF
- block gpt-part-entry>part-type-guid a + w@
- block gpt-part-entry>part-type-guid c + l@ swap lxjoin
- GPT-PREP-PARTITION-5 = IF
- TRUE EXIT
- THEN
- THEN
- THEN
- THEN
+ block gpt-part-entry>part-type-guid
+ dup l@-le GPT-PREP-PARTITION-1 <> IF drop false EXIT THEN
+ dup 4 + w@-le GPT-PREP-PARTITION-2 <> IF drop false EXIT THEN
+ dup 6 + w@-le GPT-PREP-PARTITION-3 <> IF drop false EXIT THEN
+ 8 + x@ GPT-PREP-PARTITION-4 =
+;
+
+\ Check for GPT MSFT BASIC DATA GUID - fat based
+EBD0A0A2 CONSTANT GPT-BASIC-DATA-PARTITION-1
+B9E5 CONSTANT GPT-BASIC-DATA-PARTITION-2
+4433 CONSTANT GPT-BASIC-DATA-PARTITION-3
+87C068B6B72699C7 CONSTANT GPT-BASIC-DATA-PARTITION-4
+
+: gpt-basic-data-partition? ( -- true|false )
+ block gpt-part-entry>part-type-guid
+ dup l@-le GPT-BASIC-DATA-PARTITION-1 <> IF drop false EXIT THEN
+ dup 4 + w@-le GPT-BASIC-DATA-PARTITION-2 <> IF drop false EXIT THEN
+ dup 6 + w@-le GPT-BASIC-DATA-PARTITION-3 <> IF drop false EXIT THEN
+ 8 + x@ GPT-BASIC-DATA-PARTITION-4 =
+;
+
+\
+\ GPT Signature
+\ ("EFI PART", 45h 46h 49h 20h 50h 41h 52h 54h)
+\
+4546492050415254 CONSTANT GPT-SIGNATURE
+
+\ The routine checks whether the protective MBR has GPT ID and then
+\ reads the gpt data from the sector. Also set the seek position and
+\ the partition size used in caller routines.
+
+: get-gpt-partition ( -- true|false )
+ no-gpt? IF false EXIT THEN
+ debug-disk-label? IF cr ." GPT partition found " cr THEN
+ 1 read-sector
+ block gpt>part-entry-lba x@-le
+ block-size * to seek-pos
+ block gpt>part-entry-size l@-le to gpt-part-size
+ gpt-part-size block-array-size > IF
+ cr ." GPT part size exceeds buffer allocated " cr
+ false exit
THEN
- FALSE
+ block gpt>signature x@ GPT-SIGNATURE =
;
: load-from-gpt-prep-partition ( addr -- size )
- no-gpt? IF drop FALSE EXIT THEN
- debug-disk-label? IF
- cr ." GPT partition found " cr
- THEN
- 1 read-sector block gpt>part-entry-lba l@-le
- block-size * to seek-pos
- block gpt>part-entry-size l@-le to gpt-part-size
- block gpt>num-part-entry l@-le dup 0= IF FALSE EXIT THEN
+ get-gpt-partition 0= IF false EXIT THEN
+ block gpt>num-part-entry l@-le dup 0= IF false exit THEN
1+ 1 ?DO
seek-pos 0 seek drop
block gpt-part-size read drop gpt-prep-partition? IF
- debug-disk-label? IF
- ." GPT PReP partition found " cr
- THEN
- block gpt-part-entry>first-lba x@ xbflip
- block gpt-part-entry>last-lba x@ xbflip
- over - 1+ ( addr offset len )
- swap ( addr len offset )
- block-size * to part-offset
- 0 0 seek drop ( addr len )
- block-size * read ( size )
+ debug-disk-label? IF ." GPT PReP partition found " cr THEN
+ block gpt-part-entry>first-lba x@-le ( addr first-lba )
+ block gpt-part-entry>last-lba x@-le ( addr first-lba last-lba)
+ over - 1+ ( addr first-lba blocks )
+ swap ( addr blocks first-lba )
+ block-size * to part-offset ( addr blocks )
+ 0 0 seek drop ( addr blocks )
+ block-size * read ( size )
+ UNLOOP EXIT
+ THEN
+ seek-pos gpt-part-size + to seek-pos
+ LOOP
+ false
+;
+
+: try-gpt-dos-partition ( -- true|false )
+ get-gpt-partition 0= IF false EXIT THEN
+ block gpt>num-part-entry l@-le dup 0= IF false EXIT THEN
+ 1+ 1 ?DO
+ seek-pos 0 seek drop
+ block gpt-part-size read drop
+ gpt-basic-data-partition? IF
+ debug-disk-label? IF ." GPT BASIC DATA partition found " cr THEN
+ block gpt-part-entry>first-lba x@-le ( first-lba )
+ dup to part-start ( first-lba )
+ block gpt-part-entry>last-lba x@-le ( first-lba last-lba )
+ over - 1+ ( first-lba s1 )
+ block-size * to part-size ( first-lba )
+ block-size * to part-offset ( )
+ 0 0 seek drop
+ block block-size read drop
+ block fat-bootblock? ( true|false )
UNLOOP EXIT
THEN
- seek-pos gpt-part-size i * + to seek-pos
+ seek-pos gpt-part-size + to seek-pos
LOOP
- FALSE
+ false
;
\ Extract the boot loader path from a bootinfo.txt file
@@ -493,7 +549,7 @@ AA26 CONSTANT GPT-PREP-PARTITION-4
debug-disk-label? IF ." Trying CHRP boot " .s cr THEN
1 disk-chrp-boot !
- dup load-chrp-boot-file ?dup 0 <> IF .s cr nip EXIT THEN
+ dup load-chrp-boot-file ?dup 0 <> IF nip EXIT THEN
0 disk-chrp-boot !
debug-disk-label? IF ." Trying GPT boot " .s cr THEN
@@ -558,14 +614,7 @@ AA26 CONSTANT GPT-PREP-PARTITION-4
: try-dos-files ( -- found? )
no-mbr? IF false EXIT THEN
- \ block 0 byte 0-2 is a jump instruction in all FAT
- \ filesystems.
- \ e9 and eb are jump instructions in x86 assembler.
- block c@ e9 <> IF
- block c@ eb <>
- block 2+ c@ 90 <> or
- IF false EXIT THEN
- THEN
+ block fat-bootblock? 0= IF false EXIT THEN
s" fat-files" (interpose-filesystem)
true
;
@@ -600,6 +649,7 @@ AA26 CONSTANT GPT-PREP-PARTITION-4
: try-partitions ( -- found? )
try-dos-partition IF try-files EXIT THEN
+ try-gpt-dos-partition IF try-files EXIT THEN
\ try-iso9660-partition IF try-files EXIT THEN
\ ... more partition types here...
false
@@ -610,7 +660,7 @@ AA26 CONSTANT GPT-PREP-PARTITION-4
: close ( -- )
debug-disk-label? IF ." Closing disk-label: block=0x" block u. ." block-size=" block-size .d cr THEN
- block d# 4096 free-mem
+ block block-array-size free-mem
;
diff --git a/roms/SLOF/slof/fs/pci-scan.fs b/roms/SLOF/slof/fs/pci-scan.fs
index b8b9fe61f..2fdf0e8f5 100644
--- a/roms/SLOF/slof/fs/pci-scan.fs
+++ b/roms/SLOF/slof/fs/pci-scan.fs
@@ -110,10 +110,13 @@ here 100 allot CONSTANT pci-device-vec
dup 100000 + pci-next-mem ! \ and write back with 1MB for bridge
over 24 + rtas-config-w@ \ check if 64bit support
1 and IF \ IF 64 bit support
- 2dup 20 rshift \ | keep upper 32 bits
- swap 28 + rtas-config-l! \ | and write it into the Base-Upper32-bits
- pci-max-mem @ 20 rshift \ | fetch max Limit address and keep upper 32 bits
- 2 pick 2C + rtas-config-l! \ | and set the Limit
+ pci-next-mem64 @ 100000000 #aligned \ | read the current Value of 64-bit and align to 4GB boundary
+ dup 100000000 + pci-next-mem64 x! \ | and write back with 1GB for bridge
+ 2 pick swap \ |
+ 20 rshift \ | keep upper 32 bits
+ swap 28 + rtas-config-l! \ | and write it into the Base-Upper32-bits
+ pci-max-mem64 @ 20 rshift \ | fetch max Limit address and keep upper 32 bits
+ 2 pick 2C + rtas-config-l! \ | and set the Limit
THEN \ FI
10 rshift \ keep upper 16 bits
pci-max-mem @ 1- FFFF0000 and or \ and Insert mmem Limit (set it to max)
@@ -129,8 +132,12 @@ here 100 allot CONSTANT pci-device-vec
1- \ make limit one less than boundary
over 24 + rtas-config-w@ \ check if 64bit support
1 and IF \ IF 64 bit support
- 2dup 20 rshift \ | keep upper 32 bits
- swap 2C + rtas-config-l! \ | and write it into the Limit-Upper32-bits
+ pci-next-mem64 @ 100000000 #aligned \ | Reat current value of 64-bar and align at 4GB
+ dup pci-next-mem64 x! \ | and write it back
+ 1- \ | make limite one less than boundary
+ 2 pick swap \ |
+ 20 rshift \ | keep upper 32 bits
+ swap 2C + rtas-config-l! \ | and write it into the Limit-Upper32-bits
THEN \ FI
FFFF0000 and \ keep upper 16 bits
over 24 + rtas-config-l@ 0000FFFF and \ fetch original Value
diff --git a/roms/SLOF/slof/fs/rmove.fs b/roms/SLOF/slof/fs/rmove.fs
deleted file mode 100644
index c28dba9c4..000000000
--- a/roms/SLOF/slof/fs/rmove.fs
+++ /dev/null
@@ -1,53 +0,0 @@
-\ *****************************************************************************
-\ * Copyright (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
-\ ****************************************************************************/
-
-defer '(r@)
-defer '(r!)
-1 VALUE /(r)
-
-
-\ The rest of the code already implemented in prim.in
-\ In the end all of this should be moved over there and this file terminated
-
-: (rfill) ( addr size pattern 'r! /r -- )
- to /(r) to '(r!) ff and
- dup 8 lshift or dup 10 lshift or dup 20 lshift or
- -rot bounds ?do dup i '(r!) /(r) +loop drop
-;
-
-: (fwrmove) ( src dest size -- )
- >r 0 -rot r> bounds ?do + dup '(r@) i '(r!) /(r) dup +loop 2drop
-;
-
-\ Move from main to device memory
-: mrmove ( src dest size -- )
- 3dup or or 7 AND CASE
- 0 OF ['] x@ ['] rx! /x ENDOF
- 4 OF ['] l@ ['] rl! /l ENDOF
- 2 OF ['] w@ ['] rw! /w ENDOF
- dup OF ['] c@ ['] rb! /c ENDOF
- ENDCASE
- ( We already know that source and destination do not overlap )
- to /(r) to '(r!) to '(r@) (fwrmove)
-;
-
-: rfill ( addr size pattern -- )
- 3dup drop or 7 AND CASE
- 0 OF ['] rx! /x ENDOF
- 4 OF ['] rl! /l ENDOF
- 2 OF ['] rw! /w ENDOF
- dup OF ['] rb! /c ENDOF
- ENDCASE (rfill)
-;
-
-
-
diff --git a/roms/SLOF/slof/fs/terminal.fs b/roms/SLOF/slof/fs/terminal.fs
index 582bedeb3..dc82e7bf4 100644
--- a/roms/SLOF/slof/fs/terminal.fs
+++ b/roms/SLOF/slof/fs/terminal.fs
@@ -167,6 +167,7 @@ false VALUE stopcsi
CREATE twtracebuf 4000 allot twtracebuf 4000 erase
twtracebuf VALUE twbp
0 VALUE twbc
+0 VALUE twtrace-enabled?
: twtrace
twbc 4000 = IF 0 to twbc twtracebuf to twbp THEN
@@ -176,7 +177,7 @@ twtracebuf VALUE twbp
: terminal-write ( addr len -- actual-len )
cursor-off
tuck bounds ?DO i c@
- twtrace
+ twtrace-enabled? IF twtrace THEN
esc-on IF esc-process
ELSE CASE
1B OF true to esc-on ENDOF
diff --git a/roms/SLOF/slof/ppc64.c b/roms/SLOF/slof/ppc64.c
index 20d927069..619d95ec7 100644
--- a/roms/SLOF/slof/ppc64.c
+++ b/roms/SLOF/slof/ppc64.c
@@ -42,24 +42,7 @@ cell *the_heap_start = &the_heap[0];
cell *the_heap_end = &the_heap[HEAP_SIZE / CELLSIZE];
extern void io_putchar(unsigned char);
-
-
-static unsigned long __attribute__((noinline))
-call_c(cell arg0, cell arg1, cell arg2, cell entry)
-{
- register unsigned long r3 asm("r3") = arg0.u;
- register unsigned long r4 asm("r4") = arg1.u;
- register unsigned long r5 asm("r5") = arg2.u;
- register unsigned long r6 = entry.u ;
-
- asm volatile("mflr 31 ; mtctr %4 ; bctrl ; mtlr 31"
- : "=r" (r3)
- : "r" (r3), "r" (r4), "r" (r5), "r" (r6)
- : "ctr", "r6", "r7", "r8", "r9", "r10", "r11",
- "r12", "r13", "r31", "lr", "cc");
-
- return r3;
-}
+extern unsigned long call_c(cell arg0, cell arg1, cell arg2, cell entry);
long
diff --git a/roms/SLOF/slof/prim.code b/roms/SLOF/slof/prim.code
index 9fbed7168..bb9e036a9 100644
--- a/roms/SLOF/slof/prim.code
+++ b/roms/SLOF/slof/prim.code
@@ -520,6 +520,19 @@ PRIM(RMOVE)
MIRP
+PRIM(MRMOVE)
+ type_u size = TOS.u; POP;
+ void *d = TOS.a; POP;
+ void *s = TOS.a; POP;
+ FAST_MRMOVE(s, d, size);
+ MIRP
+
+PRIM(RFILL)
+ type_u pat = TOS.u; POP;
+ type_u size = TOS.u; POP;
+ void *dst = TOS.a; POP;
+ FAST_RFILL(dst, size, pat);
+ MIRP
// String compare, case insensitive:
// : string=ci ( str1 len1 str2 len2 -- equal? )
diff --git a/roms/SLOF/slof/prim.in b/roms/SLOF/slof/prim.in
index 7a0d6a2ed..855f59262 100644
--- a/roms/SLOF/slof/prim.in
+++ b/roms/SLOF/slof/prim.in
@@ -104,8 +104,9 @@ cod(SEMICOLON)
cod(EXECUTE)
cod(MOVE)
-// cod(RMOVE64)
cod(RMOVE)
+cod(MRMOVE)
+cod(RFILL)
cod(ZCOUNT)
con(HASH-SIZE HASHSIZE)
cod(HASH)