#!/usr/bin/python
# ****************************************************************************
#  Copyright Statement:
#  --------------------
#  This software is protected by Copyright and the information contained
#  herein is confidential. The software may not be copied and the information
#  contained herein may not be used or disclosed except with the written
#  permission of MediaTek Inc. (C) 2018
#
#  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
#  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
#  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
#  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
#  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
#  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
#  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
#  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
#  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
#  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
#  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
#  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
#
#  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
#  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
#  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
#  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
#  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
#
#  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
#  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
#  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
#  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
#  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
#
# ****************************************************************************
#
# ****************************************************************************
#
#  Filename:
#  ---------
#    mer_codegen.py
#
#  Project:
#  --------
#    MERTOS
#
#  Description:
#  ------------
#    Generate the codes required by MERTOS.
#
#
#  Author:
#  -------
#    Ke-Ting Chen (mtk03141)
#
# ****************************************************************************

import mer_utility

import os
import sys


def extract_task_info(data_extractor):
    """
    Transform syscomp data to internal representation
    """
    #   typedef struct {
    #   kal_char             *comp_name_ptr;
    #   kal_char             *comp_qname_ptr;
    #   kal_uint32           comp_priority;
    #   kal_uint32           comp_stack_size;
    #   kal_create_func_ptr  comp_create_func;
    #   kal_bool             comp_internal_ram_stack;
    #   kal_uint8            comp_ext_qsize;
    #   kal_uint8            comp_int_qsize;
    #   kal_uint8            comp_boot_mode;
    #   kal_affinity_group   comp_affinity_attribute;
    #   kal_bool             comp_affinity_dynamic;
    #   kal_task_group_id    comp_affinity_group_id;
    # } comptask_info_struct;

    # Get structure size
    affinity_group_size = data_extractor.unpack_symbol_data('I', 'cfg_affinity_group_size')[0]
    if affinity_group_size == 1:
        struct_format_string = 'IIIIIBBBBBBxxI'
    elif affinity_group_size == 2:
        struct_format_string = 'IIIIIBBBBHBxI'
    else:
        assert 0
    field_names = ['name', 'mail_queue_name', 'priority', 'stack_size', 'create_func',
                   'is_stack_in_internal_ram', 'mail_queue_size', 'internal_queue_size',
                   'boot_mode', 'affinity', 'is_dynamic_affinity', 'affinity_group_id']

    infos = data_extractor.unpack_symbol_data_struct_array('sys_comp_config_tbl',
                                                           struct_format_string, field_names)

    # Get VPE number of MIPS
    vpe_num = data_extractor.unpack_symbol_data('I', 'cfg_sys_vpe_num')[0]

    # Get ILM struct size
    mail_size = data_extractor.unpack_symbol_data('I', 'cfg_ilm_struct')[0]

    # Tweak the format
    infos = [info for info in infos if info['create_func'] != 0xF0F0F0F0]
    for info in infos:
        if info['name'] == 0:
            info['name'] = 'UNKNOWN'
        else:
            info['name'] = data_extractor.get_string_data(info['name'])[:-1]  # Remove ending 0

        info['priority'] = info['priority'] >> 16
        info['mail_size'] = mail_size
        info['entry_func'] = 'kal_mer_task_entry_wrapper'
        info['init_func'] = 'mer_kernel_task_default_init'
        del info['mail_queue_name']
        del info['create_func']
        del info['internal_queue_size']
        del info['boot_mode']
        del info['is_dynamic_affinity']
        del info['affinity_group_id']
        
        if info['stack_size'] % 32 != 0:
            info['stack_size'] += (32 - info['stack_size'] % 32)
            
        assert info['stack_size'] >= 96, ('Stack size should not less than 96 bytes: task ' +
                                          info['name'])
    for idx in range(vpe_num):
        info = dict()
        info['name'] = 'DUMMY_IDLE_LOOP%d' % idx
        info['priority'] = 1024+idx
        info['mail_size'] = 0
        info['entry_func'] = 'mer_kernel_task_dummy_loop'
        info['init_func'] = 'mer_kernel_task_default_init'
        info['affinity'] = 2**idx
        info['mail_queue_size'] = 0
        info['mail_size'] = 0
        info['stack_size'] = 512
        infos.append(info)

    assert len(infos) <= 256, 'The current total tasks number over 256.\n'
    
    return infos


