I2C emulation in qemu-loongson

Apr 22nd, 2009 | Posted by yajin | Filed under emulation, loongson

I think most of you may think it is easy to emulate I2C device in qemu, for qemu has provided a framework of i2c, both the master and slave devices. You are right. Emulating the I2C is not difficult in qemu.

What I want to post here is not emulating I2C device directly, but emulating GPIO logic which pmon uses to emulate I2C. A little confused? Me too. Ok, let me talk the story from the began.

In pmon, it uses sm502 gpio pin 6 and 13 to emulate I2C master devices, which communicates with other slave device, such as SPD EEPROM and temperature sensors. I do not know why lemote uses gpio to emulate i2c, instead of using the I2C master in sm502. When the data is written to gpio pins according to I2C state machine, pmon expects the gpio pins acting like the I2C master devices. So qemu needs to emulate the I2C cycle accurate state machine, not only the I2C function.

I summarize the I2C emulation code logic of pmon here for reference.

(1) Start Bit

SCL=0 -> SDA=1 -> SCL=1 -> SDA=0 -> SCL=0

(2)Stop Bit

SCL=0 -> SDA=0 ->SCL=1 ->SDA=1 -> SCL=0

(3)Write a bit

Put data on sda -> SCL=1 -> SCL=0

(4)Write a byte

repeating (3) 8 times -> SDA=1

(5)Recv ACK

SCL=1 ->read sda until sda=0 -> SCL=0

(6)Read a bit

SCL=1 -> read data on SDA -> SCL=0

(7)Read a byte

repeating (6) 8 times

(8)Send ACK

put ACK on sda -> SCL=1 -> SCL=0

(9)Send a buffer

Do the following steps until the buffer is empty

  1. START
  2. Send slave address
  3. Recv ACK
  4. Send reg address
  5. Recv ACK
  6. Send one byte
  7. Recv ACK
  8. STOP

(10) Recv many bytes from slave deviceDo the following steps until finished

  1. START
  2. Send slave address
  3. Recv ACK
  4. Send reg address
  5. Recv ACK
  6. Repeat START
  7. Send slave address+1(tell slave we want to recv)
  8. Recv ACK
  9. Recv a byte
  10. Send ACK
  11. STOP

eth0 is missing on my gdium PCB board

Mar 28th, 2009 | Posted by yajin | Filed under loongson

I have an extra gdium pcb board with uart interface from fred. Thanks :) .

Today I try to compile the kernel by myself and the new kernel works well except for network card. I can not see eth0 using ifconfig command. Then I check the pci list of my gdium PCB and find the RTL8139D is on the list.

kill-bill:~# ifconfig eth0
eth0: error fetching interface information: Device not found

kill-bill:~# lspci
00:00.0 MIPS: STMicroelectronics STLS2F Host Bridge (rev 01)
00:0d.0 Network controller: RaLink RT2561/RT61 802.11g PCI
00:0e.0 Display controller: Silicon Motion, Inc. SM501 VoyagerGX Rev. AA (rev c0
)
00:0f.0 USB Controller: NEC Corporation USB (rev 44)
00:0f.1 USB Controller: NEC Corporation USB 2.0 (rev 05)
00:10.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8139/8139C/8139
C+ (rev 10)
00:11.0 USB Controller: NEC Corporation USB (rev 44)
00:11.1 USB Controller: NEC Corporation USB 2.0 (rev 05)

That shows rtl8139 is successfully initialized by the kernel. But why there is no eth0 device?

Then I grep eth0 in dmesg and find that something is wrong with udev.

kill-bill:~# dmesg | grep eth0
eth0: RealTek RTL8139 at 0x9000000051a2a100, 00:d0:35:10:00:20, IRQ 39
eth0:  Identified 8139 chip type 'RTL-8100B/8139D'
udev: renamed network interface eth0 to eth1

I cat the udev net rule and find that it sets 8139d with MAC address 00:d0:35:10:00:20 to eth1. That's exactly the network card on my gdium PCB.

kill-bill:~# cat /etc/udev/rules.d/70-persistent-net.rules
# This file was automatically generated by the /lib/udev/write_net_rules
# program run by the persistent-net-generator.rules rules file.
#
# You can modify it, as long as you keep each rule on a single line.

# PCI device 0x10ec:0x8139 (8139too)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:d0:35:10:04:a9", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

# PCI device 0x1814:0x0301 (rt61pci)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:0e:8e:19:3d:68", ATTR{type}=="1", KERNEL=="wlan*", NAME="wlan0"

# PCI device 0x10ec:0x8139 (8139too)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:d0:35:10:00:20", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"

