2012年11月16日金曜日

a800eva qemu 偽IO追加

かなり面白い記事発見。
http://myokota.github.com/qemu-a800eva/
Armadillo800EVA のQEMU エミュレータが公開されています。
initramfs で動作する例がしめされています。

ここでは、偽IOを仕立て、CF-IDEとLAN9118を追加し、FileSystemとNetworkを利用可能にします。
--- qemu-a800eva-master/hw/a800eva.c    Wed Aug 08 03:58:20 2012
+++ qemu-a800eva-master/hw/a800eva.c
@@ -16,6 +16,11 @@
 #include "arm-misc.h"
 #include "exec-memory.h"
 #include "boards.h"
+#include "loader.h"
+#include "devices.h"
+#include "net.h"
+#include "ide.h"
+#include "blockdev.h"
 
 #define SDRAM_START                     (0x40000000)
 #define SDRAM_SIZE                      (0x20000000)
@@ -47,6 +52,7 @@
     MemoryRegion *sram = g_new(MemoryRegion, 1);
     DeviceState *dev;
     SysBusDevice *busdev;
+    DriveInfo *dinfo;
     qemu_irq *irqp;
     qemu_irq pic[128];
     qemu_irq cpu_irq;
@@ -95,6 +101,15 @@
     sysbus_create_varargs("sh,cmt", 0xe6138000, 
                           pic[58], pic[59], pic[60], 
                           pic[61], pic[62], NULL);
+
+/* IDE */
+    dinfo = drive_get(IF_IDE,0,0);
+    mmio_ide_init(0xe9201000, 0xe920200c, sysmem, pic[65], 1,
+        dinfo, NULL);/* ATAPI IRQ */
+/* GbEther */
+    if(nd_table[0].used) {
+        lan9118_init(&nd_table[0],0xe9200000,pic[110]);
+    }
 
     a800_binfo.ram_size = ram_size;
     a800_binfo.kernel_filename = kernel_filename;


---------------------------------------------------------------

--- linux-2.6.35-a800eva-at3/arch/arm/mach-shmobile/board-armadillo800eva.c    Fri Jul 27 16:00:51 2012
+++ linux-2.6.35-a800eva-at3/arch/arm/mach-shmobile/board-armadillo800eva.c
@@ -42,6 +42,8 @@
 #include <media/soc_camera.h>
 #include <media/soc_camera_platform.h>
 
+#include <linux/ata_platform.h>
+
 #include <video/sh_mobile_lcdc.h>
 #include <sound/sh_fsi.h>
 
@@ -62,40 +64,66 @@
     __raw_writeb(0x00, addr);
 }
 