def write_task_config(infos, config_output_path, priority_output_path):
    # Sort by priority
    infos.sort(key=lambda x: (x['priority'], -x['affinity']))

    # To reduce the size of TCB size required in MERTOS, we have to pack the priorities
    # Also, we have to put the KAL priority to MERTOS priority mapping in another file
    original_priorities = [None] * len(infos)
    for index in xrange(len(infos)):
        if infos[index]['priority'] < 1024:
            original_priorities[index] = infos[index]['priority']
        else:
            original_priorities[index] = 0

        infos[index]['priority'] = index

    # Write task config file
    output_info_list = ['name', 'affinity', 'stack_size', 'mail_queue_size', 'mail_size',
                        'priority', 'entry_func', 'init_func']
    write_config(infos, output_info_list, 'MER_CONFIG_TASK', config_output_path)

    # Write priority mapping
    with open(priority_output_path, 'w') as out_file:
        out_file.write(', '.join([str(priority) for priority in original_priorities]))


def extract_dpc_info(data_extractor):
    """
    Transform syscomp data to internal representation
    """
    # typedef struct {
    #     kal_hisr            index;
    #     kal_uint8           priority;
    #     kal_uint8           options;
    #     kal_uint32          stack_size;
    #     kal_hisr_func_ptr   entry_func;
    #     kal_char            *hisr_name;
    #     kal_affinity_group  affinity_attribute;
    #     kal_bool            affinity_dynamic;
    # } hisr_parameter_s;

    # Get structure size
    affinity_group_size = data_extractor.unpack_symbol_data('I', 'cfg_affinity_group_size')[0]
    if affinity_group_size == 1:
        struct_format_string = 'BBBxIIIBBxx'
    elif affinity_group_size == 2:
        struct_format_string = 'BBBxIIIHBx'
    else:
        assert 0
    field_names = ['index', 'priority', 'options', 'stack_size', 'entry_func', 'name', 'affinity',
                   'is_dynamic_affinity']
    infos = data_extractor.unpack_symbol_data_struct_array('hisr_info',
                                                           struct_format_string, field_names)

    # Tweak the format
    for index, info in zip(xrange(len(infos)), infos):
        if info['name'] == 0:
            info['name'] == 'UNKNOWN'
        else:
            info['name'] = data_extractor.get_string_data(info['name'])[:-1]  # Remove ending 0

        assert info['entry_func'], ('Entry function should not be NULL: hisr ' +
                                    info['name'])
        info['entry_func'] = data_extractor.get_symbol_name(info['entry_func'])
        assert info['entry_func'] != 'SYMBOL_NOT_FOUND'

        del info['options']
        del info['is_dynamic_affinity']
        
        if info['stack_size'] % 32 != 0:
            info['stack_size'] += (32 - info['stack_size'] % 32)
        
        assert info['stack_size'] >= 96, ('Stack size should not less than 96 bytes: task ' +
                                          info['name'])

    return infos


def write_dpc_config(infos, config_output_path, index_output_path):
    # Do not sort by index
    # infos.sort(key=lambda x: x['index'])

    # Get the information to map from KAL HISR index to MERTOS DPC index
    # Also, we have to put the KAL index to MERTOS index mapping in another file
    max_index = max(info['index'] for info in infos)
    kal_to_mertos_indices = [max_index] * (max_index + 1)
    for index in xrange(len(infos)):
        kal_to_mertos_indices[infos[index]['index']] = index

    # Write dpc config file
    output_info_list = ['name', 'affinity', 'priority', 'stack_size', 'entry_func']
    write_config(infos, output_info_list, 'MER_CONFIG_DPC', config_output_path)

    # Write index mapping
    with open(index_output_path, 'w') as out_file:
        out_file.write(', '.join([str(index) for index in kal_to_mertos_indices]))