# PCI device 0x1814:0x0301 (rt61pci)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:0e:8e:19:3b:18", ATTR{type}=="1", KERNEL=="wlan*", NAME="wlan1"

I know why dev does that now. The debian system is installed on my gdium, not on the PCB and then I just use it on the PCB board. When udev finds there is another 8139d network card with different MAC address it adds another entry in rules to rename it to eth1. After changing the eth1 to eth0 in 70-persistent-net.rules, the network works now.

Following is the kernel information of my new kernel.:)

kill-bill:~# dmesg | grep 2.6.24
Linux version 2.6.24.5-gdiumv3-2.2mnb (root@debian) (gcc version 4.3.3 (GCC) ) #
2 Sat Mar 28 16:00:59 CST 2009

Tags: , ,

QEMU Does NOT Support MIPS Host Anymore

Mar 26th, 2009 | Posted by yajin | Filed under emulation, loongson

New version of qemu does not support MIPS host anymore.

For the sake of portability, the new version of qemu uses TCG, a tiny code generator, instead of dyngen to generate host code. That means one backend is needed for each host architecture. There are i386,x86_64,ppc,ppc64 and hppa backend in TCG, but MIPS is not on the list.

I confirm this conclusion on the status page of qemu web site. The MIPS's status is 'Not Supported'. Perhaps these days the most emergent work is to add MIPS host support, instead of loongson guest support to qemu.

How to Install Debian Lenny on Gdium

Mar 20th, 2009 | Posted by yajin | Filed under loongson

Although Vincent has given us a how to article of debian on gdium, but there are some detailed things missed. So I rewrite it here with some more detailed steps.

(1) Prepare the new USB disk

Format the new USB disk with at least tow partitions, one is ext2 partition for the root file system and the other is swap space. You can use fdisk to do this.

(2) Install the debian base system using debootstrap

You need to install the debootstrap in gdium first.

urpmi debootstrap

Mount the new USB disk to your gdium, /mnt for example. Replace /dev/sdc1 to the name of your USB device.

mount /dev/sdc1 /mnt

Install the debian base system using debootstrap. You can change lenny to sid if you want to use the debian testing system. To me, I prefer lenny.

debootstrap --arch=mipsel lenny /mnt

It will download the packages and install to system. So please be patient if your network speed is slow.

Copy /etc/resolv.conf  to your new system and set the hostname of the new system.

copy /etc/resolv.conf  /mnt/etc/resolv.conf

echo YOUHOSTNAME > /mnt/etc/hostname

Chroot to your new system.

chroot /mnt /bin/bash

Read more...

My New Toy: Gdium Liberty 1000

Mar 16th, 2009 | Posted by yajin | Filed under ARM/MIPS, loongson

This morning I eventually received my gdium liberty 1000 from zjs express, nearly 5 days after its shipping! Last time I use sf express to ship my mp4 player to Beijing in less than 2 days. I understand, because of the battery stuff can not be shipped by airline, but 5 days is excessive for train and even for truck!

Although a little dissatisfied with the shipping express, gdium seems very attractive to me at my first glance for its smart size and its black color. It spend me a little time to make the battery work because I do not know how to assemble the battery at first. The speed of gdium is not as good as I had expected for a 900MHZ CPU. But there is room for optimization because of the N32 MIPS ABI. The screen resolution is excellent, 1024*600 is enough for most of the web sites. The Chinese fonts display very well when I visit the sina.com.cn, thanks to wqy fonts. The Youtube videos can also display very well in Firefox. Awesome! I do not find which plugin does firefox use to display the flash, gnash maybe? The gtk desktop is not very fluent, but that's ok because I will replace it with a lightweight desktop.

Gdium, to me, is a development platform more than a notebook for daily use. I want a MIPS development platform for a long time and gdium is the very one. It is better than the yeeloong notebook, which I planned to buy a few months ago, for gdium has an bigger LCD and good look.

I have too many plans on this new toy, porting android, porting lguest and kvm. But the issue is there is no uart interface on gdium. If you want the uart interface, you need to seal it by yourself. That is too hard to me, a hardware beginner.

If there is an emulator of gdium, life would be much easier. I can use the emulator to test the pmon/linux kernel and lguest porting. I know I can develop a gdium emulator based on qemu, but I have done too much about the emulator stuff, qemu-omap3, qemu-jz, virtualmips and a little fed up with emulator development. But emulator is really a big helper for kernel related development......

Following is my todo list these months.

  • install debian and a lightweight desktop for gdium
  • develop an emulator of gdium based on qemu
  • port lguest and kvm to MIPS
  • port android to gdium and tune the performance of dalvik runtime on MIPS target

