Root is always right -- the kernel
Crossreference: ps3devwiki::FreeBSD Development
Get in touch with me if you want to help with FreeBSD development because there are only 2 developers currently working on FreeBSD PS3 support :(
Till now 0 applications :( Date: 12/18/2011
- VUART support in bootloader
- VUART support in kernel (work in progress)
- System Manager, AV and Dispatcher Manager support in kernel (work in progress)
- UDF support for BD movies
- RSX driver
- Sound driver
- Use CAM framework for HDD driver like in Blu-Ray driver
- FLASH/VFLASH drivers (work in progress)
- WiFi driver (work in progress)
- It seems that loader has issues with booting from CDROM. I made a test program which just reads several sectors from CDROM by using polling. It works for some minutes and then just hangs and BD-Drive makes strange noises. I'm quite sure the problem lies in SONY's FW (Fixed the problem, it was loader actually, pushing it to official FreeBSD head repository)
Cross-Compiling Kernel Module
- All steps below are done with a non-root user.
- It is assumed that powerpc64 toolchain was previously installed in /usr/obj/PS3 by running make buildworld. See compiling FreeBSD kernel for more details.
$ cd $ tar xvzf ps3gpu.tar.gz $ cd /usr/src $ env MAKEOBJDIRPREFIX=/usr/obj/PS3 make TARGET=powerpc TARGET_ARCH=powerpc64 buildenv Entering world for powerpc64:powerpc $ export SYSDIR=/usr/devel/sys $ cd ~/ps3gpu $ make $ file ps3gpu.ko ps3gpu.ko: ELF 64-bit MSB shared object, 64-bit PowerPC or cisco 7500, version 1 (FreeBSD), \ dynamically linked, not stripped
- Should be very simple
- Implement common ps3vuart interface which can be used by VUART port drivers
- Implement AV VUART only for now in order to be able to read screen size
- What existing kernel framework to use or create a new one ??? Maybe UART framework. UART framework is NOT suitable !!!
- Implement ps3vuart_bus.c module which handles VUART interrupts and distributes events to VUART port drivers. ps3vuart_bus should be the child of nexus.
- Each VUART port is a child of ps3vuart_bus module.
- Use siis driver as an example how to implement device children.
- VUART port drivers for: System Manager, AV and Dispatcher Manager
- What is the best way to provide access for user space applications ??? Create character devices for each VUART port. But how to synchronize kernel/user space accesses ?
- Provide IOCTL interface for all VUART ports
- Currently, to get VUART IRQ working you have to patch ps3pic.c module.
Replace this line:
powerpc_register_pic(dev, 0, sc->sc_ipi_outlet, 1, FALSE);
powerpc_register_pic(dev, 0, 63, 1, FALSE);
- Finally i can communicate with VUART ports on FreeBSD but still having trouble with hangs :( Trying to fix it.
- Currently having trouble with VUART IRQ. As soon as it is triggered, FreeBSD hangs totally. Not sure why.
- Hmm, still trying to fix VUART problems. Odd but while loader is running and i press power button then PS3 doesn't hang. But if FreeBSD kernel runs and i press the button then it hangs.
- Finally, VUART works great with freebsd-head :)
- Link: http://gitbrew.org/~glevand/ps3/freebsd/ps3vuart.tar.gz
VUART Drivers in Action
- Access to all VUART ports NOT only from kernel space but from user space too, unlike on Linux.
- Access to System Manager, AV and Dispatcher Manager.
- Rebooting FreeBSD with power button works.
[glevand@freebsd ~/ps3vuart]$ dmesg ... ps3vuart0: <Playstation 3 VUART> on nexus0 ps3vuart_bus0: <Playstation 3 VUART Bus> irq 18 on ps3vuart0 ps3av0: <Playstation 3 AV> at port 0 on ps3vuart_bus0 ps3sm0: <Playstation 3 SM> at port 2 on ps3vuart_bus0 ps3av0: detached ps3av0: <Playstation 3 AV> at port 0 on ps3vuart_bus0 ps3sm0: detached ps3sm0: <Playstation 3 SM> at port 2 on ps3vuart_bus0 ps3sm0: power button pressed ps3sm0: power button released ps3dm0: <Playstation 3 DM> at port 10 on ps3vuart_bus0 [glevand@freebsd ~/ps3vuart]$ sudo ./ps3av_user Password: send video init request read video init response video init status 0x00000000 send audio init request read audio init response audio init status 0x00000000 send AV init request read AV init response AV init status 0x00000000 send AV get hw conf request read AV get hw conf response AV get hw conf status 0x00000000 hdmi 1 avmulti 1 spdif 1 send AV get monitor info request read AV get monitor info response AV get monitor info status 0x00000000 type 2 name XXXXX [glevand@freebsd ~/ps3vuart]$ sudo ./ps3sm_user send ring buzzer send set attribute [glevand@freebsd ~/ps3vuart]$ sudo ./ps3dm_user send SM get rnd SM get rnd status 0 rnd: 0xca 0x55 0x2c 0x56 0x7c 0x0e 0x33 0x60 0xd3 0xbb 0x59 0x1e 0xa6 0x4b 0xdb 0x73 0xa6 0x28 0x09 0x28 0x74 0x34 0xba 0xda [glevand@freebsd ~/ps3vuart]$ sudo ./ps3dm_user send SM get rnd SM get rnd status 0 rnd: 0x11 0xbb 0x60 0x9d 0xf0 0xfe 0x56 0x30 0x27 0x51 0x13 0x13 0x75 0x80 0xf3 0xcf 0x5d 0xac 0x31 0x08 0xb7 0xef 0x56 0x72 [glevand@freebsd ~/ps3vuart]$ sudo ./ps3dm_user send SM get rnd SM get rnd status 0 rnd: 0xf1 0xc6 0x66 0x46 0x01 0x7b 0x7a 0x81 0xf5 0x4e 0xb2 0x54 0x7c 0xd5 0x11 0x14 0xac 0x26 0xf4 0x91 0x98 0xc9 0x4f 0xd2
- Kernel modules: if_jpt.c, jpt_sta.c and jpt_ap.c.
- Use WLAN driver an as an example how to implement WLAN drivers which handle 802.11 protocol internally.
- IOCTLs for scanning: IEEE80211_IOC_SCAN_REQ and IEEE80211_IOC_SCAN_RESULTS
- Currently, the syscons driver is very simple. It allocated video RAM and points both heads to it. There is no double buffering like on Linux. The front buffer (visible video RAM) is changed directly through memory mapping.
- I decided to implement RSX driver for FreeBSD first and then for Linux (sorry Linux fans), not because i don't like Linux but because FreeBSD has no X11 driver and it will be easier to test.
- FreeBSD DRM framework supports PCI devices only currently :-( Platform devices are NOT supported by FreeBSD's DRM framework.
- No choice as to use kernel module with my own user space interface. Yeah, hate me kernel developers, i know, it's ugly but NVIDIA does it too (/dev/nvidia, /dev/nvidiactl and nvidia.ko).
- Use pmap_mapdev to map GPU memory.
- Here is my low-level GPU driver and test program: http://gitbrew.org/~glevand/ps3/freebsd/ps3gpu.tar.gz, http://gitbrew.org/~glevand/ps3/freebsd/ps3gpu_test.tar.gz
- Here is my X11 ps3gpu driver: http://gitbrew.org/~glevand/ps3/freebsd/xf86-video-ps3gpu.tar.gz
- Here is the first screenshot of the accelerated X11 driver for FreeBSD based on ps3gpu kernel driver: http://gitbrew.org/~glevand/ps3/freebsd/freebsd_ps3_x11_fullhd_exa_accel_and_hw_cursor.png
Compiling X11 Video Driver
- You have to compile and install xorg-server from ports first.
- You have to install autoconf and automake from ports too.
$ tar xvzf xf86-video-ps3gpu.tar.gz $ cd xf86-video-ps3gpu $ ./autogen.sh $ ./configure (optional) $ make $ sudo make install
DRM Device File
- On FreeBSD, it's cdev.
- si_drv1 points to struct drm_device
- There are several types of memory: VRAM (video RAM or memory on GPU), GART (system memory mapped into GPU address space) and CPU (system memory but NOT mapped into GPU address space)
- Implement memory heap managers
- Radeon driver is a good example how to manage VRAM and GART memory heaps. The user specifies memory type, alignment and size. The driver returns the offset of allocated memory region to user. The offset is the handle of allocated memory block.
- Radeon driver supports memory types: VRAM and GART
- Nouveau driver supports memory types: VRAM, GART and CPU
- mmap syscall is used to map memory buffers into user-space. offset passed to mmap syscall is the handle of a memory map created previously with IOCTL DRM_IOCTL_ADDMAP. The handle is returned to user from IOCTL that creates the map.
- drmMap just calls mmap syscall and passes map handle as offset.
- Interesting discussion about DRM map handles: http://comments.gmane.org/gmane.comp.video.dri.devel/19657
- FreeBSD DRM framework uses alloc_unr to allocate unique map handles
- Here is a good template for a sound driver: http://people.freebsd.org/~cg/template.c
- Started to port sound driver to FreeBSD.
- Use CAM framework to implement flash drivers, it has more advantages over block device drivers
- The drivers are very similar to CDROM driver but they should handle ATA IO commands and SCSI like ps3cdrom driver
- Kernel modules: ps3flash for FLASH/VFLASH and ps3nflash for NOR flash only
ps3flash0: <Playstation 3 FLASH> irq 15 on ps3bus0 ps3nflash0: <Playstation 3 NOR FLASH> irq 12 on ps3bus0
- We need a kernel module to create/delete storage regions.
- I'm thinking about implementing a kernel module with new syscalls.
- Syscall number is allocated dynamically. Use modfind/modstat to read the syscall number.
- FreeBSD allows ONLY one syscall per module, maybe use ioctl interface instead.
- The Design and Implementation of the FreeBSD SCSI Subsystem: 
- Writing a CAM SCSI controller driver: 
- FreeBSD Kernel Reference: 
- UDF 2.6: 
- The VFS/VNODE interface in the FreeBSD kernel: 
- FreeBSD DRI: 
- FreeBSD Device Drivers: 
- FreeBSD Kernel Modules:  
- NEWBUS Intro: 
- Character Driver:  
- NVIDIA Kernel Interface: 
- Writing and Adapting Device Drivers for FreeBSD: 
- kqueue: 
- Goot example how to use kqueue for multi-client server: http://www.monkeys.com/freeware/kqueue-echo.c
- Sound driver: 
- DEVFS: 
- SMP:  (very good paper about SMP on UNIX)
- KTR: http://www.watson.org/~robert/freebsd/netperf/ktr/