Help to fix this error:
ERROR: (LSM_Start) LSMInitPattern != LSM_INIT_PATTERN
Here ma log file:
<17:17:59> ========== NEW Session ==========
<17:17:59> Session State Machine : MOSession
<17:17:59> GPS ONOFF Report : 1
<17:17:59> INFO: GPS_WAKE_LOCK_ENABLE
<17:17:59> [SIF Disabled.]
<17:17:59> [START_MODE : 1]
<17:17:59> [SSL : ENABLED]
<17:17:59> [SUPL : supl.google.com:7276]
<17:17:59> [AGPS MODE : USER PLANE]
<17:17:59> [TRACKING MODE]
<17:17:59> [HORIZONTAL ACCURACY = 50]
<17:17:59> LSM_setCapabilities
<17:17:59> Position Mode : GPS_POSITION_MODE_MS_BASED
<17:17:59> Local time is not available - wait for time udate from NTP or GPS
<17:17:59> QoP Configuration : Horizontal Accuracy : 50, Vertical Accuracy : 250, TTFF Response Time : 240
<17:17:59> session resumed : ANDROID_MO_SESSION
<17:17:59> INFO: LSM_Start is called
<17:17:59> ERROR: (LSM_Start) LSMInitPattern != LSM_INIT_PATTERN
<17:17:59> sirf_gps_start : LSM_Start Failed!!!!
<17:17:59> android_mo_session_start fail!!!!
<17:17:59> IdleState:updating session check
<17:17:59> GPS ONOFF Report : 0
<17:17:59> INFO: GPS_WAKE_LOCK_DISABLE
<17:18:59> sirf_gps_stop called
<17:18:59> no session to suspend !!!
<17:18:59> android_session_handler_suspend fail!!!
<17:57:08> sirf_gps_cleanup: called
<17:57:13> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<17:57:13> sirf_agps_update_network_availability : available = 1, apn = free
<17:59:19> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<17:59:19> sirf_agps_update_network_availability : available = 1, apn = free
<18:27:04> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<18:27:04> sirf_agps_update_network_availability : available = 1, apn = free
<18:32:07> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<18:32:07> sirf_agps_update_network_availability : available = 1, apn = free
<19:26:47> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<19:26:47> sirf_agps_update_network_availability : available = 1, apn = free
<19:31:15> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<19:31:15> sirf_agps_update_network_availability : available = 1, apn = free
<19:33:28> sirf_agps_ril_update_network_state: called - connected : 1, type : 1 extra : NULL
<19:33:28> sirf_agps_update_network_availability : available = 0, apn = free
<19:33:31> sirf_agps_ril_update_network_state: called - connected : 1, type : 1 extra : NULL
<19:33:31> sirf_agps_update_network_availability : available = 0, apn = free
<19:33:31> sirf_agps_ril_update_network_state: called - connected : 1, type : 1 extra : NULL
<19:33:31> sirf_agps_update_network_availability : available = 0, apn = free
LikeM8 said:
Help to fix this error:
ERROR: (LSM_Start) LSMInitPattern != LSM_INIT_PATTERN
Here ma log file:
<17:17:59> ========== NEW Session ==========
<17:17:59> Session State Machine : MOSession
<17:17:59> GPS ONOFF Report : 1
<17:17:59> INFO: GPS_WAKE_LOCK_ENABLE
<17:17:59> [SIF Disabled.]
<17:17:59> [START_MODE : 1]
<17:17:59> [SSL : ENABLED]
<17:17:59> [SUPL : supl.google.com:7276]
<17:17:59> [AGPS MODE : USER PLANE]
<17:17:59> [TRACKING MODE]
<17:17:59> [HORIZONTAL ACCURACY = 50]
<17:17:59> LSM_setCapabilities
<17:17:59> Position Mode : GPS_POSITION_MODE_MS_BASED
<17:17:59> Local time is not available - wait for time udate from NTP or GPS
<17:17:59> QoP Configuration : Horizontal Accuracy : 50, Vertical Accuracy : 250, TTFF Response Time : 240
<17:17:59> session resumed : ANDROID_MO_SESSION
<17:17:59> INFO: LSM_Start is called
<17:17:59> ERROR: (LSM_Start) LSMInitPattern != LSM_INIT_PATTERN
<17:17:59> sirf_gps_start : LSM_Start Failed!!!!
<17:17:59> android_mo_session_start fail!!!!
<17:17:59> IdleState:updating session check
<17:17:59> GPS ONOFF Report : 0
<17:17:59> INFO: GPS_WAKE_LOCK_DISABLE
<17:18:59> sirf_gps_stop called
<17:18:59> no session to suspend !!!
<17:18:59> android_session_handler_suspend fail!!!
<17:57:08> sirf_gps_cleanup: called
<17:57:13> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<17:57:13> sirf_agps_update_network_availability : available = 1, apn = free
<17:59:19> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<17:59:19> sirf_agps_update_network_availability : available = 1, apn = free
<18:27:04> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<18:27:04> sirf_agps_update_network_availability : available = 1, apn = free
<18:32:07> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<18:32:07> sirf_agps_update_network_availability : available = 1, apn = free
<19:26:47> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<19:26:47> sirf_agps_update_network_availability : available = 1, apn = free
<19:31:15> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<19:31:15> sirf_agps_update_network_availability : available = 1, apn = free
<19:33:28> sirf_agps_ril_update_network_state: called - connected : 1, type : 1 extra : NULL
<19:33:28> sirf_agps_update_network_availability : available = 0, apn = free
<19:33:31> sirf_agps_ril_update_network_state: called - connected : 1, type : 1 extra : NULL
<19:33:31> sirf_agps_update_network_availability : available = 0, apn = free
<19:33:31> sirf_agps_ril_update_network_state: called - connected : 1, type : 1 extra : NULL
<19:33:31> sirf_agps_update_network_availability : available = 0, apn = free
Click to expand...
Click to collapse
Read the rules
Thanks Menelkir for your repply. But I do not udestand what your mean
LikeM8 said:
Thanks Menelkir for your repply. But I do not udestand what your mean
Click to expand...
Click to collapse
from the forum rules at the top of each forum
15. Keep posts/threads on-topic
Whilst a minor amount of off-topic posting may be overlooked, the general rule is your posts / threads must be relevant to the Forum / thread in which you are posting.
General Forums - For news and announcements relating to your device.
Q&A Forums - For all question threads / posts. If there is no Q&A forum use the device General Forum
Accessories subforum - For posts related to accessories relevant to the phone model
Development Forums (ones with the word development in the title) - For developers to post release threads e.g. ROMs and Kernels including modifications to Kernels, Bootloaders, ROMs, etc.
Themes and Apps Forums - For themers to post Themes and App. announcements & discussions including modifications made to Apps and Themes.
Click to expand...
Click to collapse
LikeM8 said:
Thanks Menelkir for your repply. But I do not udestand what your mean
Click to expand...
Click to collapse
You are in wrong section bro...i think this is for developer..if you want to ask..please move to Q&A
Sent from my Galaxy Nexus using xda premium
arief347 said:
You are in wrong section bro...i think this is for developer..if you want to ask..please move to Q&A
Sent from my Galaxy Nexus using xda premium
Click to expand...
Click to collapse
OK...sorry!
All,
I try a lot of solutions (change ROMs, Kernel,...) to fix my GPS problem, without success!!!
When I launch a GPS app like GPS test, Google Maps,...there is not GPS icon blinking in status bar, and not lock! But SIRF GSD4t Initialization Success (so not hardware issue) as you can see from my SIRF Interface log :
=============================================================================
<16:59:54> ### Samsung Proxima-HSPA, CSR SiRF Software 2.0, B16 2012,06,13 FG ###
<16:59:54> ****** GSD4t Hardware Configuration ******
<16:59:54> *** [PROJECT : SAMSUNG_PROXIMA]
<16:59:54> *** [UART DRIVER : /dev/ttyO0]
<16:59:54> *** [RESET GPIO : /sys/devices/virtual/sec/gps/GPS_nRST/value]
<16:59:54> *** [ONOFF GPIO : /sys/devices/virtual/sec/gps/GPS_PWR_EN/value]
<16:59:54> *** [TCXO CLOCK : 26MHz]
<16:59:54> *** [EXTERNAL LNA : ENABLED]
<16:59:54> *** [UART BAUD RATE : 115200]
<16:59:54> *** [FREQUENCY AIDING : DISABLED]
<16:59:54> *** [SENSOR AIDING : DISABLED]
<16:59:54> *** [SETID : IMSI]
<16:59:54> *** [SSL : DISABLED]
<16:59:54> *** [DEBUGGING FILES : ENABLED]
<16:59:54> *** [REAIDING TIME : 20 (m)]
<16:59:54> *** [CONTROL PLANE : ENABLED]
<16:59:54> *** [LOG PATH : /data]
<16:59:54> *** [SGEE : 1]
<16:59:54> *** [SGEE SERVER1 : sgee.samsung.csr.com]
<16:59:54> *** [SGEE SERVER2 : instantfix.csr.com]
<16:59:54> *** [SGEE PORT : 80]
<16:59:54> *** [SGEE FILE :/diff/packedDifference.f2p3enc.ee]
<16:59:54> *** [SGEE URID : 1]
<16:59:54> *** [SGEE DEVICE ID : 00 00 00 00 00 00 00 02 ]
<16:59:54> *** [SGEE OEM ID : 00 00 00 00 ]
<16:59:54> Android Session Handler Starting
<16:59:54> IdleState:updating session check
<16:59:54> Create android_session_handler thread
<16:59:54> Android Status Report Handler Starting
<16:59:54> Create android_status_report_handler thread
<16:59:54> sirf_cpa_init: called
<16:59:54> sirf_cpa_ril_library_load: called
<16:59:54> sirf_cpa_ril_library_load : SUCCESS
<16:59:54> sirf_cpa_oem_ril_connect: called
<16:59:54> pfn_Connect_RILD Success
<16:59:54> sirf_cpa_oem_ril_connect : Success!!!
<16:59:54> sirf_cpa_init: Registering control plane callback
<16:59:54> INFO: CP_SetMessageListeners is called
<16:59:54> ERROR: (CP_SetMessageListeners) LSM is not initialized
<16:59:54> INFO: CP_SetMessageListeners exits
<16:59:54> Sirf CPA Initialization Success
<16:59:54> SIRF GSD4t Initialization Success
<16:59:54> sirf_agps_init: called
<16:59:54> sirf_gps_ni_init: called
<16:59:54> sirf_agps_ril_init: called
<16:59:54> sirf_agps_set_server - Type : 1, hostname = supl.google.com, port = 7276
<16:59:54> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<16:59:54> sirf_agps_update_network_availability : available = 1, apn = free
<16:59:54> sirf_gps_inject_location: called
<16:59:54> sirf_gps_inject_time: called
<16:59:54> Recieved utc = 1361807805539 ms ref = 35375 ms unc = 42 ms
<16:59:54> Local Time Updated : ref UTC = 1361807805539 , unc = 42, ref sys time= 35375
<16:59:54> Local time difference since last update - 189891 ms
<16:59:54> LSM TIME INJECTED: utc = 1361807805539, ref =35375, unc = 42
<17:02:47> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<17:02:47> sirf_agps_update_network_availability : available = 1, apn = free
<17:03:47> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<17:03:47> sirf_agps_update_network_availability : available = 1, apn = free
<17:04:00> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<17:04:00> sirf_agps_update_network_availability : available = 1, apn = free
<17:05:00> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<17:05:00> sirf_agps_update_network_availability : available = 1, apn = free
<17:05:00> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<17:05:00> sirf_agps_update_network_availability : available = 1, apn = free
=============================================================================
But one error: ERROR: (CP_SetMessageListeners) LSM is not initialized ??? I don't know that is meaning!
Any help please!!!
Regards
LikeM8 said:
All,
I try a lot of solutions (change ROMs, Kernel,...) to fix my GPS problem, without success!!!
When I launch a GPS app like GPS test, Google Maps,...there is not GPS icon blinking in status bar, and not lock! But SIRF GSD4t Initialization Success (so not hardware issue) as you can see from my SIRF Interface log :
=============================================================================
<16:59:54> ### Samsung Proxima-HSPA, CSR SiRF Software 2.0, B16 2012,06,13 FG ###
<16:59:54> ****** GSD4t Hardware Configuration ******
<16:59:54> *** [PROJECT : SAMSUNG_PROXIMA]
<16:59:54> *** [UART DRIVER : /dev/ttyO0]
<16:59:54> *** [RESET GPIO : /sys/devices/virtual/sec/gps/GPS_nRST/value]
<16:59:54> *** [ONOFF GPIO : /sys/devices/virtual/sec/gps/GPS_PWR_EN/value]
<16:59:54> *** [TCXO CLOCK : 26MHz]
<16:59:54> *** [EXTERNAL LNA : ENABLED]
<16:59:54> *** [UART BAUD RATE : 115200]
<16:59:54> *** [FREQUENCY AIDING : DISABLED]
<16:59:54> *** [SENSOR AIDING : DISABLED]
<16:59:54> *** [SETID : IMSI]
<16:59:54> *** [SSL : DISABLED]
<16:59:54> *** [DEBUGGING FILES : ENABLED]
<16:59:54> *** [REAIDING TIME : 20 (m)]
<16:59:54> *** [CONTROL PLANE : ENABLED]
<16:59:54> *** [LOG PATH : /data]
<16:59:54> *** [SGEE : 1]
<16:59:54> *** [SGEE SERVER1 : sgee.samsung.csr.com]
<16:59:54> *** [SGEE SERVER2 : instantfix.csr.com]
<16:59:54> *** [SGEE PORT : 80]
<16:59:54> *** [SGEE FILE :/diff/packedDifference.f2p3enc.ee]
<16:59:54> *** [SGEE URID : 1]
<16:59:54> *** [SGEE DEVICE ID : 00 00 00 00 00 00 00 02 ]
<16:59:54> *** [SGEE OEM ID : 00 00 00 00 ]
<16:59:54> Android Session Handler Starting
<16:59:54> IdleState:updating session check
<16:59:54> Create android_session_handler thread
<16:59:54> Android Status Report Handler Starting
<16:59:54> Create android_status_report_handler thread
<16:59:54> sirf_cpa_init: called
<16:59:54> sirf_cpa_ril_library_load: called
<16:59:54> sirf_cpa_ril_library_load : SUCCESS
<16:59:54> sirf_cpa_oem_ril_connect: called
<16:59:54> pfn_Connect_RILD Success
<16:59:54> sirf_cpa_oem_ril_connect : Success!!!
<16:59:54> sirf_cpa_init: Registering control plane callback
<16:59:54> INFO: CP_SetMessageListeners is called
<16:59:54> ERROR: (CP_SetMessageListeners) LSM is not initialized
<16:59:54> INFO: CP_SetMessageListeners exits
<16:59:54> Sirf CPA Initialization Success
<16:59:54> SIRF GSD4t Initialization Success
<16:59:54> sirf_agps_init: called
<16:59:54> sirf_gps_ni_init: called
<16:59:54> sirf_agps_ril_init: called
<16:59:54> sirf_agps_set_server - Type : 1, hostname = supl.google.com, port = 7276
<16:59:54> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<16:59:54> sirf_agps_update_network_availability : available = 1, apn = free
<16:59:54> sirf_gps_inject_location: called
<16:59:54> sirf_gps_inject_time: called
<16:59:54> Recieved utc = 1361807805539 ms ref = 35375 ms unc = 42 ms
<16:59:54> Local Time Updated : ref UTC = 1361807805539 , unc = 42, ref sys time= 35375
<16:59:54> Local time difference since last update - 189891 ms
<16:59:54> LSM TIME INJECTED: utc = 1361807805539, ref =35375, unc = 42
<17:02:47> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<17:02:47> sirf_agps_update_network_availability : available = 1, apn = free
<17:03:47> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<17:03:47> sirf_agps_update_network_availability : available = 1, apn = free
<17:04:00> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<17:04:00> sirf_agps_update_network_availability : available = 1, apn = free
<17:05:00> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<17:05:00> sirf_agps_update_network_availability : available = 1, apn = free
<17:05:00> sirf_agps_ril_update_network_state: called - connected : 1, type : 0 extra : free
<17:05:00> sirf_agps_update_network_availability : available = 1, apn = free
=============================================================================
But one error: ERROR: (CP_SetMessageListeners) LSM is not initialized ??? I don't know that is meaning!
Any help please!!!
Regards
Click to expand...
Click to collapse
no idea???
LikeM8 said:
no idea???
Click to expand...
Click to collapse
So, you have GPS enabled but when you start an app that uses GPS for positioning, the icon doesn't appear (also no GPS related feedback in the notification drawer)? Or, does it stay on 'searching...' forever?
Petrovski80 said:
So, you have GPS enabled but when you start an app that uses GPS for positioning, the icon doesn't appear (also no GPS related feedback in the notification drawer)? Or, does it stay on 'searching...' forever?
Click to expand...
Click to collapse
Hi Petrovski80,
Thanks for your reply. Indeed, when I start GPS app like GPS Status or GPS test, the icon doesn't appear and stay on "searching..." forever.
What do you mean by "also no GPS related feedback in the notification drawe"?
Regards
I mean a notification related to gps status. See screenshots.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Sent from my Galaxy Nexus using Tapatalk 2
Petrovski80 said:
I mean a notification related to gps status. See screenshots.
Sent from my Galaxy Nexus using Tapatalk 2
Click to expand...
Click to collapse
OK, second pic (searching loop)!!!
LikeM8 said:
OK, second pic (searching loop)!!!
Click to expand...
Click to collapse
No icon on status bar, loop search from GPS app (GPS test, GPS Test,...) only!
Are you seeing satellites when using a gps test app?
Sent from my Galaxy Nexus using Tapatalk 2
Petrovski80 said:
Are you seeing satellites when using a gps test app?
Sent from my Galaxy Nexus using Tapatalk 2
Click to expand...
Click to collapse
no I seeing nothing
LikeM8 said:
no I seeing nothing
Click to expand...
Click to collapse
do you confirm as me the GPS chip is alive according sirf file log?
LikeM8 said:
do you confirm as me the GPS chip is alive according sirf file log?
Click to expand...
Click to collapse
I'm no SIRF expert, but judging from that log it looks at least the GPS chipset is responding. This of course does not guarantee it can actually see satellites. Did GPS ever work on your device? Or did it suddenly stopped working while not related to flashing a ROM or other software changes? In both scenarios, I highly doubt this can be fixed using software. Return it and claim warranty.
Petrovski80 said:
I'm no SIRF expert, but judging from that log it looks at least the GPS chipset is responding. This of course does not guarantee it can actually see satellites. Did GPS ever work on your device? Or did it suddenly stopped working while not related to flashing a ROM or other software changes? In both scenarios, I highly doubt this can be fixed using software. Return it and claim warranty.
Click to expand...
Click to collapse
it sopped working after flasing ROM.
LikeM8 said:
it sopped working after flasing ROM.
Click to expand...
Click to collapse
In that case, return to stock images to see if that fixes the issue using this guide: http://forum.xda-developers.com/showthread.php?t=2010312
Petrovski80 said:
In that case, return to stock images to see if that fixes the issue using this guide: http://forum.xda-developers.com/showthread.php?t=2010312
Click to expand...
Click to collapse
I do this also but nothing fixe!!!
1- Does a way to flash only GPS chip firmware without use to flash a ROM?
2- I have not warranty so not a good idea to send the handset to Samsung, which log file according you which able to show me error?
3- Whay the GPS icon do not blinking in status bar when I launch GPS app like GPS test?
4- Doest a way to manually RESET GPS chip?
Did you try to manipulate the GPS using an app like GPS Control SIRF StarIV?
Petrovski80 said:
Did you try to manipulate the GPS using an app like GPS Control SIRF StarIV?
Click to expand...
Click to collapse
yes I do it and the GPS driver is lib_gsd4t_icecream.so
Really dumb question - is use gps satellites ticked off in location settings?
---------- Post added at 10:07 PM ---------- Previous post was at 10:04 PM ----------
Petrovski80 said:
Did you try to manipulate the GPS using an app like GPS Control SIRF StarIV?
Click to expand...
Click to collapse
Wanted to thank you for mentioning this app. I never heard of it before. Turns out that enabling static navigation repairs the wonky sensor. I can use photo sphere now! I can use Google sky map again! Navigation is awesome! Thank you!
LikeM8 said:
yes I do it and the GPS driver is lib_gsd4t_icecream.so
Click to expand...
Click to collapse
I find a document which this you can send NMEA message to GSD4t chip via AT command. But how to set a connection? /dev/ttyO0 port is used by GSD4t
LikeM8 said:
I find a document which this you can send NMEA message to GSD4t chip via AT command. But how to set a connection? /dev/ttyO0 port is used by GSD4t
Click to expand...
Click to collapse
Any help to send AT command to GPS GSD4t chip via /dev/ ttyO0 port?
sirf_interface_log.txt
LikeM8 said:
Any help to send AT command to GPS GSD4t chip via /dev/ ttyO0 port?
Click to expand...
Click to collapse
any fix for this issue "sirf_gps_inject_time: called" from "Galaxy Nexus" sirf_interface_log.txt?
Hello every one,
not sure if this the right place to ask but i really need help.
I am attempting to gather some data on Galaxy Nexus i9250 Android v4.3 CPU ARMv7.I am trying to use ARM Streamline but it provides the following error:
ARM Processor PMU event counters have been detected, however the event counters are reading zeroes. Event counters include those counters listed in the counter configuration options dialog under the core name but exclude the cycle counter (Clock:Cycles) as it is controlled by a dedicated counter. It is possible that the PMU configuration bit DBGEN has not been enabled, and counter values subsequently will always read as zero. To remedy, please update your firmware or Linux kernel to enable DBGEN.
after some search i found similar problem: on freescale
which suggest some modification to the SDER Secure Debug Enable Register, Security Extensions.
i do not know what to so i found a file perf_event in kernel source but not sure where to start.
i found out on infocenter of arm for ARM11 that i should use
// MRC p15, 0, <Rd>, CRn, CRm, opCode_2 ; base
MRC p15, 0, <Rd>, c15, c12, 0 ; Read Performance Monitor Control Register
MCR p15, 0, <Rd>, c15, c12, 0 ; Write Performance Monitor Control Register
this is in perf_event_v6.c kernel folder like this:
static inline unsigned long
armv6_pmcr_read(void)
{
u32 val;
asm volatile("mrc p15, 0, %0, c15, c12, 0" : "=r"(val));
return val;
}
since i'm using version arm7 so i should modify perf_event_v7.c
and my guessing that i should use c9 instead of c15 because this is the option used there and mentioned in the Cortex Reference manual for EX:
c9 registers
Table 4-10 shows the CP15 system control registers you can access when CRn is c9.
Table 4-10 c9 register summary
Op1 CRm Op2 Name Type Reset Description
0 c12 0 PMCR RW 0x41093000 Performance Monitor Control Register
1 PMCNTENSET RW 0x00000000 Count Enable Set Register
2 PMCNTENCLR RW 0x00000000 Count Enable Clear Register
3 PMOVSR RW - Overflow Flag Status Register
4 PMSWINC WO - Software Increment Register
5 PMSELR RW 0x00000000 Event Counter Selection Register
so it should be :
MRC p15, 0, <Rd>, c9, c12, 0 ; Read Performance Monitor Control Register
MCR p15, 0, <Rd>, c9, c12, 0 ; Write Performance Monitor Control Register
and
MRC p15, 0, <Rd>, c9, c12, 5 ; Read PMSELR Register
MCR p15, 0, <Rd>, c9, c12, 5 ; Write PMSELR Register
and to choose the event:
EXPORT pmn_config
; Sets the event for a programmable counter to record
; void pmn_config(unsigned counter, uint32_t event)
; counter (in r0) = Which counter to program (e.g. 0 for PMN0, 1 for PMN1)
; event (in r1) = The event code (from appropriate TRM or ARM Architecture Reference Manual)
pmn_config PROC
AND r0, r0, #0x1F ; Mask to leave only bits 4:0
MCR p15, 0, r0, c9, c12, 5 ; Write PMSELR Register
ISB ; Synchronize context
MCR p15, 0, r1, c9, c13, 1 ; Write PMXEVTYPER Register
BX lr
ENDP
the steps i should follow are as follow:
The following procedure should be followed:
Disable performance counters
Set what each event counter will count
Set cycle counter tick rate
Reset performance counters
Enable performance counters
Call function to profile
Disable performance counters
Read out performance counters
Check that performance counters did not overflow
i also found this EX:
following this code on google_code DirectPMUCodeGCC
i found on e2e support site that Galaxy Nexus is a secure device by checking the DBGAUTHSTATUS
i should push DBGEN or NIDEN high.
but i still did not know how to do it.
Any help?
This article will first describe how to locate the Monitor mode code in Nexus 5 firmware (hammerhead-ktu84p-factory-35ea0277, bootloader-hammerhead-hhz11k : c32f8bec310c659c1296739b00c6a8ac). Then, we will try to understand what it does (its functionalities). Finally, you will have to find bugs by yourself because I didn't find any...so far !
Note: Terms (Non-)Secure world & (Non-)Secure state are used as synonyms. Term Normal world is also used as synonym of Non-Secure world.
I. Quick introduction to ARM Security Extensions
"The Security Extensions define two security states: Secure state and Non-secure state. All instruction execution takes place either in Secure state or in Non-secure state.[...] The Security Extensions also define an additional processor mode, Monitor mode, that provides a bridge between software running in Non-secure state and software running in Secure state."
"The Secure Monitor Call exception is implemented only as part of the Security Extensions. The Secure Monitor Call instruction, SMC , requests a Secure Monitor function, causing the processor to enter Monitor mode."
"When an exception is taken, processor execution is forced to an address that corresponds to the type of exception. This address is called the exception vector for that exception. A set of exception vectors comprises eight consecutive word-aligned memory addresses, starting at an exception base address. These eight vectors form a vector table."
-- ARM Architecture Reference Manual ARMv7-A
II. OpenSource TrustZone examples
Trusted Execution Environment (TEE) is the "small" secure kernel executed in Secure state. The Monitor code is part of the TEE code.
To get an idea of how the Monitor code works, we can take a look at two TrustZone examples:
Cortex-A9 TrustZone example by ARM : a simple example of secure and non-secure code that communicates through Monitor mode.
OP-TEE by STMicroelectronics : an Open Source TEE 1.0 implementation.
After studying these code samples, we can clearly distinguish two parts in Monitor code:
Monitor mode initialization: called once, at TEE initialization time.
In this code, we can notice two specific instructions :
Monitor Vector Base Address Register (MVBAR) setup: MVBAR contains the Monitor vector table address. Both samples use the same instructions to setup MVBAR :
MCR p15, 0, $RX,c12,c0, 1
where $RX is a pointer to the monitor mode's vector table.
SP register setup: the Monitor mode stack address is set into SP register. This register is banked, which means this value will be automatically restored next time the processor enters in Monitor mode.
Exception vectors: called when an exception is taken to Monitor mode.
Both samples implement a simple Secure Monitor Call (SMC) handler that switches between the normal and secure worlds when a SMC call is made. As SMC handler is an entry point to the Secure state, it would be interesting to analyze it in Nexus 5 firmware.
III. Extracting Nexus 5 firmware
We know that the Monitor code may be embedded into the TEE image. In the case of Nexus 5, this image can be extracted from stock ROM.
h t t p s: / / w w w . y o u t u b e . c o m /w a t c h ? v = h 6 c K G j X K S j I
h t t p s : / / w w w . y o u t u b e . c o m / w a t c h ? v = P R K y k F U Q K m 0
Once downloaded, we use a small tool to unpack bootloader-hammerhead-hhz11k.img file. One of extracted files is an ELF ARM binary named "tz".
IV. Nexus 5 Monitor mode code
To analyze the Nexus 5 TrustZone binary, we can use IDA Demo 6.6.
Given that setting up MVBAR is very specific to the monitor mode's initialization code, we use it to locate the Monitor mode's initialization code in Nexus 5 TrustZone binary.
Using IDA regex search in code disassembly, we look for the instruction used to write MVBAR :
MCR[[:space:]]+p15, 0, [^,]+,c12,c0, 1
This search returns only 3 occurrences, and one of them also sets the SP register. These instructions are expected to be found in Monitor mode initialization code.
IV.1. Monitor mode initialization function
Here's the disassembly of the Monitor mode initialization code :
LOAD:FE80DB4C init_monitor
LOAD:FE80DB4C MSR CPSR_c, #0xD6 ; switch to Monitor mode
LOAD:FE80DB50 LDR R0, =monitor_vector_table ; load monitor vector table ptr into R0
LOAD:FE80DB54 MCR p15, 0, R0,c12,c0, 1 ; write R0 to MVBAR
LOAD:FE80DB58 BL sub_FE80DB88 ; initialize Non-Secure world
LOAD:FE80DB5C LDR SP, =0xFE82B700
LOAD:FE80DB60 MRC p15, 0, R0,c0,c0, 5 ; write MPIDR value to R0
LOAD:FE80DB64 AND R0, R0, #0xFF ; keep Affinity level 0 : current virtual CPU id
LOAD:FE80DB68 MOV R1, #0x200
LOAD:FE80DB6C MUL R1, R1, R0 ; compute stack offset for current vCPU
LOAD:FE80DB70 SUB SP, SP, R1 ; setup Monitor stack register SP
LOAD:FE80DB74 MOV R0, #0b100
LOAD:FE80DB78 MCR p15, 0, R0,c1,c1, 0 ; set FIQ flag in SCR register
LOAD:FE80DB7C ISB SY ; flush the pipeline in the processor
LOAD:FE80DB80 MSR CPSR_c, #0xD3 ; switch to Supervisor mode
LOAD:FE80DB84 BX LR
LOAD:FE80DB84 ; End of function init_monitor
We will now proceed to a detailed analysis of each step.
IV.1.A Switch to Monitor mode
MSR instruction moves an immediate value (here 0xD6) to a Special register (here CPSR_c).
LOAD:FE80DB4C MSR CPSR_c, #0xD6 ; switch to Monitor mode
The Current Program Status Register (CPSR) holds processor status and control information. CPSR with "_c" suffix enables writing of bits<0:7> of CPSR (ARM Ref. B9.3.11). This bitfield controls the processor mode and exception masks.
We can use a simple IDAPython script to replace the immediate value 0xD6 with symbols documented in ARM Ref. (B1-1148) :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from idautils import *
from idaapi import *
from idc import *
Message("%s starting...\n" % __file__)
CPSR_C_enum_id = GetEnum("CPSR_C_enum")
if CPSR_C_enum_id == BADADDR:
CPSR_C_enum_id = AddEnum(-1, "CPSR_C_enum", hexflag())
SetEnumBf(CPSR_C_enum_id,1);
AddConstEx(CPSR_C_enum_id,"CPSR_MODE_USR", 0b10000, 0x1F)
AddConstEx(CPSR_C_enum_id,"CPSR_MODE_FIQ", 0b10001, 0x1F)
AddConstEx(CPSR_C_enum_id,"CPSR_MODE_IRQ", 0b10010, 0x1F)
AddConstEx(CPSR_C_enum_id,"CPSR_MODE_SVC", 0b10011, 0x1F)
AddConstEx(CPSR_C_enum_id,"CPSR_MODE_MON", 0b10110, 0x1F)
AddConstEx(CPSR_C_enum_id,"CPSR_MODE_ABT", 0b10111, 0x1F)
AddConstEx(CPSR_C_enum_id,"CPSR_MODE_HYP", 0b11010, 0x1F)
AddConstEx(CPSR_C_enum_id,"CPSR_MODE_UND", 0b11011, 0x1F)
AddConstEx(CPSR_C_enum_id,"CPSR_MODE_SYS", 0b11111, 0x1F)
AddConstEx(CPSR_C_enum_id,"CPSR_THUMB", 0x20, 0x20)
AddConstEx(CPSR_C_enum_id,"CPSR_MASK_FIQ", 0x40, 0x40)
AddConstEx(CPSR_C_enum_id,"CPSR_MASK_IRQ", 0x80, 0x80)
ea = MinEA()
while True:
ea= FindText(ea, SEARCH_DOWN|SEARCH_NEXT|SEARCH_REGEX, 0, 0, " (CPS|MSR) ")
if ea == BADADDR:
break
mnem = GetMnem(ea)
if mnem == "MSR":
if GetOpnd(ea, 0) == "CPSR_c" and GetOpType(ea, 1) == o_imm:
OpEnumEx(ea, 1, CPSR_C_enum_id, 0)
Message("%s MSR CPSR_c, %s\n" % (hex(ea),GetOpnd(ea, 1)))
elif mnem == "CPS":
OpEnumEx(ea, 0, CPSR_C_enum_id, 0)
Message("%s CPS %s\n" % (hex(ea),GetOpnd(ea, 0)))
else:
Message("Unrecognized instruction @ %s : %s\n" % (hex(ea), GetDisasm(ea)))
ea = NextHead(ea)
Message("Done!\n")
view rawida-armv7a-cpsr_c.py hosted with ❤ by GitHub
Thus, the instruction becomes:
LOAD:FE80DB4C MSR CPSR_c, #CPSR_MODE_MON OR CPSR_MASK_FIQ OR CPSR_MASK_IRQ ; switch to Monitor mode
This instruction switches the processor to Monitor mode. It also sets CPSR.F and CPSR.I bits to mask FIQ and IRQ exceptions, meaning they cannot be taken.
IV.1.B Setup MVBAR
The Move to Coprocessor from ARM core register instruction (MCR) passes the value of an ARM core register (here R0) to a coprocessor (here CP15).
LOAD:FE80DB50 LDR R0, =monitor_vector_table ; load monitor vector table ptr into R0
LOAD:FE80DB54 MCR p15, 0, R0,c12,c0, 1 ; write R0 to MVBAR
CP15 c12 register is present on an ARMv7-A implementation that includes Security Extensions. This instruction writes R0 value to MVBAR. R0 contains a pointer to Monitor vector table. We will describe this table later.
IV.1.C Initialize Non-Secure world
The function sub_FE80DB88 is called to initialize the Non-Secure world context:
LOAD:FE80DB88 sub_FE80DB88
LOAD:FE80DB88 MRC p15, 0, R1,c1,c0, 0 ; read Secure SCTLR
LOAD:FE80DB8C MOV R0, #SCR_NS OR SCR_FW OR SCR_AW ; #0x31
LOAD:FE80DB90 MCR p15, 0, R0,c1,c1, 0 ; switch to Non-Secure (NS) state
LOAD:FE80DB94 ISB SY
LOAD:FE80DB98 MCR p15, 0, R1,c1,c0, 0 ; write Secure SCTLR value to NS SCTLR
LOAD:FE80DB9C MOV R0, #0
LOAD:FE80DBA0 MCR p15, 2, R0,c0,c0, 0 ; clear CSSELR
LOAD:FE80DBA4 MCR p15, 0, R0,c2,c0, 0 ; clear TTBR0
LOAD:FE80DBA8 MCR p15, 0, R0,c2,c0, 1 ; clear TTBR1
LOAD:FE80DBAC MCR p15, 0, R0,c2,c0, 2 ; clear TTBCR
LOAD:FE80DBB0 MCR p15, 0, R0,c3,c0, 0 ; clear DACR
LOAD:FE80DBB4 MCR p15, 0, R0,c5,c0, 0 ; clear DFSR
LOAD:FE80DBB8 MCR p15, 0, R0,c5,c0, 1 ; clear IFSR
LOAD:FE80DBBC MCR p15, 0, R0,c5,c1, 0 ; clear ADFSR
LOAD:FE80DBC0 MCR p15, 0, R0,c5,c1, 1 ; clear AIFSR
LOAD:FE80DBC4 MCR p15, 0, R0,c6,c0, 0 ; clear DFAR
LOAD:FE80DBC8 MCR p15, 0, R0,c6,c0, 2 ; clear IFAR
LOAD:FE80DBCC MCR p15, 0, R0,c7,c4, 0 ; clear PAR
LOAD:FE80DBD0 MCR p15, 0, R0,c10,c2, 0 ; clear PRRR
LOAD:FE80DBD4 MCR p15, 0, R0,c10,c2, 1 ; clear NMRR
LOAD:FE80DBD8 MCR p15, 0, R0,c10,c4, 0 ; clear "MMUDMTR" ?
LOAD:FE80DBDC MCR p15, 0, R0,c10,c4, 1 ; clear "MMUDCPR" ?
LOAD:FE80DBE0 LDR R1, =dword_FE82B8CC ; load Non-Secure VBAR ptr to R1
LOAD:FE80DBE4 LDR R0, [R1]
LOAD:FE80DBE8 MCR p15, 0, R0,c12,c0, 0 ; write Non-Secure VBAR
LOAD:FE80DBEC MOV R0, #0
LOAD:FE80DBF0 STR R0, [R1] ; clear Non-Secure VBAR ptr
LOAD:FE80DBF4 MCR p15, 0, R0,c13,c0, 0 ; clear FCSEIDR
LOAD:FE80DBF8 MCR p15, 0, R0,c13,c0, 1 ; clear CONTEXTIDR
LOAD:FE80DBFC MCR p15, 0, R0,c13,c0, 2 ; clear TPIDRURW
LOAD:FE80DC00 MCR p15, 0, R0,c13,c0, 3 ; clear TPIDRURO
LOAD:FE80DC04 MCR p15, 0, R0,c13,c0, 4 ; clear TPIDRPRW
LOAD:FE80DC08 MOV R0, #SCR_FW OR SCR_AW ; #0x30
LOAD:FE80DC0C MCR p15, 0, R0,c1,c1, 0 ; switch back to Secure state
LOAD:FE80DC10 ISB SY
LOAD:FE80DC14 BX LR
LOAD:FE80DC14 ; End of function sub_FE80DB88
First, the security state is switched to Non-Secure. Then, the coprocessor registers banked in both security states (ARM Ref. Banked system control registers) are initialized to zero. Finally, the security state is switched back to Secure.
IV.1.D Setup SP register
On ARMv7-A, Multiprocessor Affinity Register (MPIDR) holds the processor identification information. In this register, bits<0:7> are the affinity level 0 (Aff0). This number represents the current CPU id. Here, this id is used to compute the stack address of current CPU, which is then stored into SP register. The stack size for each CPU is 0x200 bytes.
LOAD:FE80DB5C LDR SP, =0xFE82B700
LOAD:FE80DB60 MRC p15, 0, R0,c0,c0, 5 ; write MPIDR value to R0
LOAD:FE80DB64 AND R0, R0, #0xFF ; keep Affinity level 0 : current virtual CPU id
LOAD:FE80DB68 MOV R1, #0x200
LOAD:FE80DB6C MUL R1, R1, R0 ; compute stack offset for current vCPU
LOAD:FE80DB70 SUB SP, SP, R1 ; setup Monitor stack register SP
IV.1.E Route FIQ exceptions to Monitor mode
CP15 c1 register is present on an ARMv7-A implementation that includes Security Extensions. This instruction sets bit<2> (0x4) in Secure Configuration Register (SCR), which means FIQ exceptions are now taken to Monitor mode.
LOAD:FE80DB74 MOV R0, #0b100 ; SCR.FIQ
LOAD:FE80DB78 MCR p15, 0, R0,c1,c1, 0 ; set FIQ flag in SCR register
LOAD:FE80DB7C ISB SY ; flush the pipeline in the processor
We can also notice that bit<0> (SCR.NS : Non-Secure) is not set, meaning current execution state is Secure.
IV.1.F Switch back to Supervisor mode
This instruction switches the processor to Supervisor mode, and sets FIQ & IRQ mask bits.
LOAD:FE80DB80 MSR CPSR_c, #CPSR_MODE_SVC OR CPSR_MASK_FIQ OR CPSR_MASK_IRQ ; switch to Supervisor mode
Monitor mode setup is now complete. Monitor code can then be entered through its exception vector table.
IV.2. Monitor Exception Vector Table
The Monitor exception vector table defines exception vectors to handle exceptions taken to Monitor Mode.
Its structure is described in ARM Ref. (B1-1167) :
The vector table entries
Thank to the Monitor initialization code, we know the address of Nexus 5's Monitor exception vector table:
LOAD:FE80CEE0 monitor_vector_table
LOAD:FE80CEE0 B dead_loop ; not used
LOAD:FE80CEE4 ; ---------------------------------------------------------------------------
LOAD:FE80CEE4 B dead_loop ; not used
LOAD:FE80CEE8 ; ---------------------------------------------------------------------------
LOAD:FE80CEE8 B smc_handler ; Secure Monitor Call
LOAD:FE80CEEC ; ---------------------------------------------------------------------------
LOAD:FE80CEEC B dead_loop ; Prefetch Abort
LOAD:FE80CEF0 ; ---------------------------------------------------------------------------
LOAD:FE80CEF0 B dead_loop ; Data Abort
LOAD:FE80CEF4 ; ---------------------------------------------------------------------------
LOAD:FE80CEF4 B dead_loop ; not used
LOAD:FE80CEF8 ; ---------------------------------------------------------------------------
LOAD:FE80CEF8 B sub_FE80CF24 ; IRQ interrupt
LOAD:FE80CEFC ; ---------------------------------------------------------------------------
LOAD:FE80CEFC B sub_FE80CFB4 ; FIQ interrupt
LOAD:FE80CEFC ; End of function monitor_vector_table
We can see that 3 exception handlers are configured: SMC, FIQ, IRQ. Others are dead loops.
IV.3. Secure Monitor Call handler function
HLOS (non-Secure state) can call the TrustZone API (Secure state) using the SMC instruction to trigger a Secure Monitor Call exception. This exception is taken to the Monitor mode, which switches the processor to Secure Supervisor mode to proceed the call. When called TrustZone function returns, a second SMC exception is triggered, so the processor enters Monitor mode again. Finally, the Monitor mode returns results to the calling function (Non-Secure state).
The Monitor mode acts as a bridge between Non-Secure state and Secure state. It's designed to handle calls initiated from the Non-Secure state only.
The exception vector dedicated to SMC exceptions is a pointer to a function at offset 0x08 in Monitor Exception Vector Table.
In this function, which will be named SMC handler, the very first instruction checks if an exception occurred in Secure or Non-Secure state (When the processor is in Monitor mode, the processor is in Secure state regardless of the value of the SCR.NS bit).
LOAD:FE80D028 smc_handler
LOAD:FE80D028
LOAD:FE80D028 varg_r0 = -0x10
LOAD:FE80D028 varg_r1 = -0xC
LOAD:FE80D028 varg_r2 = -8
LOAD:FE80D028 varg_r3 = -4
LOAD:FE80D028
LOAD:FE80D028 STMFD SP!, {R0-R3}
LOAD:FE80D02C MRC p15, 0, R0,c1,c1, 0 ; read SCR register
LOAD:FE80D030 TST R0, #1 ; test SCR.NS bit
LOAD:FE80D034 BEQ loc_FE80D210 ; jump if SCR.NS==0
When an exception is taken to the Monitor mode, CPSR.{A,I, F} bits are set to 1, meaning Abort, IRQ and FIQ exceptions can no longer be taken.
IV.3.A. Call to Secure World
If SCR.NS bit is set, it means the Non-Secure world wants to call the Secure world. We will now analyze the operations performed by the SMC handler until the exception return to the Secure world.
IV.3.A.a Setup current security state
This first step configures the Secure Configuration Register (SCR). Bits<1:3> (SCR.IRQ || SCR.FIQ || SCR.EA) are set to route IRQ, FIQ, and External Abort exceptions to Monitor mode. But the Non-Secure bit<0> is not set. So, this core will still be in the Secure state if it exits Monitor mode.
LOAD:FE80D038 MOV R0, #SCR_IRQ OR SCR_FIQ OR SCR_EA ; 0b1110
LOAD:FE80D03C MCR p15, 0, R0,c1,c1, 0 ; write SCR with SCR.NS==0
LOAD:FE80D040 ISB SY ; Instruction Synchronization Barrier
LOAD:FE80D040 ; flushes the pipeline in the processor
IV.3.A.b Monitor calls
On a HLOS like Android, SMC exceptions are triggered by the Secure Channel Manager (SCM), implemented in Linux kernel.
A quick look at its source code tells us {R0-R3} registers hold arguments of SMC calls. We also learn that R0 is a bitfield that can be defined by the following macro:
#define SCM_ATOMIC(svc, cmd, n) (((((svc) << 10)|((cmd) & 0x3ff)) << 12) | \
SCM_CLASS_REGISTER | \
SCM_MASK_IRQS | \
(n & 0xf))
With svc the service identifier, cmd the command identifier, and n the argument count of the SMC call.
In SMC handler, R0 value is first shifted right by 12. Based on the SCM_ATOMIC macro definition, resulting R0 value represents a service identifier svc and a command identifier cmd defined as ((svc) << 10)|((cmd) & 0x3ff).
Then R0 value is tested against several immediate values. For each case, a specific function is called if values match.
LOAD:FE80D048 MOV R2, R0,LSR#12 ; extract service & command identifiers
LOAD:FE80D04C MOV R1, #0x402 ; SCM_SVC_BOOT::SCM_CMD_TERMINATE_PC
LOAD:FE80D050 CMP R1, R2
LOAD:FE80D054 LDMEQFD SP!, {R1-R3}
LOAD:FE80D058 BEQ sub_FE80D360
LOAD:FE80D05C MOV R1, #0xC05 ; SCM_SVC_UTIL::CACHE_BUFFER_DUMP_COMMAND_ID
LOAD:FE80D060 CMP R1, R2
LOAD:FE80D064 LDMEQFD SP!, {R1-R3}
LOAD:FE80D068 BEQ sub_FE80D68C
LOAD:FE80D06C MOV R1, #0x404 ; SCM_SVC_BOOT::4
LOAD:FE80D070 CMP R1, R2
LOAD:FE80D074 LDMEQFD SP!, {R1-R3}
LOAD:FE80D078 BEQ sub_FE80D72C
LOAD:FE80D07C MOV R1, #0x1401 ; SCM_SVC_IO::SCM_IO_READ
LOAD:FE80D080 CMP R1, R2
LOAD:FE80D084 LDMEQFD SP!, {R1-R3}
LOAD:FE80D088 BEQ sub_FE80D5AC
LOAD:FE80D08C MOV R1, #0x1402 ; SCM_SVC_IO::SCM_IO_WRITE
LOAD:FE80D090 CMP R1, R2
LOAD:FE80D094 LDMEQFD SP!, {R1-R3}
LOAD:FE80D098 BEQ sub_FE80D5CC
LOAD:FE80D09C MOV R1, #0x3404 ; SCM_SVC_DCVS:CVS_CMD_EVENT
LOAD:FE80D0A0 CMP R1, R2
LOAD:FE80D0A4 LDMEQFD SP!, {R1-R3}
LOAD:FE80D0A8 BEQ sub_FE80D64C
LOAD:FE80D0AC MOV R1, #0x1403 ; SCM_SVC_IO::TZ_RESET_ID
LOAD:FE80D0B0 CMP R1, R2
LOAD:FE80D0B4 LDMEQFD SP!, {R1-R3}
LOAD:FE80D0B8 BEQ sub_FE80D5EC
LOAD:FE80D0BC MOV R1, #0x1404 ; SCM_SVC_IO::TZ_UPDATE_ID
LOAD:FE80D0C0 CMP R1, R2
LOAD:FE80D0C4 LDMEQFD SP!, {R1-R3}
LOAD:FE80D0C8 BEQ sub_FE80D618
LOAD:FE80D0CC MOV R1, #0x2401 ; SCM_SVC_PWR::SCM_IO_DISABLE_PMIC_ARBITER
LOAD:FE80D0D0 CMP R1, R2
LOAD:FE80D0D4 LDMEQFD SP!, {R1-R3}
LOAD:FE80D0D8 BEQ sub_FE80D74C
As Linux kernel itself initiates a lot of SMC calls, we explore Linux sources to enumerate service and command identifiers passed to SMC calls. Thereby, we will get more information on corresponding functions without reversing them.
Immediate value Service ID (imm>>10) Command ID (imm&0x3ff) Function description
0x402 SCM_SVC_BOOT SCM_CMD_TERMINATE_PC Put current core in low power state
0xC05 SCM_SVC_UTIL CACHE_BUFFER_DUMP_COMMAND_ID Dump the L1 and L2 caches on panic
0x404 SCM_SVC_BOOT 4 Dummy function, returns to Non-Secure world
0x1401 SCM_SVC_IO SCM_IO_READ Dummy function, returns to Non-Secure world
0x1402 SCM_SVC_IO SCM_IO_WRITE Dummy function, returns to Non-Secure world
0x3404 SCM_SVC_DCVS DCVS_CMD_EVENT Handle some Dynamic Clock and Voltage Scaling (DCVS) See also event definitions
0x1403 SCM_SVC_IO TZ_RESET_ID Related to GPU power management
0x1404 SCM_SVC_IO TZ_UPDATE_ID Related to GPU power management
0x2401 SCM_SVC_PWR SCM_IO_DISABLE_PMIC_ARBITER "Force the SPMI PMIC arbiter to shutdown so that no more SPMI transactions are sent from the MSM to the PMIC."
All these functions have the same epilogue:
LOAD:FE80D738 MOV R3, #SCR_NS OR SCR_FIQ OR SCR_AW ; 0b100101
LOAD:FE80D73C MCR p15, 0, R3,c1,c1, 0 ; write SCR : switch to Non-Secure state
LOAD:FE80D740 ISB SY
LOAD:FE80D744 MOV R3, #0 ; clear R3 to avoid leak
LOAD:FE80D748 MOVS PC, LR ; restore Non-Secure PC & CPSR from LR_mon & SPSR_mon
These instructions switch the processor to Non-Secure state and restore PC & CPSR to perform an exception return.
So SMC calls associated with these specific command/service IDs are kind of "Monitor calls", entirely handled in Monitor mode.
But if R0 value does not match these IDs, the execution continues in Monitor mode.
IV.3.A.c TrustZone lock
If the call has not been handled yet, Monitor code tries to acquire a lock to ensure that only one core at a time enters in TrustZone.
First, current CPU id is retrieved from MPIDR. Then, this value is incremented (because 0 means not locked) and used as lock value.
LOAD:FE80D0E0 LDR R1, =tz_lock
LOAD:FE80D0E4 MRC p15, 0, R2,c0,c0, 5 ; read MPIDR register
LOAD:FE80D0E8 AND R2, R2, #0xFF ; extract Aff0 from MPIDR
LOAD:FE80D0EC ADD R2, R2, #1
LOAD:FE80D0F0
LOAD:FE80D0F0 loc_FE80D0F0 ; CODE XREF: smc_handler+D8j
LOAD:FE80D0F0 LDREX R0, [R1] ; read current tz_lock value
LOAD:FE80D0F4 CMP R0, #0 ; test if TrustZone is locked
LOAD:FE80D0F8 STREXEQ R0, R2, [R1] ; if not locked, try to lock TrustZone
LOAD:FE80D0FC CMPEQ R0, #0 ; test if TrustZone is now locked
LOAD:FE80D100 BNE loc_FE80D0F0 ; retry if TrustZone is still not locked
LOAD:FE80D104 DMB SY ; Data Memory Barrier acts as a memory barrier
Then, it tries to acquire the TrustZone lock. This implementation is very similar to the example provided in ARM Ref. (D7.3.1 Acquiring a lock).
It relies on synchronization primitives (LDREX/STREX) to support exclusive accesses to memory shared between cores.
Once the lock is acquired, the current core is the only one running in TrustZone, and the execution can continue.
IV.3.A.d Pre-exception status
LR_mon and SPSR_mon are both banked registers. Their values are generated by the exception entry. LR_mon contains the return address in Non-Secure world (right after the SMC instruction). The purpose of SPSR_mon is to record the pre-exception value of the CPSR.
LOAD:FE80D108 LDR R0, =NS_core_status ; secure area to store Non-Secure (NS) status
LOAD:FE80D10C MOV R1, LR ; read NS return address (LR_mon)
LOAD:FE80D110 MRS R2, SPSR ; read NS CPSR (SPSR_mon)
LOAD:FE80D114 STMIA R0, {R1,R2} ; write LR_mon & SPSR_mon
These two registers are saved in Secure memory to be restored later on exception return.
IV.3.A.e IRQ interruption flag
Then a DWORD at a static address is unconditionally cleared:
LOAD:FE80D118 LDR R1, =tz_irq_interrupted
LOAD:FE80D11C MOV R0, #0
LOAD:FE80D120 STR R0, [R1] ; clear tz_irq_interrupted value
By looking at cross-references, we notice this DWORD is set to 1 in the IRQ handler of Monitor mode. But in both handlers (SMC & IRQ), when an exception returns to the Non-Secure world, the returned value (in R0) is set to 1 if this DWORD is not null.
Futhermore, we can have a look at how SCM interprets the value returned by a SMC call:
#define SCM_INTERRUPTED 1
do {
asm volatile(
__asmeq("%0", "r0")
__asmeq("%1", "r0")
__asmeq("%2", "r1")
__asmeq("%3", "r2")
#ifdef REQUIRES_SEC
".arch_extension sec\n"
#endif
"smc #0 @ switch to secure world\n"
: "=r" (r0)
: "r" (r0), "r" (r1), "r" (r2)
: "r3");
} while (r0 == SCM_INTERRUPTED);
SCM will reiterate each SMC call while the returned value is 1.
We can deduce that this DWORD indicates if the exception return is due to an IRQ interrupt. TrustZone Whitepaper (3.3.3 Secure interrupts) says ARM recommends the use of IRQ as a Normal world interrupt source. That's why IRQ interrupts are handled in the Normal world.
IV.3.A.f Configure Secure world MMU
Next block of instructions modifies the translation table of Secure MMU (ARM Ref. B3.1 About the VMSA) if two conditions are met:
--
Wouldn't it be easier to provide the link?
http://www.fredericb.info/2014/12/analysis-of-nexus-5-monitor-mode.html