diff options
Diffstat (limited to 'wlauto/devices')
-rw-r--r-- | wlauto/devices/__init__.py | 16 | ||||
-rw-r--r-- | wlauto/devices/android/__init__.py | 16 | ||||
-rw-r--r-- | wlauto/devices/android/generic/__init__.py | 37 | ||||
-rw-r--r-- | wlauto/devices/android/juno/__init__.py | 173 | ||||
-rw-r--r-- | wlauto/devices/android/nexus10/__init__.py | 48 | ||||
-rw-r--r-- | wlauto/devices/android/nexus5/__init__.py | 40 | ||||
-rw-r--r-- | wlauto/devices/android/note3/__init__.py | 76 | ||||
-rw-r--r-- | wlauto/devices/android/odroidxu3/__init__.py | 38 | ||||
-rw-r--r-- | wlauto/devices/android/tc2/__init__.py | 847 | ||||
-rw-r--r-- | wlauto/devices/android/tc2/resources/board_template.txt | 96 | ||||
-rw-r--r-- | wlauto/devices/android/tc2/resources/images_iks.txt | 25 | ||||
-rw-r--r-- | wlauto/devices/android/tc2/resources/images_mp.txt | 55 | ||||
-rw-r--r-- | wlauto/devices/linux/__init__.py | 16 | ||||
-rw-r--r-- | wlauto/devices/linux/generic/__init__.py | 37 | ||||
-rw-r--r-- | wlauto/devices/linux/odroidxu3_linux/__init__.py | 35 |
15 files changed, 1555 insertions, 0 deletions
diff --git a/wlauto/devices/__init__.py b/wlauto/devices/__init__.py new file mode 100644 index 00000000..16224d6f --- /dev/null +++ b/wlauto/devices/__init__.py @@ -0,0 +1,16 @@ +# Copyright 2014-2015 ARM Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + diff --git a/wlauto/devices/android/__init__.py b/wlauto/devices/android/__init__.py new file mode 100644 index 00000000..cd5d64d6 --- /dev/null +++ b/wlauto/devices/android/__init__.py @@ -0,0 +1,16 @@ +# Copyright 2013-2015 ARM Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + diff --git a/wlauto/devices/android/generic/__init__.py b/wlauto/devices/android/generic/__init__.py new file mode 100644 index 00000000..51a43948 --- /dev/null +++ b/wlauto/devices/android/generic/__init__.py @@ -0,0 +1,37 @@ +# Copyright 2013-2015 ARM Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +from wlauto import AndroidDevice, Parameter + + +class GenericDevice(AndroidDevice): + name = 'generic_android' + description = """ + Generic Android device. Use this if you do not have a device file for + your device. + + This implements the minimum functionality that should be supported by + all android devices. + + """ + + default_working_directory = '/storage/sdcard0/working' + has_gpu = True + + parameters = [ + Parameter('core_names', default=[], override=True), + Parameter('core_clusters', default=[], override=True), + ] diff --git a/wlauto/devices/android/juno/__init__.py b/wlauto/devices/android/juno/__init__.py new file mode 100644 index 00000000..712c4e1d --- /dev/null +++ b/wlauto/devices/android/juno/__init__.py @@ -0,0 +1,173 @@ +# Copyright 2014-2015 ARM Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +# pylint: disable=E1101 +import os +import re +import time + +import pexpect + +from wlauto import BigLittleDevice, Parameter +from wlauto.exceptions import DeviceError +from wlauto.utils.serial_port import open_serial_connection, pulse_dtr +from wlauto.utils.android import adb_connect, adb_disconnect, adb_list_devices +from wlauto.utils.uefi import UefiMenu + + +AUTOSTART_MESSAGE = 'Press Enter to stop auto boot...' + + +class Juno(BigLittleDevice): + + name = 'juno' + description = """ + ARM Juno next generation big.LITTLE development platform. + """ + + capabilities = ['reset_power'] + + has_gpu = True + + modules = [ + 'vexpress', + ] + + parameters = [ + Parameter('retries', kind=int, default=2, + description="""Specifies the number of times the device will attempt to recover + (normally, with a hard reset) if it detects that something went wrong."""), + + # VExpress flasher expects a device to have these: + Parameter('uefi_entry', default='WA', + description='The name of the entry to use (will be created if does not exist).'), + Parameter('microsd_mount_point', default='/media/JUNO', + description='Location at which the device\'s MicroSD card will be mounted.'), + Parameter('port', default='/dev/ttyS0', description='Serial port on which the device is connected.'), + Parameter('baudrate', kind=int, default=115200, description='Serial connection baud.'), + Parameter('timeout', kind=int, default=300, description='Serial connection timeout.'), + Parameter('core_names', default=['a53', 'a53', 'a53', 'a53', 'a57', 'a57'], override=True), + Parameter('core_clusters', default=[0, 0, 0, 0, 1, 1], override=True), + ] + + short_delay = 1 + firmware_prompt = 'Cmd>' + # this is only used if there is no UEFI entry and one has to be created. + kernel_arguments = 'console=ttyAMA0,115200 earlyprintk=pl011,0x7ff80000 verbose debug init=/init root=/dev/sda1 rw ip=dhcp rootwait' + + def boot(self, **kwargs): + self.logger.debug('Resetting the device.') + self.reset() + with open_serial_connection(port=self.port, + baudrate=self.baudrate, + timeout=self.timeout, + init_dtr=0) as target: + menu = UefiMenu(target) + self.logger.debug('Waiting for UEFI menu...') + menu.open(timeout=120) + try: + menu.select(self.uefi_entry) + except LookupError: + self.logger.debug('{} UEFI entry not found.'.format(self.uefi_entry)) + self.logger.debug('Attempting to create one using default flasher configuration.') + self.flasher.image_args = self.kernel_arguments + self.flasher.create_uefi_enty(self, menu) + menu.select(self.uefi_entry) + self.logger.debug('Waiting for the Android prompt.') + target.expect(self.android_prompt, timeout=self.timeout) + + def connect(self): + if not self._is_ready: + if not self.adb_name: # pylint: disable=E0203 + with open_serial_connection(timeout=self.timeout, + port=self.port, + baudrate=self.baudrate, + init_dtr=0) as target: + target.sendline('') + self.logger.debug('Waiting for android prompt.') + target.expect(self.android_prompt) + + self.logger.debug('Waiting for IP address...') + wait_start_time = time.time() + while True: + target.sendline('ip addr list eth0') + time.sleep(1) + try: + target.expect('inet ([1-9]\d*.\d+.\d+.\d+)', timeout=10) + self.adb_name = target.match.group(1) + ':5555' # pylint: disable=W0201 + break + except pexpect.TIMEOUT: + pass # We have our own timeout -- see below. + if (time.time() - wait_start_time) > self.ready_timeout: + raise DeviceError('Could not acquire IP address.') + + if self.adb_name in adb_list_devices(): + adb_disconnect(self.adb_name) + adb_connect(self.adb_name, timeout=self.timeout) + super(Juno, self).connect() # wait for boot to complete etc. + self._is_ready = True + + def disconnect(self): + if self._is_ready: + super(Juno, self).disconnect() + adb_disconnect(self.adb_name) + self._is_ready = False + + def reset(self): + # Currently, reboot is not working in Android on Juno, so + # perfrom a ahard reset instead + self.hard_reset() + + def get_cpuidle_states(self, cpu=0): + return {} + + def hard_reset(self): + self.disconnect() + self.adb_name = None # Force re-acquire IP address on reboot. pylint: disable=attribute-defined-outside-init + with open_serial_connection(port=self.port, + baudrate=self.baudrate, + timeout=self.timeout, + init_dtr=0, + get_conn=True) as (target, conn): + pulse_dtr(conn, state=True, duration=0.1) # TRM specifies a pulse of >=100ms + + i = target.expect([AUTOSTART_MESSAGE, self.firmware_prompt]) + if i: + self.logger.debug('Saw firmware prompt.') + time.sleep(self.short_delay) + target.sendline('reboot') + else: + self.logger.debug('Saw auto boot message.') + + def wait_for_microsd_mount_point(self, target, timeout=100): + attempts = 1 + self.retries + if os.path.exists(os.path.join(self.microsd_mount_point, 'config.txt')): + return + + self.logger.debug('Waiting for VExpress MicroSD to mount...') + for i in xrange(attempts): + if i: # Do not reboot on the first attempt. + target.sendline('reboot') + for _ in xrange(timeout): + time.sleep(self.short_delay) + if os.path.exists(os.path.join(self.microsd_mount_point, 'config.txt')): + return + raise DeviceError('Did not detect MicroSD mount on {}'.format(self.microsd_mount_point)) + + def get_android_id(self): + # Android ID currenlty not set properly in Juno Android builds. + return 'abad1deadeadbeef' + diff --git a/wlauto/devices/android/nexus10/__init__.py b/wlauto/devices/android/nexus10/__init__.py new file mode 100644 index 00000000..ad6f2555 --- /dev/null +++ b/wlauto/devices/android/nexus10/__init__.py @@ -0,0 +1,48 @@ +# Copyright 2013-2015 ARM Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +import time + +from wlauto import AndroidDevice, Parameter + + +class Nexus10Device(AndroidDevice): + + name = 'Nexus10' + description = """ + Nexus10 is a 10 inch tablet device, which has dual-core A15. + + To be able to use Nexus10 in WA, the following must be true: + + - USB Debugging Mode is enabled. + - Generate USB debugging authorisation for the host machine + + """ + + default_working_directory = '/sdcard/working' + has_gpu = True + max_cores = 2 + + parameters = [ + Parameter('core_names', default=['A15', 'A15'], override=True), + Parameter('core_clusters', default=[0, 0], override=True), + ] + + def init(self, context, *args, **kwargs): + time.sleep(self.long_delay) + self.execute('svc power stayon true', check_exit_code=False) + time.sleep(self.long_delay) + self.execute('input keyevent 82') diff --git a/wlauto/devices/android/nexus5/__init__.py b/wlauto/devices/android/nexus5/__init__.py new file mode 100644 index 00000000..cd2f09db --- /dev/null +++ b/wlauto/devices/android/nexus5/__init__.py @@ -0,0 +1,40 @@ +# Copyright 2013-2015 ARM Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +from wlauto import AndroidDevice, Parameter + + +class Nexus5Device(AndroidDevice): + + name = 'Nexus5' + description = """ + Adapter for Nexus 5. + + To be able to use Nexus5 in WA, the following must be true: + + - USB Debugging Mode is enabled. + - Generate USB debugging authorisation for the host machine + + """ + + default_working_directory = '/storage/sdcard0/working' + has_gpu = True + max_cores = 4 + + parameters = [ + Parameter('core_names', default=['krait400', 'krait400', 'krait400', 'krait400'], override=True), + Parameter('core_clusters', default=[0, 0, 0, 0], override=True), + ] diff --git a/wlauto/devices/android/note3/__init__.py b/wlauto/devices/android/note3/__init__.py new file mode 100644 index 00000000..9c8f42ae --- /dev/null +++ b/wlauto/devices/android/note3/__init__.py @@ -0,0 +1,76 @@ +# Copyright 2013-2015 ARM Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +import time + +from wlauto import AndroidDevice, Parameter +from wlauto.exceptions import TimeoutError +from wlauto.utils.android import adb_shell + + +class Note3Device(AndroidDevice): + + name = 'Note3' + description = """ + Adapter for Galaxy Note 3. + + To be able to use Note3 in WA, the following must be true: + + - USB Debugging Mode is enabled. + - Generate USB debugging authorisation for the host machine + + """ + + parameters = [ + Parameter('core_names', default=['A15', 'A15', 'A15', 'A15'], override=True), + Parameter('core_clusters', default=[0, 0, 0, 0], override=True), + Parameter('working_directory', default='/storage/sdcard0/wa-working', override=True), + ] + + def __init__(self, **kwargs): + super(Note3Device, self).__init__(**kwargs) + self._just_rebooted = False + + def init(self, context): + self.execute('svc power stayon true', check_exit_code=False) + + def reset(self): + super(Note3Device, self).reset() + self._just_rebooted = True + + def hard_reset(self): + super(Note3Device, self).hard_reset() + self._just_rebooted = True + + def connect(self): # NOQA pylint: disable=R0912 + super(Note3Device, self).connect() + if self._just_rebooted: + self.logger.debug('Waiting for boot to complete...') + # On the Note 3, adb connection gets reset some time after booting. + # This causes errors during execution. To prevent this, open a shell + # session and wait for it to be killed. Once its killed, give adb + # enough time to restart, and then the device should be ready. + try: + adb_shell(self.adb_name, '', timeout=20) # pylint: disable=no-member + time.sleep(5) # give adb time to re-initialize + except TimeoutError: + pass # timed out waiting for the session to be killed -- assume not going to be. + + self.logger.debug('Boot completed.') + self._just_rebooted = False + # Swipe upwards to unlock the screen. + time.sleep(self.long_delay) + self.execute('input touchscreen swipe 540 1600 560 800 ') diff --git a/wlauto/devices/android/odroidxu3/__init__.py b/wlauto/devices/android/odroidxu3/__init__.py new file mode 100644 index 00000000..60f780b7 --- /dev/null +++ b/wlauto/devices/android/odroidxu3/__init__.py @@ -0,0 +1,38 @@ +# Copyright 2013-2015 ARM Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +from wlauto import AndroidDevice, Parameter + + +class OdroidXU3(AndroidDevice): + + name = "odroidxu3" + description = 'HardKernel Odroid XU3 development board.' + + core_modules = [ + 'odroidxu3-fan', + ] + + parameters = [ + Parameter('adb_name', default='BABABEEFBABABEEF', override=True), + Parameter('working_directory', default='/data/local/wa-working', override=True), + Parameter('core_names', default=['a7', 'a7', 'a7', 'a7', 'a15', 'a15', 'a15', 'a15'], override=True), + Parameter('core_clusters', default=[0, 0, 0, 0, 1, 1, 1, 1], override=True), + Parameter('port', default='/dev/ttyUSB0', kind=str, + description='Serial port on which the device is connected'), + Parameter('baudrate', default=115200, kind=int, description='Serial connection baud rate'), + ] + diff --git a/wlauto/devices/android/tc2/__init__.py b/wlauto/devices/android/tc2/__init__.py new file mode 100644 index 00000000..9d3f92b9 --- /dev/null +++ b/wlauto/devices/android/tc2/__init__.py @@ -0,0 +1,847 @@ +# Copyright 2013-2015 ARM Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +import os +import sys +import re +import string +import shutil +import time +from collections import Counter + +import pexpect + +from wlauto import BigLittleDevice, RuntimeParameter, Parameter, settings +from wlauto.exceptions import ConfigError, DeviceError +from wlauto.utils.android import adb_connect, adb_disconnect, adb_list_devices +from wlauto.utils.serial_port import open_serial_connection +from wlauto.utils.misc import merge_dicts +from wlauto.utils.types import boolean + + +BOOT_FIRMWARE = { + 'uefi': { + 'SCC_0x010': '0x000003E0', + 'reboot_attempts': 0, + }, + 'bootmon': { + 'SCC_0x010': '0x000003D0', + 'reboot_attempts': 2, + }, +} + +MODES = { + 'mp_a7_only': { + 'images_file': 'images_mp.txt', + 'dtb': 'mp_a7', + 'initrd': 'init_mp', + 'kernel': 'kern_mp', + 'SCC_0x700': '0x1032F003', + 'cpus': ['a7', 'a7', 'a7'], + }, + 'mp_a7_bootcluster': { + 'images_file': 'images_mp.txt', + 'dtb': 'mp_a7bc', + 'initrd': 'init_mp', + 'kernel': 'kern_mp', + 'SCC_0x700': '0x1032F003', + 'cpus': ['a7', 'a7', 'a7', 'a15', 'a15'], + }, + 'mp_a15_only': { + 'images_file': 'images_mp.txt', + 'dtb': 'mp_a15', + 'initrd': 'init_mp', + 'kernel': 'kern_mp', + 'SCC_0x700': '0x0032F003', + 'cpus': ['a15', 'a15'], + }, + 'mp_a15_bootcluster': { + 'images_file': 'images_mp.txt', + 'dtb': 'mp_a15bc', + 'initrd': 'init_mp', + 'kernel': 'kern_mp', + 'SCC_0x700': '0x0032F003', + 'cpus': ['a15', 'a15', 'a7', 'a7', 'a7'], + }, + 'iks_cpu': { + 'images_file': 'images_iks.txt', + 'dtb': 'iks', + 'initrd': 'init_iks', + 'kernel': 'kern_iks', + 'SCC_0x700': '0x1032F003', + 'cpus': ['a7', 'a7'], + }, + 'iks_a15': { + 'images_file': 'images_iks.txt', + 'dtb': 'iks', + 'initrd': 'init_iks', + 'kernel': 'kern_iks', + 'SCC_0x700': '0x0032F003', + 'cpus': ['a15', 'a15'], + }, + 'iks_a7': { + 'images_file': 'images_iks.txt', + 'dtb': 'iks', + 'initrd': 'init_iks', + 'kernel': 'kern_iks', + 'SCC_0x700': '0x0032F003', + 'cpus': ['a7', 'a7'], + }, + 'iks_ns_a15': { + 'images_file': 'images_iks.txt', + 'dtb': 'iks', + 'initrd': 'init_iks', + 'kernel': 'kern_iks', + 'SCC_0x700': '0x0032F003', + 'cpus': ['a7', 'a7', 'a7', 'a15', 'a15'], + }, + 'iks_ns_a7': { + 'images_file': 'images_iks.txt', + 'dtb': 'iks', + 'initrd': 'init_iks', + 'kernel': 'kern_iks', + 'SCC_0x700': '0x0032F003', + 'cpus': ['a7', 'a7', 'a7', 'a15', 'a15'], + }, +} + +A7_ONLY_MODES = ['mp_a7_only', 'iks_a7', 'iks_cpu'] +A15_ONLY_MODES = ['mp_a15_only', 'iks_a15'] + +DEFAULT_A7_GOVERNOR_TUNABLES = { + 'interactive': { + 'above_hispeed_delay': 80000, + 'go_hispeed_load': 85, + 'hispeed_freq': 800000, + 'min_sample_time': 80000, + 'timer_rate': 20000, + }, + 'ondemand': { + 'sampling_rate': 50000, + }, +} + +DEFAULT_A15_GOVERNOR_TUNABLES = { + 'interactive': { + 'above_hispeed_delay': 80000, + 'go_hispeed_load': 85, + 'hispeed_freq': 1000000, + 'min_sample_time': 80000, + 'timer_rate': 20000, + }, + 'ondemand': { + 'sampling_rate': 50000, + }, +} + +ADB_SHELL_TIMEOUT = 30 + + +class _TC2DeviceConfig(object): + + name = 'TC2 Configuration' + device_name = 'TC2' + + def __init__(self, # pylint: disable=R0914,W0613 + root_mount='/media/VEMSD', + + disable_boot_configuration=False, + boot_firmware=None, + mode=None, + + fs_medium='usb', + + device_working_directory='/data/local/usecase', + + bm_image='bm_v519r.axf', + + serial_device='/dev/ttyS0', + serial_baud=38400, + serial_max_timeout=600, + serial_log=sys.stdout, + + init_timeout=120, + + always_delete_uefi_entry=True, + psci_enable=True, + + host_working_directory=None, + + a7_governor_tunables=None, + a15_governor_tunables=None, + + adb_name=None, + # Compatibility with other android devices. + enable_screen_check=None, # pylint: disable=W0613 + **kwargs + ): + self.root_mount = root_mount + self.disable_boot_configuration = disable_boot_configuration + if not disable_boot_configuration: + self.boot_firmware = boot_firmware or 'uefi' + self.default_mode = mode or 'mp_a7_bootcluster' + elif boot_firmware or mode: + raise ConfigError('boot_firmware and/or mode cannot be specified when disable_boot_configuration is enabled.') + + self.mode = self.default_mode + self.working_directory = device_working_directory + self.serial_device = serial_device + self.serial_baud = serial_baud + self.serial_max_timeout = serial_max_timeout + self.serial_log = serial_log + self.bootmon_prompt = re.compile('^([KLM]:\\\)?>', re.MULTILINE) + + self.fs_medium = fs_medium.lower() + + self.bm_image = bm_image + + self.init_timeout = init_timeout + + self.always_delete_uefi_entry = always_delete_uefi_entry + self.psci_enable = psci_enable + + self.resource_dir = os.path.join(os.path.dirname(__file__), 'resources') + self.board_dir = os.path.join(self.root_mount, 'SITE1', 'HBI0249A') + self.board_file = 'board.txt' + self.board_file_bak = 'board.bak' + self.images_file = 'images.txt' + + self.host_working_directory = host_working_directory or settings.meta_directory + + if not a7_governor_tunables: + self.a7_governor_tunables = DEFAULT_A7_GOVERNOR_TUNABLES + else: + self.a7_governor_tunables = merge_dicts(DEFAULT_A7_GOVERNOR_TUNABLES, a7_governor_tunables) + + if not a15_governor_tunables: + self.a15_governor_tunables = DEFAULT_A15_GOVERNOR_TUNABLES + else: + self.a15_governor_tunables = merge_dicts(DEFAULT_A15_GOVERNOR_TUNABLES, a15_governor_tunables) + + self.adb_name = adb_name + + @property + def src_images_template_file(self): + return os.path.join(self.resource_dir, MODES[self.mode]['images_file']) + + @property + def src_images_file(self): + return os.path.join(self.host_working_directory, 'images.txt') + + @property + def src_board_template_file(self): + return os.path.join(self.resource_dir, 'board_template.txt') + + @property + def src_board_file(self): + return os.path.join(self.host_working_directory, 'board.txt') + + @property + def kernel_arguments(self): + kernel_args = ' console=ttyAMA0,38400 androidboot.console=ttyAMA0 selinux=0' + if self.fs_medium == 'usb': + kernel_args += ' androidboot.hardware=arm-versatileexpress-usb' + if 'iks' in self.mode: + kernel_args += ' no_bL_switcher=0' + return kernel_args + + @property + def kernel(self): + return MODES[self.mode]['kernel'] + + @property + def initrd(self): + return MODES[self.mode]['initrd'] + + @property + def dtb(self): + return MODES[self.mode]['dtb'] + + @property + def SCC_0x700(self): + return MODES[self.mode]['SCC_0x700'] + + @property + def SCC_0x010(self): + return BOOT_FIRMWARE[self.boot_firmware]['SCC_0x010'] + + @property + def reboot_attempts(self): + return BOOT_FIRMWARE[self.boot_firmware]['reboot_attempts'] + + def validate(self): + valid_modes = MODES.keys() + if self.mode not in valid_modes: + message = 'Invalid mode: {}; must be in {}'.format( + self.mode, valid_modes) + raise ConfigError(message) + + valid_boot_firmware = BOOT_FIRMWARE.keys() + if self.boot_firmware not in valid_boot_firmware: + message = 'Invalid boot_firmware: {}; must be in {}'.format( + self.boot_firmware, + valid_boot_firmware) + raise ConfigError(message) + + if self.fs_medium not in ['usb', 'sdcard']: + message = 'Invalid filesystem medium: {} allowed values : usb, sdcard '.format(self.fs_medium) + raise ConfigError(message) + + +class TC2Device(BigLittleDevice): + + name = 'TC2' + description = """ + TC2 is a development board, which has three A7 cores and two A15 cores. + + TC2 has a number of boot parameters which are: + + :root_mount: Defaults to '/media/VEMSD' + :boot_firmware: It has only two boot firmware options, which are + uefi and bootmon. Defaults to 'uefi'. + :fs_medium: Defaults to 'usb'. + :device_working_directory: The direcitory that WA will be using to copy + files to. Defaults to 'data/local/usecase' + :serial_device: The serial device which TC2 is connected to. Defaults to + '/dev/ttyS0'. + :serial_baud: Defaults to 38400. + :serial_max_timeout: Serial timeout value in seconds. Defaults to 600. + :serial_log: Defaults to standard output. + :init_timeout: The timeout in seconds to init the device. Defaults set + to 30. + :always_delete_uefi_entry: If true, it will delete the ufi entry. + Defaults to True. + :psci_enable: Enabling the psci. Defaults to True. + :host_working_directory: The host working directory. Defaults to None. + :disable_boot_configuration: Disables boot configuration through images.txt and board.txt. When + this is ``True``, those two files will not be overwritten in VEMSD. + This option may be necessary if the firmware version in the ``TC2`` + is not compatible with the templates in WA. Please note that enabling + this will prevent you form being able to set ``boot_firmware`` and + ``mode`` parameters. Defaults to ``False``. + + TC2 can also have a number of different booting mode, which are: + + :mp_a7_only: Only the A7 cluster. + :mp_a7_bootcluster: Both A7 and A15 clusters, but it boots on A7 + cluster. + :mp_a15_only: Only the A15 cluster. + :mp_a15_bootcluster: Both A7 and A15 clusters, but it boots on A15 + clusters. + :iks_cpu: Only A7 cluster with only 2 cpus. + :iks_a15: Only A15 cluster. + :iks_a7: Same as iks_cpu + :iks_ns_a15: Both A7 and A15 clusters. + :iks_ns_a7: Both A7 and A15 clusters. + + The difference between mp and iks is the scheduling policy. + + TC2 takes the following runtime parameters + + :a7_cores: Number of active A7 cores. + :a15_cores: Number of active A15 cores. + :a7_governor: CPUFreq governor for the A7 cluster. + :a15_governor: CPUFreq governor for the A15 cluster. + :a7_min_frequency: Minimum CPU frequency for the A7 cluster. + :a15_min_frequency: Minimum CPU frequency for the A15 cluster. + :a7_max_frequency: Maximum CPU frequency for the A7 cluster. + :a15_max_frequency: Maximum CPU frequency for the A7 cluster. + :irq_affinity: lambda x: Which cluster will receive IRQs. + :cpuidle: Whether idle states should be enabled. + :sysfile_values: A dict mapping a complete file path to the value that + should be echo'd into it. By default, the file will be + subsequently read to verify that the value was written + into it with DeviceError raised otherwise. For write-only + files, this check can be disabled by appending a ``!`` to + the end of the file path. + + """ + + has_gpu = False + a15_only_modes = A15_ONLY_MODES + a7_only_modes = A7_ONLY_MODES + not_configurable_modes = ['iks_a7', 'iks_cpu', 'iks_a15'] + + parameters = [ + Parameter('core_names', mandatory=False, override=True, + description='This parameter will be ignored for TC2'), + Parameter('core_clusters', mandatory=False, override=True, + description='This parameter will be ignored for TC2'), + ] + + runtime_parameters = [ + RuntimeParameter('irq_affinity', lambda d, x: d.set_irq_affinity(x.lower()), lambda: None), + RuntimeParameter('cpuidle', lambda d, x: d.enable_idle_states() if boolean(x) else d.disable_idle_states(), + lambda d: d.get_cpuidle()) + ] + + def get_mode(self): + return self.config.mode + + def set_mode(self, mode): + if self._has_booted: + raise DeviceError('Attempting to set boot mode when already booted.') + valid_modes = MODES.keys() + if mode is None: + mode = self.config.default_mode + if mode not in valid_modes: + message = 'Invalid mode: {}; must be in {}'.format(mode, valid_modes) + raise ConfigError(message) + self.config.mode = mode + + mode = property(get_mode, set_mode) + + def _get_core_names(self): + return MODES[self.mode]['cpus'] + + def _set_core_names(self, value): + pass + + core_names = property(_get_core_names, _set_core_names) + + def _get_core_clusters(self): + seen = set([]) + core_clusters = [] + cluster_id = -1 + for core in MODES[self.mode]['cpus']: + if core not in seen: + seen.add(core) + cluster_id += 1 + core_clusters.append(cluster_id) + return core_clusters + + def _set_core_clusters(self, value): + pass + + core_clusters = property(_get_core_clusters, _set_core_clusters) + + @property + def cpu_cores(self): + return MODES[self.mode]['cpus'] + + @property + def max_a7_cores(self): + return Counter(MODES[self.mode]['cpus'])['a7'] + + @property + def max_a15_cores(self): + return Counter(MODES[self.mode]['cpus'])['a15'] + + @property + def a7_governor_tunables(self): + return self.config.a7_governor_tunables + + @property + def a15_governor_tunables(self): + return self.config.a15_governor_tunables + + def __init__(self, **kwargs): + super(TC2Device, self).__init__() + self.config = _TC2DeviceConfig(**kwargs) + self.working_directory = self.config.working_directory + self._serial = None + self._has_booted = None + + def boot(self, **kwargs): # NOQA + mode = kwargs.get('os_mode', None) + self._is_ready = False + self._has_booted = False + + self.mode = mode + self.logger.debug('Booting in {} mode'.format(self.mode)) + + with open_serial_connection(timeout=self.config.serial_max_timeout, + port=self.config.serial_device, + baudrate=self.config.serial_baud) as target: + if self.config.boot_firmware == 'bootmon': + self._boot_using_bootmon(target) + elif self.config.boot_firmware == 'uefi': + self._boot_using_uefi(target) + else: + message = 'Unexpected boot firmware: {}'.format(self.config.boot_firmware) + raise ConfigError(message) + + try: + target.sendline('') + self.logger.debug('Waiting for the Android prompt.') + target.expect(self.android_prompt, timeout=40) # pylint: disable=E1101 + except pexpect.TIMEOUT: + # Try a second time before giving up. + self.logger.debug('Did not get Android prompt, retrying...') + target.sendline('') + target.expect(self.android_prompt, timeout=10) # pylint: disable=E1101 + + self.logger.debug('Waiting for OS to initialize...') + started_waiting_time = time.time() + time.sleep(20) # we know it's not going to to take less time than this. + boot_completed, got_ip_address = False, False + while True: + try: + if not boot_completed: + target.sendline('getprop sys.boot_completed') + boot_completed = target.expect(['0.*', '1.*'], timeout=10) + if not got_ip_address: + target.sendline('getprop dhcp.eth0.ipaddress') + # regexes are processed in order, so ip regex has to + # come first (as we only want to match new line if we + # don't match the IP). We do a "not" make the logic + # consistent with boot_completed. + got_ip_address = not target.expect(['[1-9]\d*.\d+.\d+.\d+', '\n'], timeout=10) + except pexpect.TIMEOUT: + pass # We have our own timeout -- see below. + if boot_completed and got_ip_address: + break + time.sleep(5) + if (time.time() - started_waiting_time) > self.config.init_timeout: + raise DeviceError('Timed out waiting for the device to initialize.') + + self._has_booted = True + + def connect(self): + if not self._is_ready: + if self.config.adb_name: + self.adb_name = self.config.adb_name # pylint: disable=attribute-defined-outside-init + else: + with open_serial_connection(timeout=self.config.serial_max_timeout, + port=self.config.serial_device, + baudrate=self.config.serial_baud) as target: + # Get IP address and push the Gator and PMU logger. + target.sendline('su') # as of Android v5.0.2, Linux does not boot into root shell + target.sendline('netcfg') + ipaddr_re = re.compile('eth0 +UP +(.+)/.+', re.MULTILINE) + target.expect(ipaddr_re) + output = target.after + match = re.search('eth0 +UP +(.+)/.+', output) + if not match: + raise DeviceError('Could not get adb IP address.') + ipaddr = match.group(1) + + # Connect to device using adb. + target.expect(self.android_prompt) # pylint: disable=E1101 + self.adb_name = ipaddr + ":5555" # pylint: disable=W0201 + + if self.adb_name in adb_list_devices(): + adb_disconnect(self.adb_name) + adb_connect(self.adb_name) + self._is_ready = True + self.execute("input keyevent 82", timeout=ADB_SHELL_TIMEOUT) + self.execute("svc power stayon true", timeout=ADB_SHELL_TIMEOUT) + + def disconnect(self): + adb_disconnect(self.adb_name) + self._is_ready = False + + # TC2-specific methods. You should avoid calling these in + # Workloads/Instruments as that would tie them to TC2 (and if that is + # the case, then you should set the supported_devices parameter in the + # Workload/Instrument accordingly). Most of these can be replace with a + # call to set_runtime_parameters. + + def get_cpuidle(self): + return self.get_sysfile_value('/sys/devices/system/cpu/cpu0/cpuidle/state1/disable') + + def enable_idle_states(self): + """ + Fully enables idle states on TC2. + See http://wiki.arm.com/Research/TC2SetupAndUsage ("Enabling Idle Modes" section) + and http://wiki.arm.com/ASD/ControllingPowerManagementInLinaroKernels + + """ + # Enable C1 (cluster shutdown). + self.set_sysfile_value('/sys/devices/system/cpu/cpu0/cpuidle/state1/disable', 0, verify=False) + # Enable C0 on A15 cluster. + self.set_sysfile_value('/sys/kernel/debug/idle_debug/enable_idle', 0, verify=False) + # Enable C0 on A7 cluster. + self.set_sysfile_value('/sys/kernel/debug/idle_debug/enable_idle', 1, verify=False) + + def disable_idle_states(self): + """ + Disable idle states on TC2. + See http://wiki.arm.com/Research/TC2SetupAndUsage ("Enabling Idle Modes" section) + and http://wiki.arm.com/ASD/ControllingPowerManagementInLinaroKernels + + """ + # Disable C1 (cluster shutdown). + self.set_sysfile_value('/sys/devices/system/cpu/cpu0/cpuidle/state1/disable', 1, verify=False) + # Disable C0. + self.set_sysfile_value('/sys/kernel/debug/idle_debug/enable_idle', 0xFF, verify=False) + + def set_irq_affinity(self, cluster): + """ + Set's IRQ affinity to the specified cluster. + + This method will only work if the device mode is mp_a7_bootcluster or + mp_a15_bootcluster. This operation does not make sense if there is only one + cluster active (all IRQs will obviously go to that), and it will not work for + IKS kernel because clusters are not exposed to sysfs. + + :param cluster: must be either 'a15' or 'a7'. + + """ + if self.config.mode not in ('mp_a7_bootcluster', 'mp_a15_bootcluster'): + raise ConfigError('Cannot set IRQ affinity with mode {}'.format(self.config.mode)) + if cluster == 'a7': + self.execute('/sbin/set_irq_affinity.sh 0xc07', check_exit_code=False) + elif cluster == 'a15': + self.execute('/sbin/set_irq_affinity.sh 0xc0f', check_exit_code=False) + else: + raise ConfigError('cluster must either "a15" or "a7"; got {}'.format(cluster)) + + def _boot_using_uefi(self, target): + self.logger.debug('Booting using UEFI.') + self._wait_for_vemsd_mount(target) + self._setup_before_reboot() + self._perform_uefi_reboot(target) + + # Get to the UEFI menu. + self.logger.debug('Waiting for UEFI default selection.') + target.sendline('reboot') + target.expect('The default boot selection will start in'.rstrip()) + time.sleep(1) + target.sendline(''.rstrip()) + + # If delete every time is specified, try to delete entry. + if self.config.always_delete_uefi_entry: + self._delete_uefi_entry(target, entry='workload_automation_MP') + self.config.always_delete_uefi_entry = False + + # Specify argument to be passed specifying that psci is (or is not) enabled + if self.config.psci_enable: + psci_enable = ' psci=enable' + else: + psci_enable = '' + + # Identify the workload automation entry. + selection_pattern = r'\[([0-9]*)\] ' + + try: + target.expect(re.compile(selection_pattern + 'workload_automation_MP'), timeout=5) + wl_menu_item = target.match.group(1) + except pexpect.TIMEOUT: + self._create_uefi_entry(target, psci_enable, entry_name='workload_automation_MP') + # At this point the board should be rebooted so we need to retry to boot + self._boot_using_uefi(target) + else: # Did not time out. + try: + #Identify the boot manager menu item + target.expect(re.compile(selection_pattern + 'Boot Manager')) + boot_manager_menu_item = target.match.group(1) + + #Update FDT + target.sendline(boot_manager_menu_item) + target.expect(re.compile(selection_pattern + 'Update FDT path'), timeout=15) + update_fdt_menu_item = target.match.group(1) + target.sendline(update_fdt_menu_item) + target.expect(re.compile(selection_pattern + 'NOR Flash .*'), timeout=15) + bootmonfs_menu_item = target.match.group(1) + target.sendline(bootmonfs_menu_item) + target.expect('File path of the FDT blob:') + target.sendline(self.config.dtb) + + #Return to main manu and boot from wl automation + target.expect(re.compile(selection_pattern + 'Return to main menu'), timeout=15) + return_to_main_menu_item = target.match.group(1) + target.sendline(return_to_main_menu_item) + target.sendline(wl_menu_item) + except pexpect.TIMEOUT: + raise DeviceError('Timed out') + + def _setup_before_reboot(self): + if not self.config.disable_boot_configuration: + self.logger.debug('Performing pre-boot setup.') + substitution = { + 'SCC_0x010': self.config.SCC_0x010, + 'SCC_0x700': self.config.SCC_0x700, + } + with open(self.config.src_board_template_file, 'r') as fh: + template_board_txt = string.Template(fh.read()) + with open(self.config.src_board_file, 'w') as wfh: + wfh.write(template_board_txt.substitute(substitution)) + + with open(self.config.src_images_template_file, 'r') as fh: + template_images_txt = string.Template(fh.read()) + with open(self.config.src_images_file, 'w') as wfh: + wfh.write(template_images_txt.substitute({'bm_image': self.config.bm_image})) + + shutil.copyfile(self.config.src_board_file, + os.path.join(self.config.board_dir, self.config.board_file)) + shutil.copyfile(self.config.src_images_file, + os.path.join(self.config.board_dir, self.config.images_file)) + os.system('sync') # make sure everything is flushed to microSD + else: + self.logger.debug('Boot configuration disabled proceeding with existing board.txt and images.txt.') + + def _delete_uefi_entry(self, target, entry): # pylint: disable=R0201 + """ + this method deletes the entry specified as parameter + as a precondition serial port input needs to be parsed AT MOST up to + the point BEFORE recognizing this entry (both entry and boot manager has + not yet been parsed) + + """ + try: + selection_pattern = r'\[([0-9]+)\] *' + + try: + target.expect(re.compile(selection_pattern + entry), timeout=5) + wl_menu_item = target.match.group(1) + except pexpect.TIMEOUT: + return # Entry does not exist, nothing to delete here... + + # Identify and select boot manager menu item + target.expect(selection_pattern + 'Boot Manager', timeout=15) + bootmanager_item = target.match.group(1) + target.sendline(bootmanager_item) + + # Identify and select 'Remove entry' + target.expect(selection_pattern + 'Remove Boot Device Entry', timeout=15) + new_entry_item = target.match.group(1) + target.sendline(new_entry_item) + + # Delete entry + target.expect(re.compile(selection_pattern + entry), timeout=5) + wl_menu_item = target.match.group(1) + target.sendline(wl_menu_item) + + # Return to main manu + target.expect(re.compile(selection_pattern + 'Return to main menu'), timeout=15) + return_to_main_menu_item = target.match.group(1) + target.sendline(return_to_main_menu_item) + except pexpect.TIMEOUT: + raise DeviceError('Timed out while deleting UEFI entry.') + + def _create_uefi_entry(self, target, psci_enable, entry_name): + """ + Creates the default boot entry that is expected when booting in uefi mode. + + """ + self._wait_for_vemsd_mount(target) + try: + selection_pattern = '\[([0-9]+)\] *' + + # Identify and select boot manager menu item. + target.expect(selection_pattern + 'Boot Manager', timeout=15) + bootmanager_item = target.match.group(1) + target.sendline(bootmanager_item) + + # Identify and select 'add new entry'. + target.expect(selection_pattern + 'Add Boot Device Entry', timeout=15) + new_entry_item = target.match.group(1) + target.sendline(new_entry_item) + + # Identify and select BootMonFs. + target.expect(selection_pattern + 'NOR Flash .*', timeout=15) + BootMonFs_item = target.match.group(1) + target.sendline(BootMonFs_item) + + # Specify the parameters of the new entry. + target.expect('.+the kernel', timeout=5) + target.sendline(self.config.kernel) # kernel path + target.expect('Has FDT support\?.*\[y\/n\].*', timeout=5) + time.sleep(0.5) + target.sendline('y') # Has Fdt support? -> y + target.expect('Add an initrd.*\[y\/n\].*', timeout=5) + time.sleep(0.5) + target.sendline('y') # add an initrd? -> y + target.expect('.+the initrd.*', timeout=5) + time.sleep(0.5) + target.sendline(self.config.initrd) # initrd path + target.expect('.+to the binary.*', timeout=5) + time.sleep(0.5) + _slow_sendline(target, self.config.kernel_arguments + psci_enable) # arguments to pass to binary + time.sleep(0.5) + target.expect('.+new Entry.+', timeout=5) + _slow_sendline(target, entry_name) # Entry name + target.expect('Choice.+', timeout=15) + time.sleep(2) + except pexpect.TIMEOUT: + raise DeviceError('Timed out while creating UEFI entry.') + self._perform_uefi_reboot(target) + + def _perform_uefi_reboot(self, target): + self._wait_for_vemsd_mount(target) + open(os.path.join(self.config.root_mount, 'reboot.txt'), 'a').close() + + def _wait_for_vemsd_mount(self, target, timeout=100): + attempts = 1 + self.config.reboot_attempts + if os.path.exists(os.path.join(self.config.root_mount, 'config.txt')): + return + + self.logger.debug('Waiting for VEMSD to mount...') + for i in xrange(attempts): + if i: # Do not reboot on the first attempt. + target.sendline('reboot') + target.sendline('usb_on') + for _ in xrange(timeout): + time.sleep(1) + if os.path.exists(os.path.join(self.config.root_mount, 'config.txt')): + return + + raise DeviceError('Timed out waiting for VEMSD to mount.') + + def _boot_using_bootmon(self, target): + """ + This method Boots TC2 using the bootmon interface. + """ + self.logger.debug('Booting using bootmon.') + + try: + self._wait_for_vemsd_mount(target, timeout=20) + except DeviceError: + # OK, something's wrong. Reboot the board and try again. + self.logger.debug('VEMSD not mounted, attempting to power cycle device.') + target.sendline(' ') + state = target.expect(['Cmd> ', self.config.bootmon_prompt, self.android_prompt]) # pylint: disable=E1101 + + if state == 0 or state == 1: + # Reboot - Bootmon + target.sendline('reboot') + target.expect('Powering up system...') + elif state == 2: + target.sendline('reboot -n') + target.expect('Powering up system...') + else: + raise DeviceError('Unexpected board state {}; should be 0, 1 or 2'.format(state)) + + self._wait_for_vemsd_mount(target) + + self._setup_before_reboot() + + # Reboot - Bootmon + self.logger.debug('Rebooting into bootloader...') + open(os.path.join(self.config.root_mount, 'reboot.txt'), 'a').close() + target.expect('Powering up system...') + target.expect(self.config.bootmon_prompt) + + # Wait for VEMSD to mount + self._wait_for_vemsd_mount(target) + + #Boot Linux - Bootmon + target.sendline('fl linux fdt ' + self.config.dtb) + target.expect(self.config.bootmon_prompt) + target.sendline('fl linux initrd ' + self.config.initrd) + target.expect(self.config.bootmon_prompt) + target.sendline('fl linux boot ' + self.config.kernel + self.config.kernel_arguments) + + +# Utility functions. + +def _slow_sendline(target, line): + for c in line: + target.send(c) + time.sleep(0.1) + target.sendline('') + diff --git a/wlauto/devices/android/tc2/resources/board_template.txt b/wlauto/devices/android/tc2/resources/board_template.txt new file mode 100644 index 00000000..39535d13 --- /dev/null +++ b/wlauto/devices/android/tc2/resources/board_template.txt @@ -0,0 +1,96 @@ +BOARD: HBI0249 +TITLE: V2P-CA15_A7 Configuration File + +[DCCS] +TOTALDCCS: 1 ;Total Number of DCCS +M0FILE: dbb_v110.ebf ;DCC0 Filename +M0MODE: MICRO ;DCC0 Programming Mode + +[FPGAS] +TOTALFPGAS: 0 ;Total Number of FPGAs + +[TAPS] +TOTALTAPS: 3 ;Total Number of TAPs +T0NAME: STM32TMC ;TAP0 Device Name +T0FILE: NONE ;TAP0 Filename +T0MODE: NONE ;TAP0 Programming Mode +T1NAME: STM32CM3 ;TAP1 Device Name +T1FILE: NONE ;TAP1 Filename +T1MODE: NONE ;TAP1 Programming Mode +T2NAME: CORTEXA15 ;TAP2 Device Name +T2FILE: NONE ;TAP2 Filename +T2MODE: NONE ;TAP2 Programming Mode + +[OSCCLKS] +TOTALOSCCLKS: 9 ;Total Number of OSCCLKS +OSC0: 50.0 ;CPUREFCLK0 A15 CPU (20:1 - 1.0GHz) +OSC1: 50.0 ;CPUREFCLK1 A15 CPU (20:1 - 1.0GHz) +OSC2: 40.0 ;CPUREFCLK0 A7 CPU (20:1 - 800MHz) +OSC3: 40.0 ;CPUREFCLK1 A7 CPU (20:1 - 800MHz) +OSC4: 40.0 ;HSBM AXI (40MHz) +OSC5: 23.75 ;HDLCD (23.75MHz - TC PLL is in bypass) +OSC6: 50.0 ;SMB (50MHz) +OSC7: 50.0 ;SYSREFCLK (20:1 - 1.0GHz, ACLK - 500MHz) +OSC8: 50.0 ;DDR2 (8:1 - 400MHz) + +[SCC REGISTERS] +TOTALSCCS: 33 ;Total Number of SCC registers + +;SCC: 0x010 0x000003D0 ;Remap to NOR0 +SCC: 0x010 $SCC_0x010 ;Switch between NOR0/NOR1 +SCC: 0x01C 0xFF00FF00 ;CFGRW3 - SMC CS6/7 N/U +SCC: 0x118 0x01CD1011 ;CFGRW17 - HDLCD PLL external bypass +;SCC: 0x700 0x00320003 ;CFGRW48 - [25:24]Boot CPU [28]Boot Cluster (default CA7_0) +SCC: 0x700 $SCC_0x700 ;CFGRW48 - [25:24]Boot CPU [28]Boot Cluster (default CA7_0) + ; Bootmon configuration: + ; [15]: A7 Event stream generation (default: disabled) + ; [14]: A15 Event stream generation (default: disabled) + ; [13]: Power down the non-boot cluster (default: disabled) + ; [12]: Use per-cpu mailboxes for power management (default: disabled) + ; [11]: A15 executes WFEs as nops (default: disabled) + +SCC: 0x400 0x33330c00 ;CFGREG41 - A15 configuration register 0 (Default 0x33330c80) + ; [29:28] SPNIDEN + ; [25:24] SPIDEN + ; [21:20] NIDEN + ; [17:16] DBGEN + ; [13:12] CFGTE + ; [9:8] VINITHI_CORE + ; [7] IMINLN + ; [3:0] CLUSTER_ID + + ;Set the CPU clock PLLs +SCC: 0x120 0x022F1010 ;CFGRW19 - CA15_0 PLL control - 20:1 (lock OFF) +SCC: 0x124 0x0011710D ;CFGRW20 - CA15_0 PLL value +SCC: 0x128 0x022F1010 ;CFGRW21 - CA15_1 PLL control - 20:1 (lock OFF) +SCC: 0x12C 0x0011710D ;CFGRW22 - CA15_1 PLL value +SCC: 0x130 0x022F1010 ;CFGRW23 - CA7_0 PLL control - 20:1 (lock OFF) +SCC: 0x134 0x0011710D ;CFGRW24 - CA7_0 PLL value +SCC: 0x138 0x022F1010 ;CFGRW25 - CA7_1 PLL control - 20:1 (lock OFF) +SCC: 0x13C 0x0011710D ;CFGRW26 - CA7_1 PLL value + + ;Power management interface +SCC: 0xC00 0x00000005 ;Control: [0]PMI_EN [1]DBG_EN [2]SPC_SYSCFG +SCC: 0xC04 0x060E0356 ;Latency in uS max: [15:0]DVFS [31:16]PWRUP +SCC: 0xC08 0x00000000 ;Reserved +SCC: 0xC0C 0x00000000 ;Reserved + + ;CA15 performance values: 0xVVVFFFFF +SCC: 0xC10 0x384061A8 ;CA15 PERFVAL0, 900mV, 20,000*20= 500MHz +SCC: 0xC14 0x38407530 ;CA15 PERFVAL1, 900mV, 25,000*20= 600MHz +SCC: 0xC18 0x384088B8 ;CA15 PERFVAL2, 900mV, 30,000*20= 700MHz +SCC: 0xC1C 0x38409C40 ;CA15 PERFVAL3, 900mV, 35,000*20= 800MHz +SCC: 0xC20 0x3840AFC8 ;CA15 PERFVAL4, 900mV, 40,000*20= 900MHz +SCC: 0xC24 0x3840C350 ;CA15 PERFVAL5, 900mV, 45,000*20=1000MHz +SCC: 0xC28 0x3CF0D6D8 ;CA15 PERFVAL6, 975mV, 50,000*20=1100MHz +SCC: 0xC2C 0x41A0EA60 ;CA15 PERFVAL7, 1050mV, 55,000*20=1200MHz + + ;CA7 performance values: 0xVVVFFFFF +SCC: 0xC30 0x3840445C ;CA7 PERFVAL0, 900mV, 10,000*20= 350MHz +SCC: 0xC34 0x38404E20 ;CA7 PERFVAL1, 900mV, 15,000*20= 400MHz +SCC: 0xC38 0x384061A8 ;CA7 PERFVAL2, 900mV, 20,000*20= 500MHz +SCC: 0xC3C 0x38407530 ;CA7 PERFVAL3, 900mV, 25,000*20= 600MHz +SCC: 0xC40 0x384088B8 ;CA7 PERFVAL4, 900mV, 30,000*20= 700MHz +SCC: 0xC44 0x38409C40 ;CA7 PERFVAL5, 900mV, 35,000*20= 800MHz +SCC: 0xC48 0x3CF0AFC8 ;CA7 PERFVAL6, 975mV, 40,000*20= 900MHz +SCC: 0xC4C 0x41A0C350 ;CA7 PERFVAL7, 1050mV, 45,000*20=1000MHz diff --git a/wlauto/devices/android/tc2/resources/images_iks.txt b/wlauto/devices/android/tc2/resources/images_iks.txt new file mode 100644 index 00000000..05707092 --- /dev/null +++ b/wlauto/devices/android/tc2/resources/images_iks.txt @@ -0,0 +1,25 @@ +TITLE: Versatile Express Images Configuration File + +[IMAGES] +TOTALIMAGES: 4 ;Number of Images (Max : 32) +NOR0UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR0ADDRESS: BOOT ;Image Flash Address +NOR0FILE: \SOFTWARE\$bm_image ;Image File Name + +NOR1UPDATE: AUTO ;IMAGE UPDATE:NONE/AUTO/FORCE +NOR1ADDRESS: 0x00000000 ;Image Flash Address +NOR1FILE: \SOFTWARE\kern_iks.bin ;Image File Name +NOR1LOAD: 0x80008000 +NOR1ENTRY: 0x80008000 + +NOR2UPDATE: AUTO ;IMAGE UPDATE:NONE/AUTO/FORCE +NOR2ADDRESS: 0x00000000 ;Image Flash Address +NOR2FILE: \SOFTWARE\iks.dtb ;Image File Name for booting in A7 cluster +NOR2LOAD: 0x84000000 +NOR2ENTRY: 0x84000000 + +NOR3UPDATE: AUTO ;IMAGE UPDATE:NONE/AUTO/FORCE +NOR3ADDRESS: 0x00000000 ;Image Flash Address +NOR3FILE: \SOFTWARE\init_iks.bin ;Image File Name +NOR3LOAD: 0x90100000 +NOR3ENTRY: 0x90100000 diff --git a/wlauto/devices/android/tc2/resources/images_mp.txt b/wlauto/devices/android/tc2/resources/images_mp.txt new file mode 100644 index 00000000..e671a74b --- /dev/null +++ b/wlauto/devices/android/tc2/resources/images_mp.txt @@ -0,0 +1,55 @@ +TITLE: Versatile Express Images Configuration File +[IMAGES] +TOTALIMAGES: 9 ;Number of Images (Max: 32) +NOR0UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE +NOR0ADDRESS: BOOT ;Image Flash Address +NOR0FILE: \SOFTWARE\$bm_image ;Image File Name + +NOR1UPDATE: AUTO ;IMAGE UPDATE:NONE/AUTO/FORCE +NOR1ADDRESS: 0x0E000000 ;Image Flash Address +NOR1FILE: \SOFTWARE\kern_mp.bin ;Image File Name +NOR1LOAD: 0x80008000 +NOR1ENTRY: 0x80008000 + +NOR2UPDATE: AUTO ;IMAGE UPDATE:NONE/AUTO/FORCE +NOR2ADDRESS: 0x0E800000 ;Image Flash Address +NOR2FILE: \SOFTWARE\mp_a7.dtb ;Image File Name for booting in A7 cluster +NOR2LOAD: 0x84000000 +NOR2ENTRY: 0x84000000 + +NOR3UPDATE: AUTO ;IMAGE UPDATE:NONE/AUTO/FORCE +NOR3ADDRESS: 0x0E900000 ;Image Flash Address +NOR3FILE: \SOFTWARE\mp_a15.dtb ;Image File Name +NOR3LOAD: 0x84000000 +NOR3ENTRY: 0x84000000 + +NOR4UPDATE: AUTO ;IMAGE UPDATE:NONE/AUTO/FORCE +NOR4ADDRESS: 0x0EA00000 ;Image Flash Address +NOR4FILE: \SOFTWARE\mp_a7bc.dtb ;Image File Name +NOR4LOAD: 0x84000000 +NOR4ENTRY: 0x84000000 + +NOR5UPDATE: AUTO ;IMAGE UPDATE:NONE/AUTO/FORCE +NOR5ADDRESS: 0x0EB00000 ;Image Flash Address +NOR5FILE: \SOFTWARE\mp_a15bc.dtb ;Image File Name +NOR5LOAD: 0x84000000 +NOR5ENTRY: 0x84000000 + +NOR6UPDATE: AUTO ;IMAGE UPDATE:NONE/AUTO/FORCE +NOR6ADDRESS: 0x0EC00000 ;Image Flash Address +NOR6FILE: \SOFTWARE\init_mp.bin ;Image File Name +NOR6LOAD: 0x85000000 +NOR6ENTRY: 0x85000000 + +NOR7UPDATE: AUTO ;IMAGE UPDATE:NONE/AUTO/FORCE +NOR7ADDRESS: 0x0C000000 ;Image Flash Address +NOR7FILE: \SOFTWARE\tc2_sec.bin ;Image File Name +NOR7LOAD: 0 +NOR7ENTRY: 0 + +NOR8UPDATE: AUTO ;IMAGE UPDATE:NONE/AUTO/FORCE +NOR8ADDRESS: 0x0D000000 ;Image Flash Address +NOR8FILE: \SOFTWARE\tc2_uefi.bin ;Image File Name +NOR8LOAD: 0 +NOR8ENTRY: 0 + diff --git a/wlauto/devices/linux/__init__.py b/wlauto/devices/linux/__init__.py new file mode 100644 index 00000000..16224d6f --- /dev/null +++ b/wlauto/devices/linux/__init__.py @@ -0,0 +1,16 @@ +# Copyright 2014-2015 ARM Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + diff --git a/wlauto/devices/linux/generic/__init__.py b/wlauto/devices/linux/generic/__init__.py new file mode 100644 index 00000000..d6fb67a5 --- /dev/null +++ b/wlauto/devices/linux/generic/__init__.py @@ -0,0 +1,37 @@ +# Copyright 2014-2015 ARM Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +from wlauto import LinuxDevice, Parameter + + +class GenericDevice(LinuxDevice): + name = 'generic_linux' + description = """ + Generic Linux device. Use this if you do not have a device file for + your device. + + This implements the minimum functionality that should be supported by + all Linux devices. + + """ + + abi = 'armeabi' + has_gpu = True + + parameters = [ + Parameter('core_names', default=[], override=True), + Parameter('core_clusters', default=[], override=True), + ] diff --git a/wlauto/devices/linux/odroidxu3_linux/__init__.py b/wlauto/devices/linux/odroidxu3_linux/__init__.py new file mode 100644 index 00000000..f174950a --- /dev/null +++ b/wlauto/devices/linux/odroidxu3_linux/__init__.py @@ -0,0 +1,35 @@ +# Copyright 2014-2015 ARM Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +from wlauto import LinuxDevice, Parameter + + +class OdroidXU3LinuxDevice(LinuxDevice): + + name = "odroidxu3_linux" + description = 'HardKernel Odroid XU3 development board (Ubuntu image).' + + core_modules = [ + 'odroidxu3-fan', + ] + + parameters = [ + Parameter('core_names', default=['a7', 'a7', 'a7', 'a7', 'a15', 'a15', 'a15', 'a15'], override=True), + Parameter('core_clusters', default=[0, 0, 0, 0, 1, 1, 1, 1], override=True), + ] + + abi = 'armeabi' + |