local &filename
local &mmu_cr
local &ttb
local &dacr
;;refer to pbl.scl
d.save.binary c:\temp\pbl.bin 0xFFFF0000--0xFFFFFFFF
d.save.binary c:\temp\pbl_stack.bin 0x80000000--0x8003FFFF
d.save.binary c:\temp\pbl_data.bin 0xFFFEF000--0xFFFEFFFF
;d.load.binary pbl.bin 0xFFFF0000--0xFFFFFFFF
;d.load.binary pbl_stack.bin 0x80000000--0x8003FFFF
;d.load.binary pbl_data.bin 0xFFFEF000--0xFFFEFFFF
&filename="c:\temp\MMU_log.cmm"
open #1 "&filename" /create
&mmu_cr=data.long(c15:0x1)
&ttb=data.long(c15:0x2)
&dacr=data.long(c15:0x3)
write #1 "B::"
write #1 "PER.S C15:0x3 %LONG "+"&dacr"
write #1 "PER.S C15:0x2 %LONG "+"&ttb"
write #1 "PER.S C15:0x1 %LONG "+"&mmu_cr"
write #1 "ENDDO"
close #1
&filename="c:\temp\register_log.cmm"
store &filename hex register
2/26/2013
2/01/2013
How is MSM waked up from deep sleep (TCXO shutdown)?
Here, the description applies to MSM with MPM (MAO) block. When MSM is in deep sleep (TCXO shutdown), the CPU is put in SWFI (Stop and Wait For Interrupt) state, it needs a hardware interrupt to trigger the CPU into running again. Since the regular interrupt controller is disabled, and only the interrupt controller in MPM (MAO) block is active. Therefore, only interrupts described in maoint_isr_type can bring MSM out of sleep. Here are some descriptions of these interrupts.
1) MAO_WAKEUP_ISR: this interrupt is generated when a timer in MPM block expires. This is used to wake up MSM when the prescribed sleep time has expired. So you may think that MSM is waked up by MPM timer, whose expiration time is calculated and set by the sleep_task before entering sleep. Generally, such sleep time is determined by RF slot cycle and the next expiring software timers.
2) Special interrupts such as MAO_TOUCH_SCREEN_ISR and MAO_USB_HS_ISR: these interrupts are generated by the specific modules' hardware controllers (for instance, touch screen controller and USB controller).
3) GPIO interrupts: these interrupts are generated by specific GPIOs whose interrupts are enabled when the triggering condition is met.
4) PM_INT: PMIC uses one of the GPIO interrupts, which is wakeup capable, to interrupt MSM. In addition, PMIC has its own interrupt subsystem. Therefore, many PMIC interrupts (e.g. Wall charger, power key) that are handled by PMIC can wake up MSM through the PMIC GPIO pin. In other words, from MSM's perpective, all these PMIC interrupts are muxed together to wake up MSM through PMIC GPIO.
The wakeup GPIOs are generally fixed for each MSM. However, they can be completely different in different MSMs (for instance, QSD8650 and MSM7200A). As a initial step of board design, hardware engineers need to review the MSM GPIO assignment. One of the steps in GPIO assignment review is to see what pins are used as wakeup pins in the design, and make sure that the assigned GPIO pins have wakeup capability.
1) MAO_WAKEUP_ISR: this interrupt is generated when a timer in MPM block expires. This is used to wake up MSM when the prescribed sleep time has expired. So you may think that MSM is waked up by MPM timer, whose expiration time is calculated and set by the sleep_task before entering sleep. Generally, such sleep time is determined by RF slot cycle and the next expiring software timers.
2) Special interrupts such as MAO_TOUCH_SCREEN_ISR and MAO_USB_HS_ISR: these interrupts are generated by the specific modules' hardware controllers (for instance, touch screen controller and USB controller).
3) GPIO interrupts: these interrupts are generated by specific GPIOs whose interrupts are enabled when the triggering condition is met.
4) PM_INT: PMIC uses one of the GPIO interrupts, which is wakeup capable, to interrupt MSM. In addition, PMIC has its own interrupt subsystem. Therefore, many PMIC interrupts (e.g. Wall charger, power key) that are handled by PMIC can wake up MSM through the PMIC GPIO pin. In other words, from MSM's perpective, all these PMIC interrupts are muxed together to wake up MSM through PMIC GPIO.
The wakeup GPIOs are generally fixed for each MSM. However, they can be completely different in different MSMs (for instance, QSD8650 and MSM7200A). As a initial step of board design, hardware engineers need to review the MSM GPIO assignment. One of the steps in GPIO assignment review is to see what pins are used as wakeup pins in the design, and make sure that the assigned GPIO pins have wakeup capability.
How to support dual-edge triggering GPIO interrupt in MSM?
Generally, dual-edge triggering for GPIO interrupt is not supported in HW except in recent chipset such as MSM8974. If there is a need to trigger the IRQ on both rising and falling edges of a GPIO signal, this needs to be implemented in software. It can be done as follows.
Use the following steps to enable the GPIO IRQ.
(1) Configure GPIO as a general purpose input pin.
(2) Read out the current state of GPIO.
(3) If the GPIO state is HIGH, register an ISR and set the trigger type to FALLING.
(4) If the GPIO state is LOW, register an ISR and set the trigger type of RISING.
Inside the GPIO ISR, do the same steps (1)-(4) to register the ISR again. This way, GPIO interrupt will be triggered on both rising and falling edges.
Use the following steps to enable the GPIO IRQ.
(1) Configure GPIO as a general purpose input pin.
(2) Read out the current state of GPIO.
(3) If the GPIO state is HIGH, register an ISR and set the trigger type to FALLING.
(4) If the GPIO state is LOW, register an ISR and set the trigger type of RISING.
Inside the GPIO ISR, do the same steps (1)-(4) to register the ISR again. This way, GPIO interrupt will be triggered on both rising and falling edges.
How is APPS GPIO interrupt handled during APPS sleep or power collapse?
When APPS goes into sleep, Modem will take over all APPS GPIOs and any enabled APPS GPIO interrupts by calling tramp_gpio_switch_to_modem(). This API performs the following procedures:
1) It calls gpio_switch_gpio_int_to_modem() to switch all APPS GPIO ownership from PERIPHERAL (i.e. APPS) to MASTER (i.e. Modem). As a result of ownership switch, any APPS GPIOs whose interrupts are enabled before APPS sleep will now route their interrupts to Modem interrupt controller once triggered.
2) It checks all the APPS GPIOs to see whether they are enabled as an interrupt source. If yes, it assigns tramp_gpio_monitor_apps_isr as the isr, and marks in tramp_gpio.table that this is a proxy isr for APPS.
tramp_gpio.table[gpio].isr = tramp_gpio_monitor_apps_isr;
tramp_gpio.table[gpio].isr_param = gpio;
tramp_gpio.table[gpio].is_proxy = TRUE;
3) The API will also mark it as a wakeup source if the GPIO interrupt is a MAO interrupt.
Now, APPS is in sleep, and if one of APPS GPIO interrupt is triggered it will interrupt Modem processor. Then, Modem's tramp service calls tramp_gpio_monitor_apps_isr to notify DEM (Dynamic Environment Manager) module, which will wake up APPS from sleep by asserting an inter-processor interrupt. As part of wakeup process, Modem will also transfer the ownership of APPS GPIOs back to APPS. Once APPS finishes its wakeup process, it will free the IRQ and proceed to handle the GPIO interrupt by calling its real isr.
Note that this mechanism of Modem temporarily overseeing APPS GPIO interrupt during APPS sleep is transparent to APPS processor. If there is any suspicion that certain APPS GPIO interrupt does not work as expected during APPS sleep, this handoff process can be verified by setting breakpoints in tramp_gpio_switch_to_modem() or tramp_gpio_monitor_apps_isr().
1) It calls gpio_switch_gpio_int_to_modem() to switch all APPS GPIO ownership from PERIPHERAL (i.e. APPS) to MASTER (i.e. Modem). As a result of ownership switch, any APPS GPIOs whose interrupts are enabled before APPS sleep will now route their interrupts to Modem interrupt controller once triggered.
2) It checks all the APPS GPIOs to see whether they are enabled as an interrupt source. If yes, it assigns tramp_gpio_monitor_apps_isr as the isr, and marks in tramp_gpio.table that this is a proxy isr for APPS.
tramp_gpio.table[gpio].isr = tramp_gpio_monitor_apps_isr;
tramp_gpio.table[gpio].isr_param = gpio;
tramp_gpio.table[gpio].is_proxy = TRUE;
3) The API will also mark it as a wakeup source if the GPIO interrupt is a MAO interrupt.
Now, APPS is in sleep, and if one of APPS GPIO interrupt is triggered it will interrupt Modem processor. Then, Modem's tramp service calls tramp_gpio_monitor_apps_isr to notify DEM (Dynamic Environment Manager) module, which will wake up APPS from sleep by asserting an inter-processor interrupt. As part of wakeup process, Modem will also transfer the ownership of APPS GPIOs back to APPS. Once APPS finishes its wakeup process, it will free the IRQ and proceed to handle the GPIO interrupt by calling its real isr.
Note that this mechanism of Modem temporarily overseeing APPS GPIO interrupt during APPS sleep is transparent to APPS processor. If there is any suspicion that certain APPS GPIO interrupt does not work as expected during APPS sleep, this handoff process can be verified by setting breakpoints in tramp_gpio_switch_to_modem() or tramp_gpio_monitor_apps_isr().
What is latency budget in dynamic sleep?
In dynamic sleep scheme, sleep solver chooses the best low power modes from a pool of enabled low power modes to enter under a few system constraints. These constraints are:
(1) Sleep duration.
(2) Latency budget
The sleep duration is how long the subsystem can stay in the sleep state. The latency budget is how fast the subsystem needs to come out of sleep state to handle a system event. Basically, it is the interrupt latency the system can tolerate. This puts constraint on the total warmup time of the chosen low power modes. For instance, if the latency budget is 0x1, i.e. 1 sleep clock tick ~ 30us, this generally will disable XO shutdown or VDD min because either of these modes requires warmup time much longer than 30us. In other words, if system goes into XO shutdown, it will not be able to recover fast enough to satisfy the 30us latency requirement.
The latency budget is obtained by querying the sleep_latency_node, which is a NPA node.
/* Get the latency budget from the latency node. The latency node will
* return the minimum latency budget being requested by all clients.
* This lets us know how quickly we need to respond to an interrupt when
* it occurs. */
CORE_VERIFY( NPA_QUERY_SUCCESS == npa_query( gSleepLatencyNode,
NPA_QUERY_CURRENT_STATE,
&qres ) );
Software modules can register to the latency node and request for latency budget. This information is shown in the NPA dump, and logged in sleep info ulog. Here is an example of NPA dump that shows HKADC has a latency requirement of 1.
: npa_resource (name: "/core/cpu/latency") (handle: 0x90103260) (units: sclk) (resource max: 4294967295) (active max: 4294967295) (active state 1) (active headroom: 2) (request state: 1)
: npa_client (name: GPS_CPU_LATENCY_CLIENT) (handle: 0x9018B7F4) (resource: 0x90103260) (type: NPA_CLIENT_REQUIRED 0x40) (request: 0)
: npa_client (name: GSM_LATENCY) (handle: 0x90172DE4) (resource: 0x90103260) (type: NPA_CLIENT_REQUIRED 0x40) (request: 0)
: npa_client (name: HKADC) (handle: 0x9013FF24) (resource: 0x90103260) (type: NPA_CLIENT_REQUIRED 0x40) (request: 1)
: end npa_resource (handle: 0x90103260)
: npa_resource (name: "/core/cpu/wakeup") (handle: 0x901032AC) (units: sclk) (resource max: 4294967295) (active max: 4294967295) (active state 0) (active headroom: 0) (request state: 0)
: end npa_resource (handle: 0x901032AC)
As a result, the latency budget logged in solver constraints of sleep info ulog is 0x1.
0xF9AB62A3: Solver constraints (hard duration: 0x0000003C) (soft duration: 0xFFFFFFFF) (latency budget: 0x00000001)
Since latency budget affect low power operation,
(1) Sleep duration.
(2) Latency budget
The sleep duration is how long the subsystem can stay in the sleep state. The latency budget is how fast the subsystem needs to come out of sleep state to handle a system event. Basically, it is the interrupt latency the system can tolerate. This puts constraint on the total warmup time of the chosen low power modes. For instance, if the latency budget is 0x1, i.e. 1 sleep clock tick ~ 30us, this generally will disable XO shutdown or VDD min because either of these modes requires warmup time much longer than 30us. In other words, if system goes into XO shutdown, it will not be able to recover fast enough to satisfy the 30us latency requirement.
The latency budget is obtained by querying the sleep_latency_node, which is a NPA node.
/* Get the latency budget from the latency node. The latency node will
* return the minimum latency budget being requested by all clients.
* This lets us know how quickly we need to respond to an interrupt when
* it occurs. */
CORE_VERIFY( NPA_QUERY_SUCCESS == npa_query( gSleepLatencyNode,
NPA_QUERY_CURRENT_STATE,
&qres ) );
Software modules can register to the latency node and request for latency budget. This information is shown in the NPA dump, and logged in sleep info ulog. Here is an example of NPA dump that shows HKADC has a latency requirement of 1.
: npa_resource (name: "/core/cpu/latency") (handle: 0x90103260) (units: sclk) (resource max: 4294967295) (active max: 4294967295) (active state 1) (active headroom: 2) (request state: 1)
: npa_client (name: GPS_CPU_LATENCY_CLIENT) (handle: 0x9018B7F4) (resource: 0x90103260) (type: NPA_CLIENT_REQUIRED 0x40) (request: 0)
: npa_client (name: GSM_LATENCY) (handle: 0x90172DE4) (resource: 0x90103260) (type: NPA_CLIENT_REQUIRED 0x40) (request: 0)
: npa_client (name: HKADC) (handle: 0x9013FF24) (resource: 0x90103260) (type: NPA_CLIENT_REQUIRED 0x40) (request: 1)
: end npa_resource (handle: 0x90103260)
: npa_resource (name: "/core/cpu/wakeup") (handle: 0x901032AC) (units: sclk) (resource max: 4294967295) (active max: 4294967295) (active state 0) (active headroom: 0) (request state: 0)
: end npa_resource (handle: 0x901032AC)
As a result, the latency budget logged in solver constraints of sleep info ulog is 0x1.
0xF9AB62A3: Solver constraints (hard duration: 0x0000003C) (soft duration: 0xFFFFFFFF) (latency budget: 0x00000001)
Since latency budget affect low power operation,
Unified boot cookie
Background
A cookie is needed to be set in AMSS for a number of features that are triggered from AMSS but executed in boot.
the cookie is stored in the first 2K of IRAM because the higher 2K of IRAM is used by AMSS clock switch.
Implementation
the unified boot cookie has the following set of properties:
1. A boot cookie gets set in AMSS context. Setting can be triggered from Modem or from Apps through proc.comm
2. Once the cookie is set, the boot_set_cookie API never returns. It enables WATCHDOG and goes into an infinite
loop so the phone resets and enters BOOT.
3. Reset of the phone can be avoided by using an overriding argument: reset
4. The supported boot cookies are added in an enumeration list: boot_cookie_t
5. Once in BOOT, boot_get_cookie will be called in appropriate places for the needed action.
boot_set_cookie() can be called from AMSS and it sets the boot cookie,
boot_get_cookie() can be called from Boot or AMSS and it retrieves the saved cookie.
Customization
Customer can add their own cookie per their requirement befor BOOT_COOKIE_MAX
typedef enum
{
BOOT_COOKIE_SD_IMG_UPGRADE,
BOOT_COOKIE_BACKUP,
BOOT_COOKIE_RECOVERY,
/*****************************
** ADD YOUR ENUM ABOVE THIS **
*****************************/
BOOT_COOKIE_MAX
}boot_cookie_t;
A cookie is needed to be set in AMSS for a number of features that are triggered from AMSS but executed in boot.
the cookie is stored in the first 2K of IRAM because the higher 2K of IRAM is used by AMSS clock switch.
Implementation
the unified boot cookie has the following set of properties:
1. A boot cookie gets set in AMSS context. Setting can be triggered from Modem or from Apps through proc.comm
2. Once the cookie is set, the boot_set_cookie API never returns. It enables WATCHDOG and goes into an infinite
loop so the phone resets and enters BOOT.
3. Reset of the phone can be avoided by using an overriding argument: reset
4. The supported boot cookies are added in an enumeration list: boot_cookie_t
5. Once in BOOT, boot_get_cookie will be called in appropriate places for the needed action.
boot_set_cookie() can be called from AMSS and it sets the boot cookie,
boot_get_cookie() can be called from Boot or AMSS and it retrieves the saved cookie.
Customization
Customer can add their own cookie per their requirement befor BOOT_COOKIE_MAX
typedef enum
{
BOOT_COOKIE_SD_IMG_UPGRADE,
BOOT_COOKIE_BACKUP,
BOOT_COOKIE_RECOVERY,
/*****************************
** ADD YOUR ENUM ABOVE THIS **
*****************************/
BOOT_COOKIE_MAX
}boot_cookie_t;
How to collect share memory log (smemlog)
Run smemlog.cmm in t32 by "do smemlog"
Detail: The directions to collect smemlog:
1) make sure ARM9 was build with debug symbols, you can check by looking at build\ms\xxxxxxxxxxxxm.elf file size is > 80MB
1 a) to make arm9 debug build, go to build\ms, armtools.min, search for debug and modify accordingly.
2) After the interesting event happen, wake up the device, connected with T32, halt the device.
3) copy smemlog.cmm c:\yourfolder
4) change dir in T32 to c:\yourfolder
5) run smemlog.cmm in t32 by "do smemlog" This will place several .lst files in c:\yourfolder. The smemlog.cmm script is located in the tools\debug directory. To parse the contents of these files you will need to copy the files to the tools\debug directory, then: smem_log.pl > smeminfo.txt This will output the date in a readible manner in the smeminfo.txt file.
Detail: The directions to collect smemlog:
1) make sure ARM9 was build with debug symbols, you can check by looking at build\ms\xxxxxxxxxxxxm.elf file size is > 80MB
1 a) to make arm9 debug build, go to build\ms, armtools.min, search for debug and modify accordingly.
2) After the interesting event happen, wake up the device, connected with T32, halt the device.
3) copy smemlog.cmm c:\yourfolder
4) change dir in T32 to c:\yourfolder
5) run smemlog.cmm in t32 by "do smemlog" This will place several .lst files in c:\yourfolder. The smemlog.cmm script is located in the tools\debug directory. To parse the contents of these files you will need to copy the files to the tools\debug directory, then: smem_log.pl > smeminfo.txt This will output the date in a readible manner in the smeminfo.txt file.
How can I extract a CEFS partition MODEM_ST1 and MODEM_ST2 with QRD8x25 ?
1. set FEATURE_EFS_ENABLE_FACTORY_IMAGE_SECURITY_HOLE, and download whole image and qcn file.
2. switch the device to the mass storage (download) mode, use "sudo fdisk" to find the right partition of MODEM_ST1 and MODEM_ST2, add dump it. for example:
sudo dd if=/dev/sdb10 of=./st1.bin
sudo dd if=/dev/sdb11 of=./st2.bin
3.creat a dummy file.
dd if=/dev/zero of=./dummy.bin count=1 bs=3145728
4.modify the rawprogram0.xml
+++++<program file_sector_offset="0" filename="dummy.bin" label="BACKUP" num_partition_sectors="6144" physical_partition_number="0" size_in_KB="3072.0" sparse="false" start_byte_hex="0x50ad000" start_sector="165224" />
--------<program file_sector_offset="0" filename="" label="BACKUP" num_partition_sectors="6144" physical_partition_number="0" size_in_KB="3072.0" sparse="false" start_byte_hex="0x50ad000" start_sector="165224" />
+++++<program file_sector_offset="0" filename="st1.bin" label="MODEM_ST1" num_partition_sectors="6144" physical_partition_number="0" size_in_KB="3072.0" sparse="false" start_byte_hex="0x53ad000" start_sector="171368" />
------<program file_sector_offset="0" filename="" label="MODEM_ST1" num_partition_sectors="6144" physical_partition_number="0" size_in_KB="3072.0" sparse="false" start_byte_hex="0x53ad000" start_sector="171368" />
++++<program file_sector_offset="0" filename="st2.bin" label="MODEM_ST2" num_partition_sectors="6144" physical_partition_number="0" size_in_KB="3072.0" sparse="false" start_byte_hex="0x56ad000" start_sector="177512" />
-------<program file_sector_offset="0" filename="" label="MODEM_ST2" num_partition_sectors="6144" physical_partition_number="0" size_in_KB="3072.0" sparse="false" start_byte_hex="0x56ad000" start_sector="177512" />
5. download the st1.bin and st2.bin with xml.
2. switch the device to the mass storage (download) mode, use "sudo fdisk" to find the right partition of MODEM_ST1 and MODEM_ST2, add dump it. for example:
sudo dd if=/dev/sdb10 of=./st1.bin
sudo dd if=/dev/sdb11 of=./st2.bin
3.creat a dummy file.
dd if=/dev/zero of=./dummy.bin count=1 bs=3145728
4.modify the rawprogram0.xml
+++++<program file_sector_offset="0" filename="dummy.bin" label="BACKUP" num_partition_sectors="6144" physical_partition_number="0" size_in_KB="3072.0" sparse="false" start_byte_hex="0x50ad000" start_sector="165224" />
--------<program file_sector_offset="0" filename="" label="BACKUP" num_partition_sectors="6144" physical_partition_number="0" size_in_KB="3072.0" sparse="false" start_byte_hex="0x50ad000" start_sector="165224" />
+++++<program file_sector_offset="0" filename="st1.bin" label="MODEM_ST1" num_partition_sectors="6144" physical_partition_number="0" size_in_KB="3072.0" sparse="false" start_byte_hex="0x53ad000" start_sector="171368" />
------<program file_sector_offset="0" filename="" label="MODEM_ST1" num_partition_sectors="6144" physical_partition_number="0" size_in_KB="3072.0" sparse="false" start_byte_hex="0x53ad000" start_sector="171368" />
++++<program file_sector_offset="0" filename="st2.bin" label="MODEM_ST2" num_partition_sectors="6144" physical_partition_number="0" size_in_KB="3072.0" sparse="false" start_byte_hex="0x56ad000" start_sector="177512" />
-------<program file_sector_offset="0" filename="" label="MODEM_ST2" num_partition_sectors="6144" physical_partition_number="0" size_in_KB="3072.0" sparse="false" start_byte_hex="0x56ad000" start_sector="177512" />
5. download the st1.bin and st2.bin with xml.
How to generate one image for QRD8x25?
produce the dataio, please refer to the step below:
1, Create a directory(ex:factoryimage),and copy all the ap & bp images&backupnv into it.
2. copy emmcswdownload.exe (C:\Program Files\Qualcomm\QPST\bin) into the directory .
3. run "cmd",switch to the dir "C:\Program Files\Qualcomm\QPST\bin", exec "emmcswdownload.exe -f factoryimage.bin"
4. the next action is like normal download (not emergency download) .
5, After downloading, the factoryimage will be produced in the directory.
1, Create a directory(ex:factoryimage),and copy all the ap & bp images&backupnv into it.
2. copy emmcswdownload.exe (C:\Program Files\Qualcomm\QPST\bin) into the directory .
3. run "cmd",switch to the dir "C:\Program Files\Qualcomm\QPST\bin", exec "emmcswdownload.exe -f factoryimage.bin"
4. the next action is like normal download (not emergency download) .
5, After downloading, the factoryimage will be produced in the directory.
Subscribe to:
Posts (Atom)