$ ====================================================================== $ $ TOPPERS ATK2 $ Toyohashi Open Platform for Embedded Real-Time Systems $ Automotive Kernel Version 2 $ $ Copyright (C) 2013 by Embedded and Real-Time Systems Laboratory $ Graduate School of Information Science, Nagoya Univ., JAPAN $ $ 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ $ ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改 $ 変・再配布(以下,利用と呼ぶ)することを無償で許諾する. $ (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作 $ 権表示,この利用条件および下記の無保証規定が,そのままの形でソー $ スコード中に含まれていること. $ (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使 $ 用できる形で再配布する場合には,再配布に伴うドキュメント(利用 $ 者マニュアルなど)に,上記の著作権表示,この利用条件および下記 $ の無保証規定を掲載すること. $ (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使 $ 用できない形で再配布する場合には,次のいずれかの条件を満たすこ $ と. $ (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著 $ 作権表示,この利用条件および下記の無保証規定を掲載すること. $ (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに $ 報告すること. $ (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損 $ 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること. $ また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理 $ 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを $ 免責すること. $ $ 本ソフトウェアは,無保証で提供されているものである.上記著作権者お $ よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的 $ に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ $ アの利用により直接的または間接的に生じたいかなる損害に関しても,そ $ の責任を負わない. $ $ $ ===================================================================== $DEBUG_OPT_TF = 1$ $ $ パス4のプロセッサ依存テンプレート(V850E2M用) $ $FUNCTION GET_SSTK_TSKINICTXB$ $bottom = PEEK(ARGV[1] + offsetof_TINIB_TSKINICTXB_sstk_bottom, sizeof_void_ptr)$ $size = PEEK(ARGV[1] + offsetof_TINIB_TSKINICTXB_sstksz, sizeof_StackType)$ $RESULT = (bottom - size)$ $END$ $FUNCTION GET_USTK_TSKINICTXB$ $bottom = PEEK(ARGV[1] + offsetof_TINIB_TSKINICTXB_stk_bottom, sizeof_void_ptr)$ $size = PEEK(ARGV[1] + offsetof_TINIB_TSKINICTXB_stksz, sizeof_StackType)$ $RESULT = (bottom - size)$ $END$ $ $ OSAP.ID_LISTを読み込むため $ $INCLUDE "cfg2_out.tf"$ $ $ 保護ドメインのラベルの作成 $ OSAP.LABEL[domid]:保護ドメインのラベル $ $OSAP.LABEL[TDOM_KERNEL] = "kernel"$ $FOREACH domid OSAP.ID_LIST$ $OSAP.LABEL[domid] = domid$ $END$ $OSAP.LABEL[TDOM_NONE] = "shared"$ $ $ 標準のセクションのメモリオブジェクト属性の定義 $ $MEMATR_TEXT = (TA_NOWRITE|TA_EXEC)$ $MEMATR_RODATA = (TA_NOWRITE|TA_EXEC)$ $MEMATR_DATA = TA_MEMINI$ $MEMATR_BSS = TA_NULL$ $MEMATR_PRSV = TA_MEMPRSV$ $MEMATR_ROSDATA = (TA_SDATA|TA_MEMINI|TA_NOWRITE|TA_EXEC)$ $MEMATR_SDATA = (TA_SDATA|TA_MEMINI)$ $MEMATR_SBSS = TA_SDATA$ $ $ 保護ドメイン毎のデフォルトのアクセス許可パターンの作成 $ $DEFAULT_ACPTN[TDOM_KERNEL] = VALUE("TACP_KERNEL", TACP_KERNEL)$ $FOREACH domid OSAP.ID_LIST$ $DEFAULT_ACPTN[domid] = VALUE(FORMAT("TACP(%1%)", domid), 1 << (domid - 1))$ $END$ $DEFAULT_ACPTN[TDOM_NONE] = VALUE("TACP_SHARED", TACP_SHARED)$ $ $ OSAP初期化コンテキストブロックのための宣言 $ $FUNCTION PREPARE_OSAPINICTXB$ $IF LENGTH(TSK.ID_LIST)$ $FOREACH tskid TSK.ID_LIST$ $IF !OSAP.TRUSTED[TSK.OSAPID[tskid]]$ extern uint8 $FORMAT("__start_user_stack%s", tskid)$;$NL$ extern uint8 $FORMAT("__limit_user_stack%s", tskid)$;$NL$ $END$ $END$ $END$ $FOREACH tskpri RANGE(TMIN_TPRI, TMAX_TPRI)$ $IF LENGTH(shared_ustack_size[tskpri])$ extern uint8 $FORMAT("__start_shared_user_stack%s", tskpri)$;$NL$ extern uint8 $FORMAT("__limit_shared_user_stack%s", tskpri)$;$NL$ $END$ $END$ $IF LENGTH(OSAP.ID_LIST)$ $FOREACH domid OSAP.ID_LIST$ $IF !OSAP.TRUSTED[domid]$ $ RX領域(専用) extern uint8 __start_text_$OSAP.LABEL[domid]$;$NL$ extern uint8 __limit_text_$OSAP.LABEL[domid]$;$NL$ $ R領域(専用) extern uint8 __start_sram_$OSAP.LABEL[domid]$_$FORMAT("%x", MEMATR_ROSDATA & ~TA_MEMINI)$;$NL$ extern uint8 __limit_sram_$OSAP.LABEL[domid]$_$FORMAT("%x", MEMATR_ROSDATA & ~TA_MEMINI)$;$NL$ $ RWX領域(専用) extern uint8 __start_ram_$OSAP.LABEL[domid]$;$NL$ extern uint8 __limit_ram_$OSAP.LABEL[domid]$;$NL$ extern uint8 __start_sram_$OSAP.LABEL[domid]$;$NL$ extern uint8 __limit_sram_$OSAP.LABEL[domid]$;$NL$ $ 共有リード専用ライト extern uint8 $FORMAT("__start_ram_%s_%x_%x", OSAP.LABEL[domid], +DEFAULT_ACPTN[domid], +TACP_SHARED)$;$NL$ extern uint8 $FORMAT("__limit_ram_%s_%x_%x", OSAP.LABEL[domid], +DEFAULT_ACPTN[domid], +TACP_SHARED)$;$NL$ extern uint8 $FORMAT("__start_sram_%s_%x_%x", OSAP.LABEL[domid], +DEFAULT_ACPTN[domid], +TACP_SHARED)$;$NL$ extern uint8 $FORMAT("__limit_sram_%s_%x_%x", OSAP.LABEL[domid], +DEFAULT_ACPTN[domid], +TACP_SHARED)$;$NL$ $ extern uint8 $FORMAT("__start_ram_%s_srpw", OSAP.LABEL[domid])$;$NL$ $ extern uint8 $FORMAT("__limit_ram_%s_srpw", OSAP.LABEL[domid])$;$NL$ $ extern uint8 $FORMAT("__start_sram_%s_srpw", OSAP.LABEL[domid])$;$NL$ $ extern uint8 $FORMAT("__limit_sram_%s_srpw", OSAP.LABEL[domid])$;$NL$ $END$ $END$ $NL$ $END$$NL$ $ 共有領域 extern uint8 __start_text_$OSAP.LABEL[TDOM_NONE]$;$NL$ extern uint8 __limit_text_$OSAP.LABEL[TDOM_NONE]$;$NL$ extern uint8 __start_sram_$OSAP.LABEL[TDOM_NONE]$_$FORMAT("%x", MEMATR_ROSDATA & ~TA_MEMINI)$;$NL$ extern uint8 __limit_sram_$OSAP.LABEL[TDOM_NONE]$_$FORMAT("%x", MEMATR_ROSDATA & ~TA_MEMINI)$;$NL$ extern uint8 __start_ram_$OSAP.LABEL[TDOM_NONE]$;$NL$ extern uint8 __limit_ram_$OSAP.LABEL[TDOM_NONE]$;$NL$ extern uint8 __start_sram_$OSAP.LABEL[TDOM_NONE]$;$NL$ extern uint8 __limit_sram_$OSAP.LABEL[TDOM_NONE]$;$NL$ $ 共有リード専用ライト領域全体 extern uint8 __start_srpw_all;$NL$ extern uint8 __limit_srpw_all;$NL$ extern uint8 __start_ssrpw_all;$NL$ extern uint8 __limit_ssrpw_all;$NL$ $NL$ $ extern const OSAPMPUINFOB_INFO _kernel_osap_mpu_info_tbl[];$NL$ $END$ $FUNCTION GENERATE_TARGET_MPUINFOB$ $ $ ドメインごとのMPU設定情報を生成 $ $FILE "kernel_mem.c"$ $PREPARE_OSAPINICTXB()$ $ $ 共有リードライト領域 / 共有リード専有ライト領域(sdata) / rosdata_shared領域 $ の情報取得 $ $check_shared_mo = 0x00$ $check_srpw_mo = 0x00$ $check_rosdata_mo = 0x00$ $check_sdata_mo = 0x00$ $LIST_SHARED_MO = {}$ $LIST_SRPW_MO = {}$ $LIST_ROSDATA_MO = {}$ $preid = -1$ $FOREACH moid MO_START_LIST$ $ // メモリオブジェクトの先頭をパス2時点での順にチェック $IF LENGTH(FIND(MO_MPROTECT_LIST, moid))$ $ // メモリ保護単位の先頭の場合 $IF (MO.ACPTN1[moid] == TACP_SHARED) && (MO.ACPTN2[moid] == TACP_SHARED)$ $IF ((check_shared_mo & 0x10) != 0x10)$ $ // 共有リードライト領域の先頭の場合 $SHARED_AREA_BASE[check_shared_mo] = MO.BASEADDR[moid]$ $SHARED_AREA_MO[check_shared_mo] = moid$ $LIST_SHARED_MO = APPEND(LIST_SHARED_MO, check_shared_mo)$ $check_shared_mo = check_shared_mo | 0x10$ $END$ $ELIF (check_shared_mo & 0x10) == 0x10$ $ // 共有リードライト領域の終端の場合 $IF preid == -1$ $ERROR$ $FORMAT("unexpected preid.")$ $END$ $END$ $check_shared_mo = check_shared_mo & 0x0f$ $SHARED_AREA_LIMIT[check_shared_mo] = MO.LIMITADDR[preid]$ $SHARED_AREA_SIZE[check_shared_mo] = SHARED_AREA_LIMIT[check_shared_mo] - SHARED_AREA_BASE[check_shared_mo]$ $SHARED_AREA_LIMIT_MO[check_shared_mo] = preid$ $check_shared_mo = check_shared_mo + 1$ $END$ $END$ $preid = moid$ $END$ $IF (check_shared_mo & 0x10) == 0x10$ $IF preid == -1$ $ERROR$ $FORMAT("unexpected preid.")$ $END$ $END$ $check_shared_mo = check_shared_mo & 0x0f$ $SHARED_AREA_LIMIT[check_shared_mo] = MO.LIMITADDR[preid]$ $SHARED_AREA_LIMIT_MO[check_shared_mo] = preid$ $SHARED_AREA_SIZE[check_shared_mo] = SHARED_AREA_LIMIT[check_shared_mo] - SHARED_AREA_BASE[check_shared_mo]$ $check_shared_mo = check_shared_mo + 1$ $END$ $ $ エラーチェック $ $FOREACH id LIST_SHARED_MO$ $IF DEBUG_OPT_TF$ $WARNING$ $id$$NL$ $SHARED_AREA_MO[id]$$NL$ $SHARED_AREA_LIMIT_MO[id]$$NL$ $FORMAT("0x%x", SHARED_AREA_BASE[id])$$NL$ $FORMAT("0x%x", SHARED_AREA_LIMIT[id])$$NL$ $FORMAT("0x%x", SHARED_AREA_SIZE[id])$$NL$ $END$ $END$ $IF ((MO.MEMATR[SHARED_AREA_MO[id]] & TA_SDATA) == TA_SDATA)$ $IF LENGTH(SHARED_DATA.BASE)$ $ERROR$ $FORMAT("unexpected mematr: %d, %x", id, MO.MEMATR[SHARED_AREA_MO[id]])$ $END$ $ELSE$ $SHARED_DATA.BASE = SHARED_AREA_BASE[id]$ $SHARED_DATA.LIMIT = SHARED_AREA_LIMIT[id]$ $SHARED_DATA.SIZE = SHARED_AREA_SIZE[id]$ $SHARED_DATA.BASE_MO = SHARED_AREA_MO[id]$ $SHARED_DATA.LIMIT_MO = SHARED_AREA_LIMIT_MO[id]$ $END$ $ELSE$ $ERROR$ $FORMAT("unexpected mematr: %d, %x", id, MO.MEMATR[SHARED_AREA_MO[id]])$ $END$ $END$ $END$ $FOREACH info RANGE(3,3)$ $ // 領域の開始アドレスを読み込む $start_address = SHARED_DATA.BASE$ $ // 領域の終了アドレスを読み込む $end_address = SHARED_DATA.LIMIT$ $ipal = (start_address & 0xfffffff0)$ $ipau = (end_address & 0xfffffff0)$ $WARNING$ $FORMAT("info%d: start=0x%x, end=0x%x", info, start_address, end_address)$ $END$ $IF (ipal != start_address) || (ipau != end_address)$ $ERROR$ $FORMAT("Not aligned: start=0x%x, end=0x%x", start_address, end_address)$ $END$ $END$ $IF ipal != ipau$ $valid[info] = 0x01$ $ipau = (ipau - 0x1) & 0xfffffffc$ $FOREACH osap OSAP.ID_LIST$ $IF !OSAP.TRUSTED[osap]$ $OSAP.MPRC[osap] = 0x09$ $END$ $END$ $ELSE$ $valid[info] = 0x00$ $END$ $WARNING$ $FORMAT("info%d: ipal=0x%x, ipau=0x%x", info, ipal, ipau)$ $END$ $END$ $ $IF LENGTH(OSAP.ID_LIST) > 0$ $ $ RX領域(専用) $ $comment[0] = "iregion 0"$ $ $access[0] = 0x03$ $ $ RX領域(専用ショートデータ) $ $comment[1] = "iregion 1"$ $ $access[1] = 0x03$ $ $ RWX領域(専用) $ $comment[2] = "dregion 1"$ $ $access[2] = 0x06$ $ $ RWX領域(専用ショートデータ) $ $comment[3] = "dregion 2"$ $ $access[3] = 0x06$ $ $ 共有リード専用ライト $ $comment[4] = "dregion 3"$ $ $access[4] = 0x06$ $ $ 共有リード専用ライト(ショートデータ) $ $comment[5] = "dregion 4"$ $ $access[5] = 0x06$ $ $ $dominib_info = SYMBOL("_kernel_osap_mpu_info_tbl")$ $ const OSAPMPUINFOB_INFO _kernel_osap_mpu_info_tbl[TNUM_OSAP] ={$NL$ $ $JOINEACH domid OSAP.ID_LIST ",\n"$ $ $label[0] = FORMAT("text_%s", OSAP.LABEL[domid])$ $ $label[1] = FORMAT("rosdata_%s", OSAP.LABEL[domid])$ $ $label[2] = FORMAT("ram_%s", OSAP.LABEL[domid])$ $ $label[3] = FORMAT("sram_%s", OSAP.LABEL[domid])$ $ $label[4] = FORMAT("ram_%s_%x_%x", OSAP.LABEL[domid], +DEFAULT_ACPTN[domid], +TACP_SHARED)$ $ $label[5] = FORMAT("sram_%s_%x_%x", OSAP.LABEL[domid], +DEFAULT_ACPTN[domid], +TACP_SHARED)$ $ $ $TAB${$NL$ $ $FOREACH info RANGE(0,5)$ $ $ // 領域の開始アドレスを読み込む $ $start_address = PEEK(dominib_info, 4)$ $ $ // 領域の終了アドレスを読み込む $ $end_address = PEEK(dominib_info + 4, 4)$ $ $dominib_info = dominib_info + 8$ $ $ $ipal = (start_address & 0xfffffff0)$ $ $ipau = (end_address & 0xfffffff0)$ $ $IF (ipal != start_address) || (ipau != end_address)$ $ $ERROR$ $ $FORMAT("Not aligned: start=0x%x, end=0x%x", start_address, end_address)$$NL$ $ $FORMAT("ipal=0x%x, ipau=0x%x", ipal, ipau)$ $ $END$ $ $END$ $ $IF ipal != ipau$ $ $valid = 0x01$ $ $ELSE$ $ $valid = 0x00$ $ $END$ $ $ipal = (ipal | valid)$ $ $ipau = (ipau | access[info])$ $ $ $IF !OSAP.TRUSTED[domid]$ $ $TAB$$TAB$( (uint8 *)(&__start_$label[info]$ + $valid$) ), /* IPAL($comment[info]$) : $FORMAT("0x%x", ipal)$ */$NL$ $ $TAB$$TAB$( (uint8 *)(&__limit_$label[info]$ + $access[info]$ - 0x10) ), /* IPAU($comment[info]$) : $FORMAT("0x%x", ipau)$ */$NL$ $ $ELSE$ $ $TAB$$TAB$( (uint8 *)NULL ), /* IPAL($comment[info]$) : $FORMAT("0x%x", ipal)$ */$NL$ $ $TAB$$TAB$( (uint8 *)NULL ), /* IPAU($comment[info]$) : $FORMAT("0x%x", ipau)$ */$NL$ $ $END$ $ $END$ $ $TAB$} $ $END$ $ ,$NL$};$NL$ $ $NL$ $ $END$ $END$ $ $ TSKINICTXBの初期化情報を生成 $ $DOMINICTXB_KERNEL = "{ NULL }"$ $FUNCTION GENERATE_OSAPINIB_MPUINFOB$ $ $TAB$$TAB${ (OSAPMPUINFOB_INFO *)&_kernel_osap_mpu_info_tbl[$ARGV[1]$] }$NL$ $IF !LENGTH(OSAP.MPRC[ARGV[1]])$ $OSAP.MPRC[ARGV[1]] = 0x01$ $END$ $ RX領域(専用) $comment[0] = "iregion 0"$ $access[0] = 0x03$ $ RX領域(専用ショートデータ) $comment[1] = "iregion 1"$ $access[1] = 0x03$ $ RWX領域(専用) $comment[2] = "dregion 1"$ $access[2] = 0x06$ $ RWX領域(専用ショートデータ) $comment[3] = "dregion 2"$ $access[3] = 0x06$ $ 共有リード専用ライト $comment[1] = "dregion 3"$ $access[1] = 0x07$ $ 共有リード専用ライト(ショートデータ) $comment[2] = "dregion 4"$ $access[2] = 0x07$ $osapinib_info = SYMBOL("osapinib_table")$ $osapinib_offset = sizeof_OSAPINIB * (ARGV[1] - 1)$ $osapinib_info = osapinib_info + osapinib_offset + offsetof_OSAPINIB_osapmpu$ $label[0] = FORMAT("text_%s", OSAP.LABEL[ARGV[1]])$ $label[1] = FORMAT("sram_%s_%x", OSAP.LABEL[ARGV[1]], MEMATR_ROSDATA & ~TA_MEMINI)$ $label[2] = FORMAT("ram_%s", OSAP.LABEL[ARGV[1]])$ $label[3] = FORMAT("sram_%s", OSAP.LABEL[ARGV[1]])$ $label[1] = FORMAT("ram_%s_%x_%x", OSAP.LABEL[ARGV[1]], +DEFAULT_ACPTN[ARGV[1]], +TACP_SHARED)$ $label[2] = FORMAT("sram_%s_%x_%x", OSAP.LABEL[ARGV[1]], +DEFAULT_ACPTN[ARGV[1]], +TACP_SHARED)$ $ $label[4] = FORMAT("ram_%s_srpw", OSAP.LABEL[ARGV[1]])$ $ $label[5] = FORMAT("sram_%s_srpw", OSAP.LABEL[ARGV[1]])$ $TAB$$TAB${$NL$ $FOREACH info RANGE(1,2)$ $ // 領域の開始アドレスを読み込む $start_address = PEEK(osapinib_info, 4)$ $ // 領域の終了アドレスを読み込む $end_address = PEEK(osapinib_info + 4, 4)$ $osapinib_info = osapinib_info + 8$ $ipal = (start_address & 0xfffffff0)$ $ipau = (end_address & 0xfffffff0)$ $IF (ipal != start_address) || (ipau != end_address)$ $ERROR$ $FORMAT("osap is %s, info is %d", ARGV[1], info)$$NL$ $FORMAT("Not aligned: start=0x%x, end=0x%x", start_address, end_address)$$NL$ $FORMAT("ipal=0x%x, ipau=0x%x", ipal, ipau)$ $END$ $END$ $IF ipal != ipau$ $valid[info] = 0x01$ $ipau = (ipau - 0x1) & 0xfffffffc$ $OSAP.MPRC[ARGV[1]] = OSAP.MPRC[ARGV[1]] | (0x01 << info)$ $ELSE$ $valid[info] = 0x00$ $END$ $IF !OSAP.TRUSTED[ARGV[1]]$ $TAB$$TAB$$TAB$( (uint8 *)($FORMAT("0x%x", ipal)$) ), /* MPLA$info$ : &__start_$label[info]$ */$NL$ $TAB$$TAB$$TAB$( (uint8 *)($FORMAT("0x%x", ipau)$) ), /* MPLA$info$ : &__limit_$label[info]$ */$NL$ $ELSE$ $TAB$$TAB$$TAB$( (uint8 *)NULL ), /* MPLA$info$ : $FORMAT("0x%x", ipal)$ */$NL$ $TAB$$TAB$$TAB$( (uint8 *)NULL ), /* MPUA$info$ : $FORMAT("0x%x", ipau)$ */$NL$ $END$ $END$ $IF !OSAP.TRUSTED[ARGV[1]]$ $OSAP.MPRC[ARGV[1]] = OSAP.MPRC[ARGV[1]] | 0x01$ $TAB$$TAB$$TAB$( (uint32)($FORMAT("0x%x", OSAP.MPRC[ARGV[1]])$) ), /* MPRC */$NL$ $ELSE$ $TAB$$TAB$$TAB$( (uint32)0 ), /* MPRC */$NL$ $END$ $TAB$$TAB$}$NL$ $NL$ $END$ $FUNCTION GENERATE_TSKINICTXB$ $TAB$$TAB${$NL$ $TAB$$TAB$$TAB$$TSK.TINIB_SSTKSZ[ARGV[1]]$,$NL$ $TAB$$TAB$$TAB$((void *)((uint8 *)($TSK.TINIB_SSTK[ARGV[1]]$) $SPC$+ ($TSK.TINIB_SSTKSZ[ARGV[1]]$))),$NL$ $IF OSAP.TRUSTED[TSK.OSAPID[ARGV[1]]]$ $TAB$$TAB$$TAB$0,$NL$ $TAB$$TAB$$TAB$0,$NL$ $ELSE$ $TAB$$TAB$$TAB$$TSK.TINIB_USTKSZ[ARGV[1]]$,$NL$ $TAB$$TAB$$TAB$((void *)((uint8 *)($TSK.TINIB_USTK[ARGV[1]]$) $SPC$+ ($TSK.TINIB_USTKSZ[ARGV[1]]$))),$NL$ $END$ $TAB$$TAB$},$NL$ $END$ $FUNCTION GENERATE_STKMPUINFOB$ $TAB$$TAB${$NL$ $IF OSAP.TRUSTED[TSK.OSAPID[ARGV[1]]]$ $TAB$$TAB$$TAB$0,$NL$ $TAB$$TAB$$TAB$0,$NL$ $ELSE$ $p_tinib = SYMBOL("tinib_table")$ $TRACE(TSK.ID[ARGV[1]])$ $p_tinib = p_tinib + TSK.ID[ARGV[1]] * sizeof_TINIB$ $start_address = PEEK(p_tinib + offsetof_TINIB_STKMPUINFOB_start_ustk, 4)$ $end_address = PEEK(p_tinib + offsetof_TINIB_STKMPUINFOB_limit_ustk, 4)$ $mpl = (start_address & 0xfffffff0)$ $mpu = (end_address & 0xfffffff0)$ $IF (mpl != start_address) || (mpu != end_address)$ $ERROR$ $FORMAT("task is %s", ARGV[1])$$NL$ $FORMAT("user stack in not aligned: start=0x%x, end=0x%x", start_address, end_address)$$NL$ $FORMAT("mpla=0x%x, mpua=0x%x", mpl, mpu)$ $END$ $END$ $IF mpl == mpu$ $ERROR$ $FORMAT("task is %s", ARGV[1])$$NL$ $FORMAT("user stack size is 0: start=0x%x, end=0x%x", start_address, end_address)$$NL$ $FORMAT("mpla=0x%x, mpua=0x%x", mpl, mpu)$ $END$ $END$ $mpu = (mpu - 0x1) & 0xfffffffc$ $TAB$$TAB$$TAB$$FORMAT("(uint8 *)0x%x /* &__start_user_stack %s */", mpl, ARGV[1])$,$NL$ $TAB$$TAB$$TAB$$FORMAT("(uint8 *)0x%x /* &__limit_user_stack %s */", mpu, ARGV[1])$,$NL$ $ $ $IF EQ(TSK.STK[tskid],"NULL")$ $ $ $ // stkがNULLの場合の処理 $ $ $IF LENGTH(TSK.SHARED_USTK_ID[tskid])$ $ $ $ // 共有スタック $ $ $TAB$$TAB$$TAB$$FORMAT("&__start_shared_user_stack%s", TSK.PRIORITY[ARGV[1]])$,$NL$ $ $ $TAB$$TAB$$TAB$$FORMAT("(&__limit_shared_user_stack%s - 0x10)", TSK.PRIORITY[ARGV[1]])$,$NL$ $ $ $ELSE$ $ $ $ // 固有スタック $ $ $TAB$$TAB$$TAB$$FORMAT("&__start_user_stack%s", ARGV[1])$,$NL$ $ $ $TAB$$TAB$$TAB$$FORMAT("(&__limit_user_stack%s - 0x10)", ARGV[1])$,$NL$ $ $ $END$ $ $ $ELSE$ $ $ $ // stkがNULLでない場合の処理 $ $ $TAB$$TAB$$TAB$$FORMAT("(uint8 *)%s", TSK.TINIB_USTK[ARGV[1]])$,$NL$ $ $ $TAB$$TAB$$TAB$$FORMAT("(uint8 *)((uint32)%s + %d - 0x10)", TSK.TINIB_USTK[ARGV[1]], TSK.TINIB_USTKSZ[ARGV[1]])$,$NL$ $ $ $END$ $END$ $TAB$$TAB$},$NL$ $END$ $ $ 非依存部の読込み $ $INCLUDE "kernel/kernel_mem.tf"$ $ $ 共有のMPU設定情報を生成 $ kernel_mem3.cの宣言位置と合わせる $ $FILE "kernel_mem.c"$ $ RWX領域 $comment[3] = "MPU 3"$ $access[3] = 0x47$ $shared_meminib = SYMBOL("shared_meminib_table")$ $TNUM_SHARED_REGION = 1$ const uint32 tnum_shared_mem = $TNUM_SHARED_REGION * 2$;$NL$ uint8 * const shared_meminib_table[$TNUM_SHARED_REGION * 2$] = {$NL$ $FOREACH info RANGE(3,3)$ $ // 領域の開始アドレスを読み込む $start_address = SHARED_DATA.BASE$ $ // 領域の終了アドレスを読み込む $end_address = SHARED_DATA.LIMIT$ $ipal = (start_address & 0xfffffff0)$ $ipau = (end_address & 0xfffffff0)$ $WARNING$ $FORMAT("info%d: start=0x%x, end=0x%x", info, start_address, end_address)$ $END$ $IF (ipal != start_address) || (ipau != end_address)$ $ERROR$ $FORMAT("Not aligned: start=0x%x, end=0x%x", start_address, end_address)$ $END$ $END$ $IF ipal != ipau$ $valid[info] = 0x01$ $ipau = (ipau - 0x1) & 0xfffffffc$ $ELSE$ $valid[info] = 0x00$ $END$ $WARNING$ $FORMAT("info%d: ipal=0x%x, ipau=0x%x", info, ipal, ipau)$ $END$ $TAB$$TAB$$FORMAT("( (uint8 *)0x%x )", ipal)$, /* MPLA($comment[info]$) */$NL$ $TAB$$TAB$$FORMAT("( (uint8 *)0x%x )", ipau)$, /* MPUA($comment[info]$) */$NL$ $END$ };$NL$ $NL$ $TRACE(valid[1])$ $TRACE(valid[2])$ $TRACE(valid[3])$ $ $mpu_region_control = 0x01$ $ $mprc_ex = 2$ $ $FOREACH x RANGE(1,3)$ $ $IF valid[x] == 0x01$ $ $mpu_region_control = mpu_region_control | mprc_ex$ $ $END$ $ $mprc_ex = mprc_ex * 2$ $ $END$ $ const uint32 mpu_region_control = $mpu_region_control$; /* MPRC */$NL$