PS3:HvReverseEngineering

From wikibrew
Jump to: navigation, search


Contents

Repository Nodes

3.15 Linux

3.41 GameOS

Gelic Device

Crossreference: ps3devwiki.com::Gelic Device

sys.hw.config

Note:old vs. new: Old == CECHA up to CECHK, New == CECHL and later

Control Interface

HV calls 195 and 196 are used by GameOS to send commands to Gelic device directly.

lv1_undocumented_function_196

Parameters

r3 - LPAR address of data buffer

r4 - size of data buffer

r5 - must be 0

lv1_undocumented_function_195

Parameters

r3 - command (16 bit value)

r4 - command data size

r5 - must be 0

Data Buffer

Command Data Buffer

Header

0x0 - command = request command + 1 (2 bytes)

0x4 - result, 0x1 - success, 0x2 - invalid command length, 0x3 - invalid command, 0x4 - invalid parameter (2 bytes)

0x6 - body size (2 bytes)

Event Data Buffer

Header

offset 0x0 - GET index (4 bytes)

offset 0x4 - PUT index (4 bytes)

GameOS

Parameters

r3 - command (16 bits)

r4 - effective address of command data buffer

r5 - size of command data buffer

Commands

Unknown (0x1)

Get AP SSID (0x3)

offset 0xC - SSID (32 bytes)

Set AP SSID (0x5)

offset 0xC - SSID (32 bytes)

Get Channel (0xf)

offset 0x2F - active channel (2 bytes)

Set Channel (0x11)

offset 0xC - channel (1 byte)

Unknown (0x27)

Set Antenna (0x29)

offset 0xC - ??? (1 byte)

offset 0xD - ??? (1 byte)

Set AP WEP Configuration (0x5b)

offset 0xE - security mode: 0 - none, 1 - wep64, 2 - wep128 (1 byte)

offset 0x10 - WEP key (4 * 18 bytes)

Unknown (0x61)

Unknown (0x65)

Get Eurus Firmware Version (0x99)

Here is the response on my PS3 Slim:

00000000: 4a 55 50 49 54 45 52 2d 54 57 4f 2d 46 57 2d 32 |JUPITER-TWO-FW-2|
00000010: 30 2e 30 2e 31 32 2e 70 30 28 4a 61 6e 20 31 39 |0.0.12.p0(Jan 19|
00000020: 20 32 30 31 30 20 32 31 3a 32 30 3a 35 33 29 00 | 2010 21:20:53).|
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00       |..............  |

Get AP Operating Mode (0xb7)

offset 0xC - opmode: 0 - 11b, 1 - 11g, 2 - 11bg (4 bytes)

Set AP Operating Mode (0xb9)

offset 0xC - opmode: 0 - 11b, 1 - 11g, 2 - 11bg (4 bytes)

Unknown (0xc5)

offset 0xC - ??? (4 bytes)

Set AP WPA AKM Suite (0xc9)

offset 0xC - AKM suite (4 bytes)

Set AP WPA Group Cipher Suite (0xcf)

offset 0xC - group cipher suite: group (4 bytes)

Set AP WPA PSK Binary (0xd3)

offset 0xC - PSK (64 bytes)

Set AP WPA Reauthentication Timeout (0xd5)

offset 0xC - timeout value in seconds (2 bytes)

Unknown (0x127)

Unknown (0x12b)

Set AP WPA PSK Passphrase (0x17d)

offset 0xD - passphrase (32 bytes)

Set AP WPA Pairwise Cipher Suite (0x1bf)

offset 0xC - pairwise cipher suite (4 bytes)

offset 0x10 - ??? (1 byte)

Unknown (0x1d9)

Start AP (0x1dd)

Unknown (0x1ed)

Get Eurus HW Revision (0x1fb)

Associate (0x1001)

Get Common Configuration (0x1003)

Set Common Configuration (0x1005)

offset 0xC - BSS type: 0 - infrastructure, 1 - ???, 2 - adhoc (1 byte)

offset 0xD - authentication mode: 0 - open, 1 - shared key

offset 0xE - opmode: 0 - 11bg, 1 - 11b, 2 - 11g (1 byte)

offset 0xF - ??? (1 byte)

offset 0x10 - BSSID (6 bytes)

offset 0x16 - capability (2 bytes)

Get WEP Configuration (0x1013)

Set WEP Configuration (0x1015)

Get WPA Configuration (0x1017)

Set WPA Configuration (0x1019)

offset 0xE - security type: 0 - WPA, 1 - RSNA (1 byte)

offset 0xF - psk type: 0 - hex, 1 - bin (1 byte)

offset 0x10 - psk key: hex or bin (64 bytes)

offset 0x50 - group cipher suite: 0x0050f202 - WPA TKIP, 0x0050f204 - WPA AES, 0x000fac02 - RSNA TKIP, 0x000fac04 - RSNA CCMP (4 bytes)

offset 0x54 - pairwise cipher suite: 0x0050f202 - WPA TKIP, 0x0050f204 - WPA AES, 0x000fac02 - RSNA TKIP, 0x000fac04 - RSNA CCMP (4 bytes)

offset 0x58 - AKM suite: 0x0050f202 - WPA PSK, 0x000fac02 - RSNA PSK (4 bytes)

See IEEE 802.11 specification for more details about cipher/AKM suites

802.11 spec: [1]

Unknown (0x1025)

offset 0xC - 0 - off, 1 - on (1 byte)

Unknown (0x1031)

Get Scan Results (0x1033)

Scan Results

offset 0x0 - number of scan entries (1 byte)

offset 0x1 - array of scan entries

Scan Entry

offset 0x0 - size of this entry in bytes, this field is NOT included (2 bytes)

offset 0x2 - BSSID (6 bytes)

offset 0x8 - RSSI (1 byte)

offset 0x9 - timestamp (8 bytes)

offset 0x11 - beacon period (2 bytes)

offset 0x13 - capability (2 bytes)

offset 0x15 - information elements (see 802.11 specification)

Start Scan (0x1035)

Diassociate (0x1037)

Get RSSI (0x103d)

offset 0x10 - MAC address of node (6 bytes)

offset 0x16 - RSSI (1 byte)

Get MAC Address (0x103f)

offset 0xD - MAC address (6 bytes)

Set MAC Address (0x1041)

Unsupported command (0x104b)

Set Short Slot Time (0x104d)

offset 0xC - enable (1 byte)

Get Short Slot Time (0x104f)

offset 0xC - enabled (1 byte)

Unknown (0x1051)

offset 0xE - ??? (1 byte)

offset 0xF - ??? (1 byte)

offset 0x10 - array of some data (each entry is 0xD bytes)

Unknown (0x1053)

offset 0xC - ??? (4 bytes)

offset 0x10 - MAC address (6 bytes)

Unknown (0x1059)

offset 0xC - ??? (1 byte)

offset 0xD - number of MAC addresses

offset 0xE - MAC address list (each MAC address is 6 bytes)

Unknown (0x105f)

Get Zephyr HW Revision (0x1101)

Get MAC Address List (0x1117)

offset 0xC - number of MAC addresses (2 bytes)

offset 0xE - MAC addresses (6 * number of MAC addresses)

Unknown (0x1133)

Set WOL MAC Address Filter (0x1139)

Unknown (0x113b)

Set WOL Multicast Address Filter (0x113d)

Clear WOL Multicast Address Filter (0x113f)

Unknown (0x1141)

Clear WOL Address Filter (0x1143)

Unknown (0x114b)

Set WOL Magic Packet Mode (0x1155)

offset 0xC - mode: 0 - disable, 1 - enable (4 bytes)

Unknown (0x1157)

Set WOL Multicast Address Filter Mode (0x1159)

offset 0xC - mode: 0 - disable, 1 - enable (4 bytes)

Set Unicast Address Filter (0x115b)

offset 0xC - ??? (2 bytes)

offset 0xE - ??? (2 bytes)

offset 0x10 - MAC address (6 bytes)

Clear Unicast Address Filter (0x115d)

Get Unicast Address Filter (0x115f)

Set Multicast Address Filter (0x1161)

Clear Multicast Address Filter (0x1163)

offset 0xC - multicast address filter (4 * 8 bytes)

Get Multicast Address Filter (0x1165)

Set WOL Address Filter (0x1167)

Set WOL Address Filter Mode (0x116d)

offset 0xC - mode: 0 - disable, 1 - enable (4 bytes)

Set Unicast Address Filter Mode (0x116f)

offset 0xC - mode: 0 - disable, 1 - enable (4 bytes)

Get Device Status (0xfffb)

Unknown (0xfffc)

Get Channel Information (0xfffd)

Set Response Timeout (0xfffe)

Unknown (0xffff)

Events

struct ps3_eurus_event_hdr {
	__le32 type;
	__le32 id;
	__le32 timestamp;
	__le32 payload_length;
	__le32 unknown;
} __packed;

struct ps3_eurus_event {
	struct ps3_eurus_event_hdr hdr;
	u8 payload[44];
} __packed;

Event Type 0x00000040

Id Description
0x00000001 Deauthenticated

Event Type 0x00000008

Id Description
0x00000010 Client associated

Event Type 0x00000010

Id Description
0x00000002 Client disassociated

Event Type 0x00000080

Id Description
0x00000001 Beacon Lost
0x00000002 Connected
0x00000004 Scan Completed
0x00000020 WPA Connected
0x00000040 WPA Error (MIC Error)

Event Type 0x00000100

Id Description
0x00000002  ???
0x00000010  ???

Event Type 0x80000000

Id Description
0x00000001 Device Ready

Enabling WLAN Gelic On FAT

Linux kernel doesn't use Gelic Device Control Interface like GameOS does it. To get WLAN working on Linux booted with GameOS rights, we have to disable Gelic Device Control Interface first because it's enabled for GameOS by default.

The value of repository node "ios.net.eurus.lpar" controls access to Gelic Device Control Interface. It's a bitmap. The position of a bit corresponds to LPAR id. During GameOS booting, HV process 9 (System Manager) sets bit at postion 2 to 1 which means enable Gelic Device Control Interface for LPAR 2.

To disable Gelic Device Control Interface on Linux, first unload Gelic device driver, then set value of repository node "ios.net.eurus.lpar" to 0 and load Gelic device driver again. After that WLAN should work again but only on FATs.

For PS3 Slim we need a new Linux Gelic device driver which uses Gelic Device Control Interface directly.


USB WLAN Interface (Codename Jupiter 2)

Endpoints

Bus 002 Device 002: ID 054c:036f Sony Corp. 
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass          224 Wireless
  bDeviceSubClass         1 Radio Frequency
  bDeviceProtocol         1 Bluetooth
  bMaxPacketSize0        64
  idVendor           0x054c Sony Corp.
  idProduct          0x036f 
  bcdDevice           20.12
  iManufacturer           1 
  iProduct                2 
  iSerial                 0 
  bNumConfigurations      1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        3
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      2 
      bInterfaceProtocol      1 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x85  EP 5 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x4000  1x 0 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x05  EP 5 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x4000  1x 0 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        4
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      2 
      bInterfaceProtocol      2 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x86  EP 6 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0002  1x 2 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x06  EP 6 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0002  1x 2 bytes
        bInterval             255
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        5
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      2 
      bInterfaceProtocol      3 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x87  EP 7 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0002  1x 2 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x07  EP 7 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0002  1x 2 bytes
        bInterval             255

Device Initialization

Magic Data in Control Transfer

unsigned char ps3_usb_wlan_magic_data[] = {
	0x76, 0x4e, 0x4b, 0x07, 0x24, 0x42, 0x53, 0xfb, 0x5a, 0xc7, 0xcc, 0x1d, 0xae, 0x00, 0xc6, 0xd8,
	0x14, 0x40, 0x61, 0x8b, 0x13, 0x17, 0x4d, 0x7c, 0x3b, 0xb6, 0x90, 0xb8, 0x6e, 0x8b, 0xbb, 0x1d,
};

Initialization State Machine

State 1
State 2
State 3
State 4
State 5
State 6
State 7
State 8
State 9
State 10
State 11
State 12
State 13
State 14
State 15
State 16
State 17

Test Program

Source Code


/*
 * PS3 USB WLAN
 *
 * Copyright (C) 2011 glevand (geoffrey.levand@mail.ru)
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published
 * by the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdint.h>
#include <unistd.h>
#include <pthread.h>

#include <libusb-1.0/libusb.h>

#define USB_VENDOR_ID				0x054c /* $ONY */
#define USB_PRODUCT_ID				0x036f
#define USB_IFACE_NUMBER			3

#define USB_INTR_TRANSFER_EP5_IN_BUF_SIZE	0x800
#define USB_INTR_TRANSFER_EP5_OUT_BUF_SIZE	0x800

struct wlan_cmd_pkt_hdr {
	uint8_t unknown1;
	uint8_t unknown2;
	uint8_t unknown3;
	uint8_t unknown4;
	uint16_t unknown5;
	uint8_t res1[2];
	uint16_t tag;
	uint8_t res2[14];
} __attribute__ ((packed));

struct wlan_cmd_hdr {
	uint16_t command;
	uint16_t tag;
	uint16_t status;
	uint16_t payload_size;
	uint8_t res[4];
} __attribute__ ((packed));

struct wlan_event_pkt_hdr {
	uint8_t unknown1;
	uint8_t unknown2;
	uint8_t unknown3;
	uint8_t event_count;
} __attribute__ ((packed));

static libusb_context *usb_ctx;
static libusb_device_handle *usb_dev_handle;

static struct libusb_transfer *usb_intr_transfer_ep5_in;
static unsigned char usb_intr_transfer_ep5_in_buf[USB_INTR_TRANSFER_EP5_IN_BUF_SIZE];

static unsigned char usb_intr_transfer_ep5_out_buf[USB_INTR_TRANSFER_EP5_OUT_BUF_SIZE];

static pthread_mutex_t usb_wlan_cmd_mutex;
static pthread_cond_t usb_wlan_cmd_cond;
static int volatile usb_wlan_cmd_busy;
static uint16_t usb_wlan_cmd;
static void *usb_wlan_cmd_data;

static int volatile usb_wlan_cmd_thread_done;

/*
 * WLAN won't work without this magic !!!
 */
static unsigned char usb_magic_data[] = {
	0x76, 0x4e, 0x4b, 0x07, 0x24, 0x42, 0x53, 0xfb, 0x5a, 0xc7, 0xcc, 0x1d, 0xae, 0x00, 0xc6, 0xd8,
	0x14, 0x40, 0x61, 0x8b, 0x13, 0x17, 0x4d, 0x7c, 0x3b, 0xb6, 0x90, 0xb8, 0x6e, 0x8b, 0xbb, 0x1d,
};

static unsigned char my_mac_addr[] = {
	0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
};

/*
 * hexdump
 */
static void hexdump(const unsigned char *data, unsigned int data_size)
{
	int i, j;

	for (i = 0; i < data_size; i += 16) {
		fprintf(stdout, "%08x:", i);

		for (j = 0; j < 16; j++) {
			if (i + j < data_size) {
				fprintf(stdout, " %02x", data[i + j]);
			} else {
				fprintf(stdout, "   ");
			}
		}

		fprintf(stdout, " |");

		for (j = 0; j < 16; j++) {
			if (i + j < data_size) {
				if (isprint(data[i + j]))
					fprintf(stdout, "%c", data[i + j]);
				else
					fprintf(stdout, ".");
			} else {
				fprintf(stdout, " ");
			}
		}

		fprintf(stdout, "|\n");
	}
}

/*
 * usb_handle_wlan_event
 */
static void usb_handle_wlan_event(struct wlan_event_pkt_hdr *wlan_event_pkt_hdr)
{
	fprintf(stdout, "%s:%d: === got WLAN event ===\n", __func__, __LINE__);

	/*
	fprintf(stdout, "%s:%d: event packet header:\n", __func__, __LINE__);
	fprintf(stdout, "%s:%d: unknown1 (0x%02x)\n", __func__, __LINE__,
		wlan_event_pkt_hdr->unknown1);
	fprintf(stdout, "%s:%d: unknown2 (0x%02x)\n", __func__, __LINE__,
		wlan_event_pkt_hdr->unknown2);
	fprintf(stdout, "%s:%d: unknown3 (0x%02x)\n", __func__, __LINE__,
		wlan_event_pkt_hdr->unknown3);
	*/
	fprintf(stdout, "%s:%d: event_count (0x%02x)\n", __func__, __LINE__,
		wlan_event_pkt_hdr->event_count);

	hexdump((unsigned char *) (wlan_event_pkt_hdr + 1), wlan_event_pkt_hdr->event_count * 64);
}

/*
 * usb_handle_wlan_cmd_response
 */
static void usb_handle_wlan_cmd_response(struct wlan_cmd_pkt_hdr *wlan_cmd_pkt_hdr)
{
	struct wlan_cmd_hdr *wlan_cmd_hdr;
	uint8_t *wlan_cmd_payload;

	fprintf(stdout, "%s:%d: === got WLAN command response ===\n", __func__, __LINE__);

	wlan_cmd_hdr = (struct wlan_cmd_hdr *) (wlan_cmd_pkt_hdr + 1);
	wlan_cmd_payload = (uint8_t *) (wlan_cmd_hdr + 1);

	/* convert all header fields to big-endian byte order !!! */

	wlan_cmd_pkt_hdr->unknown5 = le16toh(wlan_cmd_pkt_hdr->unknown5);
	wlan_cmd_pkt_hdr->tag = le16toh(wlan_cmd_pkt_hdr->tag);			/* returned from request */

	wlan_cmd_hdr->command = le16toh(wlan_cmd_hdr->command);			/* request command + 1 */
	wlan_cmd_hdr->tag = le16toh(wlan_cmd_hdr->tag);				/* returned from request */
	wlan_cmd_hdr->status = le16toh(wlan_cmd_hdr->status);			/* 1 - success
										   2 - invalid parameters ???
										   3 - invalid command ??? */
	wlan_cmd_hdr->payload_size = le16toh(wlan_cmd_hdr->payload_size);	/* length of data that follows the header */

	/*
	fprintf(stdout, "%s:%d: command packet header:\n", __func__, __LINE__);
	fprintf(stdout, "%s:%d: unknown1 (0x%02x)\n", __func__, __LINE__,
		wlan_cmd_pkt_hdr->unknown1);
	fprintf(stdout, "%s:%d: unknown2 (0x%02x)\n", __func__, __LINE__,
		wlan_cmd_pkt_hdr->unknown2);
	fprintf(stdout, "%s:%d: unknown3 (0x%02x)\n", __func__, __LINE__,
		wlan_cmd_pkt_hdr->unknown3);
	fprintf(stdout, "%s:%d: unknown4 (0x%02x)\n", __func__, __LINE__,
		wlan_cmd_pkt_hdr->unknown4);
	fprintf(stdout, "%s:%d: unknown5 (0x%04x)\n", __func__, __LINE__,
		wlan_cmd_pkt_hdr->unknown5);
	fprintf(stdout, "%s:%d: tag (0x%04x)\n", __func__, __LINE__,
		wlan_cmd_pkt_hdr->tag);
	*/

	fprintf(stdout, "%s:%d: command header:\n", __func__, __LINE__);
	fprintf(stdout, "%s:%d: command (0x%04x)\n", __func__, __LINE__,
		wlan_cmd_hdr->command);

	if ((usb_wlan_cmd + 1) != wlan_cmd_hdr->command)
		fprintf(stdout, "%s:%d: ==> command does not match, got (0x%04x) expected (0x%04x)\n",
			__func__, __LINE__, wlan_cmd_hdr->command, usb_wlan_cmd + 1);

	fprintf(stdout, "%s:%d: tag (0x%04x)\n", __func__, __LINE__,
		wlan_cmd_hdr->tag);
	fprintf(stdout, "%s:%d: status (0x%04x)\n", __func__, __LINE__,
		wlan_cmd_hdr->status);

	if (wlan_cmd_hdr->status != 0x1)
		fprintf(stdout, "%s:%d: ==> command status != 0x1\n", __func__, __LINE__);

	fprintf(stdout, "%s:%d: payload_size (0x%04x)\n", __func__, __LINE__,
		wlan_cmd_hdr->payload_size);

	fprintf(stdout, "%s:%d: command payload:\n", __func__, __LINE__);

	hexdump(wlan_cmd_payload, wlan_cmd_hdr->payload_size);

	memcpy(usb_wlan_cmd_data, wlan_cmd_payload, wlan_cmd_hdr->payload_size);

	pthread_mutex_lock(&usb_wlan_cmd_mutex);

	usb_wlan_cmd_busy = 0;

	pthread_cond_signal(&usb_wlan_cmd_cond);

	pthread_mutex_unlock(&usb_wlan_cmd_mutex);
}

