diff options
Diffstat (limited to 'qemu/roms/SLOF/slof/fs/usb')
-rw-r--r-- | qemu/roms/SLOF/slof/fs/usb/dev-hci.fs | 71 | ||||
-rw-r--r-- | qemu/roms/SLOF/slof/fs/usb/dev-hub.fs | 32 | ||||
-rw-r--r-- | qemu/roms/SLOF/slof/fs/usb/dev-keyb.fs | 54 | ||||
-rw-r--r-- | qemu/roms/SLOF/slof/fs/usb/dev-mouse.fs | 20 | ||||
-rw-r--r-- | qemu/roms/SLOF/slof/fs/usb/dev-parent-calls.fs | 15 | ||||
-rw-r--r-- | qemu/roms/SLOF/slof/fs/usb/dev-storage.fs | 361 | ||||
-rw-r--r-- | qemu/roms/SLOF/slof/fs/usb/slofdev.fs | 8 | ||||
-rw-r--r-- | qemu/roms/SLOF/slof/fs/usb/usb-static.fs | 70 |
8 files changed, 631 insertions, 0 deletions
diff --git a/qemu/roms/SLOF/slof/fs/usb/dev-hci.fs b/qemu/roms/SLOF/slof/fs/usb/dev-hci.fs new file mode 100644 index 000000000..5fb25b8b6 --- /dev/null +++ b/qemu/roms/SLOF/slof/fs/usb/dev-hci.fs @@ -0,0 +1,71 @@ +\ ***************************************************************************** +\ * Copyright (c) 2006, 2012, 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 +\ ****************************************************************************/ +\ * +\ * [OEX]HCI functions +\ * +\ **************************************************************************** + +\ ( num $name type ) + +VALUE usb_type \ USB type + +\ Open Firmware Properties +device-type +" usb" 2dup device-name + +rot +VALUE usb_num \ controller number +usb_num $cathex strdup \ create alias name +2dup find-alias 0= IF + get-node node>path set-alias +ELSE 3drop THEN + +/hci-dev BUFFER: hcidev +usb_num hcidev usb-setup-hcidev +TRUE VALUE first-time-init? +0 VALUE open-count + +false VALUE dev-hci-debug? + +1 encode-int s" #address-cells" property +0 encode-int s" #size-cells" property + +\ converts physical address to text unit string +: encode-unit ( port -- unit-str unit-len ) 1 hex-encode-unit ; + +\ Converts text unit string to phyical address +: decode-unit ( addr len -- port ) 1 hex-decode-unit ; + +: get-hci-dev ( -- hcidev ) + hcidev +; + +: hc-cleanup ( -- ) + my-phandle set-node + dev-hci-debug? IF ." USB-HCI: Cleaning up " pwd cr THEN + hcidev USB-HCD-EXIT + 0 set-node +; + +: open ( -- true | false ) + true +; + +: close +; + +\ create a new entry to cleanup and suspend HCI +\ after first init +first-time-init? IF + ['] hc-cleanup add-quiesce-xt + false to first-time-init? +THEN diff --git a/qemu/roms/SLOF/slof/fs/usb/dev-hub.fs b/qemu/roms/SLOF/slof/fs/usb/dev-hub.fs new file mode 100644 index 000000000..ba0b33437 --- /dev/null +++ b/qemu/roms/SLOF/slof/fs/usb/dev-hub.fs @@ -0,0 +1,32 @@ +new-device + +VALUE sudev + +s" slofdev.fs" included +sudev slof-dev>port l@ dup set-unit encode-phys " reg" property +sudev slof-dev>udev @ VALUE udev + +s" hub" device-name + +s" dev-parent-calls.fs" included + +1 encode-int s" #address-cells" property +0 encode-int s" #size-cells" property +: decode-unit 1 hex-decode-unit ; +: encode-unit 1 hex-encode-unit ; + +: usb-hub-init ( usbdev -- true | false ) + udev USB-HUB-INIT +; + +: open ( -- true | false ) + TRUE +; + +: close +; + +." USB HUB " cr +usb-hub-init drop + +finish-device diff --git a/qemu/roms/SLOF/slof/fs/usb/dev-keyb.fs b/qemu/roms/SLOF/slof/fs/usb/dev-keyb.fs new file mode 100644 index 000000000..db9e23ef1 --- /dev/null +++ b/qemu/roms/SLOF/slof/fs/usb/dev-keyb.fs @@ -0,0 +1,54 @@ +new-device + +VALUE sudev +false VALUE usb-keyb-debug? + +s" slofdev.fs" included +sudev slof-dev>port l@ dup set-unit encode-phys " reg" property +sudev slof-dev>udev @ VALUE udev + +s" usb-keyboard" device-name +s" keyboard" device-type +s" EN" encode-string s" language" property +s" keyboard" get-node node>path set-alias + +s" dev-parent-calls.fs" included + +0 VALUE open-count + +: open ( -- true | false ) + usb-keyb-debug? IF ." USB-KEYB: Opening (count is " open-count . ." )" cr THEN + open-count 0= IF + udev USB-HID-INIT 0= IF + ." USB keyboard setup failed " pwd cr false EXIT + THEN + THEN + open-count 1 + to open-count + true +; + +: close + usb-keyb-debug? IF ." USB-KEYB: Closing (count is " open-count . ." )" cr THEN + open-count 0> IF + open-count 1 - dup to open-count + 0= IF + my-phandle set-node + udev USB-HID-EXIT drop + 0 set-node + THEN + THEN +; + +\ method to check if a key is present in output buffer +\ used by 'term-io.fs' +: key-available? ( -- true|false ) + udev USB-KEY-AVAILABLE IF TRUE ELSE FALSE THEN +; + +: read ( addr len -- actual ) + 0= IF drop 0 EXIT THEN + udev USB-READ-KEYB ?dup IF swap c! 1 ELSE 0 swap c! 0 then +; + +." USB Keyboard " cr +finish-device diff --git a/qemu/roms/SLOF/slof/fs/usb/dev-mouse.fs b/qemu/roms/SLOF/slof/fs/usb/dev-mouse.fs new file mode 100644 index 000000000..f6acd7e28 --- /dev/null +++ b/qemu/roms/SLOF/slof/fs/usb/dev-mouse.fs @@ -0,0 +1,20 @@ +new-device + +VALUE sudev +s" slofdev.fs" included +sudev slof-dev>port l@ dup set-unit encode-phys " reg" property +sudev slof-dev>udev @ VALUE udev + +s" usb-mouse" device-name + +\ .S cr +\ dup slof-dev>udev dup . @ . cr +\ dup slof-dev>port dup . l@ . cr +\ dup slof-dev>devaddr dup . l@ . cr +\ dup slof-dev>hcitype dup . l@ . cr +\ dup slof-dev>num dup . l@ . cr +\ dup slof-dev>devtype dup . l@ . cr + +." USB mouse " cr + +finish-device diff --git a/qemu/roms/SLOF/slof/fs/usb/dev-parent-calls.fs b/qemu/roms/SLOF/slof/fs/usb/dev-parent-calls.fs new file mode 100644 index 000000000..57fa8ebdc --- /dev/null +++ b/qemu/roms/SLOF/slof/fs/usb/dev-parent-calls.fs @@ -0,0 +1,15 @@ +\ ****************************************************************************/ +\ * 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 +\ ****************************************************************************/ + +get-node CONSTANT my-phandle + +s" dma-function.fs" included diff --git a/qemu/roms/SLOF/slof/fs/usb/dev-storage.fs b/qemu/roms/SLOF/slof/fs/usb/dev-storage.fs new file mode 100644 index 000000000..94f8421d3 --- /dev/null +++ b/qemu/roms/SLOF/slof/fs/usb/dev-storage.fs @@ -0,0 +1,361 @@ +\ ***************************************************************************** +\ * 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 +\ ****************************************************************************/ + +\ ( usbdev -- ) + +new-device + +VALUE usbdev + +s" slofdev.fs" included + +false VALUE usb-disk-debug? + +usbdev slof-dev>port l@ dup set-unit encode-phys " reg" property +s" storage" device-name + +s" dev-parent-calls.fs" included + +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 ; + +0 CONSTANT USB_PIPE_OUT +1 CONSTANT USB_PIPE_IN + +\ ----------------------------------------------------------- +\ Specific properties +\ ----------------------------------------------------------- + +usbdev slof-dev>udev @ VALUE udev +usbdev slof-dev>port l@ VALUE port +usbdev slof-dev>hcitype l@ VALUE hcitype + +0 INSTANCE VALUE lun +10000 VALUE dev-max-transfer +0 VALUE resp-buffer +0 VALUE resp-size +0f CONSTANT SCSI-COMMAND-OFFSET + +\ ------------------------------------------------------- +\ DMA-able buffers +\ ------------------------------------------------------- + +STRUCT + dev-max-transfer FIELD usb>data + 40 FIELD usb>cmd + 20 FIELD usb>csw +CONSTANT /dma-buf + +0 VALUE dma-buf +0 VALUE dma-buf-phys +0 VALUE td-buf +0 VALUE td-buf-phys +1000 CONSTANT /td-buf + +: (dma-buf-init) ( -- ) + /dma-buf dma-alloc TO dma-buf + dma-buf /dma-buf 0 dma-map-in TO dma-buf-phys + /td-buf dma-alloc TO td-buf + td-buf /td-buf 0 dma-map-in TO td-buf-phys +; + +: (dma-buf-free) ( -- ) + td-buf td-buf-phys /td-buf dma-map-out + td-buf /td-buf dma-free + 0 TO td-buf + 0 TO td-buf-phys + dma-buf dma-buf-phys /dma-buf dma-map-out + dma-buf /dma-buf dma-free + 0 TO dma-buf + 0 TO dma-buf-phys +; + + +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 +\ + +: do-bulk-command ( resp-buffer resp-size -- TRUE | FALSE ) + TO resp-size + TO resp-buffer + udev USB_PIPE_OUT td-buf td-buf-phys dma-buf-phys usb>cmd 1F + usb-transfer-bulk IF \ transfer CBW + resp-size IF + d# 125 us + udev USB_PIPE_IN td-buf td-buf-phys resp-buffer resp-size + usb-transfer-bulk 1 = not IF \ transfer data + usb-disk-debug? IF ." Data phase failed " cr THEN + \ FALSE EXIT + \ in case of a stall/halted endpoint we clear the halt + \ Fall through and try reading the CSW + THEN + THEN + d# 125 us + udev USB_PIPE_IN td-buf td-buf-phys dma-buf-phys usb>csw 0D + usb-transfer-bulk \ transfer CSW + ELSE + FALSE EXIT + THEN +; + +STRUCT \ cbw + /l FIELD cbw>sig + /l FIELD cbw>tag + /l FIELD cbw>len + /c FIELD cbw>flags + /c FIELD cbw>lun \ 0:3 bits + /c FIELD cbw>cblen \ 0:4 bits +CONSTANT cbw-length + +STRUCT \ csw + /l FIELD csw>sig + /l FIELD csw>tag + /l FIELD csw>data-residue + /c FIELD csw>status +CONSTANT cbw-length + +0 VALUE cbw-addr +0 VALUE csw-addr + +: build-cbw ( tag xfer-len dir lun cmd-len addr -- ) + TO cbw-addr ( tag xfer-len dir lun cmd-len ) + cbw-addr cbw-length erase ( tag xfer-len dir lun cmd-len ) + cbw-addr cbw>cblen c! ( tag xfer-len dir lun ) + cbw-addr cbw>lun c! ( tag xfer-len dir ) + \ dir is true or false + \ bmCBWFlags + \ BIT 7 Direction + \ 0 - OUT + \ 1 - IN + IF 80 ELSE 0 THEN + cbw-addr cbw>flags c! ( tag xfer-len ) + cbw-addr cbw>len l!-le ( tag ) + cbw-addr cbw>tag l!-le ( ) + 43425355 cbw-addr cbw>sig l!-le +; + +0 INSTANCE VALUE usb-buf-addr +0 INSTANCE VALUE usb-buf-len +0 INSTANCE VALUE usb-dir +0 INSTANCE VALUE usb-cmd-addr +0 INSTANCE VALUE usb-cmd-len +1 VALUE tag + +: execute-scsi-command ( buf-addr buf-len dir cmd-addr cmd-len -- ... ) + ( ... [ sense-buf sense-len ] stat ) + \ Cleanup virtio request and response + to usb-cmd-len to usb-cmd-addr to usb-dir to usb-buf-len to usb-buf-addr + + dma-buf usb>cmd 40 0 fill + dma-buf usb>csw 20 0 fill + + tag usb-buf-len usb-dir lun usb-cmd-len dma-buf usb>cmd + ( tag transfer-len dir lun cmd-len addr ) + build-cbw + 1 tag + to tag + + usb-cmd-addr + dma-buf usb>cmd SCSI-COMMAND-OFFSET + + usb-cmd-len + move + + \ Send it + dma-buf-phys usb>data usb-buf-len + do-bulk-command IF + dma-buf usb>data usb-buf-addr usb-buf-len move + ELSE + ." USB-DISK: Bulk commad failed!" cr + 0 0 -1 EXIT + THEN + + dma-buf usb>csw to csw-addr + csw-addr csw>sig l@ 55534253 <> IF + ." USB-DISK: CSW signature invalid " cr + 0 0 -1 EXIT + THEN + + csw-addr csw>status c@ CASE + 0 OF ENDOF \ Good + 1 OF + usb-disk-debug? IF + ." USB-DISK: CSW Data residue: " + csw-addr csw>data-residue l@-le . cr + THEN + 0 0 8 EXIT ENDOF \ Command failed, Retry + dup OF 0 0 -1 EXIT ENDOF \ Anything else -> HW error + ENDCASE + + \ Other error status + csw-addr csw>status c@ dup 0<> IF + usb-disk-debug? IF + over scsi-get-sense-data + ." USB-DISK: Sense key [ " dup . ." ] " .sense-text + ." ASC,ASCQ: " . . cr + THEN + rot + THEN +; + +\ -------------------------------- +\ Include the generic host helpers +\ -------------------------------- + +" scsi-host-helpers.fs" included + +0 VALUE open-count + +: usb-storage-init ( -- TRUE ) + td-buf 0= IF + usb-disk-debug? IF ." USB-DISK: Allocating buffer " cr THEN + (dma-buf-init) + udev USB-MSC-INIT 0= IF + ." USB-DISK: Unable to initialize MSC " cr + FALSE + ELSE + TRUE + THEN + THEN +; + +: usb-storage-cleanup + td-buf 0<> IF + usb-disk-debug? IF ." USB-DISK: Freeing buffer " cr THEN + (dma-buf-free) + udev USB-MSC-EXIT 0= IF ." USB-DISK: Unable to exit MSC " cr THEN + THEN +; + +: open + usb-disk-debug? IF ." USB-DISK: Opening (count is " open-count . ." )" cr THEN + + open-count 0= IF + usb-storage-init IF + 1 to open-count true + ELSE ." USB-DISK initialization failed !" cr false THEN + ELSE + open-count 1 + to open-count + true + THEN +; + +: close + usb-disk-debug? IF ." USB-DISK: Closing (count is " open-count . ." )" cr THEN + + open-count 0> IF + open-count 1 - dup to open-count + 0= IF + usb-storage-cleanup + THEN + THEN +; + +\ ----------------------------------------------------------- +\ SCSI scan at boot and child device support +\ ----------------------------------------------------------- + +\ We use SRP luns of the form 01000000 | (target << 8) | lun +\ in the top 32 bits of the 64-bit LUN +: (set-target) + dup 20 >> FFFF and to lun + dup 30 >> FF and to port + to current-target + usb-disk-debug? IF ." USB-DISK: udev " udev . ." lun:" lun . ." port:" port . cr THEN +; + +: dev-generate-srplun ( target lun-id -- srplun ) + swap drop port 0100 or 10 << or 20 << +; + +\ FIXME: Check max transfer coming from virtio config +: max-transfer ( -- n ) + dev-max-transfer +; + +\ 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) + usb-disk-debug? IF ." USB-DISK: udev " udev . ." lun:" lun . ." port:" port . cr THEN +; + +1 CONSTANT #target +: dev-max-target ( -- #target ) + #target +; + +" scsi-probe-helpers.fs" included + +scsi-close \ no further scsi words required + +\ 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 +; + +: usb-storage-init-and-scan ( -- ) + usb-disk-debug? IF ." Initializing usb-disk: udev " udev . cr THEN + + \ Create instance for scanning: + 0 0 get-node open-node ?dup 0= IF EXIT THEN + my-self >r + dup to my-self + + hcitype + CASE + 1 OF 4000 TO dev-max-transfer ENDOF \ OHCI + 2 OF 10000 TO dev-max-transfer ENDOF \ EHCI + 3 OF F000 TO dev-max-transfer ENDOF \ XHCI + ENDCASE + usb-storage-init + scsi-find-disks + setup-alias + usb-storage-cleanup + \ Close the temporary instance: + close-node + r> to my-self +; + +." USB Storage " cr +: usb-scsi-add-disk + " scsi-disk.fs" included +; + +usb-scsi-add-disk +usb-storage-init-and-scan + +finish-device diff --git a/qemu/roms/SLOF/slof/fs/usb/slofdev.fs b/qemu/roms/SLOF/slof/fs/usb/slofdev.fs new file mode 100644 index 000000000..d6e20fdcd --- /dev/null +++ b/qemu/roms/SLOF/slof/fs/usb/slofdev.fs @@ -0,0 +1,8 @@ +STRUCT + /n FIELD slof-dev>udev + /l FIELD slof-dev>port + /l FIELD slof-dev>devaddr + /l FIELD slof-dev>hcitype + /l FIELD slof-dev>num + /l FIELD slof-dev>devtype +CONSTANT slof-usb-dev diff --git a/qemu/roms/SLOF/slof/fs/usb/usb-static.fs b/qemu/roms/SLOF/slof/fs/usb/usb-static.fs new file mode 100644 index 000000000..47db7276a --- /dev/null +++ b/qemu/roms/SLOF/slof/fs/usb/usb-static.fs @@ -0,0 +1,70 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2011, 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 +\ ****************************************************************************/ + +\ Load dev hci +: load-dev-hci ( num name-str name-len ) + s" dev-hci.fs" INCLUDED +; + +0 VALUE ohci-init +0 VALUE ehci-init +0 VALUE xhci-init +0 VALUE usb-alias-num + +: get-usb-alias-num + usb-alias-num dup 1+ to usb-alias-num +; + +\ create a new ohci device alias for the current node +: set-ohci-alias ( -- ) + 1 to ohci-init + get-usb-alias-num ( num ) + s" ohci" 1 load-dev-hci +; + +\ create a new ehci device alias for the current node +: set-ehci-alias ( -- ) + 1 to ehci-init + get-usb-alias-num ( num ) + s" ehci" 2 load-dev-hci +; + +\ create a new xhci device alias for the current node +: set-xhci-alias ( -- ) + 1 to xhci-init + get-usb-alias-num ( num ) + s" xhci" 3 load-dev-hci +; + +: usb-enumerate ( hcidev -- ) + USB-HCD-INIT +; + +: usb-scan ( -- ) + ." Scanning USB " cr + ohci-init 1 = IF USB-OHCI-REGISTER THEN + ehci-init 1 = IF USB-EHCI-REGISTER THEN + xhci-init 1 = IF USB-XHCI-REGISTER THEN + + usb-alias-num 0 ?DO + " usb" i $cathex find-device + " get-hci-dev" get-node find-method + IF + execute usb-enumerate + ELSE + ." get-base-address method not found for usb@" i . + ." Device type: " + " device_type" get-node get-property 0= IF decode-string type cr 2drop THEN + THEN + LOOP + 0 set-node \ FIXME Setting it back +; |