Let's bring virtualization into MIPS's world

Feb 25th, 2009 | Posted by yajin | Filed under ARM/MIPS, JZ, kernel

I have spent about 1 month in making linux run on onda vx747 and it works now. Although it is a achievement, it's not the end of project jz-hacking.

These days I am always thinking about bringing virtualization into MIPS's world. You know, xen has been ported into ARM by Samsung and kvm into PPC by IBM. X86, not even to say,  has the most complete support of virtualization in hardware and software. But to MIPS, there is nothing. Neither there is no virtualization support in MIPS's world nor anyone wants to do this(at least I have NOT heard of that).

I think you may ask who needs virtualization or why we need virtualization in MIPS's world. Well, that's a good question which is not easy to answer. Let's divide MIPS's world into two parts: high performance computing and embedded devices. For the first part, the advantage of virtualization is obvious, for example, making better resource utilization.To the embedded world, let's use mobile phone as an example, using virtualization can make your device more secure by isolating the critical part, communicating protocol for example, from feature rich os(linux for example). Because of isolation, the virus on linux can not control your system's critical part.

Loongson has done great job in developing 2E and 2F, but that's not enough. I find that loongson has put many effort into x86 binary translation acceleration in last few years. That's a good point to get more market share. But we need to consider one thing first, if one customer wants to buy a MIPS translated x86 cpu, why does not he buy a x86 cpu directly? I think there is one area which loongson should put even more effort into. That is virtualization!

Virtualization can be achieved by hardware and/or software, with the better performance if hardware supports this feature. To the software virtualization, we already have xen/kvm/lguest and OKL4(it seems to focus on embedded world). Xen is a paravirtualization solution while kvm is a full virtualization solution. The most obvious difference between paravirtualization and full virtualization is prarvirtualization needs to modify the guest operation system while full virtualization needn't. Of course you can do this in full virtualization to achieve better performance.

According to MIPS, I think there should be a solution of virtualization. Either kvm or xen is ok. The important part is that we need to have one. That's what I was planned todo even in one year ago when I was busy developing virtualmips. I spent some days on porting lguest to jz4740 in last July. But at last I gave up. Now I want to do it again. I plan to port lguest to jz4740 and  loongson 2f first. With the help of this experience, I can gain some knowledge about virtualization on MIPS platform. And then kvm is planned to be ported to loongson 2f. Image that one day we can run five linux operating systems on loongson 2f at the same time, is it cool?

If you are interested in virtualization, let's work together to make this happen. Do not leave MIPS alone while other boys all have virtualization to play with. :)

Problems I meet when porting linux to onda vx747

Feb 24th, 2009 | Posted by yajin | Filed under JZ, kernel

1. About jz4740 DMA

JZ4740 has 2 groups of DMA, 4 channels in each group. The default prority is channel 0 has the highest priority and channel 7 has the loweset priority.

Channel 0 is used for SLCD and channel 2/3 are used for MMC TX/RX. Because the SLCD DMA is busy transmitting data from frame buffer to LCD controller, so that MMC DMA is in hunger and the root filesystem can not be loaded from micro sd card.

In SLCD driver, set the DMA priority to round bin.

2. Issues about qtopia

(1)QWSServerSocket: could not bind to file /tmp/qtembedded-unknown/QtEmbedded-0

Error: File exists

Failed to bind to /tmp/qtembedded-unknown/QtEmbedded-0

Add networking support in linux kernel.

Networking support->Networking options->Unix domain sockets

(2)QServerSocket: failed to bind or listen to the socket
Failed to bind to port 4243
QServerSocket: failed to bind or listen to the socket
Failed to bind to port 4242

According to http://osdir.com/ml/handhelds.opie/2002-10/msg00253.html,

Opie is binding to the ports 4242(ftp) and 4243(qcopbridge) this is needed for
syncing.. Opie got terminated and restarted somehow and did not properly
release the sockets..
I guess this is a kernel security feature.

That's because Opie can not bind to port 4242 and 4243. After enabling TCP/IP support in linux kernel, this problem is solved.

Networking support->Networking options->TCP/IP networking

(3)Unable to open /usr/share/zoneinfo/zone.tab

That's because zoneinfo directory is missed. Copy it from my debian and it works.

3. Issues about framebuffer console

When I pass console=fb0 to linux kernel, the framebuffer does not appear on LCD. I am sure the LCD driver is working because the qtopia can run successfully. And I have enabled framebuffer console support in linux kernel.

Pass console=tty0 to linux kernel can solve this problem.

linux on onda vx747(updated)

Feb 24th, 2009 | Posted by yajin | Filed under JZ, kernel

