$ ====================================================================== $ $ TOPPERS ATK2 $ Toyohashi Open Platform for Embedded Real-Time Systems $ Automotive Kernel Version 2 $ $ Copyright (C) 2013-2015 by Center for Embedded Computing Systems $ Graduate School of Information Science, Nagoya Univ., JAPAN $ 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$ $FILE "kernel_mem.c"$ #pragma section kernel $ $ パス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)$ $ $ ユーザスタック領域のセクション名を返す $ ARGV[1]:タスクID $ $FUNCTION SECTION_USTACK$ $RESULT = FORMAT(".user_stack.%s.bss", ARGV[1])$ $END$ $ $ 基本タスクの共有スタックのセクション名 $ ARGV[1]:共有スタックID(タスク優先度) $ kernel.tfから呼ばれる $ $FUNCTION SECTION_SHARED_USTACK$ $RESULT = FORMAT(".shared_user_stack.%s.bss", ARGV[1])$ $END$ $FUNCTION START_SYMBOL$ $symbol = CONCAT("__s", MO.SECTION[ARGV[1]])$ $IF !EQ(MO.ILABEL[ARGV[1]], "")$ $symbol = CONCAT(symbol, ".R")$ $END$ $RESULT = SYMBOL(symbol)$ $END$ $FUNCTION LIMIT_SYMBOL$ $symbol = CONCAT("__e", MO.SECTION[ARGV[1]])$ $IF !EQ(MO.ILABEL[ARGV[1]], "")$ $symbol = CONCAT(symbol, ".R")$ $END$ $RESULT = SYMBOL(symbol)$ $END$ $ $ MPU設定情報生成の準備 $ $check = 0$ $FOREACH mo MO_MPROTECT_LIST$ $IF LENGTH(pre_mo) && check >= 2$ $ // 空でないメモリオブジェクトを探す $FOREACH at RANGE(FIND(MO_ORDER, pre_mo), FIND(MO_ORDER, mo) - 1)$ $cur_mo = AT(MO_ORDER, at)$ $start = START_SYMBOL(cur_mo)$ $limit = LIMIT_SYMBOL(cur_mo)$ $IF LENGTH(start)$ $IF !LENGTH(start_sym)$ $start_sym = start$ $END$ $IF LENGTH(limit)$ $limit_sym = limit$ $END$ $END$ $END$ $END$ $IF check == 1$ $NOOP()$ $ELIF check == 2$ $ // 共有領域の終端番地 $IF !LENGTH(shared_mo_start)$ $shared_mo_start = start_sym$ $END$ $shared_mo_limit = limit_sym$ $ELIF check == 3$ $ // 共有リード専有ライトsdata領域の終端番地 $sosap_mo_start[MO.OSAPID[pre_mo]] = start_sym$ $sosap_mo_limit[MO.OSAPID[pre_mo]] = limit_sym$ $ELIF check == 4$ $ // 共有リード専有ライト領域の終端番地 $osap_mo_start[MO.OSAPID[pre_mo]] = start_sym$ $osap_mo_limit[MO.OSAPID[pre_mo]] = limit_sym$ $END$ $start_sym = START_SYMBOL(mo)$ $limit_sym = LIMIT_SYMBOL(mo)$ $IF EQ(MO.TYPE[mo], "TOPPERS_USTACK")$ $ // ユーザスタック $ustk_mo = APPEND(ustk_mo, mo)$ $check = 1$ $ELIF EQ(MO.ACPTN_W[mo], "TACP_SHARED")$ $ // 共有リードライト $IF LENGTH(shared_mo_start)$ $ERROR$ shared mo duplicate $END$ $END$ $shared_mo_start = start_sym$ $check = 2$ $ELIF !EQ(MO.ACPTN_W[mo], "TACP_KERNEL")$ $ // 共有リード専有ライト $IF (MO.MEMATR[mo] & TA_SDATA) != 0$ $ // sdata $sosap_mo_start[MO.OSAPID[mo]] = start_sym$ $check = 3$ $ELSE$ $ // not sdata $osap_mo_start[MO.OSAPID[mo]] = start_sym$ $check = 4$ $END$ $ELSE$ $check = 0$ $END$ $pre_mo = mo$ $END$ $IF check >= 2$ $ // 空でないメモリオブジェクトを探す $FOREACH at RANGE(FIND(MO_ORDER, pre_mo), FIND(MO_ORDER, mo))$ $cur_mo = AT(MO_ORDER, at)$ $start = START_SYMBOL(cur_mo)$ $limit = LIMIT_SYMBOL(cur_mo)$ $IF LENGTH(start)$ $IF !LENGTH(start_sym)$ $start_sym = start$ $END$ $IF LENGTH(limit)$ $limit_sym = limit$ $END$ $END$ $END$ $END$ $IF check == 1$ $NOOP()$ $ELIF check == 2$ $ // 共有領域の終端番地 $shared_mo_start = start_sym$ $shared_mo_limit = limit_sym$ $ELIF check == 3$ $ // 共有リード専有ライトsdata領域の終端番地 $sosap_mo_start[MO.OSAPID[pre_mo]] = start_sym$ $sosap_mo_limit[MO.OSAPID[pre_mo]] = limit_sym$ $ELIF check == 4$ $ // 共有リード専有ライト領域の終端番地 $osap_mo_start[MO.OSAPID[pre_mo]] = start_sym$ $osap_mo_limit[MO.OSAPID[pre_mo]] = limit_sym$ $END$ $FUNCTION GENERATE_TARGET_MPUINFOB$ $ $ ドメインごとのMPU設定情報を生成 $ $FOREACH info RANGE(3,3)$ $start_address = 0$ $end_address = 0$ $IF LENGTH(shared_mo_start)$ $ // 領域の開始アドレスを読み込む $start_address = shared_mo_start$ $ // 領域の終了アドレスを読み込む $end_address = shared_mo_limit$ $END$ $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$ $END$ $ $ TSKINICTXBの初期化情報を生成 $ $DOMINICTXB_KERNEL = "{ NULL }"$ $FUNCTION GENERATE_OSAPINIB_MPUINFOB$ $IF !LENGTH(OSAP.MPRC[ARGV[1]])$ $OSAP.MPRC[ARGV[1]] = 0x01$ $END$ $info = 1$ $TAB$$TAB${$NL$ $start_address = 0$ $end_address = 0$ $IF LENGTH(osap_mo_start[ARGV[1]])$ $ // 領域の開始アドレスを読み込む $start_address = osap_mo_start[ARGV[1]]$ $ // 領域の終了アドレスを読み込む $end_address = osap_mo_limit[ARGV[1]]$ $END$ $TRACE(ARGV[1])$ $TRACE(start_address)$ $TRACE(end_address)$ $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[1] = 0x01$ $ipau = (ipau - 0x1) & 0xfffffffc$ $OSAP.MPRC[ARGV[1]] = OSAP.MPRC[ARGV[1]] | 0x02$ $ELSE$ $valid[1] = 0x00$ $END$ $IF !OSAP.TRUSTED[ARGV[1]]$ $TAB$$TAB$$TAB$( (uint8 *)($FORMAT("0x%x", ipal)$) ), /* MPLA0 */$NL$ $TAB$$TAB$$TAB$( (uint8 *)($FORMAT("0x%x", ipau)$) ), /* MPLA0 */$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$ $info = 2$ $start_address = 0$ $end_address = 0$ $IF LENGTH(sosap_mo_start[ARGV[1]])$ $ // 領域の開始アドレスを読み込む $start_address = sosap_mo_start[ARGV[1]]$ $ // 領域の終了アドレスを読み込む $end_address = sosap_mo_limit[ARGV[1]]$ $END$ $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[2] = 0x01$ $ipau = (ipau - 0x1) & 0xfffffffc$ $OSAP.MPRC[ARGV[1]] = OSAP.MPRC[ARGV[1]] | 0x04$ $ELSE$ $valid[2] = 0x00$ $END$ $IF !OSAP.TRUSTED[ARGV[1]]$ $TAB$$TAB$$TAB$( (uint8 *)($FORMAT("0x%x", ipal)$) ), /* MPLA1 */$NL$ $TAB$$TAB$$TAB$( (uint8 *)($FORMAT("0x%x", ipau)$) ), /* MPLA1 */$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$ $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$ $IF EQ(TSK.STK[ARGV[1]],"NULL")$ $ // stkがNULLの場合の処理 $IF LENGTH(TSK.SHARED_USTK_ID[ARGV[1]])$ $ // 共有スタック $section = SECTION_SHARED_USTACK(TSK.SHARED_USTK_ID[ARGV[1]])$ $start_address = SYMBOL(CONCAT("__s", section))$ $end_address = SYMBOL(CONCAT("__e", section))$ $ELSE$ $ // 固有スタック $section = SECTION_USTACK(ARGV[1])$ $start_address = SYMBOL(CONCAT("__s", section))$ $end_address = SYMBOL(CONCAT("__e", section))$ $END$ $ELSE$ $ // stkがNULLでない場合の処理 $p_tinib = SYMBOL("tinib_table")$ $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)$ $END$ $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("(void *)0x%x /* &__start_user_stack %s */", mpl, ARGV[1])$,$NL$ $TAB$$TAB$$TAB$$FORMAT("(void *)0x%x /* &__limit_user_stack %s */", mpu, ARGV[1])$,$NL$ $END$ $TAB$$TAB$},$NL$ $END$ $ $ meminibの依存部の読込み $ $INCLUDE "arch/v850_ccrh/prc_meminib.tf"$ $ $ 非依存部の読込み $ $INCLUDE "kernel/kernel_mem.tf"$ $FILE "kernel_mem.c"$ $ $ 共有のMPU設定情報を生成 $ kernel_mem3.cの宣言位置と合わせる $ $comment[3] = "MPU 3"$ $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 = 0$ $end_address = 0$ $IF LENGTH(shared_mo_start)$ $ // 領域の開始アドレスを読み込む $start_address = shared_mo_start$ $ // 領域の終了アドレスを読み込む $end_address = shared_mo_limit$ $END$ $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$