def extract_fixmem_info(data_extractor):
    """
    Transform syscomp data to internal representation
    """
    # First parse control buffer
    # typedef struct
    # {
    #     kal_uint32 buf_size;
    #     kal_uint16 buf_num;
    # } buffer_size_s;
    struct_format_string = 'IHxx'
    field_names = ['size', 'number']
    infos = data_extractor.unpack_symbol_data_struct_array('cfg_ctrl_buff',
                                                           struct_format_string, field_names)

    # Get control buffer overhead for each block
    control_buffer_total_overhead = data_extractor.unpack_symbol_data('I', 'cfg_ctrl_buff_overhead')[0]
    
    # Get control buffer OS overhead for each block
    control_buffer_os_overhead = data_extractor.unpack_symbol_data('I', 'cfg_os_buff_overhead')[0]
    
    # Before KAL refactoring cfg_event_buff is controlled by MERTOS
    # That is, we don't need to know the certain pool_id of memory buffer from header
    # It must be evshed_pool_id
    # However, KAL refactoring gather the porting layer from each OS
    # and use the common level API(kal_os_allocate_buffer/kal_os_deallocate_buffer) to allocate/free memory

    
    # Add the overhead to each control buffer, this buffer is for user, apply total overhead(header/footer)
    for entry in infos:
        entry['size'] += control_buffer_total_overhead
        entry['type'] = 'fixmem'
    
    # Get event scheduler buffer requirement
    event_scheduler_infos = data_extractor.unpack_symbol_data_struct_array(
        'cfg_event_buff', struct_format_string, field_names)
    
    # Add the overhead to each control buffer, this buffer is for OS, apply only the OS overhead
    for entry in event_scheduler_infos:
        entry['size'] += control_buffer_os_overhead
        entry['type'] = 'event'
    
    infos.extend(event_scheduler_infos)
    
    return infos


def write_fixmem_config(infos, config_output_path):
    # Write dpc config file
    output_info_list = ['type', 'size', 'number']
    write_config(infos, output_info_list, 'MER_SERVICE_CONFIG_FIXMEM', config_output_path)


def write_mutex_semaphore_config(mutex_number, semaphore_number, config_output_path):
    output_info_list = ['name', 'count']
    infos = list({output_info_list[0]: 'M{0}'.format(index), output_info_list[1]: 1}
                 for index in xrange(mutex_number - 1))
    infos.append({output_info_list[0]: 'LAST_MUTEX', output_info_list[1]: 1})
    infos.extend(list({output_info_list[0]: 'S{0}'.format(index), output_info_list[1]: 1}
                      for index in xrange(semaphore_number)))
    write_config(infos, output_info_list, 'MER_SERVICE_CONFIG_SEMAPHORE', config_output_path)


def write_enhmutex_config(number, config_output_path):
    output_info_list = ['name']
    infos = list({output_info_list[0]: index} for index in xrange(number))
    write_config(infos, output_info_list, 'MER_SERVICE_CONFIG_SYNC_ENHMUTEX', config_output_path)


def write_event_group_config(number, config_output_path):
    output_info_list = ['name']
    infos = list({output_info_list[0]: index} for index in xrange(number))
    write_config(infos, output_info_list, 'MER_SERVICE_CONFIG_EVENT_GROUP', config_output_path)


def write_config(infos, column_names, row_name, output_path):
    def merge_dicts(a, b):
        c = a.copy()
        c.update(b)
        return c

    column_width = {}
    for name in column_names:
        column_width[name + '_width'] = max(len(name), max(len(str(info[name])) for info in infos))
    output_format = ', '.join('{{{0}:{{{0}_width}}}}'.format(name) for name in column_names)

    # Write config file
    with open(output_path, 'w') as out_file:
        #Guard header
        out_file.write('#if !defined(__MER_CONFIG_MUST_REBUILD__)\n')
        out_file.write('    #error "should not include this file since this module is library release or binary release"\n')
        out_file.write('#endif\n')
        # Write info comment line
        column_name_dict = {name: name for name in column_names}
        out_file.write('/*' + ' ' * (len(row_name) - 2 + 1) + output_format.format(
            **merge_dicts(column_name_dict, column_width)) + '*/\n')
        for info in infos:
            out_file.write('{0}('.format(row_name) + output_format.format(
                **merge_dicts(info, column_width)) + ')\n')


def main(argv):
    def get_config_output_path(filename):
        return os.path.join(task_config_output_folder, filename)

    readelf_exec = argv[1]
    elf_path = argv[2]
    task_config_output_folder = argv[3]

    data_extractor = mer_utility.ElfDataExtractor(readelf_exec, elf_path)
    task_infos = extract_task_info(data_extractor)
    dpc_infos = extract_dpc_info(data_extractor)
    fixmem_infos = extract_fixmem_info(data_extractor)

    write_task_config(task_infos,
                      get_config_output_path('kal_mertos_config_task.inc'),
                      get_config_output_path('kal_mertos_config_task_priority_mapping.inc'))
    write_dpc_config(dpc_infos,
                     get_config_output_path('kal_mertos_config_dpc.inc'),
                     get_config_output_path('kal_mertos_config_dpc_index_mapping.inc'))
    write_fixmem_config(fixmem_infos,
                        get_config_output_path('kal_mertos_config_fixmem.inc'))


if __name__ == '__main__':
    main(sys.argv)