Before reading this article, please please visit the following website and help this little girl. She is the daughter of panjet, the core member of this project. Without him, this project can not even happen.

http://yifanfund.com (English)

在阅读这篇文章前, 我恳请您花一点时间来帮助panjet的女儿怡帆. Panjet是这个项目的核心成员.如果没有他的参与,这个项目不可能成功地port linux到vx747上面. 赠人玫瑰,手留余香.  您的爱心一定能让小怡帆度过目前的困难.

http://help-yifan.org (中文)

Hi guys, a good news for you who are interested in running linux on jz4740 based devices. First I would link to say it is not a very easy work although ingenic has released the linux source code. Secondly I would like to say thanks to many people who helped me a lot, vxworks,panjet,esoul of linuxforum and Maurus Cuelenaere, the great rockbox guy.

Hey do not be so boring to say these useless words. Tell me how do you do that. Ok. Please be patient.

Currently linux can run on onda vx747 without writting any things to your nand flash. What you need is just a micro sd card  bigger than 128M bytes where you put linux kernel and root filesystem. Of course, if you want to replace the original firmware and write u-boot into nand flash, I can tell you how to do it. Even after writing u-boot into your nand flash you can still reinstall the original firmware. So please do not worry about your devices.  It won't be damaged.

1. Download the following files from jz_hacking.

(1)jz_tools_20090224.tar.bz2: It contains a tool called usbtool which uploads your program into jz4740's internal sram directly.

md5:1520851babe97da15651f9bef2c1ac5f

(2)jz_hacking_20090224.tar.bz2: It contains u-boot image, jz_xloader and linux image.

md5:ac755b694f6e38224560a9051f1392e7

(3)root26.tar.bz2: root file system of linux 2.6 kernel with qtopia

md5:738f6dfc648d36229a799d1d608655d1

Some guy says that this bz2 file is corrupted. I have tried downloading it using firefox in window and the file downloaded is corrupted!. But when I use other download tool it is ok. So if you can not unpack this package, you can try downloading it using other download tool. Wget in linux works well.

2. Make usbtool

Decompress the jz_tools_20090224.tar.bz2 and build the usbtool. It can be compiled in linux or minigw on windows. Please first read the README file in 'jz_tools_20090224/usb_tools'.

In linux, libusb-dev needs to be installed first. In windows, install MingW32 and LibUSB-Win32 and edit "Makefile" to make sure "WIN_DRIVERS_LIBUSB_DIR" is set correctly.

Type 'make linux' in linux platform and 'make win' on windows to build usbtool. After that copy jz_xloader.bin and u-boot-boot-linux.bin and u-boot-program-nand.bin from jz_hacking_20090224 into this directory.

3. Prepare your micro sd card

First you need to format sd card into two three partitions, one is fat and the other is ext2 and the third partition is swap. You do not know how to do it? Do not worry. This wiki page on beagle board tells you how to do it.  Please  to format your first partition to FAT16 format, not FAT32 referred on the wiki page. That mean you have to use 'mkfs.vfat -F 16' to format the first partition. Use mkswap command in linux to format the third partition into swap space. In xp, you can use partition magic to do this job.

Download the following files:

After you finish formatting your micro sd card, rename uImage-vx747-20090303 to uImage and copy it to your fat partition. Copy u-boot-nand.bin from jz_hacking_20090224 to your fat pattition. Do NOT copy uImage in jz_hacking_20090224 to your fat partition. It is the old linux kernel image. Now we have uImage-vx747-20090303 and we do not need it anymore. Copy all the files in root26 into the ext2 partition. Rename rcS-vx747-20090303 to rcS and copy it to directory 'ext/init.d/rcS' of the ext2 partition of your SD card. Rename pointercal-vx747-20090302 to pointercal and copy it to the directory 'ext/pointercal'.

4. Boot linux

Ok, it is time to boot linux. Insert the sd card into onda vx747. Press the reset button and hold the M button at the same time to enter usb boot mode. Run the usbtool using the following commands.

./usbtool 1 jz_xloader.bin 0x80000000

./usbtool 1 u-boot-boot-linux.bin 0x80100000

If that does not work in your system(some guy says it does that work on ubuntu), you can try the following commands:

sudo ./usbtool 12

Then you can see the u-boot logo. It will load uImage from micro sd card into SDRAM automatically and then boot from SDRAM. After that, linux logo will appear on LCD with framebuffer console output. At last, qtopia is running and you can play with it.

5. Programing u-boot into nand flash(optional)

If you decide to replace the original firmware and write u-boot into nand flash, you can use u-boot-program-nand.bin to do that.

