LoginSignup
1
0

NetBSD/armのuart

Last updated at Posted at 2022-12-04

NetBSDではシリアルコンソールはデフォルトのシリアルからデバイスのシリアルになります。

デフォルトのシリアルでは割り込みを使わずビジーループで出力しますが、タイマーを動かすところから割り込みが使われるようになります。

初期のデフォルトのシリアルの初期化はsys/arch/evbarm/gemini/gemini_machdep.cには下記のようにあります。

void
consinit(void)
{
        static int consinit_called = 0;

        if (consinit_called != 0)
                return;
        consinit_called = 1;

        if (comcnattach(&gemini_a4x_bs_tag, consaddr, conspeed,
                GEMINI_COM_FREQ, COM_TYPE_16550_NOERS, conmode))
                        panic("Serial console can not be initialized.");
}

comcnattach()はdev/ic/com.cにある関数です。

sys/kern/init_main.cからもよばれるので、一度しか処理しないようにしています。

第三引数のTYPEはいのように定義があります。

        /*
         * There are a great many almost-ns16550-compatible UARTs out
         * there, which have minor differences.  The type field here
         * lets us distinguish between them.
         */
        int sc_type;
#define COM_TYPE_NORMAL         0       /* normal 16x50 */
#define COM_TYPE_HAYESP         1       /* Hayes ESP modem */
#define COM_TYPE_PXA2x0         2       /* Intel PXA2x0 processor built-in */
#define COM_TYPE_AU1x00         3       /* AMD/Alchemy Au1x000 proc. built-in */
#define COM_TYPE_OMAP           4       /* TI OMAP processor built-in */
#define COM_TYPE_16550_NOERS    5       /* like a 16550, no ERS */
#define COM_TYPE_INGENIC        6       /* JZ4780 built-in */
#define COM_TYPE_TEGRA          7       /* NVIDIA Tegra built-in */
#define COM_TYPE_BCMAUXUART     8       /* BCM2835 AUX UART */
#define COM_TYPE_16650          9
#define COM_TYPE_16750          10
#define COM_TYPE_DW_APB         11      /* DesignWare APB UART */

この関数はレジスタが1バイト毎に並んでる場合に使います。SOCによっては4バイト毎になっていて、その場合はcomcnattach()の中身をいじる必要があるので、自前で用意します。4バイトすなわち2ビットシフトでcom_init_regs_stride()関数を呼びます。

int
m83comcnattach(bus_space_tag_t iot, bus_addr_t iobase, int rate,
    int frequency, int type, tcflag_t cflag)
{
        struct com_regs regs;

        /*XXX*/
        bus_space_handle_t dummy_bsh;
        memset(&dummy_bsh, 0, sizeof(dummy_bsh));

        /*
         * dummy_bsh required because com_init_regs() wants it.  A
         * real bus_space_handle will be filled in by cominit() later.
         * XXXJRT Detangle this mess eventually, plz.
         */
        com_init_regs_stride(&regs, iot, dummy_bsh/*XXX*/, iobase,
                2);


        return comcnattach1(&regs, rate, frequency, type, cflag);
}

これでデバイスになるまではOKです。

あとはcomデバイスのattach()でもcom_init_regs_strideを呼びます。

comにも上記のようにいくつかのタイプの処理がはいっていますが、大幅に違う場合は独自に実装しているケースもあるようです。

comの実装は分かりにくくて、よくありません。

sys/arch/evbarm/devにもcomのコードがあるようです。

RT1310でuartが暴走するので調べてみたら受信をsoftintしているところで、暴走してました。とりあえず、rxはsoftintしないで直に実行するようにしたらうごきました。なんか動きが変です。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0