/*
 * usb_intr_transfer_ep5_in_cb
 */
static void usb_intr_transfer_ep5_in_cb(struct libusb_transfer *transfer)
{
	struct wlan_cmd_pkt_hdr *wlan_cmd_pkt_hdr;
	int error;

	fprintf(stdout, "%s:%d: === got interrupt transfer ===\n", __func__, __LINE__);

	fprintf(stdout, "%s:%d: transfer status (%d) length (%d)\n",
		__func__, __LINE__, transfer->status, transfer->actual_length);

	wlan_cmd_pkt_hdr = (struct wlan_cmd_pkt_hdr *) transfer->buffer;

	if (wlan_cmd_pkt_hdr->unknown3 == 0x6)
		usb_handle_wlan_cmd_response(wlan_cmd_pkt_hdr);
	else if (wlan_cmd_pkt_hdr->unknown3 == 0x8)
		usb_handle_wlan_event((struct wlan_event_pkt_hdr *) transfer->buffer);
	else
		fprintf(stdout, "%s:%d: got unknown packet (0x%02x)\n",
			__func__, __LINE__, wlan_cmd_pkt_hdr->unknown3);

	memset(usb_intr_transfer_ep5_in_buf, 0, sizeof(usb_intr_transfer_ep5_in_buf));

	libusb_fill_interrupt_transfer(usb_intr_transfer_ep5_in, usb_dev_handle, LIBUSB_ENDPOINT_IN | 0x5,
		usb_intr_transfer_ep5_in_buf, sizeof(usb_intr_transfer_ep5_in_buf),
		usb_intr_transfer_ep5_in_cb, NULL, 0);

	error = libusb_submit_transfer(usb_intr_transfer_ep5_in);
	if (error) {
		fprintf(stderr, "%s:%d: could not submit transfer (%d)\n",
			__func__, __LINE__, error);
		exit(1);
	}
}

/*
 * usb_intr_transfer_ep5_out_cb
 */
static void usb_intr_transfer_ep5_out_cb(struct libusb_transfer *transfer)
{
	/*
	fprintf(stdout, "%s:%d: sent interrupt transfer\n", __func__, __LINE__);

	fprintf(stdout, "%s:%d: transfer status (%d)\n", __func__, __LINE__, transfer->status);
	*/

	libusb_free_transfer(transfer);
}

/*
 * usb_wlan_cmd_send
 */
static int usb_wlan_cmd_send(uint16_t command, const uint8_t *data, unsigned int data_size)
{
	struct wlan_cmd_pkt_hdr *wlan_cmd_pkt_hdr;
	struct wlan_cmd_hdr *wlan_cmd_hdr;
	uint8_t *wlan_cmd_payload;
	struct libusb_transfer *transfer;
	int error;

	fprintf(stdout, "%s:%d: sending command (0x%04x) data size (0x%04x) command size (0x%04x)\n",
		__func__, __LINE__, command, data_size, data_size + sizeof(struct wlan_cmd_hdr));

	transfer = libusb_alloc_transfer(0);
	if (!transfer) {
		fprintf(stderr, "%s:%d: could not allocate transfer\n", __func__, __LINE__);
		error = -1;
		goto fail;
	}

	wlan_cmd_pkt_hdr = (struct wlan_cmd_pkt_hdr *) usb_intr_transfer_ep5_out_buf;
	wlan_cmd_hdr = (struct wlan_cmd_hdr *) (wlan_cmd_pkt_hdr + 1);
	wlan_cmd_payload = (uint8_t *) (wlan_cmd_hdr + 1);

	wlan_cmd_pkt_hdr->unknown1 = 0x1;
	wlan_cmd_pkt_hdr->unknown2 = 0x1;
	wlan_cmd_pkt_hdr->unknown3 = 0x6;
	wlan_cmd_pkt_hdr->unknown4 = 0x0;
	wlan_cmd_pkt_hdr->unknown5 = 0x1;
	wlan_cmd_pkt_hdr->tag = 0xf00d;		/* returned in response */

	wlan_cmd_hdr->command = command;
	wlan_cmd_hdr->tag = 0xcafe;		/* returned in response */
	wlan_cmd_hdr->status = 0xa;
	wlan_cmd_hdr->payload_size = data_size;

	memcpy(wlan_cmd_payload, data, data_size);

	usb_wlan_cmd = command;
	usb_wlan_cmd_data = (void *) data;

	libusb_fill_interrupt_transfer(transfer, usb_dev_handle, LIBUSB_ENDPOINT_OUT | 0x5,
		usb_intr_transfer_ep5_out_buf,
		sizeof(struct wlan_cmd_pkt_hdr) + sizeof(struct wlan_cmd_hdr) + wlan_cmd_hdr->payload_size,
		usb_intr_transfer_ep5_out_cb, NULL, 0);

	/* convert all header fields to little-endian byte order !!! */

	wlan_cmd_pkt_hdr->unknown5 = htole16(wlan_cmd_pkt_hdr->unknown5);
	wlan_cmd_pkt_hdr->tag = htole16(wlan_cmd_pkt_hdr->tag);

	wlan_cmd_hdr->command = htole16(wlan_cmd_hdr->command);
	wlan_cmd_hdr->tag = htole16(wlan_cmd_hdr->tag);
	wlan_cmd_hdr->status = htole16(wlan_cmd_hdr->status);
	wlan_cmd_hdr->payload_size = htole16(wlan_cmd_hdr->payload_size);

	error = libusb_submit_transfer(transfer);
	if (error) {
		fprintf(stderr, "%s:%d: could not submit transfer (%d)\n",
			__func__, __LINE__, error);
		goto fail_free_transfer;
	}

	pthread_mutex_lock(&usb_wlan_cmd_mutex);

	usb_wlan_cmd_busy = 1;

	while (usb_wlan_cmd_busy)
		pthread_cond_wait(&usb_wlan_cmd_cond, &usb_wlan_cmd_mutex);

	pthread_mutex_unlock(&usb_wlan_cmd_mutex);

	return 0;

fail_free_transfer:

	libusb_free_transfer(transfer);

fail:

	return error;
}

/*
 * usb_wlan_cmd_start_scan
 */
static int usb_wlan_cmd_start_scan(void)
{
	unsigned char data[256], *ptr;
	unsigned int data_size;

	memset(data, 0, sizeof(data));

	ptr = data;
	*ptr++ = 0x0;
	*ptr++ = 0x1;
	*ptr++ = 0x64;
	*ptr++ = 0x0;

	ptr = data + 0xa;
	*ptr++ = 0x3;

	*ptr++ = 13;	/* number of channels */
	*ptr++ = 1;	/* channels */
	*ptr++ = 2;
	*ptr++ = 3;
	*ptr++ = 4;
	*ptr++ = 5;
	*ptr++ = 6;
	*ptr++ = 7;
	*ptr++ = 8;
	*ptr++ = 9;
	*ptr++ = 10;
	*ptr++ = 11;
	*ptr++ = 12;
	*ptr++ = 13;

	data_size = ptr - data;

	return usb_wlan_cmd_send(0x1035, data, data_size);
}

/*
 * usb_wlan_cmd_get_scan_results
 */
static int usb_wlan_cmd_get_scan_results(void)
{
	unsigned char data[1456];
	unsigned int data_size;

	memset(data, 0, sizeof(data));

	data_size = sizeof(data);

	return usb_wlan_cmd_send(0x1033, data, data_size);
}

/*
 * usb_wlan_cmd_0x99
 */
static int usb_wlan_cmd_0x99(void)
{
	unsigned char data[0x3e];
	unsigned int data_size;

	memset(data, 0, sizeof(data));

	data_size = sizeof(data);

	return usb_wlan_cmd_send(0x99, data, data_size);
}

/*
 * usb_wlan_init
 */
static int usb_wlan_init(void)
{
	unsigned char data[1456], *ptr;
	unsigned int data_size;
	int error;

	/* state 0x1 */

	memset(data, 0, sizeof(data));

	data_size = 0x518;

	error = usb_wlan_cmd_send(0x114f, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x114f (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	/* state 0x2 */

	memset(data, 0, sizeof(data));

	data_size = 0;

	error = usb_wlan_cmd_send(0x1171, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x1171 (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	/* wait for a WLAN event */

	/* state 0x4 */

	memset(data, 0, sizeof(data));

	ptr = data;

	*ptr++ = 0x1;

	data_size = 0x4;

	error = usb_wlan_cmd_send(0x116f, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x116f (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	/* state 0x5 */

	memset(data, 0, sizeof(data));

	ptr = data;

	*ptr++ = 0x1;

	ptr = data + 0x4;
	memcpy(ptr, my_mac_addr, sizeof(my_mac_addr));

	data_size = 0x5e;

	error = usb_wlan_cmd_send(0x115b, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x115b (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	/* state 0x6 */

	memset(data, 0, sizeof(data));

	ptr = data + 0x1c;

	*ptr++ = 0x20;

	data_size = 0x20;

	error = usb_wlan_cmd_send(0x1161, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x1161 (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	memset(data, 0, sizeof(data));

	ptr = data + 0xc;
	memset(ptr, 0xff, 7 * 4);

	data_size = 0x80;

	error = usb_wlan_cmd_send(0x110d, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x110d (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	memset(data, 0, sizeof(data));

	data_size = 0x2;

	error = usb_wlan_cmd_send(0x1031, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x1031 (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	memset(data, 0, sizeof(data));

	ptr = data;
	memcpy(ptr, my_mac_addr, sizeof(my_mac_addr));

	data_size = 0x6;

	error = usb_wlan_cmd_send(0x1041, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x1041 (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	/* state 0xa */

	memset(data, 0, sizeof(data));

	ptr = data;

	*ptr++ = 0x2;
	*ptr++ = 0x2;

	data_size = 0x2;

	error = usb_wlan_cmd_send(0x29, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x29 (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	memset(data, 0, sizeof(data));

	ptr = data;

	*ptr++ = 0x1;

	ptr = data + 8;

	*ptr++ = 0x20;

	data_size = 0xc;

	error = usb_wlan_cmd_send(0x110b, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x110b (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	memset(data, 0, sizeof(data));

	ptr = data;

	*ptr++ = 0x1;

	ptr = data + 0x4;

	*ptr++ = 0x15;
	*ptr++ = 0x27;

	*ptr++ = 0x12;
	*ptr++ = 0x0;

	*ptr++ = 0x6;
	*ptr++ = 0x0;

	ptr = data + 0xc;

	*ptr++ = 0x9;
	*ptr++ = 0x0;
	*ptr++ = 0x1;

	ptr = data + 0x10;

	*ptr++ = 0xff;
	*ptr++ = 0xff;
	*ptr++ = 0xff;
	*ptr++ = 0xff;
	*ptr++ = 0xff;
	*ptr++ = 0xff;

	data_size = 0x16;

	error = usb_wlan_cmd_send(0x1109, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x1109 (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	memset(data, 0, sizeof(data));

	ptr = data;

	*ptr++ = 0x1;

	data_size = 0x4;

	error = usb_wlan_cmd_send(0x207, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x207 (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	memset(data, 0, sizeof(data));

	ptr = data;

	*ptr++ = 0x4;

	data_size = 0x4;

	error = usb_wlan_cmd_send(0x203, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x203 (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	/* state 0xf */

	memset(data, 0, sizeof(data));

	ptr = data;

	*ptr++ = 0xff;
	*ptr++ = 0x1f;

	memcpy(ptr, my_mac_addr, sizeof(my_mac_addr));

	ptr = data + 0x8;

	*ptr++ = 0x2;
	*ptr++ = 0x2;

	data_size = 0xa;

	error = usb_wlan_cmd_send(0x105f, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x105f (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	return 0;
}

/*
 * usb_wlan_cmd_thread
 */
static void *usb_wlan_cmd_thread(void *arg)
{
	int error;

	error = usb_wlan_init();
	if (error) {
		fprintf(stderr, "%s:%d: could not initialize device (%d)\n",
			__func__, __LINE__, error);
		goto done;
	}

	sleep(5);

	error = usb_wlan_cmd_0x99();
	if (error) {
		fprintf(stderr, "%s:%d: could not start scanning (%d)\n",
			__func__, __LINE__, error);
		goto done;
	}

	error = usb_wlan_cmd_start_scan();
	if (error) {
		fprintf(stderr, "%s:%d: could not start scanning (%d)\n",
			__func__, __LINE__, error);
		goto done;
	}

	sleep(10);

	error = usb_wlan_cmd_get_scan_results();
	if (error) {
		fprintf(stderr, "%s:%d: could not get scan results (%d)\n",
			__func__, __LINE__, error);
		goto done;
	}

	sleep(10);

done:

	usb_wlan_cmd_thread_done = 1;

	return NULL;
}

/*
 * main
 */
int main(int argc, char **argv)
{
	unsigned char buf[256];
	pthread_t tid;
	struct timeval tv;
	int error;

	pthread_mutex_init(&usb_wlan_cmd_mutex, NULL);
	pthread_cond_init(&usb_wlan_cmd_cond, NULL);

	error = libusb_init(&usb_ctx);
	if (error) {
		fprintf(stderr, "%s:%d: libusb_init failed (%d)\n", __func__, __LINE__, error);
		exit(1);
	}

	libusb_set_debug(usb_ctx, 5);

	usb_dev_handle = libusb_open_device_with_vid_pid(usb_ctx, USB_VENDOR_ID, USB_PRODUCT_ID);
	if (!usb_dev_handle) {
		fprintf(stderr, "%s:%d: could not open device\n", __func__, __LINE__);
		exit(1);
	}

	if(libusb_kernel_driver_active(usb_dev_handle, USB_IFACE_NUMBER)) {
		fprintf(stdout, "%s:%d: kernel driver is attached\n", __func__, __LINE__);

		error = libusb_detach_kernel_driver(usb_dev_handle, USB_IFACE_NUMBER);
		if (error) {
			fprintf(stderr, "%s:%d: could not detach kernel driver (%d)\n",
				__func__, __LINE__, error);
			exit(1);
		}

		fprintf(stdout, "%s:%d: kernel driver dettached\n", __func__, __LINE__);
	}

	error = libusb_claim_interface(usb_dev_handle, USB_IFACE_NUMBER);
	if (error) {
		fprintf(stderr, "%s:%d: could not claim interface (%d)\n",
			__func__, __LINE__, error);
		exit(1);
	}

	error = libusb_control_transfer(usb_dev_handle, 0x40, 0x1, 0x9, 0x0,
		usb_magic_data, sizeof(usb_magic_data), 0);
	if (error < 0) {
		fprintf(stderr, "%s:%d: could not do control transfer (%d)\n",
			__func__, __LINE__, error);
		exit(1);
	}

	fprintf(stdout, "%s:%d: number of bytes transferred (%d)\n", __func__, __LINE__, error);

	error = libusb_control_transfer(usb_dev_handle, 0xc0, 0x0, 0x2, 0x0, buf, 2, 0);
	if (error < 0) {
		fprintf(stderr, "%s:%d: could not do control transfer (%d)\n",
			__func__, __LINE__, error);
		exit(1);
	}

	fprintf(stdout, "%s:%d: number of bytes received (%d)\n", __func__, __LINE__, error);

	fprintf(stdout, "%s:%d: 0x%02x 0x%02x\n", __func__, __LINE__, buf[0], buf[1]);

	usb_intr_transfer_ep5_in = libusb_alloc_transfer(0);
	if (!usb_intr_transfer_ep5_in) {
		fprintf(stderr, "%s:%d: could not allocate transfer\n", __func__, __LINE__);
		exit(1);
	}

	memset(usb_intr_transfer_ep5_in_buf, 0, sizeof(usb_intr_transfer_ep5_in_buf));

	libusb_fill_interrupt_transfer(usb_intr_transfer_ep5_in, usb_dev_handle, LIBUSB_ENDPOINT_IN | 0x5,
		usb_intr_transfer_ep5_in_buf, sizeof(usb_intr_transfer_ep5_in_buf),
		usb_intr_transfer_ep5_in_cb, NULL, 0);

	error = libusb_submit_transfer(usb_intr_transfer_ep5_in);
	if (error) {
		fprintf(stderr, "%s:%d: could not submit transfer (%d)\n",
			__func__, __LINE__, error);
		exit(1);
	}

	error = pthread_create(&tid, NULL, usb_wlan_cmd_thread, NULL);
	if (error) {
		fprintf(stderr, "%s:%d: could not create WLAN command thread (%d)\n",
			__func__, __LINE__, error);
		exit(1);
	}

	while (!usb_wlan_cmd_thread_done) {
		tv.tv_sec = 1;
		tv.tv_usec = 0;

		error = libusb_handle_events_timeout(usb_ctx, &tv);
		if (error) {
			fprintf(stderr, "%s:%d: could not handle events (%d)\n",
				__func__, __LINE__, error);
			exit(1);
		}
	}

	libusb_free_transfer(usb_intr_transfer_ep5_in);

	error = libusb_release_interface(usb_dev_handle, USB_IFACE_NUMBER);
	if (error)
		fprintf(stderr, "%s:%d: could not release interface (%d)\n",
			__func__, __LINE__, error);

	libusb_close(usb_dev_handle);

	libusb_exit(usb_ctx);

	exit(0);
}

Output

glevand@debian-hdd:~/ps3_usb_wlan$ sudo ./ps3_usb_wlan 
sudo: unable to resolve host debian-hdd
main:824: number of bytes transferred (32)
main:833: number of bytes received (2)
main:835: 0x20 0x31
usb_wlan_cmd_send:288: sending command (0x114f) data size (0x0518) command size (0x0524)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (36)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x1150)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0006)
usb_handle_wlan_cmd_response:205: ==> command status != 0x1
usb_handle_wlan_cmd_response:207: payload_size (0x0000)
usb_handle_wlan_cmd_response:210: command payload:
usb_wlan_cmd_send:288: sending command (0x1171) data size (0x0000) command size (0x000c)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (36)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x1172)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0000)
usb_handle_wlan_cmd_response:210: command payload:
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (68)
usb_handle_wlan_event:133: === got WLAN event ===
usb_handle_wlan_event:144: event_count (0x01)
00000000: 00 04 00 00 10 00 00 00 3c 22 02 00 00 00 00 00 |........<"......|
00000010: fc 90 02 c0 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020: 13 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 |... ............|
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
usb_wlan_cmd_send:288: sending command (0x116f) data size (0x0004) command size (0x0010)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (36)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x1170)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0000)
usb_handle_wlan_cmd_response:210: command payload:
usb_wlan_cmd_send:288: sending command (0x115b) data size (0x005e) command size (0x006a)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (36)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x115c)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0000)
usb_handle_wlan_cmd_response:210: command payload:
usb_wlan_cmd_send:288: sending command (0x1161) data size (0x0020) command size (0x002c)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (36)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x1162)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0000)
usb_handle_wlan_cmd_response:210: command payload:
usb_wlan_cmd_send:288: sending command (0x110d) data size (0x0080) command size (0x008c)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (36)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x110e)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0000)
usb_handle_wlan_cmd_response:210: command payload:
usb_wlan_cmd_send:288: sending command (0x1031) data size (0x0002) command size (0x000e)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (38)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x1032)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0002)
usb_handle_wlan_cmd_response:210: command payload:
00000000: 00 00                                           |..              |
usb_wlan_cmd_send:288: sending command (0x1041) data size (0x0006) command size (0x0012)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (42)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x1042)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0006)
usb_handle_wlan_cmd_response:210: command payload:
00000000: 00 11 22 33 44 55                               |.."3DU          |
usb_wlan_cmd_send:288: sending command (0x0029) data size (0x0002) command size (0x000e)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (38)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x002a)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0002)
usb_handle_wlan_cmd_response:210: command payload:
00000000: 02 02                                           |..              |
usb_wlan_cmd_send:288: sending command (0x110b) data size (0x000c) command size (0x0018)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (48)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x110c)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x000c)
usb_handle_wlan_cmd_response:210: command payload:
00000000: 01 00 00 00 00 00 00 00 20 00 00 00             |........ ...    |
usb_wlan_cmd_send:288: sending command (0x1109) data size (0x0016) command size (0x0022)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (58)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x110a)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0016)
usb_handle_wlan_cmd_response:210: command payload:
00000000: 01 00 00 00 15 27 12 00 06 00 00 00 09 00 01 00 |.....'..........|
00000010: ff ff ff ff ff ff                               |......          |
usb_wlan_cmd_send:288: sending command (0x0207) data size (0x0004) command size (0x0010)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (40)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x0208)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0004)
usb_handle_wlan_cmd_response:210: command payload:
00000000: 01 00 00 00                                     |....            |
usb_wlan_cmd_send:288: sending command (0x0203) data size (0x0004) command size (0x0010)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (40)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x0204)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0004)
usb_handle_wlan_cmd_response:210: command payload:
00000000: 04 00 00 00                                     |....            |
usb_wlan_cmd_send:288: sending command (0x105f) data size (0x000a) command size (0x0016)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (36)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x1060)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0000)
usb_handle_wlan_cmd_response:210: command payload:
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (68)
usb_handle_wlan_event:133: === got WLAN event ===
usb_handle_wlan_event:144: event_count (0x01)
00000000: 80 00 00 00 00 10 00 00 9e 2b 02 00 04 00 00 00 |.........+......|
00000010: fc 90 02 c0 01 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020: 13 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 |... ............|
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
usb_wlan_cmd_send:288: sending command (0x0099) data size (0x003e) command size (0x004a)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (98)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x009a)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x003e)
usb_handle_wlan_cmd_response:210: command payload:
00000000: 4a 55 50 49 54 45 52 2d 54 57 4f 2d 46 57 2d 32 |JUPITER-TWO-FW-2|
00000010: 30 2e 30 2e 31 32 2e 70 30 28 4a 61 6e 20 31 39 |0.0.12.p0(Jan 19|
00000020: 20 32 30 31 30 20 32 31 3a 32 30 3a 35 33 29 00 | 2010 21:20:53).|
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00       |..............  |
usb_wlan_cmd_send:288: sending command (0x1035) data size (0x0019) command size (0x0025)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (61)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x1036)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0019)
usb_handle_wlan_cmd_response:210: command payload:
00000000: 00 01 64 00 00 00 00 00 00 00 03 0d 01 02 03 04 |..d.............|
00000010: 05 06 07 08 09 0a 0b 0c 0d                      |.........       |
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (68)
usb_handle_wlan_event:133: === got WLAN event ===
usb_handle_wlan_event:144: event_count (0x01)
00000000: 80 00 00 00 04 00 00 00 96 2e 02 00 01 00 00 00 |................|
00000010: fc 90 02 c0 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020: 13 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 |... ............|
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
usb_wlan_cmd_send:288: sending command (0x1033) data size (0x05b0) command size (0x05bc)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (1403)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x1034)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0557)
usb_handle_wlan_cmd_response:210: command payload:
...
Here is scan output (removed by me)
...

