もう一度書くが、ベースとするのは、
『USBBOOTプログラム用ライブラリ』の記事の usbboot-wk19.tar.gz。
Ingenic の MIPS プロセッサ 用として作っていたのだが、放置中。ライブラリの名前は jzlib 。AVR-libc ようなものを目指していて MichroChip のライブラリと全然違うもの。PIC32 とか名前に入れずに jzlib の PIC32MX 対応版という位置づけにしようかと思う。
ライブラリ自体は、AVR-libc から取ってきたり、NetBSD から取ってきたりしてでっち上げている。mips16e には対応できていないが、mips32 なら コンパイルするだけで済む。課題は、
・ スタートアップ
・ 割り込みエントリ
・ リンカ・スクリプト
・ ヘッダファイル
・ libm
こんなところで、PIC32MX の環境に対応することなのだ。あ、libm は単に後回しになっているだけ。
ディレクトリ体系
ディレクトリ体系とか ファイル名をどうするか -- こういうところから始めないといけない。さて、どうしよう。
まずは、手本となる AVR-libc がどうなっているのかの確認から。
TOP/avr/include/
alloca.h ctype.h inttypes.h setjmp.h stdio.h string.h
assert.h errno.h math.h stdint.h stdlib.h
TOP/avr/include/util/
atomic.h crc16.h delay.h delay_basic.h
parity.h setbaud.h twi.h
TOP/avr/include/avr/io.h
TOP/avr/include/avr/iousbxx2.h
TOP/avr/include/avr/iousb162.h
TOP/avr/lib/avr3/crtusb162.o
TOP/avr/lib/avr3/libc.a
TOP/avr/lib/avr3/libm.a
TOP/avr/lib/ldscripts/avr3.x
おおざっぱに書いてしまうと、AVR は avr3 とかのカテゴライズがあって、その中での空間定義は同じ。libc とか libm ライブラリは共通になっている。
スタートアップファイルはチップの種類毎に違う。レジスタの定義ファイルも別で、crtXXX.o と ioXXX.h の関係になっている。ただし、ヘッダファイルは、共通部分が別にあったりする。
これをもとに jzlib のディレクトリ体系を考えてみる。
TOP/mips-elf/include/
alloca.h ctype.h inttypes.h limits.h setjmp.h stdio.h string.h
assert.h errno.h math.h stdint.h stdlib.h
TOP/mips-elf/include/p32mx/interrupt.h
TOP/mips-elf/include/p32mx/io.h
TOP/mips-elf/include/p32mx/io2xx.h (?)
TOP/mips-elf/include/p32mx/io220.h (?)
インクルードは、こんな感じでどうだろう。p32 は pinguino とか 名前がぶつかるので避けて p32mx で作る。レジスタの定義は、とにかく io.h をインクルードするルール。
#if defined(__32M4KCORE__)
:
#if defined(__32MX220F032B__)
:
define は、こういう決まりがあるみたいだから踏襲するが、
#if defined(__32MX1XX__) || defined(__32MX2XX__)
:
こういうコードは使いたい。
TOP/mips-elf/lib/p32mx/crt220.o
TOP/mips-elf/lib/p32mx/libc.a
TOP/mips-elf/lib/p32mx/libm.a
ライブラリは、スタートアップ以外は共通にする。
TOP/mips-elf/lib/ldscripts/p32mxb3k.x
TOP/mips-elf/lib/ldscripts/p32mxb12k.x
ldscripts は 2種類。ブートローダ の最後に コンフィグ情報があるので、ブートローダのサイズによって空間が変わる。メモリのサイズや 割り込みが空間として定義されなければ、これだけの違い。
インクルードファイル
pinguino に添付されている p32mx220f032b.h p32mx250f128b.h をチェックしたのだが、 220 B と 250 B は本質的な違いがない。 220 D と 250 D も同様。だが、 220 B と 220 D には、850 行もの違いがあった。調べてみると PORTC の追加によってこれだけの違いが出ている。
220 B と 120B も比較してみたのだが、400 行ぐらいの差分で、USB レジスタの有無が違いだった。
どうも 220 D 用を基準にすると、後の 1xx/2xx は、そのサブセットになるようだ。とりあえず 220 D 用を作ってあとは、おいおいやっていくことにしよう。
さて、 p32mx220f032d.h だが、14278 lines もある。ここから使うものだけ抜き出して 再定義していくつもり。
まず XXX_BASE_ADDRESS に注目して抜き出す。これは、42 個。機能ブロックが 42 個もあるということ。-- 相当面倒な予感がする。
次に .extern の行が レジスタ名の定義らしいので抜き出すと ...
.extern WDTCONINV /* 0xBF80000C */
.extern RTCCON /* 0xBF800200 */
.extern RTCCONCLR /* 0xBF800204 */
.extern RTCCONSET /* 0xBF800208 */
こんな感じ。これは、1139 個もある。AVR なんかと比べると相当に多い。幸いなことに アドレスが入っている。
#define WDTCONINV (*(volatile unsigned *)0xBF80000C)
#define _WDTCONINV 0xBF80000C
これなら、スクリプトで変換できる。
次は、レジスタの中のフラグ名。恐ろしいことになりそうだ。
#define _WDTCON_WDTCLR_POSITION 0x00000000
#define _WDTCON_WDTCLR_MASK 0x00000001
#define _WDTCON_WDTCLR_LENGTH 0x00000001
こんな感じで定義されていた。_POSITION に注目すると 1994 個。だが、_DEVCFG1_w_POSITION みたいな変なのが混じっている。これは不要なので抜くと 1861 個。
#define _WDTCON_WDTCLR 0x00
こんな風に変換はできるのだが、どうも気に入らない。整理して特徴を掴まないと使いこなせる気がしない。
だが、整理するのにも時間がかかる。
PORT の定義
/* x=0:PORTA , x=1:PORTB , x=2:PORTC */
#define ANSELx(x) (*(volatile unsigned *)(0xBF886000 + (x)*0x100))
#define ANSELxCLR(x) (*(volatile unsigned *)(0xBF886004 + (x)*0x100))
#define ANSELxSET(x) (*(volatile unsigned *)(0xBF886008 + (x)*0x100))
#define ANSELxINV(x) (*(volatile unsigned *)(0xBF88600C + (x)*0x100))
:
他に、TRISx, PORTx, LATx, ODCx, CNPUx, CNPDx, CNCONx, CNENx, CNSTAT
#define CNCON_SIDL 0x0D
#define CNCON_ON 0x0F
どうも、こういうことらしい。 レジスタが base としてあって、CLR 用, SET 用, 反転用の Write-Only レジスタが規則正しく並ぶ。CLR 用といっても PORT出力 を L にするわけではない。単にレジスタの操作として 定義されていて、どのレジスタにも CLR がある。
そして、0x100 おきに PORTA , PORTB, PORTC と並んでいる。
オリジナルでは、それぞれの ビットの定義に数千行を費やしているのだが、あっさり切る。
/* x=0:PORTA , x=1:PORTB , x=2:PORTC */
#define ANSEL(x) (*(volatile unsigned *)(0xBF886000 + (x)*0x100))
#define ANSEL_CLR(x) (*(volatile unsigned *)(0xBF886004 + (x)*0x100))
#define ANSEL_SET(x) (*(volatile unsigned *)(0xBF886008 + (x)*0x100))
#define ANSEL_INV(x) (*(volatile unsigned *)(0xBF88600C + (x)*0x100))
:
他のレジスタなども見てたのだが、CLE/SET/INV の前に _ を付けることにする。ANSELx としたのは、正式名が ANSELA などで x は 置き換わるという意味。だが、このルールで統一すると I2C1STAT_CLR は、 I2CxSTAT_CLR となって見栄えが悪い。 I2C_STAT_CLR のほうがすっきりする。
というわけで、x はやめて、_ にする。末尾が _ になったり __ と重なる場合は、省略。
こうやって モジュール単位でまとめ p32mx/port.h にしようと思う。p32mx/io.h にまとめるのは、ヤメ。
実を言うともうひとつ課題がある。全部 32bit でとりあえず作っていくが、MIPS は 32bit の即値は効率が悪い。これだと アドレスも データも 32bit になってしまう。
8bit アクセスや 16bit アクセス のマクロなども必要に応じて作っていこうかと思う。たぶんレジスタ名 + b が 8bit , レジスタ名 + w が 16bit になると思うが、実際にコードを書き始めてから決める。
・ p32mx-inc-wk001.tar.gz
なんか、出来た。
152 include/p32mx/adc.h (ADC & camparator & CTMU)
53 include/p32mx/capt.h (Input & Output Capture)
70 include/p32mx/clkc.h (Oscillator Control)
60 include/p32mx/devcfg.h
123 include/p32mx/dmac.h
70 include/p32mx/i2c.h
109 include/p32mx/intc.h
31 include/p32mx/nvm.h
57 include/p32mx/port.h
134 include/p32mx/pps.h
67 include/p32mx/rtc.h
66 include/p32mx/spi.h
300 include/p32mx/sys.h (PPS - Peripheral Pin Select 他)
30 include/p32mx/timer.h
61 include/p32mx/uart.h
220 include/p32mx/usbotg.h
42 include/p32mx/wdt.h (Watch Dog Timer & Reset Control)
1511 total
1500 行だから、だいぶコンパクトになった。どれかに振り分けているから、不足はないはず。
振り分けについては、アナログ関係は、adc.h にまとめ、リセット関係は wdt.h にまとめた。そして、良くわからないものは、全部 sys.h 。ただの define のかたまりだし、それぞれ独立。
あと、jzlib では、スタートアップ と 割り込みに必要なものだけ使う。
ちょっと 220 と 440 を比べて見たのだが随分違う。当面 1xx/2xx 専用ということにする。
追記: ファイル名変更。
チップのデバイスの ヘッダファイルは、p32mx_ を頭に付けることにした。ライブラリで定義する機能用のヘッダファイルと同名になってしまうのを避けるため。timer.h / wdt.h が実際に同名になってしまった。
あまり大した機能を提供するつもりはないのだが、wdt.h は、AVR-libc タイプの API にするもの。timer.h は、割り込みのテスト用みたいなもの。あと時刻用の ostimer.h もある。
追記: ファイル追加
1つ忘れていた。デバイス関係ではなく、CPU コア関係で、p32mx_core.h
read_c0_status() とか CP0 へのアクセス関数が主。割り込み禁止/許可も これに入っている irq_disable()/irq_restore() を使う。
シャドウレジスタの制御とかも CP0 を使うことがわかった。使い方は、
・ MicroChip 製品ページ
のリンクにある、リファレンス・マニュアル 第二章 CPU に書いてあった。
キーワードは、IntCtl とか SRSCtl とか。( M14K のみとあるのは、使えないので注意。) これらのアクセス関数も p32mx_core.h に追加している。
割り込み
PIC32MX は、シングルベクターモードにすると、ユーザプログラムに来る割り込みは、たったひとつになる。
Flush:
0xBD00_0000 (EBase)
0xBD00_0200 Single Vector Mode (BEV==0)
0xBD00_0200 Multi Vector Mode (BEV==0)
+ vector_no * 32 * VS(VS==1)
Boot:
0xBFC0_0000 Reset,Soft Reset,NMI
0xBFC0_0200 EJTAG Debug (EJTAG ProbEn==1)
0xBFC0_0380 all generic interrupt (BEV==1)
0xBFC0_0480 EJTAG Debug (EJTAG ProbEn==0)
0xBD00_0200 に飛び込んでくるわけなのだが、ここは kseg1 。キャッシュが効く kseg0 に同じメモリイメージがあるので、速やかに移動したほうが良い。
kseg0 kseg1
Flash 0x9D00_00000 0xBD00_0000
Boot 0x9FC0_0000 0xBFC0_0000
Config 0x9FC0_0BF0 0xBFC0_0BF0
次に、レジスタのセーブだが、シャドウレジスタを最終的に使うつもり。割り込みも多段割り込みはサポートしない。どうせレジスタのアクセスは割り込み禁止にするのだ。一気に走り切った方が良いだろう。... これで随分簡単な話になる。
その次に C 関数に飛び 割り込みを振り分けて ベクターを call する。振り分けるのは、IFS0/IFS1 に割り込み要因が入っているので、その bit 位置を ベクター番号(IRQ)にする。IRQ は、マルチベクターモードでのベクター番号とは違うもの。ベクターもただの関数テーブル。
IRQ と 割り込み要因の割付は、p32mx/intc.h で定義した。
#define IRQ_U2RX 0x36
#define IRQ_U2TX 0x37
こんな感じで 1xx/2xx では、きっちり 64 個ある。あと調べてみたのだが、3xx/4xx は、これより少ない。5xx/6xx/7xx は、IFS2 もあって 64 個を超える。
さて、ベクターの登録だが、こんな風にする。
(p32mx/interrupt.h)
#define _VECTOR(irq) __vector_ ## irq
#define SIGNAL(irq) int _VECTOR(irq) ()
(user program)
SIGNAL(IRQ_U2RX)
{
:
__intc_ack_irq(IRQ_U2RX);
return IRQ_HANDLED;
}
戻り値 IRQ_HANDLED(非ゼロ) は、割り込みのブロック解除。多重割り込みをサポートしないつもりだから、割り込み関数内で解除しても良いのだが、一応仕様上はこういうルールにしておく。
割り込み要求は、呼ばれた関数が __intc_ack_irq() を実行して解除しないといけない。IRQ のフラグだけ解除しても多段になっていたりして、すぐに 1 になってしまうかも知れないので、原因を先にクリアしないとダメなのだ。
uint32_t intent(uint32_t c0_status, uint32_t c0_cause, uint32_t c0_epc)
{
uint32_t isr;
int v,r;
c0_status &= ~0x1e;
write_c0_status(c0_status & ~0x1); /* irq_disable */
do {
isr = IFS(0);
v = ffs(isr);
if (v) {
v--;
__intc_mask_irq(v & 0x1f);
r = (__vectors[v])();
if (r) {
__intc_unmask_irq(v & 0x1f);
}
}
} while (isr);
do {
isr = IFS(1);
v = ffs(isr);
if (v) {
v--;
__intc_mask_irq(v & 0x1f | 0x20);
r = (__vectors[v | 0x20])();
if (r) {
__intc_unmask_irq(v & 0x1f | 0x20);
}
}
} while (isr);
write_c0_cause(0);
return c0_status;
}
割り込みエントリの intent は、こんな感じ。前に作ったのを改造しただけなので、細いことは、思い出さないといけない。
#define __intc_mask_irq(v) { \
if ((v) & 0x20) IEC_CLR(1) = (1 << ((v) & 0x1f); \
else IEC_CLR(0) = (1 << ((v) & 0x1f); \
}
#define __intc_unmask_irq(v) { \
if ((v) & 0x20) IEC_SET(1) = (1 << ((v) & 0x1f); \
else IEC_SET(0) = (1 << ((v) & 0x1f); \
}
#define __intc_ack_irq(v) { \
if ((v) & 0x20) IFS_CLR(1) = (1 << ((v) & 0x1f); \
else IFS_CLR(0) = (1 << ((v) & 0x1f); \
}
mask/unmask/ack は、こうした。(p32mx/intc.h 更新)
さて、C やヘッダの部分は、改造するだけで良いのだが、アセンブラのエントリは、設計しないと。.... その前にリンカ・スクリプトとメモリマップの設計がいる。
リンカ・スクリプトとメモリマップ
これは、普通意識していないのだが、作る立場だと定義から始めないといけない。定義するにしてもゼロから作るわけにもいかないので、いろいろ見ている。
まず、gcc をビルドしたときに作られるものが、すべてのベースのようだ。だが、これは UNIX などのプログラム向け。次に MicroChip のブートローダのソースに添付されていたもの。これは、Flash や Boot に割り当てるような対応とか PIC32 への対応とか。最後に pinguino に添付されているもの。これは、MicroChip のものをベースに これまたいろいろ変更していて、一部 gcc 版に戻しているようなところもある。
OUTPUT_FORMAT("elf32-tradlittlemips" → "elf32-littlemips")
OUTPUT_ARCH(pic32mx → mips)
pinguino は、冒頭が変わっている。これでないと普通の gcc が使えないのかも。
まぁリンカ・スクリプトは、メモリへの割り当てを指示するものだから、マップに整理してみよう。
Flash:
exception_mem : ORIGIN = 0x9D000000, LENGTH = 0x1000
.app_excpt _GEN_EXCPT_ADDR(0x180)
.vector_0 _ebase_address + 0x200
:
.vector_63 _ebase_address + 0x200 + 32 * 63
kseg0_program_mem (rx) : ORIGIN = 0x9D001000, LENGTH = 0x4FFF
.text
.rodata
.sdata2
.sbss2
ユーザプログラムは、4KB オフセットして始まる。最初の 4KB は、exception_mem という領域に取られる。ここにマルチベクターモード用のベクターが置かれるが、2xx だと 2KB 。だいぶガラガラのようだ。
まずは、exception_mem を詰めないと。シングルベクターモードにする意味が無い。.vector_1 - .vector_63 を削除して、kseg0_program_mem の ORIGIN を 0x9D000400 あたりにしてしまおう。
アセンブラの割り込みエントリは .vector_0 を使うことにして、スタートアップのコードは、どうしよう。exception_mem の先頭 から 0x200(0x180 ?)を使いたいのだが、新たなセクションを作らないと、そこを使うすべがない。.startup とか .reset とか の名前を使いたいのだが ... .app_reset にするか。
Boot:
kseg1_boot_mem : ORIGIN = 0xBFC00000, LENGTH = 0x490
.reset _RESET_ADDR
.bev_excpt _BEV_EXCPT_ADDR :
debug_exec_mem : ORIGIN = 0x9FC00490, LENGTH = 0x760
kseg0_boot_mem : ORIGIN = 0x9FC00490, LENGTH = 0x0
.startup ORIGIN(kseg0_boot_mem) :
Config:
config3 : ORIGIN = 0xBFC00BF0, LENGTH = 0x4
.config_BFC00BF0
config2 : ORIGIN = 0xBFC00BF4, LENGTH = 0x4
.config_BFC00BF4
config1 : ORIGIN = 0xBFC00BF8, LENGTH = 0x4
.config_BFC00BF8
config0 : ORIGIN = 0xBFC00BFC, LENGTH = 0x4
.config_BFC00BFC
configsfrs : ORIGIN = 0xBFC00BF0, LENGTH = 0x10
RAM:
kseg1_data_mem (w!x) : ORIGIN = 0xA0000000, LENGTH = 0x2000
:
.sdata
_sdata_begin = . ;
:
_sdata_end = . ;
.lit8
:
.lit4
:
_data_end = . ;
_bss_begin = . ;
.sbss
_sbss_begin = . ;
:
_sbss_end = . ;
.bss
:
_end = . ;
_bss_end = . ;
これは、スタートアップ作成のためのメモ。これを使うのは少し先。
ところで、普通の GCC は、config のための #pragma など記述できない。だが、 .config_BFC00BF0 といったセクション内にデータを作れば良さそう。
unsigned devcfg3 __attribute__((section(".config_BFC00BF0"))) = 0xXXXXXXXX;
KEEP になっているから バイナリ(elf)には、出力されるはず。構造体を使って省略なしに きっちり記述するのでも良い。
あとメモリは、kseg1 (キャッシュ Off) を使う。どうせ データ用のキャッシュはないし、関係ないのだろう。
ostimer.c を 移植してみる。
あまり大したものではないのだが、もともと作っていた ostimer というものを PIC32MX 向けに書きなおしてみた。
timer2/3 , timer4/5 は 2 つを合わせて 32bit タイマーにできる。時刻用なので、これでも足りず 割り込みで 上位 32bit をインクリメントして 64bit タイマーにする。
思ったものが、作れるかどうかの確認が目的。ビルドは出来たのだが、結構バグがあった。デバイスの定義も 適当に変換したものがベースなので、いろいろ不満があったり、バグもあったり。やはり使ってみないと 完成度が上がらないようだ。
それはともかく ... コードがでかい。AVR だと 2KB もあれば相当なことが出来るのだが、この程度のもので 632
バイトも使っている。MIPS 自体も効率が悪いのだろうが、レジスタのアクセスの仕方も悪いのかも知れない。ちょっとサイズを減らすことを考えないと。
mips16 の検討
text data bss dec hex filename
14880 16 76 14972 3a7c others16.o (68 %)
21948 136 76 22160 5690 others32.o
2668 84 0 2752 ac0 stdio16.o (59 %)
4512 84 0 4596 11f4 stdio32.o
3168 20 0 3188 c74 stdlib16.o (66 %)
4768 20 0 4788 12b4 stdlib32.o
2328 0 4 2332 91c string16.o (72 %)
3216 0 4 3220 c94 string32.o
ちょっと行き詰まったので、mips16e を 試してみることにした。とりあえず、libc 部分はこんな感じ。.o をサブ・ディレクトリ毎にまとめた。(ld -r) アセンブラコードも含まれているのだが、その部分は全部 -mips32。
string はアセンブラが多いのでこんなものか。others が巨大なのは、strtod のせい。
これら stdio, stdli, string , others は、全部 CFLAGS に -mips16 を設定してビルドできる。アセンブラは、コード中に
.set nomips16
と書けば mips32 にしてくれる。問題は、C の方で、インラインアセンブラが効かない .. ではなく CP0 アクセス命令がないこと。これがないので割り込み禁止にするコードでエラーになる。... まぁ関数にしてしまえば良いのだが
・ jzlib-wk002.tar.gz
とりあえず、ここまでの成果。
スタートアップの検討
crtXXX.o をどうするか、悩んでいたのだが、そろそろ手をつけることにした。幸いなことに、pinguino に MicroChip 由来のソースコードがあった。これをもとに、AVR-libc のコードもみながら、作ろうとおもう。
まずは、なにを作るのか整理。
pinguino 添付のものは、完全なスタンドアローン用みたいだ。_reset から始まって 最終的に main を call 。万が一リターンしてきたら無限ループ。
こういうものだから、ブートローダー領域にあるはずのコードまで含まれる。これを ユーザフラッシュの先頭から実行するようなものに変える。
あと、不要な機能は、全部削り スタックやヒープの初期化は、AVR libc のやりかたに合わせる。
最後にベクタ。これは今まで書いてきた通りのものを crtXXX.o に含めるようにする。
MicroChip 由来のコードの調査
見ているのだが、削るところは、まぁはっきりしている。ベクタはとにかく全部削る。あと ramfunc ? この機能はないし作るつもりもないので、あっさり削る。
結局は、CP0 レジスタの初期化 スタック/ヒープの設定、あと gp の設定 と RAM の初期化 ぐらいが残った。
CP0 レジスタの初期化は、これを見ないと作れないと思うレベル。シャドウレジスタの gp の初期化が必要だとか分からないし、やりかたも知らない。gp は、(elf の )PIC のコードで使う。-fno-pic で進めてきたが、PIC を使った方が良いかも知れない。
AVR-libc の調査
AVR とどう関係あるのかと言うと、jzlib の もとが AVR-libc なのだ。まず、スタック/ヒープの設定の仕方は 合わせるべき。.weak 使っていたりして、ユーザレベルで設定変更が可能になっていて、そこは継承したい。
あと、初期化でフックを入れられるようになっている。.init0 , .init1 ,... とセクションを並べていて、セクション指定で コードを書くとそこに挟まるようになっている。これも対応したいものだが、後回しで良いだろう。
なんとなく分かったような気がするので、とにかく作ってみよう。
一応はできた。
まず crt0.S では、-mips32r2 を指定しなければならなかった。次に デフォルトが big-endian になってしまっていた。他のものも含めて -EL オプションの追加が必要。
これ自体は、4xx とかでも共通っぽいのだが、libc.a を共通にするために、チップ依存の部分を引きこまないといけない。割り込みベクタと 上記の intent は、例えば 4xx と IRQの数が違うから 引き込む。アセンブラの エントリ関数は、共通だがこれも。実を言うと 各レジスタのベースアドレスを変数にしていて、これもチップ依存みたいなので引きこむ。
引き込むと書いているが、ld の -r オプションを使って 1 つにまとめる方法にした。ld にも -EL オプションが必要だった。
一応はできたから リンク
$ mips-elf-ld crt220.o main.o -T p32mxb3k.x -Map tmp.map
map 抜粋:
.app_reset 0x000000009d000000 0x108
*(.app_reset)
.app_reset 0x000000009d000000 0x108 crt220.o
0x000000009d000000 _start
.app_excpt 0x000000009d000180 0x4
*(.gen_handler)
.gen_handler 0x000000009d000180 0x4 crt220.o
.vector_0 0x000000009d000200 0x100
*(.vector_0)
.vector_0 0x000000009d000200 0x100 crt220.o
0x000000009d000200 __intent
.startup
*(.startup)
.text 0x000000009d000400 0x2f0
0x000000009d000400 _text_begin = .
動くものなのかどうか、どうやって動かすか課題は多いのだが、最初のバイナリが出来た。
0 - 0x180 までに スタートアップを入れるつもりだったが、0x108 で少し余裕がある。0x180 に割り込みが来るかも知れないので一応空ける。0x200 からは、アセンブラの 割り込みエントリ。レジスタセーブ版で 0x100 に収まっている。0x400 からの .text には、(擬似)割り込みベクタと C の intent などが入り 0x2f0 を専有している。
最低限度のもので 2KB 弱というわけだ。まぁ 残りの 30KB は自由に使えるわけなので良しとしよう。
まずは、どうやって動かすか についてしらべないと。
・なんらかのブートローダがあったとして、ユーザー FLASH の先頭に Jump してくれるものなのかどうか?
・なにもない場合はブートローダのスタブが必要だが これも考えておかないと。
・あと pinguino は手に入れたが、どうやって動かすのか? pinguino に合わせた スタートアップとリンカ・スクリプトが必要そうな気がする。
次は動くものなのかどうか?とにかく一式用意できたわけだが、検証していない。
・コンパイルオプションをどうするのか? PIC にするかどうかがポイント。
・割り込み関係、シャドウレジスタの扱いも含めて 整理しないと動くような気がしない。
... 考えてみれば、すべてを自前で用意している。コンパイラ - ライブラリ - ライタ。そのすべてが動いたという実績がない ... だけでなく ライブラリ - ライタ は かなりの部分作り込んでいる。これは、最初に main で L チカできるまで、結構厳しい道のりになりそう。
MIPS32r2 について
ちょっと脱線。スタートアップの コンパイルで wrpgpr や ext , ins という見慣れない命令でエラーになったため、-mips32r2 にしてみたのだが、調べて見ると便利な命令が増えている。
di/ei
AVR でいうところの cli/sei 命令。1 命令で 禁止許可ができることが分かったので、インラインアセンブラで __cli()/__sei() を作ることにした。mips16 では使えないので、関数 cli()/sei() も作る。
また、di/ei は 変更前の CP0_STATUS を戻すので、irq_disable() を作るのに複数命令必要だったのが、1 命令で出来るようになった。( irq_restore() は、もともと 1 命令 )
ext/ins
ext は、レジスタから offset n bit , size m bit のフィールドを取り出す命令。 ins は、その逆で フィールドを埋め込む。デバイスのレジスタの操作いかにも便利そうな命令。
clz
これは、MSB から 0 の数をカウントしてくれる命令。最初のビット位置を見つけるのに便利な命令で、割り込みで ビットマスクを IRQ 番号に変換するのに使える。
他にも 積和演算とか あるようだ。gcc は、これらの命令を有効に使ってくれるのだろうか? もしダメなら マクロを用意しないと。
割り込み制御の検証
CP0 STATUS レジスタが、どういう風に設定されるかを中心に チェックしてみた。
4 3 2 1 0
CP0_STATUS ... UM x ERL EXL IE
下位 5 bit のこのフィールドがとりあえず重要。IE=1 は割り込み許可。.. なのだが ERL/EXL のいずれかが 1 だと割り込み処理実行中を意味して、割り込みが許可されない。UM=1 は、ユーザモードを意味する。組み込みプロセッサで ユーザモードなど使えないだろうと思っていたのだが、なんと使えるのだ。
BMXDUDBA (DATA RAM USER DATA BASE ADDRESS REGISTER) というレジスタで USER 空間のメモリを指定するらしい。使う気はないが、割り込みは一応考慮しておく。
あと SR, NMI, BEV といった bit がある。SR/NMI は 通常のリセット以外が発生したかどうかの 情報。BEV=1 は、ブートローダで割り込みを使うという意味で良い。
スタートアップ:
CP0_STATUS ... UM x ERL EXL IE
0 0 0 0
この状態で main が call される。SR, NMI, BEV bit はそのまま。
interrupt_enable() 後
jzlib で割り込みを使うには、interrupt_enable() を call する。
CP0_STATUS ... UM x ERL EXL IE
0 0 0 1
これ以外では、SR, NMI , BEV をクリアし、IPL=2 にする。また、IECx を all 1 にしてすべての IRQ を許可する。
割り込みが来ると ...
CP0_STATUS ... UM x ERL EXL IE
X 0 1 1
たぶんこの状態? ERL/EXL いずれかが 1 なら IE=1 でも 割り込みは禁止されている。UM も無視される。
C の 割り込みハンドラ intent では、もとの状態をセーブして
CP0_STATUS ... UM x ERL EXL IE
0 0 0 0
この状態にして、割り込み関数を順番に実行。
最後に CP0_CAUSE を 0 にして、レジスタを復帰して eret 直前に C0_STATUS を元に戻す(ERL/EXL はクリア)。
検証しながら直したのだが、動きそうな気がしてきた。
a.out の検証
できあがった 実行形式 (ELF) をチェックしてみた。
Disassembly of section .app_reset:
9d000000 <_start>:
9d000000: 3c1a9d00 lui k0,0x9d00
9d000004: 275a0010 addiu k0,k0,16
9d000008: 03400008 jr k0
9d00000c: 00000000 nop
9d000010 <_start_k0>:
9d000010: 3c1d0000 lui sp,0x0
9d000014: 27bd0000 addiu sp,sp,0
9d000018: 3c1ca000 lui gp,0xa000
9d00001c: 279c7ff0 addiu gp,gp,32752
まずは、新規に作った .app_reset が先頭で そこからスタートアップが始まる。kseg1 の 0xBD00_0000 に 飛んできても、kseg0 に jump している 。アドレスも正しい。_start_k0 は、MicroChip のスタートアップベースでいろいろ初期化をする。
9d000100: 01000008 jr t0
9d000104: 00000000 nop
Disassembly of section .app_excpt:
9d000180 <_gen_exception>:
9d000180: 00000000 nop
Disassembly of section .vector_0:
9d000200 <__intent>:
9d000200: 3c1a9d00 lui k0,0x9d00
9d000204: 275a0210 addiu k0,k0,528
9d000208: 03400008 jr k0
9d00020c: 00000000 nop
9d000210 <__intent_k0>:
9d000210: 40046000 mfc0 a0,c0_status
9d000214: 40056800 mfc0 a1,c0_cause
9d000218: 40067000 mfc0 a2,c0_epc
9d00021c: 3c199d00 lui t9,0x9d00
9d000220: 27390594 addiu t9,t9,1428
9d000224: 0320f809 jalr t9
9d000228: 0040d021 move k0,v0
9d00022c: 409a6000 mtc0 k0,c0_status
9d000230: 42000018 eret
...
Disassembly of section .text:
スタートアップは、0x104 で終わり、0x180 からは、.app_excpt 。
_gen_exception はなにもないが、call されないはず。ただ、今のままだと コード を入れたくとも入れられない。AVR-libc の .initN のようなもので、コードを挿入可能にしたい。
0x200 の __intent は、__intent_k0 にまず飛ぶ。これはスタートアップと同じ。次にいきなり c0_status などを 引数に入れて intent を call 。戻り値を c0_status に入れて eret 。
シャドウレジスタの設定が出来ていれば、これで良いはず。
9d000400 <_main_entry>:
9d000400: 774001c4 jalx 9d000710 <main>
9d000404: 00000000 nop
9d000408: 1000ffff b 9d000408 <_main_entry+0x8>
9d00040c: 00000000 nop
...
9d000420 <__vectors>:
9d000420: 9d000520 0x9d000520
9d000424: 9d000520 0x9d000520
9d000428: 9d000520 0x9d000520
9d00042c: 9d000520 0x9d000520
:
9d00047c: 9d000520 0x9d000520
9d000480: 9d000789 0x9d000789
9d000484: 9d000520 0x9d000520
:
9d000520 <_bad_interrupt>:
9d000520: 00001021 move v0,zero
9d000524: 03e00008 jr ra
9d000528: 00000000 nop
:
9d000788 <__vector_24>:
9d000788: 675c move v0,gp
9d00078a: f010 9a70 lw v1,-32752(v0)
9d00078e: 4b01 addiu v1,1
9d000790: f010 da70 sw v1,-32752(v0)
9d000794: b203 lw v0,9d0007a0 <__vector_24+0x18>
9d000796: b304 lw v1,9d0007a4 <__vector_24+0x1c>
9d000798: da60 sw v1,0(v0)
9d00079a: e820 jr ra
9d00079c: 6a01 li v0,1
9d00079e: 6500 nop
ベクターのチェック。0x528 は、_bad_interrupt で、0 をリターンする。こうすると、二度と call されなくなる。0x789 は mips16 を call することを意味する。実際に 0x788 から ostimer.c で定義した 割り込みハンドラが入っている。gp を使っているから PIC (Position Independent Code) になっている。
コードを見たかぎり、なんだか動きそうな気がしてきた。
ただし、ユーザフラッシュの先頭に飛んできてくれないと、ダメ。このあたりはどうなっているのだろうか?
・ jzlib-wk005.tar.gz
ここまでのものを wk005 として置いた。ちゃんとした スペックファイルがないので 全部明示的に指定しないといけないのだが、
$ mips-elf-gcc -mips32r2 -EL -fpic -msoft-float -O2 \
-I/d/MIPS32_Toolchain/mips-elf/include \
-c xxx.c
$ mips-elf-ld -T /d/MIPS32_Toolchain/lib/ldscripts/p32mxb3k.x \
-o xxx /d/MIPS32_Toolchain/lib/p32mx/crt220.o \
xxx.o -L /d/MIPS32_Toolchain/lib/p32mx -lc -lgcc
こういう風に指定することで、ビルドできるようにしようと思う。
-fpic -msoft-float は、たぶん省略可。-EL は必要。-mips32r2 の代わりに -mips16 とすると mips16e のコードが出る。混在は可能。
ブートローダとの連携
MicroChip が出している。AN1388 のブートローダのコードを見てみたのだが ...
Include/BootLoader.h:
#define USER_APP_RESET_ADDRESS (0x9D006000 + 0x1000 + 0x970)
void JumpToApp(void)
{
void (*fptr)(void);
fptr = (void (*)(void))USER_APP_RESET_ADDRESS;
fptr();
}
こんな風になっていた。これでは動くはずはない。ただ、Flash から 0x7970 オフセットされているから 32KB の終わりのほう。このアドレスに jump コードを入れておけばあるいは、いけるのかも知れない。
一方 pinguino のほう。p32/lkr/PIC32_PINGUINO_220/procdefs.ld を見ると
_ebase_address = 0x9D003000;
_RESET_ADDR = 0x9D004000;
こんな風になっている。オフセット 16KB のところに ジャンプしてくるということか。ただし、オフセット 12KB に ebase を設定しているから、標準から 12KB オフセットされているとも言える。
kseg1_boot_mem : ORIGIN = 0x9D004000, LENGTH = 0x490
kseg0_boot_mem : ORIGIN = 0x9D004490, LENGTH = 0x570
kseg0_program_mem (rx) : ORIGIN = 0x9D004A00, LENGTH = 0x3600
ただ、こういう設定もあるのだった。どうやら 本来ブートにあるべきものが、0x9D004000 から入っていて、0x9D004A00 に飛んでも 動く。ひょっとしたら こっちがエントリアドレスかも知れない。
_ebase_address = 0x9D004000;
_RESET_ADDR = 0xBFC04000;
exception_mem : ORIGIN = 0x9D004000, LENGTH = 0x400
kseg0_program_mem (rx) : ORIGIN = 0x9D004A00, LENGTH = 0x1FC00
p32mxb3k.x に対して、上記を変更すれば、対応できるような気はする。
ただ、なんだか無駄だらけ。32KB もあっても 随分余計なものに喰われてしまっている印象がある。
gcc の specs ファイル
mips-elf-gcc -dumpspecs > specs
mv specs /d/MIPS32_Toolchain/lib/gcc/mips-elf/4.4.3/
例えばこういう風にすることで、gcc の動作を定義する specs ファイルを読みこませることができる。
mips-elf-gcc -v として確認してみれば、
Reading specs from d:/mips32_toolchain/bin/../lib/gcc/mips-elf/4.4.3/specs
と表示され、確かに 読み込まれている。それは、良いのだが、悲しいことにどう変更すれば良いのやら分からないのであった。
まず分かる範囲でちょっと。
*endian_spec:
-%{!EL:%{!mel:-EB}} %{EL|mel:-EL}
+%{!EB:%{!mel:-EL}} %{EB|mel:-EB}
EB と EL を入れ替える。
*endfile:
-crtend%O%s crtn%O%s
+
*startfile:
-crti%O%s crtbegin%O%s
+crt220%O%s
endfile の指定を削除、startfile 変更。
こうしておいて、
TOP/mips-elf/include ( jzlib の include をコピー)
TOP/mips-elf/lib/libc.a
TOP/mips-elf/lib/crt220.o
こんな風にインストールすると ...
$ mips-elf-gcc -D__32M4KCORE__ -D__32MX2XX__ -D__32MX220F032B_ \
-mips32r2 -O2 -Xlinker -T p32mxb3k.x main.c -lc
こういうオプションで ビルドまでは行く。ただ、p32mxb3k.x は手元に置いておかないとならない。define と リンカ・スクリプトのサーチは、難しい。
それに、startfile をチップ別に作ったり、mips-elf/lib に サブディレクトリを作り、libc.a を そこに置きたい。AVR でこういうことが出来ているのは、gcc 自体にそういう機能を追加しているためだから、spec だけでは無理かも知れない。
適切な gcc のオプションを作ってくれるプリプロセッサを作るのが近道かも知れない。
インストールとかビルドとかの方法
一切説明してこなかったのだが、少々まともになってきたし、少し説明しておこう。
まずコンパイラは、自分でビルドしたものを使っている。だが Pinguino IDE のコンパイラと gcc のバージョンは違うものの config の方法はほぼ同じ。Pinguino の gcc を借りて説明しよう。
Pinguino をインストールすると たとえば /c/PinguinoX.3/win32/p32/bin/ に mips-gcc がある。ここに PATH を通して
$ export CROSS_COMPILE=mips-
とする。... のではあるが、肝心のことを忘れていた。環境は MSYS を使っている。
msys-1.0.10 いまだに、この古い 1.0.10 をベースにして使い続けている。この msys-1.0.10 と Pinguino だけ使うことを前提にする。
・ jzlib-wk006.tar.gz
最新ソースはこれで、TOP ディレクトリで make を実行すると
libc.a
p32mx/crt2xx.o
この 2 つが作られる。
で次にどうインストールするか... p32/mips-elf/include は、Pinguino に使われてしまっている。
p32/jzlib に置くことにしよう。
$ mkdir -p /c/PinguinoX.3/win32/p32/jzlib/lib
$ cp libc.a p32mx/crt2xx.o /c/PinguinoX.3/win32/p32/jzlib/lib
$ mkdir /c/PinguinoX.3/win32/p32/jzlib/lib/ldscripts
$ cp p32mx/p32mxb* /c/PinguinoX.3/win32/p32/jzlib/lib/ldscripts/
$ cp -r include /c/PinguinoX.3/win32/p32/jzlib
これで一応 OK だが、指定が面倒なので、
・ p32mx-gcc.gz
これを gunzip したものを /c/PinguinoX.3/win32/p32/bin に置いて使う。
p32mx-gcc は、スクリプトで 面倒な指定 (特にディレクトリ関係) を省略できるようにしたもの。基本的には、足りないオプションを 追加して、mips-gcc を 呼び出すような仕組みとする。ただし、その足りないオプションもカスタマイズしたいので、専用のオプションを新設。
専用のオプションとは、
-mmcu=p32mx1xx
-mmcu=p32mx2xx
-mmcu=p32mx4xx
-mmcu=p32mx2xx-b
-mmcu=p32mx2xx-bu
こんなもの。-b/-bu といったものは何かというと デフォルトの リンカスクリプトの拡張子。通常は、
TOP/jzlib/lib/ldscripts/p32mxb3k.x (1xx/2xx の場合)
TOP/jzlib/lib/ldscripts/p32mxb12k.x (3xx/4xx の場合)
を使うが、-XXX で リンカスクリプトを変えることができるようにする。指定しないと -mmcu=p32mx2xx が指定されたとみなす。
あと、-mmcu の指定で以下の define を追加する。
-D__32M4KCORE__ -D__32MX2XX__ (2xx の場合)
その他、標準オプション でいくつか省略可能にした。
-mips32r2
-EL
-EL は強制的に付ける。-mips32r2 は -mips16 など -mips* が指定されない場合のみ。
-Xlinker XXX
あと、リンカオプションを明示的に指定した場合、標準のリンカスクリプトは指定しないようにしている。
次、このスクリプトは、リンクモード を意識する。"-lc" が含まれると リンクモード 。その場合、crtXXX.o ファイル と リンカスクリプト を 指定するようにしている。
結局のところ動作がどうなるかというと
p32mx-gcc -O2 main.c -lc
とすると
mips-gcc -mips32r2 -EL -D__32M4KCORE__ -D__32MX2XX__ \
-nostdinc -I/c/PinguinoX.3/win32/p32/bin/../jzlib/include \
-Xlinker -T /c/PinguinoX.3/win32/p32/bin/../jzlib/lib/ldscripts/p32mxb3k.x \
/c/PinguinoX.3/win32/p32/bin/../jzlib/lib/crt2xx.o main.c -lc
こんな風にして、mips-elf-gcc を実行する。
p32mx-gcc -mips16 -O2 -c main.c
だと
mips-gcc -EL -D__32M4KCORE__ -D__32MX2XX__ \
-nostdinc -I/c/PinguinoX.3/win32/p32/bin/../jzlib/include \
-mips16 -O2 -c main.c
こう。ただ、適当なスクリプトなので、ディレクトリ名に スペースが入ったりすると具合が悪い。エスケープで指定しても 無効。
プログラムを書いてみる
# include <p32mx/p32mx_core.h>
# include <p32mx/p32mx_port.h>
int main() {
int i;
LAT_CLR(1) = 1 << 7; // PORTB bit7 : 0
for (i=0; i< 1000; i++) {
__delay_loop_1(4000000);
TRIS_INV(1) = 1 << 7; // PORTB bit7 : output
}
}
実を言うと PORT の使い方がよく分かっていないのだが、こんな感じ?
LAT_CLR() のパラメータ 1 は、2 番目の PORT すなわち PORTB の指定。TRIS レジスタは 0 で 出力にするようなので、そちらをトグルするようにしてみた。(LED は L で点灯するようにする )
__delay_loop_1 は、2 クロックで 1 ループ。(mips32r2 の場合) 4000000 だから もし 8MHz ならば、1 秒毎に反転するはず。
初期化が少々不安。PORT と 組み込み機能の選択だとか いろいろあるようなので、設定が他に必要かも知れない。
これがうまくいくようなら、delay_us() を試してみる。delay_us() は、OSCCON からクロックの設定を読み出して、それに合わせてループ回数を計算するようにしているのだが、出来が悪いかも。
p32mx-gcc -mmcu=p32mx2xx -O2 main.c -lc -o main.bin
これで main.bin が出来るはずなのだが、動かす環境によって -b とかのオプションの指定が必要。( 予定 : まだ確認できていない )
コードが動いた。
Olimex PIC32-PINGUINO-MX220 を入手したので、これを使ってデバッグ開始。書き込みには、pic32prog (r55) を使った。
まずは、こんな Lチカのコード
#include <p32mx/p32mx_core.h>
#include <p32mx/p32mx_port.h>
// Olimex PIC32-PINGUINO-MX220
// LED1 (Green) D13 = RB15 Active H (1: Light on)
// LED2 (Red ) D9 = RA10 Active H (1: Light on)
// BUT D8 = RB7 Active L (0 : Pressed)
int main() {
TRIS_CLR(1) = 1 << 15;
TRIS_CLR(0) = 1 << 10;
LAT_CLR(1) = 1 << 15;
LAT_SET(0) = 1 << 10;
for (;;) {
__delay_loop_1(10000000);
LAT_INV(1) = 1 << 15;
}
}
をコンパイル。__delay_loop_1() は 2 クロックで 1ループなので 40 MHz なら 1秒周期で点滅するはず。
Programmer for Microchip PIC32 microcontrollers, Version 1.51M
Copyright: (C) 2011-2012 Serge Vakulenko
Adapter: HID Bootloader
Program area: 1d003000-1d007fff
Processor: Bootloader (id DEAFB00B)
Flash memory: 20 kbytes
ブートローダモードにして pic32prog (最新版 : r55)をオプションなしで起動すると、こういうメッセージがでる。 (物理アドレス) 0x1d003000 からがプログラムエリアだが、最初はベクタなので 0x1d004000 に jump してくる。だから 0x4000 ずらした リンカ・スクリプト p32mxb3k.bu を使う。
$ p32mx-gcc -mmcu=p32mx2xx-bu -O2 test1.c -lc -o test1.elf
まずは、これを試す。
問題は HEX ファイルの作り方だった。
$ objcopy -O ihex test1.elf test1.hex
mips 版は、何故かエラーになるのだ。mingw の i386 だと問題なく作れたり。
書き込みには、
$ pic32prog -S test1.hex
として、ベリファイをスキップさせる。ベリファイさせようとすると止まってしまう。... もともと AN1388 HID ブートローダ には読み込みの機能はないのだが ...
で動かしてみると、赤が点灯し、緑が1秒周期で点滅したのだった。
$ p32mx-gcc -mmcu=p32mx2xx-bu -O2 test1.c -lc -o test1.elf \
-D_USE_SFRS_BASE_ADDR
次はこれを試す。ちょっとバグがあって、修正する必要があったが、これも動いた。
何を確認したかというと、グローバル変数のアクセス。
$ p32mx-gcc -mmcu=p32mx2xx-bu -O2 test1.c -lc -o test1.elf \
-mips16
これは、動かなかった。__delay_loop_1() は、ディレイドスロット前提のコードなのだが、mips16 には ディレイドスロットが無いのだった。
しょうがないので、delay_loop_1() を -mips32r2 で関数として作った。で、試してみると ... 全然動かない。赤 LED も点灯しない。-mips16 をやめても同じ現象。
調べてむると、これが最初にスタックを使うコードだった。main の頭で レジスタセーブしているので、全然動かなかったのだ。
.set __stack , _stack
というのが、crt0.S に必要だった。ちなみに スタックは bss の終わりから 1KB 。サイズは __stack を定義することで、プログラム側で変更可能。
これで関数呼び出しも OK 。-mips16 も OK になった。
ただ、相変わらず __delay_loop_1 が使えてしまう。pic32mx-gcc スクリプトでは、-mips16 があったら
-D_MIPS16
と定義しようかと思う。
さて、ようやく次の段階に入れる。次とは、割り込みハンドラの確認。これさえ動けば随分完成に近づく。... というか、チップ対応の機能として、ostimer と timer しか提供するつもりはなかったりする。API とかディレクトリ構成だとかを見直して完成にするつもり。
あと、動くプログラムが作れたので、『pic32progの改造』も進められる。
コードは、まだ公開しない。割り込みが動いたら 新記事で。
割り込み関係のメモ
割り込みを動かすのは難航している。組み込み用に拡張された MIPS の割り込み制御はなかなか難しい。
とりあえず メモだけ。
シャドウレジスタの扱い
割り込みが発生すると、シャドウレジスタセット(SRS) を切り替える。使わないにしても 使わないように設定する必要がある。
面倒なのは、カレントの SRS (C0_SRSCTL_CSS で示される) は、簡単には切り替えられないこと。レジスタの値がいきなり変わってしまうと困るから当然かもしれない。切り替えるには、割り込みからの復帰命令である eret を使う。eret では、 C0_STATUS_BEV = 0 で C0_STATUS_ERL = 0 のとき C0_SRSCTL_PSS で指定されている SRS に 切り替える。
スタートアップでは、C0_SRSCTL_CSS が 0 とは限らない という 前提にして 0 に切り替えることにした。そうしないと、ユーザプログラムが 1 で動き続けたりして 面倒な話になる可能性がある。
一般例外と EIC モード
MIPS では 割り込み や 例外は C0_EBASE + 0x180 に飛ぶことになっている。だが、PIC32MX など組み込み用では、外部 割り込みコントローラ(EIC: External Interrupt Controller) を使用することで、 C0_EBASE + 0x200 + ベクタに飛ぶこと (も) できる。
ややこしいのは、C0_STATUS_BEV の存在。BEV は Bootstrap Exception Vector モードで、ROM 領域の 割り込みベクタ(アドレス固定) を使う。組み込み用では 両方ROM だが Boot 領域を指す。
C0_EBASE + 0x200 が使われるには、BEV = 0 と C0_CAUSE_IV = 1 である必要がある。また、C0_EBASE + 0x180 を使うことは (推奨)されていない。
シングルベクタモード
INTCON_MVEC = 0 とすると シングルベクタモードになる。INTCON_SS0=1 とすると、シングルベクタモードでの割り込み時 シャドウレジスタセット(SRS) を 1 にする。( INTCON_SS0 = 0 では、SRS を 0 にする )
上がたぶん正しいとおもわれるのだが、CPU の定義では、C0_CAUSE_IV = 1(EIC モード) で、C0_INTCTL_VS(割り込みベクタ1 つのサイズ) が 0 のとき シングルベクターモードで、C0_SRSCTL_EICSS に切り替えることになっている。
一般例外ベクタ (C0_EBASE + 0x180) を使う場合には、 C0_SRSCTL_ESS で指定された番号になる。マルチベクタモードのときは、もっとややこしい。C_SRSMAP に割り込みレベル毎の 番号を指定されている。
他に INTCON_VS というのがあって、これがあるプロセッサでは、C0_INTCTL_VS は使うなと書いてある。.. 正直良くわからないのだが、P32MX2XX (P32MX4XX も) INTCON_VS は存在せず INTCON_SS0 が存在する。 たぶん C0_INTCTL_VS は 0 にしておけば良いのだろう 。
割り込みレベル と 実行レベル
C0_STATUS_IPL に CPU が実行しているレベルが 格納されている。この値より 高い 割り込みレベルの割り込みしか発生しない。割り込みを許可しても この条件がクリアされないとダメなのだ。
C0_CAUSE_RIPL に 発生した割り込みレベルが格納されている。一般的には、これを C0_STATUS_IPL にコピーするらしい。が、守る必要はない。
さてこの 割り込みレベルだが、PC1-IPC10 で 割り込みベクタ毎に指定する。シングルベクターモードの場合は、割り込みベクタ 0 のみを使用する。... のだが INTSTAT_RIPL というのもあって シングルベクタモードで使うことになっている。この関係が良くわかっていない。
さて、実行レベルをどうするのか? これは決めなのだが、常に 0 としようかと思う。で、割り込みレベルは、1 。この 2 つしか使わない。
割り込み関係のデバッグの状況
まず、割り込みのデバッグを行うには、割り込みを発生させなければならない。
これに ostimer を使っている。ostimer は Timer 4/5 を 1 つにまとめて 32bit タイマーにする機能を使って実装している。32bit もあれば、割り込み間隔を (40MHz で) 2分弱まで 伸ばせるのだ。もっとも そんなに待てないので、1/16 にして 6.7 秒で 最初の割り込みが来るようにした。ostimer は、単に時刻用で 64 bit の値を返すような機能にしている。call back などは本来ないのだが、デバッグ用に call back 機能を付けて、LED を点灯させたりしている。
割り込み処理なのだが、従来のプロセッサ用のコード と SRS を使うコード (-D_USE_SRS で指定) の 2 種類を作ったのだが、SRS を使う方は、全然だめ。まずは、従来コードのデバッグをやって、その後 SRS のコードに移るつもり。だいたい、割り込み処理を C で書いているので、C の分の レジスタのセーブ・リストアが結構ある。ここもアセンブラ化しないと SRS を使うメリットが出ない。
で、従来用のコードだが、割り込みを 1 回発生させて、復帰する。平タスクはちゃんと動き続けるところまでは来た。だが、2 回目の割り込みが発生しない。理由は不明だが、どうも C0_STATUS 関係っぽい。
ちなみに、従来用のコードでは、ERET は使っていない。ERET は、MIPS32 からの命令で、MIPS32R2 で SRS の切り替え機能が付いた。ターゲットの 1 つとして考えている Jz47xx (4770 以前) は、MIPS32 ですらないので、ERET 命令を持っていないのだ。
閑話休題
text data bss dec hex filename
608 0 0 608 260 interrupt.o (OLD)
580 0 0 580 244 interrupt.o (NEW)
ちょっとヘッダファイルを変更したら、サイズが小さくなった。
extern const void * _sfrs_base_addr_1;
#define _INTC_ADDR ( _sfrs_base_addr_1 + 0x1000 )
#define INTCON (*(volatile uint32_t *)( 0x00 + _INTC_ADDR)) (OLD)
#define INTCON (*(volatile uint32_t *)(_INTC_ADDR + 0x00 )) (NEW)
たぶん、オフセットを ポインタの先に書くか後に書くかの違い。編集の都合で 先に書いてしまっていたのだが、interrupt.c の出力アセンブラを見てみたら、レジスタのアクセスが全部独立したポインタになっていた。ちゃんと後で書くと、_sfrs_base_addr_1 + オフセットの形でアクセスしてくれるようになった。サイズが多少小さくなるだけなのだが、小さくなったのは、多分 割り込みハンドラ intent での GPR レジスタの セーブ・リストアなのだ。
割り込み関係のデバッグの現状(2)
割り込み処理が 1 回しか動かなくて困っていたのだが、どうも割り込み処理の中で例外を起こしているようだ。
void
__attribute__((section(".gen_handler0")))
never_return()
{
for (;;) {
__delay_loop_1(2000000);
LAT_INV(0) = 1 << 10;
}
}
こんな風に .gen_handler0 にコードを置くと EBase + 0x180 に飛んできたら LED を高速点滅させるようにしたのだが、最初の割り込みと同時に 高速点滅 。
だからといって、原因がすぐ判明するわけではないが、一歩前進した。
割り込み関係のデバッグの現状(3) (2012/07/29)
・ retorobsd startup.S
をみていたら、HI,LO レジスタのセーブ・リストアをしているのに気がついた。関係なかったが、バグなので修正。
ところで retorobsd 存在も知っていたし、PIC32MX で動くことも。だが、そのときはただ感心しただけだった。『たけおか ぼちぼち日記: retroBSD on PIC32マイコン』を見て 再発見。相当に参考になりそうなので、ソースコードをちゃんと眺めてみたい。
・ retrobsd-src-r561-20110729.tar.gz
とりあえずソースコード(一部)を 取り出したものをここに置く。
https://trello.com/c/ULlRRyIu/39-crucc-24-car-radio-code-calculator
https://toquasicteroling.wixsite.com/dacumbnantpred/post/recipe-for-hill-utorrent-software-zip-cracked-activation-x64-pc
https://feapowasesi.wixsite.com/muskcomrivi/post/blu-ray-pro-contrac-mkv-watch-online-subtitles-kickass
https://wakelet.com/wake/Kk1KKvDNLvB--B3t1kO_C
https://bethanyefford676yu.wixsite.com/lurallimon/post/hermosaricura-rar-google-drive
https://smithsusanne1993.wixsite.com/liasabchopa/post/international-marketing-17th-nulled-activation-utorrent-pro
https://trello.com/c/XOEzzO0K/18-21-pink-lips-w-utorrent-windows-pro-patch-rar-x32
https://wakelet.com/wake/oc-npLlHY9wrfiK8jYqrt
https://trello.com/c/FooqwnY4/20-super-nani-tamil-movies
https://trello.com/c/chY7xYtz/23-delphi-20133-keygen-v1-23
https://trello.com/c/zpLOcfoZ/15-crack-motorola-phone-tools-432iso
https://trello.com/c/PfKGyLnX/36-download-film-tiga-meter-di-atas-langit-part-3
https://wakelet.com/wake/wP28QsQPLFcQcJJzDCxp0
https://wakelet.com/wake/TGdp--2oyyNBqAjs1j1ON
https://wakelet.com/wake/loE7uEpI9mcTCTwd0KyKs
https://wakelet.com/wake/mD8Qq1WtXW1i0oV3SNoiT
https://trello.com/c/JB8nNFmF/17-magadheera-mp4-movie-download
https://trello.com/c/2orAEutf/28-aerofly-fs-2-switzerland-download-with-crack
https://trello.com/c/3I4WSWSJ/32-easycap-model-dc60-version-35c
https://trello.com/c/xdmPuEil/33-cadsoft-envisioneer-9-crack
https://wakelet.com/wake/-LA8x9mXgRxe-cdZE168r
https://wakelet.com/wake/MhxvjYygM5VeKg5YihGTr
https://wakelet.com/wake/O0xGql4h_K9PprNko4Ihy
https://wakelet.com/wake/OT9CSMYRvOkLWd26hOO2M
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgIC_wc3yCQwLEgZDb3Vyc2UYgIDAwMDs3QsMCxIIQWN0aXZpdHkYgIDA0MCU-wgMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgMCAhK7QCAwLEgZDb3Vyc2UYgICAv6OBpggMCxIIQWN0aXZpdHkYgIDAkPOm6AoMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgIC_35XnCwwLEgZDb3Vyc2UYgIDAwKWbswoMCxIIQWN0aXZpdHkYgIDAoJP9pgkMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgID_04enCQwLEgZDb3Vyc2UYgICA_9PdqgsMCxIIQWN0aXZpdHkYgICA_5fRygsMogEQNTcyODg4NTg4Mjc0ODkyOA
https://wakelet.com/wake/Ryl6-vaoGtQZiSjwhtuJj
https://wakelet.com/wake/zYqULRpf_nVxD_e3vhpSH
https://wakelet.com/wake/jAGHG_43oYCgzoZuDxqqK
https://wakelet.com/wake/J5sEiC5kH4eY1Wfuoxhfn
https://coub.com/stories/2732521-active-sav-moded-papkat
https://coub.com/stories/2732522-work-download-photographic-toning-gradients
https://coub.com/stories/2732523-repack-conan-the-adventurer-free-download
https://coub.com/stories/2732525-link-ballance-game-free-download-full-version-for-58
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgID_2dT0CwwLEgZDb3Vyc2UYgICA34uptwsMCxIIQWN0aXZpdHkYgIDAkPOm5QsMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgIC_g-yCCQwLEgZDb3Vyc2UYgIDAwIfOmwkMCxIIQWN0aXZpdHkYgIDAoNK7kwsMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgIC_wZuBCgwLEgZDb3Vyc2UYgIDAoNrFnQkMCxIIQWN0aXZpdHkYgIDAwOmbwgoMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgMDA1dLeCQwLEgZDb3Vyc2UYgIDAwI7kwAoMCxIIQWN0aXZpdHkYgICA_7yFsQsMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgMDA57CICAwLEgZDb3Vyc2UYgICAv8HN0ggMCxIIQWN0aXZpdHkYgIDAoLPxyAsMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgIC__ZeUCgwLEgZDb3Vyc2UYgIDAgOKrkgoMCxIIQWN0aXZpdHkYgIDAoPOglQkMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgIC_vevPCwwLEgZDb3Vyc2UYgICA_5PaigkMCxIIQWN0aXZpdHkYgIDAkLPShQsMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgMDA7OT9CgwLEgZDb3Vyc2UYgICAn5urpwgMCxIIQWN0aXZpdHkYgIDAkPPmrggMogEQNTcyODg4NTg4Mjc0ODkyOA
https://coub.com/stories/2750286-best-patched-adobe-acrobat-pro-dc-2018-011-20035-crack
https://coub.com/stories/2750281-origami-koi-fish-instructions-pdf
https://coub.com/stories/2750280-livro-olericultura-teoria-e-prgtica-pdf-dechil
https://coub.com/stories/2750278-verified-edipo-rey-libro
https://coub.com/stories/2633123-clinical-infectious-disease-case-reports-tholei
https://coub.com/stories/2633121-the-namesake-2006-english-480p-341mb-movies-download-afilmywap-net-gertchat
https://coub.com/stories/2633122-download-buku-haraki-pdf-wylfabr
https://coub.com/stories/2633120-exclusive-nastia-muntean-set-2-145
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgMDAh86zCQwLEgZDb3Vyc2UYgICAn4Sh6QkMCxIIQWN0aXZpdHkYgIDAoNPBoAoMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgMCAv4qlCAwLEgZDb3Vyc2UYgICAv7_ipgsMCxIIQWN0aXZpdHkYgIDA4I6s-wkMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgID_k-GSCgwLEgZDb3Vyc2UYgIDAgP_o1QoMCxIIQWN0aXZpdHkYgIDAkNPN2QoMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgID_092BCQwLEgZDb3Vyc2UYgIDAwOyu8wsMCxIIQWN0aXZpdHkYgIDA4PeoqQoMogEQNTcyODg4NTg4Mjc0ODkyOA
https://coub.com/stories/2724200-serious_sam_4_v1_08-razor1911-jerofra
https://coub.com/stories/2705314-echo-sound-works-x-keys-bonuses-multiformat
https://coub.com/stories/2704327-patched-dish-network-guide-font-size
https://coub.com/stories/2704326-ms-excel-97-2003-free-_verified_-download
https://wakelet.com/wake/jOUytKdiMLtfLJYEJj1iy
https://wakelet.com/wake/z_Dft8zQ9zoh3RzTxGKov
https://wakelet.com/wake/_GrRC_SMklLQUfx_fD_T4
https://wakelet.com/wake/QcKGAN9OT6UtkMAwmm72p
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgICfm7_WCwwLEgZDb3Vyc2UYgIDAwJe4rgkMCxIIQWN0aXZpdHkYgIDAoPHipwkMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgMCQ06mACwwLEgZDb3Vyc2UYgIDA0Nyt1AsMCxIIQWN0aXZpdHkYgIDAoImvuwgMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgMCQ6PCQCwwLEgZDb3Vyc2UYgIDA0IDojgoMCxIIQWN0aXZpdHkYgIDAoPG9rggMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgMDg9Ib3CgwLEgZDb3Vyc2UYgIDAoNOqjQgMCxIIQWN0aXZpdHkYgIDAoJr4-AsMogEQNTcyODg4NTg4Mjc0ODkyOA
https://wakelet.com/wake/lFNW14grk1JzOO3G2NWAv
https://wakelet.com/wake/OUscJAD27U3SvzR_kGXLU
https://wakelet.com/wake/kM5bWYbkS_gVXtYW6JS0D
https://wakelet.com/wake/7a084EuKcALBSoF1VK2p-
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgMDA7KPICwwLEgZDb3Vyc2UYgICAn-Si4goMCxIIQWN0aXZpdHkYgIDAoKrZ7AkMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgMCg2vTWCQwLEgZDb3Vyc2UYgIDAgNKrjQoMCxIIQWN0aXZpdHkYgICA_4_M_AkMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgIC_g43YCQwLEgZDb3Vyc2UYgICAv_6dmAsMCxIIQWN0aXZpdHkYgIDA4O-PgQsMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgMCAuPnOCgwLEgZDb3Vyc2UYgIDAgNjm-wgMCxIIQWN0aXZpdHkYgIDA0J6BhwoMogEQNTcyODg4NTg4Mjc0ODkyOA
https://coub.com/stories/3042222-adjprog-cracked-exe-epson-l120-software-patched
https://coub.com/stories/3042221-rocket-mania-deluxe-activation-code-addons-extra-quality
https://coub.com/stories/3042220-__link__-calman-5-enthusiast-keygen-17
https://coub.com/stories/3042219-io-cable-pl-2303-drivers-generic-windows-wd-pl2303h-hx-x-v20019v2021-zip-idawest
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgMDAgMPACAwLEgZDb3Vyc2UYgIDAwI7OrwgMCxIIQWN0aXZpdHkYgIDA0LD-mgsMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgMDQgNyJCQwLEgZDb3Vyc2UYgIDA4I7-lAkMCxIIQWN0aXZpdHkYgIDA4NWLrggMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgMDgjN61CAwLEgZDb3Vyc2UYgIDAoLLe0wkMCxIIQWN0aXZpdHkYgIDAoNju7goMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgMCgktWoCQwLEgZDb3Vyc2UYgIDAoJG8vggMCxIIQWN0aXZpdHkYgIDAwPPDxggMogEQNTcyODg4NTg4Mjc0ODkyOA
https://trello.com/c/w3pKssew/55-eagle-point-software-crack-keygen-hughante
https://trello.com/c/ntvo7pjR/27-pcsx2-r1675-maetel-4-5-rar
https://trello.com/c/8kp9wkOs/49-arturia-brass-vsti-rtas-v205-incl-keygen-air-rar-11600m-top
https://trello.com/c/7q1LcdGZ/67-verified-download-driver-lan-g41d3lm
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgID_gO3ZCAwLEgZDb3Vyc2UYgIDAwICu-AgMCxIIQWN0aXZpdHkYgIDAgIvMwgkMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgMCgupiKCwwLEgZDb3Vyc2UYgIDAoKuhjQkMCxIIQWN0aXZpdHkYgIDA4OyfyAsMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgMDAtsC8CQwLEgZDb3Vyc2UYgICA_4Tp8gkMCxIIQWN0aXZpdHkYgIDA4J_ozwsMogEQNTcyODg4NTg4Mjc0ODkyOA
https://www.cloudschool.org/activities/ahFzfmNsb3Vkc2Nob29sLWFwcHI5CxIEVXNlchiAgMCQ87aeCAwLEgZDb3Vyc2UYgIDAoMiLuwkMCxIIQWN0aXZpdHkYgIDA4N71lggMogEQNTcyODg4NTg4Mjc0ODkyOA
https://trello.com/c/r9hoiPS1/53-native-instruments-massive-151-download-win-mac-nadibeno
https://trello.com/c/jxj2n6P2/29-link-hhmi-lizard-lab-answer-key
https://trello.com/c/4hA2Jos9/56-thandordieinvasionwindowsvollversiondownload38-install
https://trello.com/c/uMG8a7oi/39-blackfish-2013-torrent-hot
https://coub.com/stories/3034056-2011-descargar-winunisoft-3-4-gratis-crack-waiwash
https://coub.com/stories/3034055-blue-lagoon-the-awakening-720p-english-subtitles-high-quality
https://coub.com/stories/3034054-exclusive-bangla-khilafat-o-malookiat-book-download
https://coub.com/stories/3034052-download-gspbb-by-gsp-team-free-download-ranmant
https://coub.com/stories/3124949-top-keygen-full-v13-build-autocom-15
https://coub.com/stories/3124944-windows-server-2012-x86-download-2021-iso-torrent-mega
https://coub.com/stories/3124948-soda-pdf-desktop-11-1-4-crack-link-2020-with-serial-keys
https://coub.com/stories/3124946-link-assassin-s-creed-1-only-crack-download
https://coub.com/stories/2942521-acdsee-photo-studio-ultimate-2018-v33-3-patched-crack-serial-key-keygen
https://coub.com/stories/2942520-_best_-james-l-hosay-persis-pdf-download
https://coub.com/stories/2942518-deep-freeze-standard-8-30-220-4627-crack-hot
https://coub.com/stories/2942519-work-saints-row-iv-bling-bling-pack-free-download-pc-l
https://coub.com/stories/2978338-2021-sap-grc-330-pdf-download
https://coub.com/stories/2978337-quantum-mechanics-theory-and-applications-ajoy-ghatak-pdf-download-patched-40
https://coub.com/stories/2978336-all-activation-windows-7-8-10-v12-windows-office-activator
https://coub.com/stories/2978334-witness-simulation-software-download-12-palyake
https://coub.com/stories/3011341-abvent-artlantis-studio-5-1-2-7-rar-bervass
https://coub.com/stories/3011337-hd-online-player-cars-2-hindi-dubbed-movie
https://coub.com/stories/3011342-baixar-re3-hack-tool-exclusive
https://coub.com/stories/3011339-excelpasswordrecoverykey61crack-link
https://coub.com/stories/3052958-danka-a-janka-kniha-pdf-75
https://coub.com/stories/3052956-bioexcess-plus-crack-_verified_
https://coub.com/stories/3052954-3design-cad-7-torrent-emomari
https://coub.com/stories/3052953-software-easy-dental-80-para-dentistas-garkail
https://coub.com/stories/2954410-wondershare-recoverit-7-1-3-7-crack-rar-kaicneal
https://coub.com/stories/2954407-verified-family-and-friends-5-class-book-pdf-free-106
https://coub.com/stories/2954406-historias-de-um-portugal-assombrado-pdf-13-lauobel
https://coub.com/stories/2954405-patched-red-alert-2-yuri-s-revenge-trainer-1-001-11
https://coub.com/stories/3223476-roblox-sex-hack-gilwak
https://coub.com/stories/3223472-invoice-expert-4-28-serial-keys-gen
https://coub.com/stories/3223470-vernier-caliper-experiment-pdf-download-jaciyona
https://coub.com/stories/3223468-mad-max-fury-road-movie-hot-download-in-hindi-dubbed-mp4
https://wakelet.com/wake/0BoLHfCRjS3Zlr_b4SUyI
https://wakelet.com/wake/38hGCTdHxmTRMPSrX--bT
https://wakelet.com/wake/csr1EgEPLfrew4bYB2FnK
http://mompachrobin.com/bonjour-tout-le-monde/
https://coub.com/stories/3422777-summit1studentbookpdffreedownload-top
https://coub.com/stories/3422775-kabhi-alvida-naa-kehna-hindi-movie-utorrent-free-__full__-downloadgolkes
https://coub.com/stories/3422773-dhoondte-reh-jaoge-in-hindi-torrent-download-720p-katval
https://inomarka54.ru/tishe-edesh-dalshe-budesh-renault-arkana-okazalas-na-40-tishe-renault-duster-uzhe-s-konvejera
https://coub.com/stories/3304692-matrox-imaging-library-mil-9-0-link-crack
https://coub.com/stories/3304689-tamar-braxton-love-and-war-zip-download-top-sharebeast
https://coub.com/stories/3304687-2021-download-free-pdf-raj-comics-new-set
https://erinmagazine.com/4-major-mistakes-to-avoid-when-buying-property-in-dubai/
https://coub.com/stories/3242012-rhinogold-5-7-crack-extra-quality-fullbfdcm
https://coub.com/stories/3242010-babra-sharif-scandal-with-sheikh-zayed-story
https://coub.com/stories/3242009-top-mt-power-drumkit-2-full-crack
https://blog.agronavt.ge/%E1%83%98%E1%83%9B%E1%83%9E%E1%83%9D%E1%83%A0%E1%83%A2%E1%83%98%E1%83%A0%E1%83%94%E1%83%91%E1%83%A3%E1%83%9A%E1%83%98-%E1%83%9E%E1%83%A0%E1%83%9D%E1%83%93%E1%83%A3%E1%83%A5%E1%83%A2%E1%83%98/
https://coub.com/stories/3397575-euro-truck-simulator-2-v1-4-1-crackfix-without-human-verification-yitzfran
https://coub.com/stories/3397574-fixed-food-hygiene-and-sanitation-by-s-roday-pdfbfdcm
https://coub.com/stories/3397572-extra-quality-i-cyborg-activation-code-serial-number
https://permaze.com/sienaphege