-static struct sh_eth_plat_data sh_eth_platdata = {
-    .phy = 0x00,
-    .edmac_endian = EDMAC_LITTLE_ENDIAN,
-    .register_type = SH_ETH_REG_GIGABIT,
+static struct smsc911x_platform_config smsc_eth_platdata = {
+    .flags = SMSC911X_USE_32BIT,
+    .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+    .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
     .phy_interface = PHY_INTERFACE_MODE_MII,
 };
 
-static struct resource sh_eth_resources[] = {
-    {
-        .start = 0xe9a00000,
-        .end = 0xe9a00800 - 1,
-        .flags = IORESOURCE_MEM,
-    },
+static struct resource smsc_eth_resources[] = {
     {
-        .start = 0xe9a01800,
-        .end = 0xe9a02000 - 1,
+        .start = 0xe9200000,
+        .end =   0xe9200fff,
         .flags = IORESOURCE_MEM,
     },
     {
-        .start = gic_spi(110),
+        .start = gic_spi(110), /* GbEth */
         .flags = IORESOURCE_IRQ,
     },
 };
 
 static struct platform_device eth_device = {
-    .name = "sh-eth",
-    .id = 0,
+    .name = "smsc911x",
+    .id = -1,
     .dev = {
-        .platform_data = &sh_eth_platdata,
+        .platform_data = &smsc_eth_platdata,
+    },
+    .resource = smsc_eth_resources,
+    .num_resources = ARRAY_SIZE(smsc_eth_resources),
+};
+
+static struct resource cf_ide_resources[] = {
+    [0] = {
+        .start = 0xe9200000 + 0x1000,    
+        .end   = 0xe9200000 + 0x1000 + 0x10 - 0x2,
+        .flags = IORESOURCE_MEM,
+    },
+    [1] = {
+        .start = 0xe9200000 + 0x200c,
+        .end   = 0xe9200000 + 0x200c,
+        .flags = IORESOURCE_MEM,
+    },
+    [2] = {
+        .start = gic_spi(65), /* ATAPI */
+        .flags = IORESOURCE_IRQ,
     },
-    .resource = sh_eth_resources,
-    .num_resources = ARRAY_SIZE(sh_eth_resources),
 };
 
+static struct pata_platform_info pata_info = {
+    .ioport_shift = 1,
+};
+
+static struct platform_device cf_ide_device = {
+    .name = "pata_platform",
+    .id = -1,
+    .num_resources = ARRAY_SIZE(cf_ide_resources),
+    .resource = cf_ide_resources,
+    .dev = {
+        .platform_data = &pata_info,
+    },
+};
+#ifdef CONFIG_MMC
 static void sdhi0_set_pwr(struct platform_device *pdev, int state)
 {
     /* todo */
@@ -271,7 +299,7 @@
     .num_resources    = ARRAY_SIZE(sh_mmcif_resources),
     .resource    = sh_mmcif_resources,
 };
-
+#endif
 static struct sh_fsi_dma sh_fsi2_dma = {
     .dma_porta_tx = {
         .slave_id    = SHDMA_SLAVE_FSIA_TX,
@@ -1065,9 +1093,12 @@
 
 static struct platform_device *rma1evb_devices[] __initdata = {
     &eth_device,
+    &cf_ide_device, /* QEMU */
+#ifdef CONFIG_MMC
     &sh_mmcif_device,
     &sdhi0_device,
     &sdhi1_device,
+#endif
     &ohci_device,
     &ehci_device,
     &hdmi_device,
---------------------------------------------------------------
注意点
linux 側 Config
メモリ設定を256Mbyte(0x10000000)
CD-IDEは Device->ATA->Plaform Driver for IDE interface
LAN9118はDevice->Network->Ethernet(19..)->SMSC_LAN911x/LAN921x

rootfsの作成は以下を参考にしました。
http://memo.saitodev.com/home/arm/arm_emulation/

/dev/mapper/nbd0p1 に
debian-squeeze_xxx20120727.tar.gz
を展開します。

---------------------------------------------------------------
起動例
./qemu-a800eva-master/arm-softmmu/qemu-system-arm \
    -m 256M -M a800eva \
    -kernel ./linux-2.6.35-a800eva-at3/arch/arm/boot/uImage \
    -hda hda.qcow2 \
    -append "console=ttySC1 root=/dev/hda1" \
    -nographic \
    -serial telnet:0.0.0.0:1200,server \
    -net nic,model=lan9118 \
    -net user -redir tcp:5555::22

guest OSが起動できたら
/etc/network/interfaces ?に
 allow-hotplug eth0
 iface eth0 inet dhcp

を追加し、再起動し、その後 時刻設定を行い、
#apt-get update 
# apt-get install ssh
など行います。
[記事が壊れたので、再投稿 2012.11.16]

2012年8月11日土曜日

RSPI on RX63N

GR-SAKURA ボードで CQPUB RX62Nのコード
http://www.kumikomi.net/interface/editors/2011/04/6cd-romrx62n.php
mp3p_rx62n_hew.zip を RX63Nで動作させようとしたが、手間取ったので、記載しておきます。
要は、RSPI0.SPSR.BIT.SPRF,SPTEFビットが RX63Nで消えたのが問題で
ある人はRSPI0.SPSR.BIT.IDLNF ビットを流用していたので、真似てみたが、動きが怪しい。
やっぱり、IR(RSPI0,SPRI0) で見るしかないもんかというわけで、IR(RSPI0,SPRI0)をみるようにしてやっと動作確認できた。

初期化部は
/* CS#(PC0/SSLA1)をLにする(RSPI_CH=0のとき) */
static void CS_LOW() {
 PORTC.PODR.BIT.B0 = 0;
}

/* CS#(PC0/SSLA1)をHにする(RSPI_CH=0のとき) */
static void CS_HIGH() {
 PORTC.PODR.BIT.B0 = 1;
}

//#define INS (!PORT1.PIDR.BIT.B5) /* SD_CD(P15)カード検出(真:あり, 偽:なし) */
//#define WP 0   /* 書き込み禁止(真:禁止, 偽:許可) */

static void CS_INIT() {  /* CS#,INS#,WP 各端子の初期化(RSPI_CH=0のとき) */
 PORTC.PMR.BIT.B0 = 0; /* CS#=GPIO */ 
 PORTC.PDR.BIT.B0 = 1; /* CS#=OUT */   
 PORTC.PODR.BIT.B0 = 1; /* CS#=H  */ 
}

void SPI_ATTACH() { 
      
 SYSTEM.PRCR.WORD = 0xA502; 
 MSTP(RSPI0)=0;        
        SYSTEM.PRCR.WORD = 0xA500;
 
 PORTC.PMR.BIT.B5 = 0;   
 PORTC.PMR.BIT.B6 = 0;   
 PORTC.PMR.BIT.B7 = 0;   
 MPC.PWPR.BIT.B0WI = 0;      
        MPC.PWPR.BIT.PFSWE = 1;     
 MPC.PC5PFS.BYTE = 13;  /* RSPI RSPCKA */       
 MPC.PC6PFS.BYTE = 13;  /* RSPI MOSIA  */
 MPC.PC7PFS.BYTE = 13;  /* RSPI MISOA  */
 MPC.PWPR.BIT.PFSWE = 0; 
 PORTC.ODR0.BYTE = 0;   /* CMOS */ 
 PORTC.ODR1.BYTE = 0;   /* CMOS */   
 PORTC.PMR.BIT.B5 = 1;   
 PORTC.PMR.BIT.B6 = 1;   
 PORTC.PMR.BIT.B7 = 1;   

 IPR(RSPI0,SPRI0)=0;
 IEN(RSPI0,SPRI0)=0;
}
送受信部(他3箇所も修正)
/* Receive a byte */
static
BYTE rcvr_spi (void)
{
 BYTE c;
+ IR(RSPI0,SPRI0)=0;
 RSPI0.SPDR = 0xFF;  /* Send a 0xFF */
- while (!RSPI.SPSR.BIT.SPRF) ; /* Wait for end of transfer */
+        while (!IR(RSPI0,SPRI0)) ; /* Wait for end of transfer */
 return RSPI0.SPDR;  /* Returen received byte */
}

電源ON部
static
void power_on (void) /* Enable SPI */
{
 CS_INIT();

 /* Attach RSPI module to I/O pads */
 SPI_ATTACH();

 /* Initialize RSPI module */
 RSPI0.SPCR.BYTE = 0;     /* Stop SPI */
 RSPI0.SPSR.BYTE = 0xa0;
 RSPI0.SPPCR.BYTE = 0x00;    /* Fixed idle value, disable loop-back mode */
 RSPI0.SPSCR.BYTE = 0;     /* Disable sequence control */
 RSPI0.SPDCR.BYTE = 0x20;    /* SPLW=1 */
 RSPI0.SPCMD0.WORD = 0x0700; /* LSBF=0, SPB=7, BRDV=0, CPOL=0, CPHA=0 */
 RSPI0.SPBR.BYTE = (PCLK / 2 / CLK_SLOW )- 1; /* Bit rate */
- RSPI0.SPCR.BYTE = 0x49;     /* Start SPI in master mode */
+ RSPI0.SPCR.BYTE = 0xC9;     /* Start SPI in master mode w/SPRIE */
 RSPI0.SPCR2.BYTE = 0;     /* */
}

2012年8月2日木曜日

TNKernel for RX

https://github.com/msalov/TNKernel-RX
TNkernel の RX62N移植作業をやっているのを発見。
さっそく、RX621でためしたら、動作確認できた。
ボードは http://akizukidenshi.com/catalog/g/gK-05763/ これ。
気をよくして、RX63Nではどうか?

ボードは http://japan.renesas.com/products/promotion/gr/index.jsp これ。
結構はまった。
RX62NからRX63Nの違い
1) SYSTEM.SCKCR の下位bitは仕様書では 00000000bなのだが、その値ではクロックが動作しない
そこで、FreeRTOSの RX63Nのソースを見ると、00010001bにしているではないか。

2) クロック関連レジスタを触る際は SYSTEM.PRCR レジスタでアクセス解除が必要。
MSTP(RTC)などの箇所の前後にアクセス解除と禁止をいれる必要あり。
(RX63N UM 表13.1 PRCRレジスタと保護されるレジスタの対応 参照)

3) MPC ポート機能設定の前後で、MPC.PWPRでのアクセス解除が必要、具体的には PxnPFSレジスタの設定時。
(RX63N UM 22.4.2 MPCレジスタ設定する場合の注意事項 参照)

4) RTC関連レジスタでIODEFINE.H でビットフィールド定義されているレジスタをそのまま、アクセスは危険。
たとえば
RTC.RCR1.BIT.PES = 6; /* Set periodic interrupts frequency to 256 Hz */
RTC.RCR1.BIT.PIE = 1; /* Enable periodic interrupts */
ではなく
RTC.RCR1.BYTE = 0x64;
while(0x64 != RTC.RCR1.BYTE) ;
と書く。
要は、書いた値が反映されるまでは、新しい値を書いたらダメということ。

(RX63N UM 29.2.17 RTCコントロールレジスタ1(RCR1)
...
AIE、PIE、PES[3:0]ビットは、カウントソースに同期して更新されます。RCR1レジスタを書き換えた場 合は、全ビットの値が更新されたことを確認してから次の処理を実行してください
...
RX62Nにはそんな制限なかった)

コンパイラは nahitechさんのと、kpit gnu toolで確認。
あっ、IODEFINE.H は GR-SAKURA のWEBコンパイル環境から落としました。