Associate with AP

How to Associate with WPA AP

Packet Reception

Test with libusb

usb_bulk_transfer_ep6_in_cb:318: === got data transfer ===
usb_bulk_transfer_ep6_in_cb:321: transfer status (0) length (98)
00000000: ff ff ff ff ff ff ?? ?? ?? ?? ?? ?? 08 00 45 00 |..............E.|
00000010: 00 54 00 00 40 00 40 01 b5 fe c0 a8 01 5b c0 a8 |.T..@.@......[..|
00000020: 01 ff 08 00 9c 69 0d 45 00 e2 4e 5d 34 26 00 07 |.....i.E..N]4&..|
00000030: df e1 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 |................|
00000040: 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 |.......... !"#$%|
00000050: 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 |&'()*+,-./012345|
00000060: 36 37                                           |67              |
usb_bulk_transfer_ep6_in_cb:318: === got data transfer ===
usb_bulk_transfer_ep6_in_cb:321: transfer status (0) length (16)
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 |................|
usb_bulk_transfer_ep6_in_cb:318: === got data transfer ===
usb_bulk_transfer_ep6_in_cb:321: transfer status (0) length (16)
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 |................|
usb_bulk_transfer_ep6_in_cb:318: === got data transfer ===
usb_bulk_transfer_ep6_in_cb:321: transfer status (0) length (16)
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 00 |................|

Multicast Address Filter

MAC Address Hash Function
unsigned char hash(unsigned char *data, unsigned int size)
{
        unsigned int hash;
        int i, j;

        /*XXX: reverse data bits */

        hash = 0xffffffff;

        for (i = 0; i < size; i++) {
                hash = (((unsigned int) data[i]) << 24) ^ hash;

                for (j = 0; j < 8; j++) {
                        if (((int) hash) >= 0) {
                                hash = hash << 1;
                        } else {
                                hash = (hash << 1) ^ 0x04c10000;
                                hash = hash ^ 0x00001db7;
                        }
                }
        }

        hash = ((hash >> 24) & 0xf8) | (hash & 0x7);

        return hash & 0xff;
}

h = hash(mac_addr, 6);
v = 1 << (h & 0x1f);    /* word value in filter */
p = h >> 5;             /* word position in filter */


For broadcast address:
------------------------

v = 0x20000000
p = 7

That's why 0x20 is used with command 0x1161 !!! Without it the device won't deliver broadcast traffic.
Learned it the hard way, after 2 days of trying to get packet reception working :)

Packet Transmission

AP Mode

AP Mode with Security Disabled

Test:

[glevand@arch ps3_jupiter_libusb]$ sudo ./ps3_jupiter_ap
EURUS command 0x114f status (0x0006)
got event (0x00000400 0x00000010 0x00023968 0x00000000 0xc00290fc)
got event (0x00000080 0x00001000 0x0002396b 0x00000004 0xc00290fc)
firmware version: JUPITER-TWO-FW-20.0.12.p0(Jan 19 2010 21:20:53)
got event (0x00000100 0x00000010 0x0002396d 0x00000001 0xc00290fc)

got event (0x00000008 0x00000010 0x00023d80 0x00000008 0xc00290fc)
RX transfer completed with length 42
RX transfer completed with length 42
RX transfer completed with length 42
RX transfer completed with length 42
RX transfer completed with length 42
RX transfer completed with length 42
RX transfer completed with length 42
RX transfer completed with length 42  <----------- 42 is length of ARP packet

ps3-jupiter Linux Drivers


Finally, after several weeks of hard programming and reversing, the WLAN driver ps3_jupiter_sta achieved the milestone where i can use it with WPA2 :) I actually use it currently with WPA2 on my PS3 slim. It works damn !!! Try it out and report bugs and problems to me.

TODO

LV2 Network Stack

Network Device

IOCTLs

Set Multicast Address Filter (0x81012000)
Unknown (0x8101200E)
Unknown (0x81040000)
Enable/Disable WOL Magic Packet (0x81080000)
Unknown (0x81080001)
Unknown (0x81080002)
Unknown (0x81080003)
Unknown (0x81080005)

Network Packet

SYSCON

Crossreference: ps3devwiki.com::SYSCON

SYSCON MMIO registers can be accessed on Linux with a driver using lv1_undocumented_function_114, e.g. ps3sbmmio. Use ps3sbmmio device driver carefully, an access at some addresses could shutdown your PS3.

Packet Header

struct sc_hdr {
    uint8_t service_id;
    uint8_t version;              /* must be 1 !!! */
    uint16_t transaction_id;      /* returned in response */
    uint8_t res[2];
    uint16_t cksum;               /* checksum of first 6 header bytes */
    uint32_t index;               /* SYSCON index: 0-4 */
    uint16_t payload_size[2];     /* body size */
};

Sending Packets

uint32_t cksum = 0;

for (i = 0; i < packet_size; i++)
    cksum -= packet[i];

cksum = cksum & 0xffff;
 
value = value + 1;
value &= 0xffff;
value = (value << 16) | value;

Receiving Packets

which gives us the possibility to communicate with SYSCON on Linux easily :)

Test

1. Before sending SYSCON packet:

root@debian-hdd:~# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8cff4)) status=noxfer | hexdump -C

00000000  01 18 01 18                                       |....|
00000004

root@debian-hdd:~# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8dff0)) status=noxfer | hexdump -C

00000000  01 18 01 18                                       |....|
00000004

root@debian-hdd:~# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8cff0)) status=noxfer | hexdump -C

00000000  01 24 01 24                                       |.$.$|
00000004

root@debian-hdd:~# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8dff4)) status=noxfer | hexdump -C

00000000  01 24 01 24                                       |.$.$|
00000004

2. SYSCON packet was sent by using ps3dm_scm read_eprom.

3. After sending SYSCON packet:

root@debian-hdd:~# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8cff4)) status=noxfer | hexdump -C

00000000  01 19 01 19                                       |....|
00000004

root@debian-hdd:~# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8dff0)) status=noxfer | hexdump -C

00000000  01 19 01 19                                       |....|
00000004

root@debian-hdd:~# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8cff0)) status=noxfer | hexdump -C

00000000  01 25 01 25                                       |.%.%|
00000004

root@debian-hdd:~# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8dff4)) status=noxfer | hexdump -C

00000000  01 25 01 25                                       |.%.%|
00000004

4. Received Header

root@debian-hdd:~# dd if=/dev/ps3sbmmio bs=1 count=16 skip=$((0x8c000)) status=noxfer | hexdump -C

00000000  14 01 00 00 00 00 80 15  00 00 00 03 00 05 00 05  |................|
00000010

5. Received Body

root@debian-hdd:~# dd if=/dev/ps3sbmmio bs=1 count=8 skip=$((0x8c010)) status=noxfer | hexdump -C

00000000  00 00 c7 01 ff 00 00 00                           |..Ç.ÿ...|
00000008

Examples

Get RTC

Request:

# write packet

# echo "0: 13 01 0000 0000 8014 00000004 0001 0001 33 00 00 00 0000ff1f" | xxd -c256 -r | \
       dd of=/dev/ps3sbmmio bs=1 seek=$((0x8d000)) status=noxfer

# dump packet counter

# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8dff0)) status=noxfer | hexdump -C

00000000  00 c0 00 c0                                       |.À.À|
00000004

# increment packet counter

echo "0: 00c1 00c1" | xxd -c256 -r | dd of=/dev/ps3sbmmio bs=1 seek=$((0x8dff0)) status=noxfer

# kick packet

# echo "0: 00000001" | xxd -c256 -r | dd of=/dev/ps3sbmmio bs=1 seek=$((0x8e100)) status=noxfer

Response:

# dump packet counter

# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8dff0)) status=noxfer | hexdump -C

00000000  00 c1 00 c1                                       |.Á.Á|
00000004

# dump response packet

# dd if=/dev/ps3sbmmio bs=1 count=24 skip=$((0x8c000)) status=noxfer | hexdump -C

00000000  13 01 00 00 00 00 80 14  00 00 00 04 00 08 00 08  |................|
00000010  00 00 00 00 15 af 47 6b                           |.....¯Gk|
00000018

Ring Buzzer

Request:

# write packet

# echo "0: 16 01 1620 0000 804d 00000001 0008 0008 20 29 0a 00 000001b6 0000fdcb" | xxd -c256 -r | \
       dd of=/dev/ps3sbmmio bs=1 seek=$((0x8d000)) status=noxfer

# dump packet counter

# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8dff0)) status=noxfer | hexdump -C

00000000  00 c0 00 c0                                       |.À.À|
00000004

# increment packet counter

echo "0: 00c1 00c1" | xxd -c256 -r | dd of=/dev/ps3sbmmio bs=1 seek=$((0x8dff0)) status=noxfer

# kick packet

# echo "0: 00000001" | xxd -c256 -r | dd of=/dev/ps3sbmmio bs=1 seek=$((0x8e100)) status=noxfer

# you should hear a beep

Response:

# dump packet counter

# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8dff0)) status=noxfer | hexdump -C

00000000  00 c1 00 c1                                       |.Á.Á|
00000004

# dump response packet

# dd if=/dev/ps3sbmmio bs=1 count=24 skip=$((0x8c000)) status=noxfer | hexdump -C
00000000  16 01 16 20 00 00 80 4d  00 00 00 01 00 01 00 01  |... ...M........|
00000010  00 00 00 00 00 00 fe e3                           |......þã|
00000018

Isolation

Crossreference: ps3devwiki::Isolation

Running Isolated SPE Modules On OtherOS++ Linux

root@debian-hdd:/home/glevand/spp_verifier# cat spp_verifier_355.self > /proc/spp_verifier/spu
root@debian-hdd:/home/glevand/spp_verifier# cat default_355.spp > /proc/spp_verifier/profile
root@debian-hdd:/home/glevand/spp_verifier# echo 1 > /proc/spp_verifier/run
root@debian-hdd:/home/glevand/spp_verifier# cat /proc/spp_verifier/debug 

PPE id (0x0000000000000001) VAS id (0x0000000000000002)
lv1_construct_logical_spe (0x00000000)
SPE id (0x000000000000002b)
lv1_undocumented_function_209 (0x00000000)
shadow execution status (0x0000000000000002)
lv1_get_spe_interrupt_status(1) (0x00000000)
interrupt status 1 (0x0000000000000000)
sleep
shadow execution status (0x0000000000000002)
lv1_get_spe_interrupt_status(1) (0x00000000)
interrupt status 1 (0x0000000000000001)
ea (0xc000000002920000) esid (0xc000000008000000) vsid (0x0000408f92c94500)
lv1_undocumented_function_62 (0x00000000)
lv1_clear_spe_interrupt_status(1) (0x00000000)
lv1_undocumented_function_168 (0x00000000)
sleep
shadow execution status (0x0000000000000007)
lv1_get_spe_interrupt_status(1) (0x00000000)
interrupt status 1 (0x0000000000000000)
lv1_get_spe_interrupt_status(2) (0x00000000)
interrupt status 2 (0x0000000000000000)
out interrupt mbox (0x0000000000000002)
out interrupt mbox (0x0000000000000002)
lv1_undocumented_function_167 (0x00000000)
lv1_clear_spe_interrupt_status (0x00000000)
lv1_undocumented_function_200 (0x00000000)
sleep
shadow execution status (0x000000000000000b)
lv1_get_spe_interrupt_status(1) (0x00000000)
interrupt status 1 (0x0000000000000000)
shadow execution status (0x000000000000000b)
problem status (0x01000082)
lv1_destruct_logical_spe (0x00000000)

root@debian-hdd:/home/glevand/spp_verifier# hexdump -C /proc/spp_verifier/profile | less
...
...
00000200  00 02 00 05 00 00 20 a0  00 00 00 01 00 03 00 00  |......  ........|
00000210  00 00 00 00 00 00 00 01  00 00 00 0e 00 00 00 00  |................|
00000220  00 00 02 88 00 00 00 01  10 70 00 00 01 00 00 01  |.........p......|
00000230  00 00 00 00 00 00 00 00  53 43 45 5f 43 45 4c 4c  |........SCE_CELL|
00000240  4f 53 5f 50 4d 45 00 00  00 00 00 00 00 00 00 00  |OS_PME..........|
00000250  00 00 00 00 00 00 00 00  00 00 00 06 00 00 02 50  |...............P|
00000260  10 70 00 00 01 00 00 01  2f 66 6c 68 2f 6f 73 2f  |.p....../flh/os/|
00000270  74 68 69 73 5f 69 73 5f  64 75 6d 6d 79 00 00 00  |this_is_dummy...|
00000280  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
...
...

Using metldr On OtherOS++ Linux

root@debian-hdd:/home/glevand/spp_verifier_direct# insmod ./spp_verifier_direct.ko
root@debian-hdd:/home/glevand/spp_verifier_direct# cat metldr > /proc/spp_verifier_direct/metldr
root@debian-hdd:/home/glevand/spp_verifier_direct# cat isoldr_355 > /proc/spp_verifier_direct/isoldr
root@debian-hdd:/home/glevand/spp_verifier_direct# cat RL_FOR_PROGRAM_355.img > /proc/spp_verifier_direct/rvkprg
root@debian-hdd:/home/glevand/spp_verifier_direct# cat EID0 > /proc/spp_verifier_direct/eid0
root@debian-hdd:/home/glevand/spp_verifier_direct# cat spp_verifier_355.self > /proc/spp_verifier_direct/spu
root@debian-hdd:/home/glevand/spp_verifier_direct# cat default_355.spp > /proc/spp_verifier_direct/profile
root@debian-hdd:/home/glevand/spp_verifier_direct# echo 1 > /proc/spp_verifier_direct/run
root@debian-hdd:/home/glevand/spp_verifier_direct# cat /proc/spp_verifier_direct/debug
 
PPE id (0x0000000000000001) VAS id (0x0000000000000002)
lv1_construct_logical_spe (0x00000000)
SPE id (0x0000000000000033)
lv1_enable_logical_spe (0x00000000)
lv1_set_spe_interrupt_mask(0) (0x00000000)
lv1_set_spe_interrupt_mask(1) (0x00000000)
lv1_set_spe_interrupt_mask(2) (0x00000000)
lv1_set_spe_privilege_state_area_1_register (0x00000000)
ea (0xc000000002680000) esid (0xc000000008000000) vsid (0x0000408f92c94500)
lv1_get_spe_interrupt_status(0) (0x00000000)
lv1_get_spe_interrupt_status(1) (0x00000000)
lv1_get_spe_interrupt_status(2) (0x00000000)
sleep
lv1_get_spe_interrupt_status(0) (0x00000000)
lv1_get_spe_interrupt_status(1) (0x00000000)
lv1_get_spe_interrupt_status(2) (0x00000000)
out interrupt mbox (0x0000000000000001)
lv1_clear_spe_interrupt_status(2) (0x00000000)
transferring EID0, ldr args and revoke list to LS
waiting until MFC transfers are finished
MFC transfers done
out mbox (0x00000001)
sleep
lv1_get_spe_interrupt_status(0) (0x00000000)
lv1_get_spe_interrupt_status(1) (0x00000000)
lv1_get_spe_interrupt_status(2) (0x00000000)
out interrupt mbox (0x0000000000000002)
lv1_clear_spe_interrupt_status(2) (0x00000000)
out mbox (0x00000002)
lv1_clear_spe_interrupt_status(2) (0x00000000)
sleep
lv1_get_spe_interrupt_status(0) (0x00000000)
lv1_get_spe_interrupt_status(1) (0x00000000)
lv1_get_spe_interrupt_status(2) (0x00000000)
problem status (0x01000082)
lv1_destruct_logical_spe (0x00000000)

root@debian-hdd:/home/glevand/spp_verifier_direct# hexdump -C /proc/spp_verifier_direct/profile | less
...
...
00000200  00 02 00 05 00 00 20 a0  00 00 00 01 00 03 00 00  |......  ........|
00000210  00 00 00 00 00 00 00 01  00 00 00 0e 00 00 00 00  |................|
00000220  00 00 02 88 00 00 00 01  10 70 00 00 01 00 00 01  |.........p......|
00000230  00 00 00 00 00 00 00 00  53 43 45 5f 43 45 4c 4c  |........SCE_CELL|
00000240  4f 53 5f 50 4d 45 00 00  00 00 00 00 00 00 00 00  |OS_PME..........|
00000250  00 00 00 00 00 00 00 00  00 00 00 06 00 00 02 50  |...............P|
00000260  10 70 00 00 01 00 00 01  2f 66 6c 68 2f 6f 73 2f  |.p....../flh/os/|
00000270  74 68 69 73 5f 69 73 5f  64 75 6d 6d 79 00 00 00  |this_is_dummy...|
00000280  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
...
...

RSX

Crossreference: ps3devwiki.com::RSX

HV Calls

lv1_gpu_memory_allocate

<memory handle> = 0x5a5a5a5a xor <memory handle index>

Memory Context Object

offset 0x8 - memory handle (4 bytes)

offset 0x10 - VRAM LPAR start address (8 bytes)

offset 0x18 - VRAM LPAR end address (8 bytes)

Test

Before allocating VRAM:

glevand@debian-hdd:~$ sudo dd if=/dev/ps3ram bs=1 count=$((0x20)) skip=$((0x1f85b0)) | hexdump -C 
00000000  00 00 00 00 00 00 01 ff  00 00 00 00 00 00 00 00  |.......ÿ........|
00000010  00 00 00 00 00 00 00 00  c0 00 00 00 00 00 00 00  |........À.......|