./usbtool 1 jz_xloader.bin 0x80000000

./usbtool 1 u-boot-program-nand.bin 0x80100000

Also 'sudo ./usbtool 13' can work.

It will write u-boot into nand flash and reboot onda vx747 automatically.

If you want to restore the original firmware, this information may help you.

I only test the linux kernel and u-boot on my 4G bytes onda vx747 with 16M SDRAM. Some guy says that there is another model of vx747 with 32M SDRAM, I have not tried on that device. If you have any suggestion, please wirte to me(yajin AT vm-kernel.org). Spams are not welcome. :) .

Current Issue:

  • Touch screen is not accurate (solved)
  • Sound is not working (solved)
  • time and date setting (solved)
  • nand driver of u-boot is not working on 8G vx747 (not yet. I do not have the 8G version of vx747)

Please be patient. I will solve these problems.

Also any donation of jz4740/4750 based device is appreciated.

For anyone interested, the source code of u-boot and linux-kernel is available here.

http://code.google.com/p/jz-hacking/wiki/Index?tm=6#source_code

Cause register bug in qemu-jz

Jan 16th, 2009 | Posted by yajin | Filed under JZ, emulation

In MIPS, cause register is responsible for telling CPU which interrupt is happening. CPU read the IP bits in cause register and dispatch interrupt to interrupt service routine.

One question: who is responsible for clear IP bits in cause register? That is interrupt handler. Interrupt handler must clear the corresponding IP bit in cause register, othewise next time, interrupt is reenabled, CPU thinks the interrupt is still happening!

In linux, the function to clear IP bit in mask_and_ack_intc_irq. In JZ4740, it is:

50 static void mask_and_ack_intc_irq(unsigned int irq)
51 {
52         __intc_mask_irq(irq);
53         __intc_ack_irq(irq);
54 }

1372 #define __intc_mask_irq(n)      ( REG_INTC_IMSR = (1 << (n)) )
1373 #define __intc_ack_irq(n)       ( REG_INTC_IPR = (1 << (n)) )

Linux writes to REG_INTC_IPR to clear pending interrupt and JZ4740 interrupt controller will clear the interrupt signal to MIPS CPU.

In qemu-jz, when writing to REG_INTC_IPR, the interrupt to MIPS cpu is not cleared and linux runs in a dead loop.

The following is the interrupt handling process in MIPS CPU.

1. Set ECP=PC and CPU jumps to 0x80000200 and then to handle_int. The interrupt is disabled.

2. Function handle_int will save all the register(including EPC so that interrupt can be nested) to stack and call plat_irq_dispatch.

3. After the irq is processed, it will reenable the in function __do_softirq. If a new interrupt is coming at this time(check the IP bits cause register), go to 1. otherwise go to 4.

4. Call ret_from_irq and restore all the register(including EPC) and using ERET to set PC=EPC.

5. Runs from PC.

Because of the IP bits in cause register is not cleared, linux will run into a dead loop between 1 and 3.

Thanks to the log function and remote gdb. Really hard to find this bug in qemu-jz.

How to run rockbox on vx747

Jan 12th, 2009 | Posted by yajin | Filed under JZ

Caution: This article is out-dated. You can find the new how to in rockbox's wiki.

This article describes how to run rockbox on vx747 and vx747+.

1. Download rockbox from daily archive or svn. I use the svn version 19703.

2. build the toolchain. You can build the toolchain from ingenic or use the script in rockbox to build the toolchain.

Option 1) download the source code from ingenic ftp and build it.

Option 2) use the rockboxdev.sh in rockbox/tools to build the toolchain.

Add the toolchain to your system's PATH.

3. build the rockbox. If you use the toolchain from ingenic, you should comment the following line in firmware/target/mips/ingenic_jz47xx/boot.lds

#OUTPUT_FORMAT("elf32-littlemips")

If you buile the toolchain from rockboxdev.sh, we do not need to change boot.lds.

cd rockbox-19703

mkdir build

cd build

../tools/configure

Choose 120 for vx747 and 122 for vx747+ and then choose B for buile rockbox for bootloader. It will create Makefile in build directory. Type make to build the rockbox. If everything goes ok, file rockboot.vx747 is created. Rename it to onda.bin.

4. Build and use the usbtool to upload onda.bin to vx747.

cd utils/jz4740_tools/

make

Libusb-dev is needed to build usbtool. You can read the README in jz4740_tools.

Downlaod Log_files.rar and decompress it. Copy 1.bin to utils/jz4740_tools.

./usbtool 10

It will upload onda.bin to your vx747's SDRAM. Do not worry, it won't corrupt your device.

Following is the screenshot of rockbox on vx747.