# Application Programming Environment

Copyright © 2006 Sony Computer Entertainment Inc.
Copyright © 2006 Sony Corp.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".

DISCLAIMER

THIS DOCUMENT IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THE DOCUMENT ARE SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE DOCUMENT OR THE PERFORMANCE OR IMPLEMENTATION OF THE CONTENTS THEREOF.

This note explains howto setup programing environment, programing environment itself includng SPE programming and PS3 platform specific programming.

## Setup PPE Programming Environment

PPE programs can be developed and run in the same way as conventional programs on Linux. Readers of the document are supposed to have knowledge of application programming on conventional Linux, and are provided no descriptions about details of application programming, here. In general, packages such as GCC, G++ and GDB, are required to develop PPE programs in C and/or C++. Please refer manuals of Linux distribution which you use, for detail.

## Set up SPE Programming Environment

The following add-on packages are needed to be installed, to develop SPE programs in addition to the PPE programming environment.

SPU compilers, binutils and debugger
  Following SPU compilers, binutils and debugger packages are avaiable on Barcelona Super Computer Center (BSC) website. Please refer to "GNU Toolchain 4.0.2 and GDB for the Cell BE's SPU" page on the website, for details.
  To reach the page, you would visit the page "Linux on Cell" , then go down to "Cell BE Components".

- spu-binutils-3-2-6.ppc.rpm
- spu-gcc-3-2-6.ppc.rpm
- spu-gcc++-3-2-6.ppc.rpm
- spu-gdb-3-2-6.ppc.rpm

SPU newlib

- spu-newlib-1.14.0.200610300000-1.ps3pf.ppc.rpm

libspe2

- elfspe2-2.0.0-be0644.3.20061107.1.ps3pf.ppc.rpm
- libspe2-2.0.0-be0644.3.20061107.1.ps3pf.ppc64.rpm
- libspe2-2.0.0-be0644.3.20061107.1.ps3pf.ppc.rpm
- libspe2-devel-2.0.0-be0644.3.20061107.1.ps3pf.ppc64.rpm
- libspe2-devel-2.0.0-be0644.3.20061107.1.ps3pf.ppc.rpm

After installing Linux distribution, install the add-on packages above by executing the following command:

# rpm -ivh *.rpm

## PPE Programming Environment

The conventional development and runtime environment on Linux is used to develop and to run PPE programs. Readers of the document are supposed to have generic knowledge of application programming on such conventional Linux, and descriptions about details of application programming will not provided here.Please refer to manuals of the Linux distribution which you use, and/or published books, for details of application programming environment on Linux.

## SPE Programming Environment Overview

Fig. 1 shows overview of SPE runtime environment, including diagram consists of SPUFS from kernel, libspe2 and SPU newlib.

Fig. 1 Diagram of SPE runtime environment

Linux kernel has equipped SPUFS for abstraction of SPEs, and application programs can handle SPEs by using libspe, which utilize the SPUFS internally. For SPE side, GCC and G++ are available as compilers, and newlib is provided as a standard C library.

Libspe2

  Libspe, the SPE management library, is needed to access SPEs by application programs on PS3 Linux. On PS3 Linux, libspe version 2 (libspe2) is provided as a standard library. Please refer libspe-v2.0.pdf.

SPU compilers

  To develop SPE application programs, binutils and gcc with SPE support are used on PS3 Linux. Currently, the following versions in Cell SDK 1.1 are recommended.

- binutils 2.16.1
- gcc 4.0.2

SPU newlib

  SPU newlib is an implementation of C runtime library for SPE. It is required to develop application programs in C and/or C++. The new version of newlib for PS3 Linux is recommended because of improvements as following against the other version in Cell SDK 1.1:

- Mainlined SPE support.
- Optimized size by off-loading stdio functions such as printf

## Platform Specific Programming

### Programming with Frame Buffer

The frame buffer on PS3 platform has been implemented as virtual frame buffer allocated on main memory. We’ll explain how it works and how user program could be control it, here.

#### Virtual Frame Buffer and VSYNC

Fig. 2 shows a whole picture of double buffering and VSYNC support with the frame buffer device.

Fig. 2 Virtual frame buffer and VSYNC timimg

Virtual frame buffer is allocated two sides, on main memory in Kernel space. User space application can use this frame buffer with mapping it to user space by mmap(). With mmap() against /dev/fb, User can map up to 2 buffers and choose two model. One is “single buffer”. With this model, user can map and draw to frame buffer just same as conventional frame buffer. The kernel daemon would take place flip hvc. The other is “double buffer” model, with it application need to take care to issue flip through ioctl by program itself, although it could achieve flicker-less drawing

#### Single Buffer Model

Fig. 3 shows timing chart of hypervisor call, dma and irq with a single buffer scenario, inside Kernel.

Fig. 3 VFB behavior in the Linux kernel

The kernelkernel daemon “ps3fbd” implements single frame buffer model and controls its dma and flip using hvc.

1. In the GPU side flip is done at vsync timing and after finishing it, the interrupt is issued to the kernel. Handling the interrupt, the kernel daemon requests dma via hyper visor and the data in the frame buffer on main memory is transferred to the GPU. This hvc is blocking call.
2. The daemon calls non-blocking FLIP request via hyper visor. At the next vsync timing, flip will be done in the GPU side.
3. Return to 1.

#### Double Buffer Model

Fig. 4 shows timing of IOCTL, hypervisor call, dma and irq with double buffer scenario.

Fig. 4 IOCTL usgae from the user Application

From the user applications, the frame buffer can be used with double buffering as following.

1. Get a screen size and number of frame buffers by ioctl PS3FB_IOCTL_SCREENINFO.
2. Stop the “ps3fbd” which performs flip in the kernel by ioctl PS3FB_IOCTL_ON. Then flip will be controllable from the user space.
3. Wait the next vsync by blocking ioctl FBIO_WAITFORVSYNC.
4. After the vsync, call blocking ioctl PS3FB_IOCTL_FSEL with frame buffer number in user space. This number indicates which frame buffer will be used at the next flip. After calling the ioctl, the data in the frame buffer is transferred with dma and flip request is issued in the kernel.
5. Return to 3.
6. Call the ioctl PS3FB_IOCTL_OFF at the end of the applications.

#### Sample Code

You can find the sample code as "vsync-sample" pacakge.

This sample code is a simple drawing program with frame buffer using double buffering.

How to compile
  To build binaries, simple use make as follwos.
  % make clean; make
How to run
  Before running the sample code, get root privilage which /dev/fb0 operations require.
  Sample 1 - shows "moving line" with double buffering.
  # vsync 1
  Sample 2 - shows "moving line" with single buffering.
  # vsync 2
  Sample 3 - red and blue screen by turns with double buffering
  # vsync 3
What it shows
  The code shows how to use ioctl for frame buffer with double buffering. Brief description is as follows. Please check the source code "vsync.c" for more details.
  After opening /dev/fb0 and get handle, you can use ioctl for frame buffer in the kernel via /dev/fb0. Check the size of the frame buffer by ioctl and map it to the user space. After writing data to the buffer in the user space, issue ioctl PS3FB_IOCTL_FSEL and then the data will be displayed at the next vsync timing. You can get this timing by blocking ioctl FBIO_WAITFORVSYNC, after returning the ioctl you can reuse the buffer. Fig. 4 shows ioctl and flip timing, please see it for more details. Don't forget to call PS3FB_IOCTL_OFF at the end of your application, or frame buffer in the kernel remains blank.
Note
  You can also use console ioctl to switch text/graphics mode. Please check man pages for console_ioctl.

---