After allocating 32 MB VRAM:

glevand@debian-hdd:~$ sudo dd if=/dev/ps3ram bs=1 count=$((0x20)) skip=$((0x1f85b0)) | hexdump -C 
00000000  00 00 01 ff ff ff ff ff  00 00 00 00 00 00 00 00  |...ÿÿÿÿÿ........|
00000010  00 00 00 00 00 00 00 00  c0 00 00 00 00 00 00 00  |........À.......|

lv1_gpu_context_allocate

<context handle> = 0x55555555 xor <context index>

Context Object

offset 0x8 - handle (4 bytes)

offset 0x48 - IO page size, valid range is 4kB, 64KB and 1MB (8 bytes)

Graphic Objects

Dump of graphic objects from VRAM:

glevand@debian-hdd:~/ps3rsx_user$ sudo dd if=/dev/ps3rsxmmio bs=1 count=32 skip=$((0x2050000)) status=noxfer  | hexdump -C
00000000  00 00 00 30 00 00 00 00  01 00 00 00 00 00 00 00  |...0............|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

# 3D object

glevand@debian-hdd:~/ps3rsx_user$ sudo dd if=/dev/ps3rsxmmio bs=1 count=32 skip=$((0x2050020)) status=noxfer  | hexdump -C
00000000  00 00 40 97 00 00 00 00  01 00 00 00 00 00 00 00  |..@.............|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

glevand@debian-hdd:~/ps3rsx_user$ sudo dd if=/dev/ps3rsxmmio bs=1 count=32 skip=$((0x2050040)) status=noxfer  | hexdump -C
00000000  02 00 00 39 00 00 40 00  01 00 40 0e 00 00 40 0d  |...9..@...@...@.|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

glevand@debian-hdd:~/ps3rsx_user$ sudo dd if=/dev/ps3rsxmmio bs=1 count=32 skip=$((0x2050060)) status=noxfer  | hexdump -C
00000000  02 00 00 39 00 00 40 00  01 00 40 0d 00 00 40 0e  |...9..@...@...@.|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 10 00  |................|

glevand@debian-hdd:~/ps3rsx_user$ sudo dd if=/dev/ps3rsxmmio bs=1 count=32 skip=$((0x2050080)) status=noxfer  | hexdump -C
00000000  00 00 30 9e 00 00 40 00  01 00 00 00 00 00 00 00  |..0...@.........|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

glevand@debian-hdd:~/ps3rsx_user$ sudo dd if=/dev/ps3rsxmmio bs=1 count=32 skip=$((0x20500a0)) status=noxfer  | hexdump -C
00000000  00 00 30 62 00 00 40 00  01 00 00 00 00 00 00 00  |..0b..@.........|
00000010  00 00 00 00 00 00 00 00  00 00 00 08 00 00 00 00  |................|

glevand@debian-hdd:~/ps3rsx_user$ sudo dd if=/dev/ps3rsxmmio bs=1 count=32 skip=$((0x20500c0)) status=noxfer  | hexdump -C
00000000  04 98 30 89 34 00 40 00  01 00 40 0e 00 00 00 00  |..0.4.@...@.....|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

glevand@debian-hdd:~/ps3rsx_user$ sudo dd if=/dev/ps3rsxmmio bs=1 count=32 skip=$((0x20500e0)) status=noxfer  | hexdump -C
00000000  04 18 30 8a 34 00 40 00  01 00 00 00 00 00 00 00  |..0.4.@.........|
00000010  00 00 00 00 00 10 00 00  00 00 00 00 00 00 00 00  |................|

glevand@debian-hdd:~/ps3rsx_user$ sudo dd if=/dev/ps3rsxmmio bs=1 count=32 skip=$((0x2050100)) status=noxfer  | hexdump -C
00000000  ca fe ba be 7f ff ff ff  ff fb eb ff ff ff ff ff  |ÊþºŸ.ÿÿÿÿûëÿÿÿÿÿ|
00000010  40 00 00 00 00 00 02 00  00 00 00 00 80 00 20 00  |@............. .|

Flags

0x2 - tells LV1 to use 64KB pages for GART memory mapping else LV1 uses 1MB pages (with patched LV1 4KB pages are possible too)

0x4 - create DMA memory objects 0xFEED0003 and 0xFEED0004

0x20 - create DMA memory object 0xBAD68000

0x400 - create 512MB video RAM IO address space, else 256MB video RAM IO address space

0x800 - set IRQ mask to 0x00000000 else it's set to 0xFFFFFFFF which enables all IRQ types

lv1_gpu_context_iomap

lv1_gpu_context_attribute

Attribute 0x1

FIFO Command Buffer Setup
lv1_gpu_context_attribute(context handle, 0x1, PUT offset, GET offset, REF value, 0x0)

Attribute 0x2

lv1_gpu_context_attribute(context handle, 0x2, 0x0, 0x0, 0x0, 0x0)

Attribute 0x3

lv1_gpu_context_attribute(context handle, 0x3, 0x0, 0x0, 0x0, 0x0)

Attribute 0x100

Attribute 0x101

Set Flip Mode
lv1_gpu_attribute(0x2, 0x1 /* head */, 0x0, 0x0)
lv1_gpu_context_attribute(context handle, 0x101, 0x1 /* head */, sync mode, 0x0, 0x0)

Attribute 0x102

lv1_gpu_context_attribute(context handle, 0x102, head, 0x80000000 | (channel_id << 8) | buffer_id, 0, 0)

Attribute 0x103

lv1_gpu_context_attribute(context handle, 0x103, head, display buffer id, 0x0, 0x0)

Attribute 0x104

* Found a bug in LV1. Setting display buffer returns always LV1_SUCCESS because LV1 discards the return value of function which initialized display buffer.

Snippet from 3.15:

ROM:0021076C                 li      %r31, 0                       <----- BUG !!!
ROM:00210770                 bl      rsx_set_display_buffer
ROM:00210774                 b       loc_210518

It should be:

ROM:0021076C                 bl      rsx_set_display_buffer
ROM:00210770                 mr      %r31, %r3
ROM:00210774                 b       loc_210518
Set Display Buffer
lv1_gpu_context_attribute(context handle, 0x104, id, width << 32 | height, pitch << 32 | offset, 0x0)

Attribute 0x105

lv1_gpu_context_attribute(context handle, 0x105, buffer_id, 0x0, 0x0, 0x0)

Attribute 0x106

Attribute 0x108

Set V Blank Frequency
lv1_gpu_context_attribute(context handle, 0x108, head, mode, 0x1, 0x0)
Set Second V Frequency
lv1_gpu_context_attribute(context handle, 0x108, head, mode, 0x2, 0x0)

Attribute 0x109

Attribute 0x10a

Get Flip Status
Reset Flip Status
lv1_gpu_context_attribute(context handle, 0x10a, 0x1 /* id */, 0x7fffffff /* mask */, 0x0 /* value */, 0x0)

Attribute 0x10b

Initialize Cursor
lv1_gpu_context_attribute(context handle, 0x10b, head, 0x1, 0x0, 0x0)
Set Cursor Image Offset
lv1_gpu_context_attribute(context handle, 0x10b, head, 0x2, offset, 0x0)
Set Cursor Position
lv1_gpu_context_attribute(context handle, 0x10b, head, 0x3, x, y)
???
lv1_gpu_context_attribute(context handle, 0x10b, head, 0x4, ???, 0x0)

Attribute 0x10c

Enable Cursor
lv1_gpu_context_attribute(context handle, 0x10c, head, 0x1, 0x0, 0x0)
Disable Cursor
lv1_gpu_context_attribute(context handle, 0x10c, head, 0x2, 0x0, 0x0)

Attribute 0x201

lv1_gpu_context_attribute(context handle, 0x201, 0x0, 0x0, 0x0, 0x0)

Attribute 0x202

lv1_gpu_context_attribute(context handle, 0x202, 0x0, 0x0, 0x0, 0x0)

Attribute 0x300

Set Tile
Set Invalidate Tile
Bind Tile
Unbind Tile

Attribute 0x301

Set Zcull
Bind Zcull
Unbind Zcull

Attribute 0x600 (L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP)


Here is the FIFO program executed by LV1 during this LV1 call:

0x42000
0x31337303

0x42180
0x66604200

0x82184
0xFEED0001
0xFEED0000

0x44000
0x3137C0DE

0x44180
0x66604200

0x84184
0xFEED0000
0xFEED0001

0x46000
0x313371C3

0x46180
0x66604200

0x46184
0xFEED0000

0x46188
0xFEED0000

0x4A000
0x31337808

0x20A180
0x66604200
0x0
0x0
0x0
0x0
0x0
0x0
0x313371C3

0x8A2FC
0x3
0x4

0x48000
0x31337A73

0x48180
0x66604200

0x48184
0xFEED0000

0x4C000
0x3137AF00

0x4C180
0x66604200

0x0

Attribute 0x601 (L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT)

FIFO commands:

0x0004C184                     # set source location
0xFEED0001                     # GART memory, that's where ps3fb frame buffer is located

0x0004C198
0x313371C3

0x00046300
0x0000000A

h = height
y = 0
bpp = 4
blen = 0x400

while (h)
{
    dy = min(h, blen)

    w = width
    x = 0

    while(w)
    {
        dx = min(w, blen)

        dst = dst offset + (y & ~(blen - 1)) * dst pitch + (x & ~(blen - 1)) * bpp
        src = src offset + y * src pitch + x * bpp

        0x0004630C
        <dst>

        0x00046304
        <dst pitch << 16 | dst pitch>

        0x0024C2FC
        0x00000001
        0x00000003
        0x00000003
        <(x & (blen - 1)) << 16 | y & (blen - 1)>
        <dy << 16 | dx>
        <(x & (blen - 1)) << 16 | y & (blen - 1)>
        <dy << 16 | dx>
        0x00100000
        0x00100000

        if (dx < 0x10)
            tmp = 0x10
        else
            tmp = (dx + 1) & ~0x1

        0x0010C400
        <dy << 16 | tmp>
        <0x00020000 | src pitch>
        <src>
        0x00000000

        w -= dx
        x += dx
    }

    h -= dy
    y += dy
}

0x00040110
0x00000000

Attribute 0x602 (L1GPU_CONTEXT_ATTRIBUTE_FB_WAIT_FOR_IDLE)

Attribute 0x603 (L1GPU_CONTEXT_ATTRIBUTE_FB_DEINIT)

lv1_gpu_attribute

Attribute 0x1

lv1_gpu_attribute(0x1, head, ???, 0x0, 0x0)

Attribute 0x2

lv1_gpu_attribute(0x2, head, ???, 0x0, 0x0)

Attribute 0x3

lv1_gpu_attribute(0x3, head, 0x0, 0x0, 0x0)

Attribute 0x100

lv1_gpu_attribute(0x100, index, value, 0x0, 0x0)

Attribute 0x105

lv1_gpu_attribute(0x105, 0x0, 0x0, 0x0, 0x0)

Attribute 0x202

lv1_gpu_attribute(0x202, head, ???, 0x0, 0x0)

Attribute 0x203

lv1_gpu_attribute(0x203, 0x0, 0x0, 0x0, 0x0)

Attribute 0x204

lv1_gpu_attribute(0x204, param, 0x0, 0x0, 0x0)

Attribute 0x400

lv1_gpu_attribute(0x400, param1, param2, 0x0, 0x0)

Attribute 0x401

lv1_gpu_attribute(0x401, param, 0x0, 0x0, 0x0)

Attribute 0x402

lv1_gpu_attribute(0x402, param, 0x0, 0x0, 0x0)

Attribute 0x403

lv1_gpu_attribute(0x403, 0x0, 0x0, 0x0, 0x0)

Attribute 0x500

lv1_gpu_attribute(0x500, param, 0x0, 0x0, 0x0)

Attribute 0x501

lv1_gpu_attribute(0x501, param, 0x0, 0x0, 0x0)

lv1_gpu_device_map

Device Table

Device ID Physical Start Address Size Description
0x0 0x28000000000 0x2000000 This region can be mapped if RSX debugging is enabled and LPAR1 syscall 0x10088 was not used previously.
0x4 0x28001800000 0x200000 -
0x8 0x2808FF10000 0x1000 Video RAM. This region of video RAM is shared by all RSX contexts.
0x9 0x28000400000 0x8000 -
0xA 0x28000100000 0x1000 -
0xB 0x2800000A000 0x1000 -
0xC 0x28000680000 0x3000 -
0xD 0x28000090000 0x1000 FIFO and FIFO cache. Useful for debugging e.g. to see what commands were processed last by RSX.
0xE 0x28000002000 0x2000 -
0xF 0x28000088000 0x1000 -

Device 0x8

lv1_undocumented_function_222

lv1_undocumented_function_230

Parameter 0x1

Parameter 0x2

Parameter 0x3

Video RAM

RAMHT

RAMHT Entry

offset 0x0 - object handle (4 bytes)
offset 0x4 - (channel id << 23) | (engine type << 20) |  (object offset >> 4) (4 bytes)

engine types: 0x0 - software, 0x1 - graphics

Example

cafebabe 00805022

0xcafebabe - object handle
0x05022 << 4 = 0x050220 - object offset
0x008 >> 3 = 0x1 - channel id

Dump of RAMHT

# dd if=/dev/ps3rsxmmio bs=1 count=$((0x4000)) skip=$((0x2010000)) | hexdump -C

00000000  00 00 00 00 00 10 50 00  00 00 00 00 00 00 00 00  |......P.........|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000400  00 00 00 00 00 90 50 12  00 00 00 00 00 00 00 00  |......P.........|
00000410  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000005d0  00 00 00 00 00 00 00 00  00 00 00 00 7f 90 00 00  |................|
000005e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000980  00 00 00 00 00 00 00 00  31 37 af 00 00 10 50 0c  |........17¯...P.|
00000990  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000d80  00 00 00 00 00 00 00 00  31 37 af 00 00 90 50 1e  |........17¯...P.|
00000d90  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000018a0  56 61 66 61 00 10 40 0b  56 61 66 60 00 10 40 0a  |Vafa..@.Vaf`..@.|
000018b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000019a0  00 00 00 00 00 00 00 00  66 62 66 60 00 90 40 23  |........fbf`..@#|
000019b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00001aa0  66 61 66 61 00 90 40 20  00 00 00 00 00 00 00 00  |fafa..@ ........|
00001ab0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00001ba0  00 00 00 00 00 00 00 00  66 60 66 60 00 90 40 1f  |........f`f`..@.|
00001bb0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00001ca0  56 61 66 61 00 90 40 22  56 61 66 60 00 90 40 21  |Vafa..@"Vaf`..@!|
00001cb0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00001da0  00 00 00 00 00 00 00 00  66 62 66 60 00 10 40 0c  |........fbf`..@.|
00001db0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00001ea0  66 61 66 61 00 10 40 09  00 00 00 00 00 00 00 00  |fafa..@.........|
00001eb0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00001fa0  00 00 00 00 00 00 00 00  66 60 66 60 00 10 40 08  |........f`f`..@.|
00001fb0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000022c0  31 33 7a 73 00 90 50 1a  00 00 00 00 00 00 00 00  |13zs..P.........|
000022d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000026c0  31 33 7a 73 00 10 50 08  00 00 00 00 00 00 00 00  |13zs..P.........|
000026d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00002940  00 00 00 00 00 00 00 00  31 33 73 03 00 90 50 16  |........13s...P.|
00002950  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00002d40  00 00 00 00 00 00 00 00  31 33 73 03 00 10 50 04  |........13s...P.|
00002d50  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00003110  00 00 00 00 00 00 00 00  31 33 78 08 00 90 50 20  |........13x...P |
00003120  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00003150  31 33 70 00 00 90 50 14  00 00 00 00 00 00 00 00  |13p...P.........|
00003160  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00003210  ca fe ba be 00 00 50 10  00 00 00 00 00 00 00 00  |ÊþºŸ..P.........| <-- The famous 0xCAFEBABE sw object of context 0
00003220  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000032d0  fe ed 00 01 00 10 40 0e  fe ed 00 00 00 10 40 0d  |þí....@.þí....@.|
000032e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00003310  31 37 c0 de 00 90 50 18  00 00 00 00 00 00 00 00  |17ÀÞ..P.........|
00003320  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00003510  00 00 00 00 00 00 00 00  31 33 78 08 00 10 50 0e  |........13x...P.|
00003520  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00003550  31 33 70 00 00 10 50 02  00 00 00 00 00 00 00 00  |13p...P.........|
00003560  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000035d0  00 00 00 00 7f 90 00 00  00 00 00 00 00 00 00 00  |................|
*
000035f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00003610  ca fe ba be 00 80 50 22  00 00 00 00 00 00 00 00  |ÊþºŸ..P"........| <-- The famous 0xCAFEBABE sw object of context 1
00003620  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000036c0  00 00 00 00 7f 90 00 00  00 00 00 00 00 00 00 00  |................|
000036d0  fe ed 00 01 00 90 40 25  fe ed 00 00 00 90 40 24  |þí....@%þí....@$|
000036e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000036f0  00 00 00 00 00 00 00 00  00 00 00 00 7f 90 00 00  |................|
00003700  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00003710  31 37 c0 de 00 10 50 06  00 00 00 00 00 00 00 00  |17ÀÞ..P.........|
00003720  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00003880  66 60 42 01 00 90 40 18  66 60 42 00 00 90 40 17  |f`B...@.f`B...@.|
00003890  66 60 42 03 00 90 40 1a  66 60 42 02 00 90 40 19  |f`B...@.f`B...@.|
000038a0  66 60 42 05 00 90 40 1c  66 60 42 04 00 90 40 1b  |f`B...@.f`B...@.|
000038b0  66 60 42 07 00 90 40 1e  66 60 42 06 00 90 40 1d  |f`B...@.f`B...@.|
000038c0  66 60 42 09 00 90 40 2c  66 60 42 08 00 90 40 2d  |f`B...@,f`B...@-|
000038d0  66 60 42 0b 00 90 40 2a  66 60 42 0a 00 90 40 2b  |f`B...@*f`B...@+|
000038e0  66 60 42 0d 00 90 40 28  66 60 42 0c 00 90 40 29  |f`B...@(f`B...@)|
000038f0  66 60 42 0f 00 90 40 26  66 60 42 0e 00 90 40 27  |f`B...@&f`B...@'|
00003900  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00003b40  00 00 00 00 00 00 00 00  31 33 71 c3 00 10 50 0a  |........13qÃ..P.|
00003b50  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00003c80  66 60 42 01 00 10 40 01  66 60 42 00 00 10 40 00  |f`B...@.f`B...@.|
00003c90  66 60 42 03 00 10 40 03  66 60 42 02 00 10 40 02  |f`B...@.f`B...@.|
00003ca0  66 60 42 05 00 10 40 05  66 60 42 04 00 10 40 04  |f`B...@.f`B...@.|
00003cb0  66 60 42 07 00 10 40 07  66 60 42 06 00 10 40 06  |f`B...@.f`B...@.|
00003cc0  66 60 42 09 00 10 40 15  66 60 42 08 00 10 40 16  |f`B...@.f`B...@.|
00003cd0  66 60 42 0b 00 10 40 13  66 60 42 0a 00 10 40 14  |f`B...@.f`B...@.|
00003ce0  66 60 42 0d 00 10 40 11  66 60 42 0c 00 10 40 12  |f`B...@.f`B...@.|
00003cf0  66 60 42 0f 00 10 40 0f  66 60 42 0e 00 10 40 10  |f`B...@.f`B...@.|
00003d00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00003f40  00 00 00 00 00 00 00 00  31 33 71 c3 00 90 50 1c  |........13qÃ..P.|
00003f50  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00004000

RAMIN

Dump of RAMIN

# dd if=/dev/ps3rsxmmio bs=1 count=$((0x1000)) skip=$((0x2050000)) | hexdump -C

00000000  00 00 00 30 00 00 00 00  01 00 00 00 00 00 00 00  |...0............|
00000010  00 00 00 00 ff ff ff ff  ff ff ff ff ff ff ff ff  |....ÿÿÿÿÿÿÿÿÿÿÿÿ|
00000020  00 00 40 97 00 00 00 00  01 00 00 00 00 00 00 00  |..@.............|
00000030  00 00 00 00 7f ff ff ff  ff ff ff ff ff ef ff ff  |.....ÿÿÿÿÿÿÿÿïÿÿ|
00000040  02 00 00 39 00 00 40 00  01 00 40 0e 00 00 40 0d  |...9..@...@...@.|
00000050  00 00 00 00 ff ff ff ff  ff ff ff ff ff ff ff ff  |....ÿÿÿÿÿÿÿÿÿÿÿÿ|
00000060  02 00 00 39 00 00 40 00  01 00 40 0d 00 00 40 0e  |...9..@...@...@.|
00000070  00 00 00 00 ff ff ff ff  ff ff ff ff ff ff ff ff  |....ÿÿÿÿÿÿÿÿÿÿÿÿ|
00000080  00 00 30 9e 00 00 40 00  01 00 00 00 00 00 00 00  |..0...@.........|
00000090  00 00 00 00 ff ff ff ff  ff ff ff ff ff ff ff ff  |....ÿÿÿÿÿÿÿÿÿÿÿÿ|
000000a0  00 00 30 62 00 00 40 00  01 00 00 00 00 00 00 00  |..0b..@.........|
000000b0  00 00 00 00 ff ff ff ff  ff ff ff ff ff ff ff ff  |....ÿÿÿÿÿÿÿÿÿÿÿÿ|
000000c0  04 98 30 89 34 00 40 00  01 00 40 0e 00 00 00 00  |..0.4.@...@.....|
000000d0  00 00 00 00 ff ff ff ff  ff ff ff ff ff ff ff ff  |....ÿÿÿÿÿÿÿÿÿÿÿÿ|
000000e0  04 18 30 8a 34 00 40 00  01 00 00 00 00 00 00 00  |..0.4.@.........|
000000f0  00 00 00 00 ff ff ff ff  fd ff fb 7f ff ff ff ff  |....ÿÿÿÿýÿû.ÿÿÿÿ|
00000100  ca fe ba be ff ff ff ff  ff ff ff ff ff ff ff ff  |ÊþºŸÿÿÿÿÿÿÿÿÿÿÿÿ|
00000110  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ|
00000120  00 00 00 30 00 00 00 00  01 00 00 00 00 00 00 00  |...0............|
00000130  00 00 00 00 ff ff ff ff  fd ff ff ff f3 ff ff ef  |....ÿÿÿÿýÿÿÿóÿÿï|
00000140  00 00 40 97 00 00 00 00  01 00 00 00 00 00 00 00  |..@.............|
00000150  00 00 00 00 fe ff fe ff  ff ff ff 7f ff ff ff ff  |....þÿþÿÿÿÿ.ÿÿÿÿ|
00000160  02 00 00 39 00 00 00 00  01 00 00 00 00 00 00 00  |...9............|
00000170  00 00 00 00 ff ff ff ff  ff ff ff ff ff ff ff ff  |....ÿÿÿÿÿÿÿÿÿÿÿÿ|
00000180  02 00 00 39 00 00 00 00  01 00 00 00 00 00 00 00  |...9............|
00000190  00 00 00 00 ff ff ff ff  ff ff ff ff ff ff ff df  |....ÿÿÿÿÿÿÿÿÿÿÿß|
000001a0  00 00 30 9e 00 00 00 00  01 00 00 00 00 00 00 00  |..0.............|
000001b0  00 00 00 00 ff ff ff ff  ff ff ff ff ff ff ff ff  |....ÿÿÿÿÿÿÿÿÿÿÿÿ|
000001c0  00 00 30 62 00 00 00 00  01 00 00 00 00 00 00 00  |..0b............|
000001d0  00 00 00 00 ff ff ff ff  ff ff fe ff f7 ff ff ff  |....ÿÿÿÿÿÿþÿ÷ÿÿÿ|
000001e0  00 00 30 89 18 00 00 00  01 00 00 00 00 00 00 00  |..0.............|
000001f0  00 00 00 00 ff ff ff ff  ff ff ff ff ff ff ff ff  |....ÿÿÿÿÿÿÿÿÿÿÿÿ|
00000200  00 00 30 8a 18 00 00 00  01 00 00 00 00 00 00 00  |..0.............|
00000210  00 00 00 00 ff ff ff ff  ff ff ff ff ff ff ff ff  |....ÿÿÿÿÿÿÿÿÿÿÿÿ|
00000220  ca fe ba be ff ff ff ff  ff ff ff ff ff ff ff ff  |ÊþºŸÿÿÿÿÿÿÿÿÿÿÿÿ|
00000230  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ|
*

lpar_dma_control

Example:


# RSX channel 0

# sudo dd if=/dev/ps3rsxmmio bs=1 count=$((0x1000)) skip=$((0xC00000)) | hexdump -C
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000040  0d 00 00 b8 0d 00 00 b8  00 00 00 00 00 00 00 00  |...ž...ž........|
00000050  00 00 00 00 0d 00 00 b8  00 00 00 00 00 00 00 00  |.......ž........|
00000060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

# RSX channel 1

# sudo dd if=/dev/ps3rsxmmio bs=1 count=$((0x1000)) skip=$((0xC01000)) | hexdump -C
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000040  01 00 00 00 01 00 00 00  00 00 00 00 00 00 00 00  |................|
00000050  00 00 00 00 01 00 00 00  00 00 00 00 00 00 00 00  |................|
00000060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

lpar_driver_info

lpar_reports

Semaphore Area

Flipping

Notify Area

Display Buffer

Calculating DMA Object Handle

const uin32_t disp_buf_id_to_handle[] = {
    0xDAC10000,
    0xDAC20000,
    0xDAC30000,
    0xDAC03000,
    0xDAC04000,
    0xDAC50000,
    0xDAC06000,
    0xDAC70000,
};

<display buffer handle> = disp_buf_id_to_handle[buffer_id] | (buffer_id << 4) | <channel_id>

Graphics Objects

0×31337000

0x66604200-0x66604208

0x66626660

0x66606660

0x66616661

0x56616660

0x56616661

0xFEED0000

0xFEED0001

0xCAFE000F

0xCAFEBABE

Here is the proof of working 0xCAFEBABE object on Linux (FW 3.55):

ROM:0035AD20                 .quad 0x3AFFB0          # 0
ROM:0035AD20                 .quad 0x1E8B60          # 1
ROM:0035AD20                 .quad 0                 # 2
ROM:0035AD38                 .quad 0                 # 0
ROM:0035AD38                 .quad 0                 # 1
ROM:0035AD38                 .quad 0                 # 2
ROM:0035AD38                 .quad 0                 # 3
ROM:0035AD38                 .quad 0                 # 4
ROM:0035AD38                 .quad 0                 # 5
ROM:0035AD38                 .quad 0                 # 6
ROM:0035AD38                 .quad 0                 # 7
ROM:0035AD78                 .quad 0                 # 0
ROM:0035AD78                 .quad 0                 # 1
ROM:0035AD78                 .quad 0                 # 2
ROM:0035AD78                 .quad 0                 # 3
ROM:0035AD78                 .quad 0                 # 4
ROM:0035AD78                 .quad 0                 # 5
ROM:0035AD78                 .quad 0                 # 6
ROM:0035AD78                 .quad 0x3AFFB0          # 7         <-------- 0xCAFEBABE object bound to subchannel 7 of context 1
ROM:0035ADB8                 .quad 0                 # 0
ROM:0035ADB8                 .quad 0                 # 1
ROM:0035ADB8                 .quad 0                 # 2
ROM:0035ADB8                 .quad 0                 # 3
ROM:0035ADB8                 .quad 0                 # 4
ROM:0035ADB8                 .quad 0                 # 5
ROM:0035ADB8                 .quad 0                 # 6
ROM:0035ADB8                 .quad 0                 # 7

ROM:003AFFB0                 .long 0
ROM:003AFFB4                 .long 0xCAFEBABE
ROM:003AFFB8                 .quad 0x324970
ROM:003AFFC0                 .quad 0x28002050100
ROM:0035AD20                 .quad 0x3AFFB0          # 0
ROM:0035AD20                 .quad 0x1E8B60          # 1
ROM:0035AD20                 .quad 0                 # 2
ROM:0035AD78                 .quad 0                 # 6
ROM:0035AD78                 .quad 0x3AFFB0          # 7         <-------- 0xCAFEBABE object bound to subchannel 7 of context 1
ROM:0035ADB8                 .quad 0                 # 0

Methods

0x920
0x924
0x940 + head << 2
0xB00
0xB04

Interrupt Handling

IRQ Bits

(1 << 11)         second v-sync head 1
(1 << 10)         second v-sync head 0
(1 << 8)          ??? - LV1 dispatches this interrupt too but for what reason no clue
(1 << 7)          user (0xcafebabe sw object methods 0xb00 and 0xb04)
(1 << 6)          queue head 1 (RSX read flip command for head 1)
(1 << 5)          queue head 0 (RSX read flip command for head 0)
(1 << 4)          flip head 1 (head 1 was flipped)
(1 << 3)          flip head 0 (head 0 was flipped)
(1 << 2)          graphics exception
(1 << 1)          v-sync head 1
(1 << 0)          v-sync head 0

Graphics Exception

ps3fb ioc0_01: ps3fb_vsync_interrupt: graphics exception
ps3rsx_intr:291: interrupt status 0x00000004

Cause

ID Description
0x1 FIFO parser error. Unsupported or invalid command was encountered by FIFO.
0x3 Flip preparation error.
0x102 RSX tried to fetch vertices from invalid address.
0x103 VRAM texture fetch protection fault.
0x104 GART memory texture fetch protection fault.
0x105 Invalid graphics state. Illegal combination of graphics settings.
0x106 Invalid graphics command data. Illegal parameters.
0x107 Invalid DMA write address.
0x108 Invalid DMA read address.
0x109 Undefined graphics error.

Exception Information

Fields
Offset (in lpar_driver_info) Size (bytes) Description
0x12F0 4 Channel ID of the RSX context which caused the exception.
0x12F4 4 Exception cause.
0x12F8 4  ???
0x12FC 4  ???
0x1318 4 DMA PUT.
0x131C 4 DMA GET.
0x132C 4 FIFO PUT.
0x1330 4 FIFO GET.
Example
ps3fb ioc0_01: ps3fb_vsync_interrupt: graphics exception
ps3fb ioc0_01: channel id 0x00000001 cause 0x00000001
ps3fb ioc0_01: fifo:
ps3fb ioc0_01:       call 0x00002644 jump 0x00002644
ps3fb ioc0_01:       get 0x000000aa put 0x0000018e
ps3fb ioc0_01:           [000] 00000060:56616661 00000064:00000030 0000006c:00000001 00000060:66616661
ps3fb ioc0_01:           [004] 0000019c:feed0000 000001a0:feed0001 000001a4:66606660 000001a8:66626660
ps3fb ioc0_01:           [008] 0000021c:00000040 00000220:00000001 00000224:00000080 00000228:00000100
ps3fb ioc0_01:           [00c] 000002cc:0fff0000 000002d0:0fff0000 000002d4:0fff0000 000002d8:0fff0000
ps3fb ioc0_01:           [010] 000003b0:00100000 00001454:00000000 00001ff4:003fffff 00001fc0:00000000
ps3fb ioc0_01:           [014] 00000b5c:00000000 00000b60:00000000 00000b64:00000000 00000a0c:00000000
ps3fb ioc0_01:           [018] 00000b00:00002dc8 00000b04:00002dc8 00000b08:00002dc8 00000b0c:00002dc8
ps3fb ioc0_01:           [01c] 000008cc:00000800 000008d0:00000000 000008d4:00000000 000008d8:00000000
ps3fb ioc0_01:           [020] 000003e0:00010101 000003e4:00010101 000003e8:00010101 000003ec:00010101
ps3fb ioc0_01:           [024] 00000420:00007421 00000424:00007421 00000428:00007421 0000042c:00007421
ps3fb ioc0_01:           [028] 00000460:56676654 00000464:33333345 00000468:54333333 0000046c:45667665
ps3fb ioc0_01:           [02c] 00000358:000000ff 0000034c:000000ff 0000035c:00001e00 00000360:00001e00
ps3fb ioc0_01:           [030] 0000183c:00000000 00001830:00000405 00000384:00000000 00000388:3f800000
ps3fb ioc0_01:           [034] 00000a68:00000000 00000a78:00000000 00000a7c:00000000 00001dac:00000000
ps3fb ioc0_01:           [038] 00001a08:00030101 00001a1c:00000000 00001a0c:00060000 00001a14:02052000
ps3fb ioc0_01:           [03c] 00001a88:00030101 00001a9c:00000000 00001a8c:00060000 00001a94:02052000
ps3fb ioc0_01:           [040] 00001b08:00030101 00001b1c:00000000 00001b0c:00060000 00001b14:02052000
ps3fb ioc0_01:           [044] 00001b88:00030101 00001b9c:00000000 00001b8c:00060000 00001b94:02052000
ps3fb ioc0_01:           [048] 00000348:00000000 00001740:00000002 00001680:00000000 00001744:00000002
ps3fb ioc0_01:           [04c] 0000169c:00000000 00001760:00000002 000016a0:00000000 00001764:00000002
ps3fb ioc0_01:           [050] 000016bc:00000000 00000a00:10000000 00000a04:10000000 00000394:00000000
ps3fb ioc0_01:           [054] 00000a2c:00000000 00000a30:45000000 00000a34:45000000 00000a38:3f000000
ps3fb ioc0_01:           [058] 00001e98:01000000 00001478:00000000 00001ff0:0000ffff 000017cc:00000000
ps3fb ioc0_01:           [05c] 00000968:00000101 0000097c:00000000 0000096c:00060000 00000974:00000000
ps3fb ioc0_01:           [060] 0000a184:00000000 0000a188:00000000 0000a18c:00000000 0000a190:00000000
ps3fb ioc0_01:           [064] 0000c31c:00100000 0000c400:03c40298 0000c404:00021a80 0000c408:0d011000
ps3fb ioc0_01:           [068] 0000c314:03c40400 0000c318:00100000 0000c31c:00100000 0000c400:03c40400
ps3fb ioc0_01:           [06c] 0000c318:00100000 0000c31c:00100000 0000c400:03c40298 0000c404:00021a80
ps3fb ioc0_01:           [070] 0000c310:00000000 0000c314:03c40400 0000c318:00100000 0000c31c:00100000
ps3fb ioc0_01:           [074] 0000c314:03c40298 0000c318:00100000 0000c31c:00100000 0000c400:03c40298
ps3fb ioc0_01:           [078] 0000c30c:03c40400 0000c310:00000000 0000c314:03c40400 0000c318:00100000
ps3fb ioc0_01:           [07c] 0000c310:00000000 0000c314:03c40298 0000c318:00100000 0000c31c:00100000
ps3fb ioc0_01:           [080] 56616661:00000000 00000030:66604200 00000001:00000000 66616661:00000000
ps3fb ioc0_01:           [084] feed0000:00900000 feed0001:00000000 66606660:00000000 66626660:00000000
ps3fb ioc0_01:           [088] 00000040:01ffffc0 00000001:00000000 00000080:00000000 00000100:00000000
ps3fb ioc0_01:           [08c] 0fff0000:00000000 0fff0000:46400000 0fff0000:ffff0000 0fff0000:00000008
ps3fb ioc0_01:           [090] 00100000:00000000 00000000:005aaae4 003fffff:00100008 00000000:01012000
ps3fb ioc0_01:           [094] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [098] 00002dc8:00000000 00002dc8:00000000 00002dc8:00000000 00002dc8:00000000
ps3fb ioc0_01:           [09c] 00000800:98766666 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [0a0] 00010101:00000000 00010101:00000111 00010101:00000f11 00010101:89aabaa9
ps3fb ioc0_01:           [0a4] 00007421:00018488 00007421:00428a02 00007421:00080008 00007421:00000000
ps3fb ioc0_01:         G [0a8] 56676654:005aaae4 33333345:00100008 54333333:01012000 45667665:00018488
ps3fb ioc0_01:           [0ac] 000000ff:00000000 000000ff:00000000 00001e00:00000000 00001e00:005aaae4
ps3fb ioc0_01:           [0b0] 00000000:00000000 00000405:00000000 00000000:00000000 3f800000:00000000
ps3fb ioc0_01:           [0b4] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [0b8] 00030101:00000111 00000000:00000f11 00060000:56676654 02052000:00000000
ps3fb ioc0_01:           [0bc] 00030101:00428a02 00000000:00080008 00060000:00000000 02052000:00000111
ps3fb ioc0_01:           [0c0] 00030101:00100008 00000000:01012000 00060000:00018488 02052000:00428a02
ps3fb ioc0_01:           [0c4] 00030101:00000000 00000000:00000000 00060000:005aaae4 02052000:00100008
ps3fb ioc0_01:           [0c8] 00000000:00000000 00000002:00000000 00000000:edcba987 00000002:00000000
ps3fb ioc0_01:           [0cc] 00000000:00000000 00000002:00000000 00000000:00000000 00000002:00000000
ps3fb ioc0_01:           [0d0] 00000000:00000f11 10000000:66667899 10000000:00000000 00000000:00000000
ps3fb ioc0_01:           [0d4] 00000000:00080008 45000000:00000000 45000000:00000111 3f000000:00000f11
ps3fb ioc0_01:           [0d8] 01000000:01012000 00000000:00018488 0000ffff:00428a02 00000000:00080008
ps3fb ioc0_01:           [0dc] 00000101:00000000 00000000:00000000 00060000:00000000 00000000:00000000
ps3fb ioc0_01:           [0e0] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [0e4] 00100000:00000000 03c40298:00000000 00021a80:00000000 0d011000:00000001
ps3fb ioc0_01:           [0e8] 03c40400:00000000 00100000:40100000 00100000:00000000 03c40400:00000000
ps3fb ioc0_01:           [0ec] 00100000:00000000 00100000:00000000 03c40298:00000000 00021a80:00000000
ps3fb ioc0_01:           [0f0] 00000000:00000000 03c40400:00000000 00100000:00000000 00100000:00000000
ps3fb ioc0_01:           [0f4] 03c40298:ffffffff 00100000:00000000 00100000:00000000 03c40298:00000000
ps3fb ioc0_01:           [0f8] 03c40400:00000000 00000000:00000000 03c40400:00000000 00100000:00000000
ps3fb ioc0_01:           [0fc] 00000000:00000000 03c40298:00000000 00100000:0001bc80 00100000:00000202
ps3fb ioc0_01:           [100] 00000000:00000000 66604200:00000008 00000000:00000000 00000000:00080008
ps3fb ioc0_01:           [104] 00900000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [108] 01ffffc0:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [10c] 00000000:00000000 46400000:00000000 ffff0000:00000000 00000008:00000000
ps3fb ioc0_01:           [110] 00000000:00000000 005aaae4:00000000 00100008:00000000 01012000:00000000
ps3fb ioc0_01:           [114] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [118] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [11c] 98766666:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [120] 00000000:00000000 00000111:00000000 00000f11:00000000 89aabaa9:00000000
ps3fb ioc0_01:           [124] 00018488:00000000 00428a02:00000000 00080008:00000000 00000000:00000000
ps3fb ioc0_01:           [128] 005aaae4:00000000 00100008:00000000 01012000:00000000 00018488:00000000
ps3fb ioc0_01:           [12c] 00000000:00000000 00000000:00000000 00000000:00000000 005aaae4:00000000
ps3fb ioc0_01:           [130] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [134] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [138] 00000111:00000000 00000f11:00000000 56676654:00000000 00000000:00000000
ps3fb ioc0_01:           [13c] 00428a02:00000000 00080008:00000000 00000000:00000000 00000111:00000000
ps3fb ioc0_01:           [140] 00100008:00000000 01012000:00000000 00018488:00000000 00428a02:00000000
ps3fb ioc0_01:           [144] 00000000:00000000 00000000:00000000 005aaae4:00000000 00100008:00000000
ps3fb ioc0_01:           [148] 00000000:00000000 00000000:00000000 edcba987:00000000 00000000:00000000
ps3fb ioc0_01:           [14c] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [150] 00000f11:00000000 66667899:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [154] 00080008:00000000 00000000:00000000 00000111:00000000 00000f11:00000000
ps3fb ioc0_01:           [158] 01012000:00000000 00018488:00000000 00428a02:00000000 00080008:00000000
ps3fb ioc0_01:           [15c] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [160] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [164] 00000000:00000000 00000000:00000000 00000000:00000000 00000001:00000000
ps3fb ioc0_01:           [168] 00000000:00000000 40100000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [16c] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [170] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [174] ffffffff:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [178] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [17c] 00000000:00000000 00000000:00000000 0001bc80:00000000 00000202:00000000
ps3fb ioc0_01:           [180] 00000000:00000000 00000008:00000000 00000000:00000000 00080008:00000000
ps3fb ioc0_01:           [184] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [188] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:       P   [18c] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [190] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [194] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [198] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [19c] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1a0] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1a4] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1a8] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1ac] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1b0] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1b4] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1b8] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1bc] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1c0] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1c4] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1c8] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1cc] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1d0] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1d4] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1d8] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1dc] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1e0] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1e4] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1e8] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1ec] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1f0] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1f4] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1f8] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000
ps3fb ioc0_01:           [1fc] 00000000:00000000 00000000:00000000 00000000:00000000 00000000:00000000

User Exception

The following FIFO command was executed:

0x0004eb00
0xdeadbabe

Result:

ps3rsx_intr:293: interrupt status 0x00000080
ps3rsx_intr:303: user exception: cause 0xdeadbabe

Debugging

Profiling

lv1_gpu_context_attribute(0x55555555 /* context handle of the first created GPU context */, 0x106, 0x1, 0x0, 0x0, 0x0)

Shaders

PS3:HvReverseEngineering:RSX:VertexShader

PS3:HvReverseEngineering:RSX:FragmentShader

Example

Rsx linux triangle blue.jpg

Rsx linux triangle colors.jpg

Hardware Registers

Offset Description
0x140 Hardware master interrupt control
0x3204 Active channel id

FIFO Command Buffer

FIFO Control Registers

Kicking FIFO Command Buffer

FIFO Setup Programs of emer_init.self

cellGcmInit FIFO Buffer Dump

FIFO Commands

Example How to Use FIFO Command Buffer

Here is a small Linux kernel module which shows you how to use FIFO command buffer on Linux.

Download source code: [2]

Source Code

/*
 * PS3 RSX
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published
 * by the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/delay.h>

#include <asm/abs_addr.h>
#include <asm/cell-regs.h>
#include <asm/lv1call.h>
#include <asm/ps3.h>

#define RSX_FIFO_CMD_BUF_SIZE	(1 * 1024 * 1024)

#define RSX_MEM_SIZE		(32 * 1024 * 1024)

#define RSX_GPU_IOIF		(0x0e000000ul)

#define RSX_FIFO_CTRL_SIZE	(4 * 1024)

struct rsx_fifo_ctrl {
	u8 res[0x40];
	u32 put;
	u32 get;
};

static u32 *rsx_fifo_cmd_buf;
static u64 rsx_fifo_cmd_buf_lpar;

static u64 rsx_mem_handle, rsx_mem_lpar;
static u64 rsx_ctx_handle;
static u64 rsx_fifo_ctrl_lpar;
static u64 rsx_drv_info_lpar;
static u64 rsx_reports_lpar, rsx_reports_size;

static struct rsx_fifo_ctrl *rsx_fifo_ctrl;

/*
 * FIFO program
 */
static u32 rsx_fifo_prg[] = {
	0x00000000, /* nop */
	0x00000000, /* nop */
	0x00000000, /* nop */
};

/*
 * ps3rsx_init
 */
static int __init ps3rsx_init(void)
{
	unsigned long timeout;
	int res;

	/* FIFO command buffer must be allocated in XDR memory */

	rsx_fifo_cmd_buf = kmalloc(RSX_FIFO_CMD_BUF_SIZE, GFP_KERNEL);
	if (!rsx_fifo_cmd_buf) {
		printk(KERN_INFO"could not allocate FIFO command buffer\n");
		res = -ENOMEM;
		goto fail;
	}

	res = lv1_gpu_memory_allocate(RSX_MEM_SIZE, 0, 0, 0, 0,
		&rsx_mem_handle, &rsx_mem_lpar);
	if (res) {
		printk(KERN_INFO"lv1_gpu_memory_allocate failed (%d)\n", res);
		res = -ENXIO;
		goto fail_free_fifo_cmd_buf_mem;
	}

	res = lv1_gpu_context_allocate(rsx_mem_handle, 0,
		&rsx_ctx_handle, &rsx_fifo_ctrl_lpar, &rsx_drv_info_lpar,
		&rsx_reports_lpar, &rsx_reports_size);
	if (res) {
		printk(KERN_INFO"lv1_gpu_context_allocate failed (%d)\n", res);
		res = -ENXIO;
		goto fail_free_gpu_mem;
	}
	
	/* map FIFO command buffer into RSX address space */

	rsx_fifo_cmd_buf_lpar = ps3_mm_phys_to_lpar(__pa(rsx_fifo_cmd_buf));

	res = lv1_gpu_context_iomap(rsx_ctx_handle,
		RSX_GPU_IOIF, rsx_fifo_cmd_buf_lpar, RSX_FIFO_CMD_BUF_SIZE,
		CBE_IOPTE_PP_W | CBE_IOPTE_PP_R | CBE_IOPTE_M);
	if (res) {
		printk(KERN_INFO"lv1_gpu_context_iomap failed (%d)\n", res);
		res = -ENXIO;
		goto fail_free_gpu_mem;
	}

	/* map RSX FIFO control registers */

	rsx_fifo_ctrl = (struct rsx_fifo_ctrl *) ioremap(rsx_fifo_ctrl_lpar, RSX_FIFO_CTRL_SIZE);
	if (!rsx_fifo_ctrl) {
		printk(KERN_INFO"could not map FIFO control\n");
		res = -ENXIO;
		goto fail_free_gpu_mem;
	}

	/* PUT and GET offsets are in RSX address space */

	res = lv1_gpu_context_attribute(rsx_ctx_handle, 0x1,
		RSX_GPU_IOIF + 0x0 /* PUT offset */, RSX_GPU_IOIF + 0x0 /* GET offset */,
		0x0, 0x0);
	if (res) {
		printk(KERN_INFO"lv1_gpu_context_attribute(0x1) failed (%d)\n", res);
		res = -ENXIO;
		goto fail_unmap_fifo_ctrl;
	}

	/* copy FIFO commands to FIFO command buffer */

	memcpy(rsx_fifo_cmd_buf, rsx_fifo_prg, sizeof(rsx_fifo_prg));

	printk(KERN_INFO"GET offset (0x%08x) PUT offset (0x%08x)\n", rsx_fifo_ctrl->get, rsx_fifo_ctrl->put);

	/* kick FIFO */

	rsx_fifo_ctrl->put = RSX_GPU_IOIF + sizeof(rsx_fifo_prg);

	/* poll until RSX is done processing FIFO commands */

	timeout = 100;

	while (timeout--) {
		if (rsx_fifo_ctrl->get == rsx_fifo_ctrl->put)
			break;

		msleep(1);
	}

	printk(KERN_INFO"GET offset (0x%08x) PUT offset (0x%08x)\n", rsx_fifo_ctrl->get, rsx_fifo_ctrl->put);

	if (rsx_fifo_ctrl->get != rsx_fifo_ctrl->put) {
		printk(KERN_INFO"FIFO command buffer timeout\n");
		res = -ENXIO;
		goto fail_unmap_fifo_ctrl;
	}

	return 0;

fail_unmap_fifo_ctrl:

	iounmap(rsx_fifo_ctrl);


fail_free_gpu_mem:

	lv1_gpu_memory_free(rsx_mem_handle);

fail_free_fifo_cmd_buf_mem:

	kfree(rsx_fifo_cmd_buf);

fail:

	return res;
}

/*
 * ps3rsx_exit
 */
static void __exit ps3rsx_exit(void)
{
	iounmap(rsx_fifo_ctrl);

	lv1_gpu_context_iomap(rsx_ctx_handle, RSX_GPU_IOIF, rsx_fifo_cmd_buf_lpar,
		RSX_FIFO_CMD_BUF_SIZE, CBE_IOPTE_M);

	lv1_gpu_context_free(rsx_ctx_handle);

	lv1_gpu_memory_free(rsx_mem_handle);

	kfree(rsx_fifo_cmd_buf);
}

module_init(ps3rsx_init);
module_exit(ps3rsx_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("PS3 RSX");
MODULE_AUTHOR("glevand");

Test

# insmod ./ps3rsx.ko
# dmesg

GET offset (0x0e000000) PUT offset (0x0e000000)  # GET and PUT offsets before kicking FIFO
GET offset (0x0e00000c) PUT offset (0x0e00000c)  # GET and PUT offsets after kicking FIFO

As you see, RSX processed our FIFO commands :)

Linux Driver

DDX Driver

Design

DRM Driver

Memory Management

Video RAM

GART Memory

CPU Memory

Mapping Memory Objects into Kernel-Space

Mapping Memory Objects into User-Space

GEM

TTM

DRM Display

FIFO Command Buffer

Example
       ---------------------------------------------------------------
      |                                                               |
      |                                                               |
     \|/     Main FIFO command buffer (one per allocated context)     |
 ------------------------------         ------------------------------------
|           |         |                    |          |          |          |
|    ...    |   CALL  |         ...        |   CALL   |   ...    |   JMP    |
|           |         |                    |          |          |          |
 ------------------------------         ------------------------------------
                 |       /|\                    |         /|\
    -------------|        |                     |          |
    |               ------|             --------|          |
   \|/              |                   |               ---|
 -----------------------                |               |
|       |       |       |               |               |
|  ...  |  ...  |  RET  |               |               |
|       |       |       |               |               |
 -----------------------                |               |
   FIFO command buffer 1                |               |
  (allocated by user space)            \|/              |
                                     -----------------------
                                    |       |       |       |
                                    |  ...  |  ...  |  RET  |
                                    |       |       |       |
                                     -----------------------
                                       FIFO command buffer 2
                                     (allocated by user space)

Fences

IOCTLs

Context Create
Context Destroy
Context Attribute
Graphic Object Creatre
Graphic Object Destroy
FIFO Execute
Framebuffer

libdrm

Test Kernel Module and Program

Links

BD Drive

Crossreference: ps3devwiki.com::HV#BD Drive


Profile

Profile Table

Profile Description
0x0 No Current Profile
0x2 Removable Disk
0x8 CD-ROM
0x9 CD-R
0xa CD-RW
0x10 DVD-ROM
0x11 DVD-R Sequential recording
0x12 DVD-RAM
0x13 DVD-RW Restricted Overwrite
0x14 DVD-RW Sequential recording
0x1a DVD+RW
0x1b DVD+R
0x40 BD-ROM
0x41 BD-R Sequential Recording(TBD)
0x42 BD-R Random Recording(TBD)
0x43 BD-RE
0x50 PS1 CD-ROM
0x60 PS2 CD-ROM
0x61 PS2 DVD-ROM
0x70 PS3 DVD-ROM
0x71 PS3 BD-ROM
0x10000 CD-DA
0x20000 SACD
0x100000 Dual Layer (Parallel)
0x200000 Dual Layer (else Parallel)

Buffer

Buffer Table

ID Size Description
0x0 0x8000 Used to transfer firmware to BD drive
0x1 0x800 Serial Flash
0x2 0x60 P-Block
0x3 0x670 S-Block
0x4 0x8000 Host Revocation List (HRL) Empty
0x5 0x8000 Host Revocation List (HRL) Current
0x6 0x670 S-Block
0x7 0x8000 Host Revocation List (HRL)

HRL Buffer

Device Commands

Get Profile (0x11)

Auto Request Sense Mode On/Off (0x30)

SCSI Commands

Get Configuration

Getting the profile of a BD movie disc:

# sg_raw -r 0x8 /dev/sr0 46 02 00 00 00 00 00 00 08 00
SCSI Status: Good 

Sense Information:
sense buffer empty

Received 8 bytes of data:
 00     00 00 00 38 00 00 00 40                             ...8...@   

# 0x40 means BD-ROM

Getting the profile of a PS3 game disc:

# sg_raw -r 0x8 /dev/sr0 46 02 00 00 00 00 00 00 08 00
SCSI Status: Good 

Sense Information:
sense buffer empty

Received 8 bytes of data:
 00     00 00 00 38 00 00 ff 71                             ...8...q 
 
# 0x71 means PS3 BD-ROM

Get SS Key

Test with PS3 game disc:

# sg_raw -r 8 /dev/sr0 a4 00 00 00 00 00 00 e0 00 08 03 00
SCSI Status: Good 

Sense Information:
sense buffer empty

Received 8 bytes of data:
 00     00 06 00 00 00 00 00 04                             ........        

Eject Media

sg_raw /dev/sr0 0x1b 00 00 00 02 00

Load Media

sg_raw /dev/sr0 0x1b 00 00 00 03 00

Mode Select 10

Enable Buffer Write

Test with sg3-utils which enables write to HRL buffer:

sg_raw /dev/sr0 55 10 00 00 00 00 00 00 10 00 00 0e 00 00 00 00 00 00 2d 06 04 00 00 00 00 00

Write Buffer

AACS

AACS SPU Module

Communication

Commands

Read 4 Bytes from XDR Buffer (0x2)
Set KCD (0x1e)
Init AES_H (0x34)
Calculate AES_H 1 (0x35)
Calculate AES_H 2 (0x36)
Generate Host Nonce (0x3c)
Get Host Nonce and Certificate (0x3d)
Set Drive Nonce and Certificate (0x3e)
Verify Drive Certificate (0x3f)
Set Drive Key (0x40)
Sign Host Key (0x44)
Get Host Key (0x45)
Calculate Bus Key (0x46)
Set Volume ID (0x47)
Calculate Volume ID MAC (0x48)
Verify Volume ID MAC (0x49)
Set PMSN (0x4a)
Calculate PMSN MAC (0x4b)
Verify PMSN (0x4c)
Set Media ID (0x4d)
Calculate Media ID MAC (0x4e)
Verify Media ID MAC (0x4f)
Unknown (0x54)
Verify Host/Drive Revocation (0x55)
Terminate Session (0xfefefeff)

Drive Revocation List (DRL)

Content Revocation List (CRL)

Host Revocation List (HRL)

Read HRL from BD Drive Flash

Empty HRL

# sg_read_buffer -m 2 -i 4 -o 0 -l $((0x40)) /dev/sr0 
 00     10 00 00 0c 00 03 10 03  00 00 00 01 21 00 00 34                    
 10     00 00 00 00 00 00 00 00  1b 0b f2 6d 47 9e 77 62                    
 20     3d 91 fc 78 b1 59 c9 52  ca a4 c7 41 85 24 96 64                    
 30     8d 1d 95 8e 9b 84 c6 fa  4a dd 43 9b 42 98 fe ff  

# byte 0x21 at offset 0xc means Record Type HRL

# as you see this HRL is empty

Current HRL

# sg_read_buffer -m 2 -i 5 -o 0 -l $((0x7c)) /dev/sr0 
 00     10 00 00 0c 00 04 10 03  00 00 00 09 21 00 00 6c                    
 10     00 00 00 07 00 00 00 07  00 09 ff ff 00 00 00 0b                    
 20     00 00 ff ff 00 00 00 16  00 08 ff ff 00 00 00 21                    
 30     00 03 ff ff 00 00 00 35  00 04 ff ff 00 00 00 4e                    
 40     00 03 ff ff 00 00 00 54  00 03 ff ff 00 00 00 5e                    
 50     80 93 3a 62 f5 5a 9c 8c  62 ce 7d b8 69 5d d7 b1                    
 60     c3 0f 36 ff 96 a2 3b 32  cb cd 58 d4 12 c9 fd bf                    
 70     f5 16 a6 4a 32 ba 60 f0  5d 71 74 10 

# the current HRL is NOT empty and is from MKBv9 because the only BD movie i played on my PS3 has MKBv9

PS3 BD Player Host Certificate

$ hexdump -C aacs_auth/ps3_host_cert.bin 
00000000  02 01 00 5c ff ff 80 00  00 39 00 00 65 ea c9 87  |...\ÿÿ...9..eêÉ.|
00000010  8b 85 ef f4 d7 7a 62 b1  d6 00 02 4a ce 68 dd 33  |..ïô×zb±Ö..JÎhÝ3|
00000020  66 88 0e 4f 84 4f 34 b7  7a 05 01 35 a2 0e 73 b6  |f..O.O4·z..5¢.s¶|
00000030  26 da ea 51 57 b3 2e b8  4b c6 e8 7b 0d ee 4d 83  |&ÚêQW³.žKÆè{.îM.|
00000040  3c ea da 86 12 01 51 00  2c 3c 66 d5 25 6f 71 cf  |<êÚ...Q.,<fÕ%oqÏ|
00000050  a6 8b 7e 55 ba 1b 35 1f  34 03 43 4e              |Š.~Uº.5.4.CN|
0000005c

# Host ID is 0xffff80000039

PS3 BD Player Host Private Key

$ hexdump -C aacs_auth/ps3_host_priv_key.bin 
00000000  00 66 8c 9a 75 ee fc 8d  a4 26 19 38 e2 71 28 50  |.f..u....&.8.q(P|
00000010  61 bb 09 f0 dd                                    |a....|

AACS Processing Keys

MKB v1

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v1.inf

=MKB=
type:
0x00031003
version:
0x00000001

MKB U masks and UVs: 514

=applying subset-difference=
index: 0
UV: 0x00000001
U mask: 0xff800000
V mask: 0xfffffffe

=applying device key=
index: 244
UV: 0x00000100
U mask: 0xff800000
V mask: 0xfffffe00
device key:
00000000: 81 08 27 a7 6e 5b 2c c1 68 5e 32 17 a2 3e 21 86 |..'.n[,.h^2..>!.|

processing key:
00000000: 09 f9 11 02 9d 74 e3 5b d8 41 56 c5 63 56 88 c0 |.....t.[.AV.cV..|

C value:
00000000: cb 06 90 db e6 54 55 7b 12 62 aa d7 89 f4 9d 92 |.....TU{.b......|

media key:
00000000: b4 6c 48 5e f7 51 ae 29 ef 87 bc 58 28 f3 2a 8d |.lH^.Q.)...X(.*.|

=MKB verify media key data=
encrypted:
00000000: 46 32 5b 42 48 b4 86 5a fc ef 75 25 47 b1 b5 12 |F2[BH..Z..u%G...|
decrypted:
00000000: 01 23 45 67 89 ab cd ef 0d ac 14 b9 ee f4 bd cc |.#Eg............|

MKB v3

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v3.inf

=MKB=
type:
0x00031003
version:
0x00000003

MKB U masks and UVs: 528

=applying subset-difference=
index: 14
UV: 0x00000080
U mask: 0xff800000
V mask: 0xffffff00

=applying device key=
index: 244
UV: 0x00000100
U mask: 0xff800000
V mask: 0xfffffe00
device key:
00000000: 81 08 27 a7 6e 5b 2c c1 68 5e 32 17 a2 3e 21 86 |..'.n[,.h^2..>!.|

processing key:
00000000: 97 39 40 bb 18 0e 83 26 62 31 ee 59 6c ef 65 b2 |.9@....&b1.Yl.e.|

C value:
00000000: 0a b7 33 82 85 62 91 d1 91 4a 95 9e 36 18 c7 a1 |..3..b...J..6...|

media key:
00000000: 6e da eb d4 88 aa 38 58 74 26 35 fd fd 36 66 d5 |n.....8Xt&5..6f.|

=MKB verify media key data=
encrypted:
00000000: 99 76 96 b0 6f 49 37 9b c4 b9 2b be 73 ce 96 1a |.v..oI7...+.s...|
decrypted:
00000000: 01 23 45 67 89 ab cd ef fb 01 cc 85 eb e5 bf 0a |.#Eg............|

MKB v4

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v4.inf

=MKB=
type:
0x00031003
version:
0x00000004

MKB U masks and UVs: 526

=applying subset-difference=
index: 12
UV: 0x00000080
U mask: 0xff800000
V mask: 0xffffff00

=applying device key=
index: 244
UV: 0x00000100
U mask: 0xff800000
V mask: 0xfffffe00
device key:
00000000: 81 08 27 a7 6e 5b 2c c1 68 5e 32 17 a2 3e 21 86 |..'.n[,.h^2..>!.|

processing key:
00000000: 97 39 40 bb 18 0e 83 26 62 31 ee 59 6c ef 65 b2 |.9@....&b1.Yl.e.|

C value:
00000000: bf 71 0c 8b 46 a0 24 d8 f0 3a a1 26 37 9d fb fc |.q..F.$..:.&7...|

media key:
00000000: ef 18 c0 dd bf 02 32 a1 2f 57 f7 65 79 2c 1c 58 |......2./W.ey,.X|

=MKB verify media key data=
encrypted:
00000000: 54 85 08 a9 6a 70 2a c9 32 e3 74 a6 55 78 6c 01 |T...jp*.2.t.Uxl.|
decrypted:
00000000: 01 23 45 67 89 ab cd ef da 90 cf 2a e5 b2 6c 45 |.#Eg.......*..lE|

MKB v7

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v7.inf

=MKB=
type:
0x00031003
version:
0x00000007

MKB U masks and UVs: 526

=applying subset-difference=
index: 7
UV: 0x00000080
U mask: 0xff800000
V mask: 0xffffff00

=applying device key=
index: 244
UV: 0x00000100
U mask: 0xff800000
V mask: 0xfffffe00
device key:
00000000: 81 08 27 a7 6e 5b 2c c1 68 5e 32 17 a2 3e 21 86 |..'.n[,.h^2..>!.|

processing key:
00000000: 97 39 40 bb 18 0e 83 26 62 31 ee 59 6c ef 65 b2 |.9@....&b1.Yl.e.|

C value:
00000000: 21 fd c9 4b 3e 1a f3 fe 9e b4 7a e6 ef 01 75 1b |!..K>.....z...u.|

media key:
00000000: af cd e2 c8 67 12 a4 b6 a8 58 0c 15 ef 07 6e f8 |....g....X....n.|

=MKB verify media key data=
encrypted:
00000000: 4b 21 29 a5 0f db 96 bc bc 01 04 71 42 79 00 e5 |K!)........qBy..|
decrypted:
00000000: 01 23 45 67 89 ab cd ef 4e f9 d2 05 6e 19 c1 79 |.#Eg....N...n..y|

MKB v8

glevand@debian-hdd:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v8.inf

=MKB=
type:
0x00031003
version:
0x00000008

MKB U masks and UVs: 523

=applying subset-difference=
index: 4
UV: 0x00000080
U mask: 0xff800000
V mask: 0xffffff00

=applying device key=
index: 244
UV: 0x00000100
U mask: 0xff800000
V mask: 0xfffffe00
device key:
00000000: 81 08 27 a7 6e 5b 2c c1 68 5e 32 17 a2 3e 21 86 |..'.n[,.h^2..>!.|

processing key:
00000000: 97 39 40 bb 18 0e 83 26 62 31 ee 59 6c ef 65 b2 |.9@....&b1.Yl.e.|

C value:
00000000: 73 2d 10 bd f8 b4 87 e2 86 a6 d5 3a 6d db 69 15 |s-.........:m.i.|

media key:
00000000: dd 46 d4 0d 26 54 5a ce 6c 59 0c 65 b7 2b 3a 9f |.F..&TZ.lY.e.+:.|

=MKB verify media key data=
encrypted:
00000000: c6 f6 f9 54 ce 90 e0 5e 2b 3b e4 1e 24 92 90 b2 |...T...^+;..$...|
decrypted:
00000000: 01 23 45 67 89 ab cd ef 97 e6 61 8b d1 69 3e a0 |.#Eg......a..i>.|

MKB v9

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v9.inf

=MKB=
type:
0x00031003
version:
0x00000009

MKB U masks and UVs: 520

=applying subset-difference=
index: 2
UV: 0x00000080
U mask: 0xff800000
V mask: 0xffffff00

=applying device key=
index: 244
UV: 0x00000100
U mask: 0xff800000
V mask: 0xfffffe00
device key:
00000000: 81 08 27 a7 6e 5b 2c c1 68 5e 32 17 a2 3e 21 86 |..'.n[,.h^2..>!.|

processing key:
00000000: 97 39 40 bb 18 0e 83 26 62 31 ee 59 6c ef 65 b2 |.9@....&b1.Yl.e.|

C value:
00000000: a4 5a c6 87 43 49 70 bb bf 0c 22 52 83 9e 2a f6 |.Z..CIp..."R..*.|

media key:
00000000: 37 02 bd fc 96 dc a2 18 2e 55 b0 79 6d ad 36 6b |7........U.ym.6k|

=MKB verify media key data=
encrypted:
00000000: 4d 5b 7b 9c 5d ee 55 a6 94 de e1 db 8d 08 c7 a2 |M[{.].U.........|
decrypted:
00000000: 01 23 45 67 89 ab cd ef cd 1d a8 8a 42 5a 10 43 |.#Eg........BZ.C|

MKB v10

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v10.inf

=MKB=
type:
0x00031003
version:
0x0000000a

MKB U masks and UVs: 522

=applying subset-difference=
index: 3
UV: 0x00000080
U mask: 0xff800000
V mask: 0xffffff00

=applying device key=
index: 244
UV: 0x00000100
U mask: 0xff800000
V mask: 0xfffffe00
device key:
00000000: 81 08 27 a7 6e 5b 2c c1 68 5e 32 17 a2 3e 21 86 |..'.n[,.h^2..>!.|

processing key:
00000000: 97 39 40 bb 18 0e 83 26 62 31 ee 59 6c ef 65 b2 |.9@....&b1.Yl.e.|

C value:
00000000: d4 77 dd 1a 8a 5c 6d d1 dd 31 2d af f7 d3 14 fa |.w...\m..1-.....|

media key:
00000000: 38 32 2b 3c 61 b0 35 b4 52 89 84 59 f4 7a 76 e6 |82+<a.5.R..Y.zv.|

=MKB verify media key data=
encrypted:
00000000: 3f d3 d5 fb 42 37 d9 05 b8 db 6b 03 a0 fe 2e 48 |?...B7....k....H|
decrypted:
00000000: 01 23 45 67 89 ab cd ef 65 b1 87 8c eb 0d 60 0f |.#Eg....e.....`.|

MKB v12

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v12.inf

=MKB=
type:
0x00031003
version:
0x0000000c

MKB U masks and UVs: 522

=applying subset-difference=
index: 3
UV: 0x00000080
U mask: 0xff800000
V mask: 0xffffff00

=applying device key=
index: 244
UV: 0x00000100
U mask: 0xff800000
V mask: 0xfffffe00
device key:
00000000: 81 08 27 a7 6e 5b 2c c1 68 5e 32 17 a2 3e 21 86 |..'.n[,.h^2..>!.|

processing key:
00000000: 97 39 40 bb 18 0e 83 26 62 31 ee 59 6c ef 65 b2 |.9@....&b1.Yl.e.|

C value:
00000000: 89 75 89 e6 6f 4a de 95 11 32 57 6a cb 99 dd 69 |.u..oJ...2Wj...i|

media key:
00000000: 4b dd 69 9d 32 98 d7 b0 ad 32 71 6b 3d 9c e3 c2 |K.i.2....2qk=...|

=MKB verify media key data=
encrypted:
00000000: 8d 43 fd f2 15 fa 58 78 64 db 25 46 62 ab 02 30 |.C....Xxd.%Fb..0|
decrypted:
00000000: 01 23 45 67 89 ab cd ef e6 1c bf 98 45 82 64 d9 |.#Eg........E.d.|

MKB v14

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v14.inf

=MKB=
type:
0x00031003
version:
0x0000000e

MKB U masks and UVs: 526

=applying subset-difference=
index: 6
UV: 0x00000248
U mask: 0xfffffe00
V mask: 0xfffffff0

=applying device key=
index: 28
UV: 0x00000280
U mask: 0xfffffe00
V mask: 0xffffff00
device key:
00000000: 44 14 5a 84 6f 19 d0 96 f2 c8 4a 2e 50 c5 c4 f5 |D.Z.o.....J.P...|

processing key:
00000000: 58 eb da df 88 dc c9 33 04 cb be db 9e e0 95 f6 |X......3........|

C value:
00000000: 8c 7e 31 e8 15 17 7e c3 2c 67 b7 cc 87 e9 39 c3 |.~1...~.,g....9.|

media key:
00000000: 4b b1 31 d1 6e 0e 86 45 89 07 a2 68 91 c4 e5 38 |K.1.n..E...h...8|

=MKB verify media key data=
encrypted:
00000000: 20 03 8c 70 7d ab d0 6f ba 86 39 f0 31 26 86 5f | ..p}..o..9.1&._|
decrypted:
00000000: 01 23 45 67 89 ab cd ef 27 9f e5 35 0b df 3d a5 |.#Eg....'..5..=.|

MKB v15

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v15.inf

=MKB=
type:
0x00031003
version:
0x0000000f

MKB U masks and UVs: 527

=applying subset-difference=
index: 6
UV: 0x00000248
U mask: 0xfffffe00
V mask: 0xfffffff0

=applying device key=
index: 28
UV: 0x00000280
U mask: 0xfffffe00
V mask: 0xffffff00
device key:
00000000: 44 14 5a 84 6f 19 d0 96 f2 c8 4a 2e 50 c5 c4 f5 |D.Z.o.....J.P...|

processing key:
00000000: 58 eb da df 88 dc c9 33 04 cb be db 9e e0 95 f6 |X......3........|

C value:
00000000: 75 da 59 cf 0d c2 c0 95 86 fc 6b 8e 2e e9 cc 85 |u.Y.......k.....|

media key:
00000000: 28 46 25 38 3d cc 4f 1f 90 be 7d f7 8a ba 7b fd |(F%8=.O...}...{.|

=MKB verify media key data=
encrypted:
00000000: 8d d2 69 e0 b7 6a 44 53 03 ad ef 58 44 fc a7 d7 |..i..jDS...XD...|
decrypted:
00000000: 01 23 45 67 89 ab cd ef ff 6a 7d c3 17 bb 19 11 |.#Eg.....j}.....|

MKB v16

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v16.inf

=MKB=
type:
0x00031003
version:
0x00000010

MKB U masks and UVs: 531

=applying subset-difference=
index: 5
UV: 0x00000248
U mask: 0xfffffe00
V mask: 0xfffffff0

=applying device key=
index: 28
UV: 0x00000280
U mask: 0xfffffe00
V mask: 0xffffff00
device key:
00000000: 44 14 5a 84 6f 19 d0 96 f2 c8 4a 2e 50 c5 c4 f5 |D.Z.o.....J.P...|

processing key:
00000000: 58 eb da df 88 dc c9 33 04 cb be db 9e e0 95 f6 |X......3........|

C value:
00000000: f8 49 9b d1 32 f9 6e 8d 33 98 35 a8 54 80 d9 fe |.I..2.n.3.5.T...|

media key:
00000000: 3a bf bf d7 7e b8 01 43 a9 3c 15 3f ba 47 8c e1 |:...~..C.<.?.G..|

=MKB verify media key data=
encrypted:
00000000: 8a 67 86 b6 9d 0d 22 dd 5d c2 88 1f 08 f3 ab b4 |.g....".].......|
decrypted:
00000000: 01 23 45 67 89 ab cd ef d6 32 1f 17 c4 2f e2 4a |.#Eg.....2.../.J|

MKB v17

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v17.inf

=MKB=
type:
0x00031003
version:
0x00000011

MKB U masks and UVs: 540

=applying subset-difference=
index: 14
UV: 0x00000308
U mask: 0xffffff00
V mask: 0xfffffff0

=applying device key=
index: 21
UV: 0x00000340
U mask: 0xffffff00
V mask: 0xffffff80
device key:
00000000: eb 55 a4 75 08 0f bc f1 85 34 ef a0 83 9a 73 73 |.U.u.....4....ss|

processing key:
00000000: 46 5f a8 be 82 85 09 01 4d 05 d2 fc ce ff 35 d2 |F_......M.....5.|

C value:
00000000: 01 f7 54 0b 34 e8 c1 ce 63 8d ea fa bc ce 6e 7b |..T.4...c.....n{|

media key:
00000000: ef 63 4e a8 ca 06 d1 6a c7 21 65 1b 18 b3 04 c6 |.cN....j.!e.....|

=MKB verify media key data=
encrypted:
00000000: d3 b9 d4 9c b6 94 47 d5 3d cc 42 fe 3e 47 40 04 |......G.=.B.>G@.|
decrypted:
00000000: 01 23 45 67 89 ab cd ef f6 b4 c8 6a b7 b8 39 fc |.#Eg.......j..9.|

MKB v18

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v18.inf

=MKB=
type:
0x00031003
version:
0x00000012

MKB U masks and UVs: 543

=applying subset-difference=
index: 17
UV: 0x00000320
U mask: 0xffffff00
V mask: 0xffffffc0

=applying device key=
index: 21
UV: 0x00000340
U mask: 0xffffff00
V mask: 0xffffff80
device key:
00000000: eb 55 a4 75 08 0f bc f1 85 34 ef a0 83 9a 73 73 |.U.u.....4....ss|

processing key:
00000000: ad 5e 54 6c 46 d7 2d c0 83 ae b5 68 69 24 e1 b3 |.^TlF.-....hi$..|

C value:
00000000: 7a 8f 03 41 27 c4 86 58 05 37 3a 90 de f8 de 26 |z..A'..X.7:....&|

media key:
00000000: e3 ed cd b4 59 b4 12 d4 ae f9 4d 8e 78 7a cd 7d |....Y.....M.xz.}|

=MKB verify media key data=
encrypted:
00000000: ea 45 fa 35 65 70 56 6f 6a 86 65 ad 52 e7 71 a4 |.E.5epVoj.e.R.q.|
decrypted:
00000000: 01 23 45 67 89 ab cd ef bd 36 f9 ce 60 54 80 3c |.#Eg.....6..`T.<|

MKB v19

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v19.inf

=MKB=
type:
0x00031003
version:
0x00000013

MKB U masks and UVs: 544

=applying subset-difference=
index: 17
UV: 0x00000320
U mask: 0xffffff00
V mask: 0xffffffc0

=applying device key=
index: 21
UV: 0x00000340
U mask: 0xffffff00
V mask: 0xffffff80
device key:
00000000: eb 55 a4 75 08 0f bc f1 85 34 ef a0 83 9a 73 73 |.U.u.....4....ss|

processing key:
00000000: ad 5e 54 6c 46 d7 2d c0 83 ae b5 68 69 24 e1 b3 |.^TlF.-....hi$..|

C value:
00000000: b9 0b 55 d1 18 3c cc 80 20 1c 9f 26 c3 58 27 18 |..U..<.. ..&.X'.|

media key:
00000000: 75 a9 79 9c 67 50 13 89 98 62 34 5b eb 54 34 dd |u.y.gP...b4[.T4.|

=MKB verify media key data=
encrypted:
00000000: c4 f0 ce 75 1b 12 b9 f0 22 2f 31 70 66 a9 6a b8 |...u...."/1pf.j.|
decrypted:
00000000: 01 23 45 67 89 ab cd ef 66 5c 65 d3 c4 4c c7 b0 |.#Eg....f\e..L..|

MKB v20

glevand@debian-hdd:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v20.inf

=MKB=
type:
0x00031003
version:
0x00000014

MKB U masks and UVs: 544

=applying subset-difference=
index: 19
UV: 0x00000384
U mask: 0xffffff80
V mask: 0xfffffff8

=applying device key=
index: 18
UV: 0x00000384
U mask: 0xffffff80
V mask: 0xfffffff8
device key:
00000000: fb 4a c3 90 09 e8 21 13 d4 5e cf 4b 7e ae a4 67 |.J....!..^.K~..g|

processing key:
00000000: 53 fc e7 8e cd 35 2d a5 0d 52 6b 5e e3 d3 d9 6b |S....5-..Rk^...k|

C value:
00000000: 10 9f f1 69 36 07 7d 7e ad 8f d2 1a 28 c5 09 ed |...i6.}~....(...|

media key:
00000000: dc 9f 08 f7 cb 1b f8 c4 cf 96 4e 96 df 23 56 58 |..........N..#VX|

=MKB verify media key data=
encrypted:
00000000: 18 ca f5 51 8f 36 ef 2f 7a 49 78 ff 54 40 a5 f1 |...Q.6./zIx.T@..|
decrypted:
00000000: 01 23 45 67 89 ab cd ef c5 5d 11 08 c3 26 db 48 |.#Eg.....]...&.H|

MKB v21

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v21.inf

=MKB=
type:
0x00031003
version:
0x00000015

MKB U masks and UVs: 552

=applying subset-difference=
index: 19
UV: 0x00000384
U mask: 0xffffff80
V mask: 0xfffffff8

=applying device key=
index: 18
UV: 0x00000384
U mask: 0xffffff80
V mask: 0xfffffff8
device key:
00000000: fb 4a c3 90 09 e8 21 13 d4 5e cf 4b 7e ae a4 67 |.J....!..^.K~..g|

processing key:
00000000: 53 fc e7 8e cd 35 2d a5 0d 52 6b 5e e3 d3 d9 6b |S....5-..Rk^...k|

C value:
00000000: c0 0c fa bf f0 fe f2 32 77 19 db c4 d8 f8 60 c9 |.......2w.....`.|

media key:
00000000: 55 83 aa 69 ff 52 16 83 c2 93 b3 48 03 2a 57 38 |U..i.R.....H.*W8|

=MKB verify media key data=
encrypted:
00000000: 12 5b f2 75 c8 f8 05 6b 4f 31 a5 ea 4a 12 9f a9 |.[.u...kO1..J...|
decrypted:
00000000: 01 23 45 67 89 ab cd ef dc 46 45 b4 79 8d 4f 68 |.#Eg.....FE.y.Oh|

MKB v23

glevand@debian-hdd:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v23.inf 

=MKB=
type:
0x00031003
version:
0x00000017

MKB U masks and UVs: 556

=applying subset-difference=
index: 17
UV: 0x00000384
U mask: 0xffffffe0
V mask: 0xfffffff8

=applying device key=
index: 7
UV: 0x00000384
U mask: 0xffffffe0
V mask: 0xfffffff8
device key:
00000000: 8b f4 fb d9 1a 7f b7 db 85 76 d1 e5 a1 5a 85 44 |.........v...Z.D|

processing key:
00000000: c3 22 38 97 6f f4 4a 51 e2 d3 35 53 cf e8 57 72 |."8.o.JQ..5S..Wr|

C value:
00000000: f0 81 d4 93 aa b5 01 1a a7 ff 8e 18 8a 48 8a 2d |.............H.-|

media key:
00000000: 02 04 59 d0 7c b5 54 94 bf 46 9b 98 91 1e 43 1f |..Y.|.T..F....C.|

=MKB verify media key data=
encrypted:
00000000: 24 a1 27 f9 30 70 25 67 07 2f 2a d4 13 89 0d aa |$.'.0p%g./*.....|
decrypted:
00000000: 01 23 45 67 89 ab cd ef 21 00 20 84 c4 5f 36 78 |.#Eg....!. .._6x|

MKB v25

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v25.inf

=MKB=
type:
0x00031003
version:
0x00000019

MKB U masks and UVs: 564

=applying subset-difference=
index: 13
UV: 0x00000384
U mask: 0xffffffe0
V mask: 0xfffffff8

=applying device key=
index: 7
UV: 0x00000384
U mask: 0xffffffe0
V mask: 0xfffffff8
device key:
00000000: 8b f4 fb d9 1a 7f b7 db 85 76 d1 e5 a1 5a 85 44 |.........v...Z.D|

processing key:
00000000: c3 22 38 97 6f f4 4a 51 e2 d3 35 53 cf e8 57 72 |."8.o.JQ..5S..Wr|

C value:
00000000: 19 62 23 7d 81 01 c2 55 2f 36 20 1b 3e 69 40 10 |.b#}...U/6 .>i@.|

media key:
00000000: 70 b5 9f 35 86 5d 18 73 bb 80 c3 2b f7 41 f6 14 |p..5.].s...+.A..|

=MKB verify media key data=
encrypted:
00000000: 89 be 1e 1e b1 93 4c f2 2d ac c3 ce ed 10 07 f0 |......L.-.......|
decrypted:
00000000: 01 23 45 67 89 ab cd ef 3f 5d 87 7a 88 09 db c4 |.#Eg....?].z....|

Documentation

CSS

CSS SPU Module

Commands

Generate Host Challenge Key (0x3)
Set Drive Key1 (0x4)
Set Drive Challenge Key (0x5)
Calculate Host Key2 (0x6)
Get Host Key2 (0x7)
Set Disc Key (0x8)
Decrypt Sector (0xc)

CSS Salt

Obfuscated:

71 ED 3F A3 DA FE E4 94  40 8C

Clear text:

F4  10  45  A3  E2

PS3 DVD Player Key Index

0x69

Documentation

CPRM

Commands

4C Secret Constant (S-Box)

Documentation

Remarrying BD Drive on OtherOS++

fdm_spu_module.self

Block types

Type Description BD Drive Buffer ID
0x1 P-Block 0x2
0x2 S-Block 0x3

Remarrying

Preparations

P-Block

Creating
Sending to BD Drive

S-Block

Creating
Sending to BD Drive

HRL

Empty HRL
Sending to BD Drive

VTRM

Crossreference: ps3devwiki.com::HV#VTRM

VTRM Services

Store With Update (0x2003)

Retrieve (0x2005)

DRL and CRL Hashes

Test with ps3dm-utils:

# mount dev_flash3

glevand@debian-hdd:~/ps3dm-utils$ sudo mount /dev/ps3vflashe /mnt

# DRL SHA1 hash

glevand@debian-hdd:~/ps3dm-utils$ sha1sum /mnt/data-revoke/drl/DRL1
8f0652bc6162a240362f90f1b2e5405bb82ee502  /mnt/data-revoke/drl/DRL1

# CRL SHA1 hash

glevand@debian-hdd:~/ps3dm-utils$ sha1sum /mnt/data-revoke/crl/CRL1 
96791f41f9a76f4d895dd5820db108ec03d19250  /mnt/data-revoke/crl/CRL1

# Retrieve DRL and CRL SHA1 hashes from VTRM
# DRL hash is first and then follows CRL hash

glevand@debian-hdd:~/ps3dm-utils$ sudo ./ps3dm_vtrm -l 0x0 -p 0x1070000034000001 /dev/ps3dmproxy retrieve 0
0x8f 0x06 0x52 0xbc 0x61 0x62 0xa2 0x40 0x36 0x2f 0x90 0xf1 0xb2 0xe5 0x40 0x5b 0xb8 0x2e 0xe5 0x02
0x96 0x79 0x1f 0x41 0xf9 0xa7 0x6f 0x4d 0x89 0x5d 0xd5 0x82 0x0d 0xb1 0x08 0xec 0x03 0xd1 0x92 0x50
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

Backup Flash (0x2012)

Test with ps3dm-utils:

# enable product mode

# ps3dm_um /dev/ps3dmproxy write_eprom 0x48c07 0x0
/dev/ps3dmproxy: SS retval 0

# ps3dm_vtrm /dev/ps3dmproxy  backup_flash 0 0x200 | hexdump -C
00000000  53 43 45 49 ff ff ff ff  ff ff ff ff ff ff ff ff  |SCEIÿÿÿÿÿÿÿÿÿÿÿÿ|
00000010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ|
*
00000200

# dd if=/dev/ps3nflasha bs=1 count=$((0x100)) skip=$((0xec0000)) | hexdump -C
00000000  53 43 45 49 ff ff ff ff  ff ff ff ff ff ff ff ff  |SCEIÿÿÿÿÿÿÿÿÿÿÿÿ|
00000010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ|
*

Flash Address Size (0x2016)

Test with ps3dm-utils:

# ps3dm_um /dev/ps3dmproxy read_eprom 0x48c07
0xff

# ps3dm_vtrm /dev/ps3dmproxy  flash_addr_size
/dev/ps3dmproxy: SS retval 5

# enable product mode

# ps3dm_um /dev/ps3dmproxy write_eprom 0x48c07 0x0
/dev/ps3dmproxy: SS retval 0

# ps3dm_um /dev/ps3dmproxy read_eprom 0x48c07
0x00

# ps3dm_vtrm /dev/ps3dmproxy  flash_addr_size
0x0000000000000000 0x0000000000040000

Revoke List

Crossreference: ps3devwiki::Revoke List

LPAR 1 System Call 0x1004A

rvk_list_verifier

root@debian-hdd:/home/glevand/rvk_list_verifier# cat /proc/rvk_list_verifier/debug 
PPE id (0x0000000000000001) VAS id (0x0000000000000002)
lv1_construct_logical_spe (0x00000000)
SPE id (0x0000000000000033)
lv1_enable_logical_spe (0x00000000)
lv1_set_spe_interrupt_mask(0) (0x00000000)
lv1_set_spe_interrupt_mask(1) (0x00000000)
lv1_set_spe_interrupt_mask(2) (0x00000000)
lv1_set_spe_privilege_state_area_1_register (0x00000000)
ea (0xc000000003f40000) esid (0xc000000008000000) vsid (0x0000408f92c94500)
lv1_get_spe_interrupt_status(0) (0x00000000)
lv1_get_spe_interrupt_status(1) (0x00000000)
lv1_get_spe_interrupt_status(2) (0x00000000)
sleep
lv1_get_spe_interrupt_status(0) (0x00000000)
lv1_get_spe_interrupt_status(1) (0x00000000)
lv1_get_spe_interrupt_status(2) (0x00000000)
out interrupt mbox (0x0000000000000001)
lv1_clear_spe_interrupt_status(2) (0x00000000)
transferring ldr args to LS
waiting until MFC transfers are finished
MFC transfers done
out mbox (0x00000001)
sleep
lv1_get_spe_interrupt_status(0) (0x00000000)
lv1_get_spe_interrupt_status(1) (0x00000000)
lv1_get_spe_interrupt_status(2) (0x00000000)
problem status (0x000b0082)
lv1_destruct_logical_spe (0x00000000)

AV Manager

Crossreference: ps3devwiki::AV Manager

Commands

Get HDCP KSV (0xC)

SYSCON request packet:

30 01 0200 0000 8033 00000000 0004 0004 11 00 0000 0000ff01

Set HDMI Mode (0x40001)

IRQ Handling

Outlet

Outlet Object

offset 0x90 - virtual IRQ number to which outlet is mapped to (4 bytes)

offset 0x94 - ??? (1 byte)

offset 0x95 - flag which signals if IRQ was EOIed or NOT: 0 - EOIed, 1 - NOT EOIed (1 byte)

End Of Interrupt

Links

VUART

Interrupt

Status

enum ps3vuart_port_intr {
	PS3VUART_PORT_INTR_TX		= (1ul << 0),
	PS3VUART_PORT_INTR_RX		= (1ul << 1),
	PS3VUART_PORT_INTR_DISCONNECT	= (1ul << 2),
	PS3VUART_PORT_INTR_CONNECT	= (1ul << 3),
};

Rx IRQ Trigger

Tx IRQ Trigger

Physical Memory

Boot Memory Region

Extended Memory Region

<bi.rgntotal> = <total physical memory size> - <memory size reserved for LPAR1>

<memory size reserved for LPAR1> - stored in default.spp and is 6MB by default.

LPAR Switching/Scheduling

SLB Table

Snippet of LV1 code which shows you how SLB entries are preserved:

ROM:00001F04                 nop
ROM:00001F08                 nop
ROM:00001F0C                 nop
ROM:00001F10
ROM:00001F10 switch_LPAR:                            # CODE XREF: int_handler_1+EC�j
ROM:00001F10                                         # sub_1BD0+58�j
ROM:00001F10                 lbz     %r7, -0x6854(%r13)
ROM:00001F14                 li      %r6, 0x18
ROM:00001F18
ROM:00001F18 loc_1F18:                               # CODE XREF: sub_1BD0+354�j
ROM:00001F18                 ldarx   %r8, %r6, %r3
ROM:00001F1C                 andc    %r8, %r8, %r7
ROM:00001F20                 stdcx.  %r8, %r6, %r3
ROM:00001F24                 bc      6, eq, loc_1F18
ROM:00001F28                 li      %r3, -0x6E80
ROM:00001F2C                 dcbz    %r3, %r13
ROM:00001F30                 li      %r8, 0          # r8 = 0 - SLB entry index
ROM:00001F34                 li      %r9, 1          # r9 = 1 - SLB entry index
ROM:00001F38                 li      %r10, 2         # r10 = 2 - SLB entry index
ROM:00001F3C                 slbmfev %r3, %r8
ROM:00001F40                 slbmfee %r4, %r8
ROM:00001F44                 slbmfev %r5, %r9
ROM:00001F48                 slbmfee %r6, %r9        # int
ROM:00001F4C                 std     %r3, -0x6F30(%r13)
ROM:00001F50                 mfsprg0 %r7             # int
ROM:00001F54                 std     %r4, -0x6F28(%r13)
ROM:00001F58                 mfsprg1 %r8             # int
ROM:00001F5C                 slbmfev %r3, %r10
ROM:00001F60                 slbmfee %r4, %r10
ROM:00001F64                 std     %r5, -0x6F20(%r13)
ROM:00001F68                 mfsprg2 %r9             # int
ROM:00001F6C                 std     %r6, -0x6F18(%r13)
ROM:00001F70                 mfsprg3 %r10            # int
ROM:00001F74                 std     %r3, -0x6F10(%r13)
ROM:00001F78                 std     %r4, -0x6F08(%r13)
ROM:00001F7C                 std     %r7, -0x6940(%r13)
ROM:00001F80                 std     %r8, -0x6938(%r13)
ROM:00001F84                 std     %r9, -0x6930(%r13)
ROM:00001F88                 std     %r10, -0x6928(%r13)
ROM:00001F8C                 mfspr   %r3, buscsr
ROM:00001F90                 mfspr   %r4, iccr
ROM:00001F94                 mfspr   %r5, pbu1       # int
ROM:00001F98                 std     %r3, -0x69C0(%r13)
ROM:00001F9C                 std     %r4, -0x69D0(%r13)
ROM:00001FA0                 std     %r5, -0x69C8(%r13)
ROM:00001FA4                 std     %r14, -0x6E90(%r13)
ROM:00001FA8                 std     %r15, -0x6E88(%r13)
ROM:00001FAC                 std     %r16, -0x6E80(%r13)
ROM:00001FB0                 std     %r17, -0x6E78(%r13)
ROM:00001FB4                 std     %r18, -0x6E70(%r13)
ROM:00001FB8                 std     %r19, -0x6E68(%r13)
ROM:00001FBC                 std     %r20, -0x6E60(%r13)
ROM:00001FC0                 std     %r21, -0x6E58(%r13)
ROM:00001FC4                 std     %r22, -0x6E50(%r13)
ROM:00001FC8                 std     %r23, -0x6E48(%r13)
ROM:00001FCC                 std     %r24, -0x6E40(%r13)
ROM:00001FD0                 std     %r25, -0x6E38(%r13)
ROM:00001FD4                 std     %r26, -0x6E30(%r13)
ROM:00001FD8                 std     %r27, -0x6E28(%r13)
ROM:00001FDC                 std     %r28, -0x6E20(%r13)
ROM:00001FE0                 std     %r29, -0x6E18(%r13)
ROM:00001FE4                 std     %r30, -0x6E10(%r13)
ROM:00001FE8                 std     %r31, -0x6E08(%r13)
ROM:00001FEC

SLB table dump from FreeBSD:

ps3dumpslb:0: 0xcffffffff8000000 0x0000052dc7f77200-----------------------
ps3dumpslb:1: 0x0000000008000000 0x0001000000000100                      |
ps3dumpslb:2: 0x00006c0078000000 0x000152eca1d00100                      |
ps3dumpslb:3: 0x0000000018000000 0x000100013bb00000                      |
ps3dumpslb:4: 0xc000000008000000 0x00010000ecc40000                      |
ps3dumpslb:5: 0xc000000018000000 0x0001000228740000                      |
ps3dumpslb:6: 0xc000000028000000 0x0001000364240000                      |
ps3dumpslb:7: 0xc000000038000000 0x000100049fd40000                      |
ps3dumpslb:8: 0xc000000048000000 0x00010005db840000                      |
ps3dumpslb:9: 0xc000000058000000 0x0001000717340000                      |
ps3dumpslb:10: 0xc000000068000000 0x0001000852e40000                     |
ps3dumpslb:11: 0xc000000078000000 0x000100098e940000                     |
ps3dumpslb:12: 0xc000000088000000 0x0001000aca440000                     |
ps3dumpslb:13: 0xc000000098000000 0x0001000c05f40000                     |
ps3dumpslb:14: 0xc0000000a8000000 0x0001000d41a40000                     |
ps3dumpslb:15: 0xc0000000b8000000 0x0001000e7d540000                     |  Too many SLB entries.
ps3dumpslb:16: 0xc0000000c8000000 0x0001000fb9040000                     |  Ahhhhhhhhh, fuck, as soon
ps3dumpslb:17: 0xc0000000d8000000 0x00010010f4b40000                     |  as LV1 switches to LPAR1 and
ps3dumpslb:18: 0xc0000000e8000000 0x0001001230640000                     |  back to LPAR2, we are screwed !!!
ps3dumpslb:19: 0xc0000000f8000000 0x000100136c140000                     |
ps3dumpslb:20: 0xc000000108000000 0x00010014a7c40000                     |
ps3dumpslb:21: 0xc000000118000000 0x00010015e3740000                     |
ps3dumpslb:22: 0xc000000128000000 0x000100171f240000                     |
ps3dumpslb:23: 0xc000000138000000 0x000100185ad40000                     |
ps3dumpslb:24: 0xc000000148000000 0x0001001996840000                     |
ps3dumpslb:25: 0xc000000158000000 0x0001001ad2340000                     |
ps3dumpslb:26: 0xc000000168000000 0x0001001c0de40000                     |
ps3dumpslb:27: 0xc000000178000000 0x0001001d49940000                     |
ps3dumpslb:28: 0xc000000188000000 0x0001001e85440000                     |
ps3dumpslb:29: 0xc000000198000000 0x0001001fc0f40000                     |
ps3dumpslb:30: 0xc0000001a8000000 0x00010020fca40000                     |
ps3dumpslb:31: 0xc0000001b8000000 0x0001002238540000                     |
ps3dumpslb:32: 0xc0000001c8000000 0x0001002374040000----------------------
ps3dumpslb:33: 0x0000000010000000 0x0000dd82ce799c80
ps3dumpslb:34: 0x0000000000000000 0x0000dcc36017ec80
ps3dumpslb:35: 0x00000000f0000000 0x0000e7fad7d13c80
ps3dumpslb:36: 0x0000000010000000 0x0000dd82ce799c80
ps3dumpslb:37: 0x00000000f0000000 0x0000ce15d890ac80
ps3dumpslb:38: 0x0000000010000000 0x0000c39dcf390c80
ps3dumpslb:39: 0x00000000f0000000 0x0000e7fad7d13c80
ps3dumpslb:40: 0x0000000010000000 0x0000dd82ce799c80
ps3dumpslb:41: 0x0000000000000000 0x0000dcc36017ec80
ps3dumpslb:42: 0x00000000f0000000 0x0000ce15d890ac80
ps3dumpslb:43: 0x0000000010000000 0x0000c39dcf390c80
ps3dumpslb:44: 0x00000000f0000000 0x0000e7fad7d13c80
ps3dumpslb:45: 0x0000000010000000 0x0000dd82ce799c80
ps3dumpslb:46: 0x0000000000000000 0x0000dcc36017ec80
ps3dumpslb:47: 0x00000000f0000000 0x000037cbb848ec80
ps3dumpslb:48: 0x0000000010000000 0x00002d53aef14c80
ps3dumpslb:49: 0x00000000f0000000 0x0000e7fad7d13c80
ps3dumpslb:50: 0x0000000010000000 0x0000dd82ce799c80
ps3dumpslb:51: 0x0000000000000000 0x0000dcc36017ec80
ps3dumpslb:52: 0x00000000f0000000 0x0000ce15d890ac80
ps3dumpslb:53: 0x0000000010000000 0x0000c39dcf390c80
ps3dumpslb:54: 0x00000000f0000000 0x0000e7fad7d13c80
ps3dumpslb:55: 0x0000000010000000 0x0000dd82ce799c80
ps3dumpslb:56: 0x0000000000000000 0x0000dcc36017ec80
ps3dumpslb:57: 0x00000000f0000000 0x000037cbb848ec80
ps3dumpslb:58: 0x0000000010000000 0x00002d53aef14c80
ps3dumpslb:59: 0x00000000f0000000 0x0000e7fad7d13c80
ps3dumpslb:60: 0x0000000010000000 0x0000dd82ce799c80
ps3dumpslb:61: 0x0000000000000000 0x0000dcc36017ec80
ps3dumpslb:62: 0x00000000f0000000 0x000037cbb848ec80
ps3dumpslb:63: 0x0000000010000000 0x00002d53aef14c80

SLB table dump from Linux:

ps3dumpslb:0: 0xc000000008000000 0x0000408f92c94500        <--------- bolted kernel segment
ps3dumpslb:1: 0xd000000008000000 0x0000f09b89af5400        <--------- bolted kernel vmalloc segment
ps3dumpslb:2: 0xc000000000000000 0x0000000000000000
ps3dumpslb:3: 0x0000000010000000 0x0000136eafb0bc80
ps3dumpslb:4: 0xd00007fff0000000 0x0000a70cf353a400
ps3dumpslb:5: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:6: 0x0000000000000000 0x00000957a0a78c80
ps3dumpslb:7: 0x00000000f0000000 0x0000148f1860dc80
ps3dumpslb:8: 0x0000000010000000 0x00000a170f093c80
ps3dumpslb:9: 0x0000000000000000 0x000012af414f0c80
ps3dumpslb:10: 0x00000000f0000000 0x00001de6b9085c80
ps3dumpslb:11: 0x0000000010000000 0x0000136eafb0bc80
ps3dumpslb:12: 0x0000000000000000 0x0000a44d91430c80
ps3dumpslb:13: 0x00000000f0000000 0x0000af8508fc5c80
ps3dumpslb:14: 0x0000000010000000 0x0000a50cffa4bc80
ps3dumpslb:15: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:16: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:17: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:18: 0x0000000010000000 0x0000a50cffa4bc80
ps3dumpslb:19: 0x00000000f0000000 0x0000af8508fc5c80
ps3dumpslb:20: 0x0000000008000000 0x00005dd45172ec80
ps3dumpslb:21: 0x00000000f8000000 0x0000690bc92c3c80
ps3dumpslb:22: 0x0000000018000000 0x00005e93bfd49c80
ps3dumpslb:23: 0xd00007fff8000000 0x0000a70cf353a400
ps3dumpslb:24: 0xd000080088000000 0x0000adc7d4c2d400
ps3dumpslb:25: 0xd00007fff0000000 0x0000a70cf353a400
ps3dumpslb:26: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:27: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:28: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:29: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:30: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:31: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:32: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:33: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:34: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:35: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:36: 0xd00007fff0000000 0x0000a70cf353a400
ps3dumpslb:37: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:38: 0x0000000020000000 0x0000c45d3d9abc80
ps3dumpslb:39: 0x0000000010000000 0x0000c39dcf390c80
ps3dumpslb:40: 0x00000000f0000000 0x0000ce15d890ac80
ps3dumpslb:41: 0xd00007fff0000000 0x0000a70cf353a400
ps3dumpslb:42: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:43: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:44: 0xd00007fff0000000 0x0000a70cf353a400
ps3dumpslb:45: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:46: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:47: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:48: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:49: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:50: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:51: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:52: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:53: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:54: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:55: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:56: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:57: 0xd00007fff0000000 0x0000a70cf353a400
ps3dumpslb:58: 0xd000080080000000 0x0000adc7d4c2d400
ps3dumpslb:59: 0x0000000020000000 0x0000c45d3d9abc80
ps3dumpslb:60: 0x0000000010000000 0x0000c39dcf390c80
ps3dumpslb:61: 0x00000000f0000000 0x0000ce15d890ac80
ps3dumpslb:62: 0x0000000000000000 0x000012af414f0c80
ps3dumpslb:63: 0x00000000f0000000 0x00001de6b9085c80
Personal tools
Namespaces
Variants
Actions
Gitbrew
Navigation
projects
Toolbox