summaryrefslogtreecommitdiff
path: root/chip/ish/aontaskfw/ish_aontask.c
diff options
context:
space:
mode:
Diffstat (limited to 'chip/ish/aontaskfw/ish_aontask.c')
-rw-r--r--chip/ish/aontaskfw/ish_aontask.c708
1 files changed, 0 insertions, 708 deletions
diff --git a/chip/ish/aontaskfw/ish_aontask.c b/chip/ish/aontaskfw/ish_aontask.c
deleted file mode 100644
index 183c61f97a..0000000000
--- a/chip/ish/aontaskfw/ish_aontask.c
+++ /dev/null
@@ -1,708 +0,0 @@
-/* Copyright 2019 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/**
- * ISH aontask is a seprated very small program from main FW, not like main FW
- * resides in main SRAM, aontask resides in a small AON memory (ISH3 has no
- * seprated AON memory, reserved last 4KB of main SRAM for AON use, from ISH4,
- * there is seprated AON memory, 4KB for ISH4, and 8KB for ISH5).
- *
- * When ISH entered into low power states, aontask may get switched and run,
- * aontask managments the main SRAM and is responsible for store and restore
- * main FW's running context, for example, when entering D0i2 state, put main
- * SRAM into retention mode, when exit D0i2 state and before switch back to
- * main FW, put main SRAM into normal access mode, when entering D0i3 state,
- * at first stores main FW's writeable data into IMR DDR (read only code and
- * data already have copies in IMR), then power off the main SRAM completely,
- * when exit D0i3 state, at first power on the main SRAM, and restore main FW's
- * code and data from IMR to main SRAM, then switch back to main FW.
- *
- * On ISH, except the hpet timer, also have other wakeup sources, peripheral
- * events, such as gpio interrupt, uart interrupt, ipc interrupt, I2C and SPI
- * access are also can wakeup ISH. ISH's PMU (power management unit HW) will
- * manage these wakeup sources and transfer to a PMU wakeup interrupt which
- * can wakeup aontask, and aontask will handle it, when aontask got up, and
- * swiched back to main FW, main FW will receive the original wakeup source
- * interrupt which triggered the PMU wakeup interrupt in aontask, then main FW
- * handle the original interrupt normally.
- *
- * In most of the time, aontask is in halt state, and waiting for PMU wakeup
- * interrupt to wakeup (reset prep interrupt also can wakeup aontask
- * if CONFIG_ISH_PM_RESET_PREP defined), after wakeup, aontask will handle the
- * low power states exit process and finaly switch back to main FW.
- *
- * aontask is running in the 32bit protection mode with flat memory segment
- * settings, paging and cache are disabled (cache will be power gated).
- *
- * We use x86's hardware context switching mechanism for the switching of
- * main FW and aontask.
- * see https://wiki.osdev.org/Context_Switching
- * https://en.wikipedia.org/wiki/Task_state_segment
- *
- */
-
-#include "common.h"
-#include "ia_structs.h"
-#include "ish_aon_share.h"
-#include "ish_dma.h"
-#include "power_mgt.h"
-
-/**
- * ISH aontask only need handle PMU wakeup interrupt and reset prep interrupt
- * (if CONFIG_ISH_PM_RESET_PREP defined), before switch to aontask, all other
- * interrupts should be masked. Since aontask is a seprated program from
- * main FW, and the main SRAM will be power offed or will be put in in
- * retention mode, aontask need its own IDT to handle PMU wakeup interrupt and
- * reset prep interrupt (if CONFIG_ISH_PM_RESET_PREP defined)
- *
- * Due to very limit AON memory size (typically total 4KB), we don't want to
- * define and allocate whole 256 entries for aontask'IDT, that almost need 2KB
- * (256 * 8), so we just defined the only needed IDT entries:
- * AON_IDT_ENTRY_VEC_FIRST ~ AON_IDT_ENTRY_VEC_LAST
- */
-#define AON_IDT_ENTRY_VEC_FIRST ISH_PMU_WAKEUP_VEC
-
-#ifdef CONFIG_ISH_PM_RESET_PREP
-/**
- * assume reset prep interrupt vector is greater than PMU wakeup interrupt
- * vector, and also need handle reset prep interrupt
- * (if CONFIG_ISH_PM_RESET_PREP defined)
- */
-#define AON_IDT_ENTRY_VEC_LAST ISH_RESET_PREP_VEC
-#else
-/* only need handle single PMU wakeup interrupt */
-#define AON_IDT_ENTRY_VEC_LAST ISH_PMU_WAKEUP_VEC
-#endif
-
-static void handle_reset(enum ish_pm_state pm_state);
-
-/* ISR for PMU wakeup interrupt */
-static void pmu_wakeup_isr(void)
-{
- /**
- * Indicate completion of servicing the interrupt to IOAPIC first
- * then indicate completion of servicing the interrupt to LAPIC
- */
- IOAPIC_EOI_REG = ISH_PMU_WAKEUP_VEC;
- LAPIC_EOI_REG = 0x0;
-
- __asm__ volatile ("iret;");
-
- __builtin_unreachable();
-}
-
-/* ISR for reset prep interrupt */
-static void reset_prep_isr(void)
-{
- /* mask reset prep avail interrupt */
- PMU_RST_PREP = PMU_RST_PREP_INT_MASK;
-
- /**
- * Indicate completion of servicing the interrupt to IOAPIC first
- * then indicate completion of servicing the interrupt to LAPIC
- */
- IOAPIC_EOI_REG = ISH_RESET_PREP_VEC;
- LAPIC_EOI_REG = 0x0;
-
- handle_reset(ISH_PM_STATE_RESET_PREP);
-
- __builtin_unreachable();
-}
-
-/**
- * Use a static data array for aon IDT, and setting IDT header for IDTR
- * register
- *
- * Due to very limit AON memory size (typically total 4KB), we don't want to
- * define and allocate whole 256 entries for aontask'IDT, that almost need 2KB
- * (256 * 8), so we just defined the only needed IDT entries:
- * AON_IDT_ENTRY_VEC_FIRST ~ AON_IDT_ENTRY_VEC_LAST
- *
- * Since on x86, the IDT entry index (count from 0) is also the interrupt
- * vector number, for IDT header, the 'start' filed still need to point to
- * the entry 0, and 'size' must count from entry 0.
- *
- * We only allocated memory for entry AON_IDT_ENTRY_VEC_FIRST to
- * AON_IDT_ENTRY_VEC_LAST, a little trick, but works well on ISH
- *
- * ------>---------------------------<----- aon_idt_hdr.start
- * | | entry 0 |
- * | +-------------------------+
- * | | ... |
- * | +-------------------------+<-----
- * aon_idt_hdr.size | AON_IDT_ENTRY_VEC_FIRST | |
- * | +-------------------------+ |
- * | | ... | allocated memory in aon_idt
- * | +-------------------------+ |
- * | | AON_IDT_ENTRY_VEC_LAST | |
- * ------>+-------------------------+<-----
- * | ... |
- * +-------------------------+
- * | entry 255 |
- * ---------------------------
- */
-
-static struct idt_entry aon_idt[AON_IDT_ENTRY_VEC_LAST -
- AON_IDT_ENTRY_VEC_FIRST + 1];
-
-static struct idt_header aon_idt_hdr = {
-
- .limit = (sizeof(struct idt_entry) * (AON_IDT_ENTRY_VEC_LAST + 1)) - 1,
- .entries = (struct idt_entry *)((uint32_t)&aon_idt -
- (sizeof(struct idt_entry) * AON_IDT_ENTRY_VEC_FIRST))
-};
-
-/* aontask entry point function */
-void ish_aon_main(void);
-
-/**
- * 8 bytes reserved on stack, just for GDB to show the correct stack
- * information when doing source code level debuging
- */
-#define AON_SP_RESERVED (8)
-
-/* TSS segment for aon task */
-static struct tss_entry aon_tss = {
- .prev_task_link = 0,
- .reserved1 = 0,
- .esp0 = (uint8_t *)(CONFIG_AON_PERSISTENT_BASE - AON_SP_RESERVED),
- /* entry 1 in LDT for data segment */
- .ss0 = 0xc,
- .reserved2 = 0,
- .esp1 = 0,
- .ss1 = 0,
- .reserved3 = 0,
- .esp2 = 0,
- .ss2 = 0,
- .reserved4 = 0,
- .cr3 = 0,
- /* task excute entry point */
- .eip = (uint32_t)&ish_aon_main,
- .eflags = 0,
- .eax = 0,
- .ecx = 0,
- .edx = 0,
- .ebx = 0,
- /* set stack top pointer at the end of usable aon memory */
- .esp = CONFIG_AON_PERSISTENT_BASE - AON_SP_RESERVED,
- .ebp = CONFIG_AON_PERSISTENT_BASE - AON_SP_RESERVED,
- .esi = 0,
- .edi = 0,
- /* entry 1 in LDT for data segment */
- .es = 0xc,
- .reserved5 = 0,
- /* entry 0 in LDT for code segment */
- .cs = 0x4,
- .reserved6 = 0,
- /* entry 1 in LDT for data segment */
- .ss = 0xc,
- .reserved7 = 0,
- /* entry 1 in LDT for data segment */
- .ds = 0xc,
- .reserved8 = 0,
- /* entry 1 in LDT for data segment */
- .fs = 0xc,
- .reserved9 = 0,
- /* entry 1 in LDT for data segment */
- .gs = 0xc,
- .reserved10 = 0,
- .ldt_seg_selector = 0,
- .reserved11 = 0,
- .trap_debug = 0,
-
- /**
- * TSS's limit specified as 0x67, to allow the task has permission to
- * access I/O port using IN/OUT instructions,'iomap_base_addr' field
- * must be greater than or equal to TSS' limit
- * see 'I/O port permissions' on
- * https://en.wikipedia.org/wiki/Task_state_segment
- */
- .iomap_base_addr = GDT_DESC_TSS_LIMIT
-};
-
-/**
- * define code and data LDT segements for aontask
- * code : base = 0x0, limit = 0xFFFFFFFF, Present = 1, DPL = 0
- * data : base = 0x0, limit = 0xFFFFFFFF, Present = 1, DPL = 0
- */
-static ldt_entry aon_ldt[2] = {
-
- /**
- * entry 0 for code segment
- * base: 0x0
- * limit: 0xFFFFFFFF
- * flag: 0x9B, Present = 1, DPL = 0, code segment
- */
- {
- .dword_lo = GEN_GDT_DESC_LO(0x0, 0xFFFFFFFF,
- GDT_DESC_CODE_FLAGS),
-
- .dword_up = GEN_GDT_DESC_UP(0x0, 0xFFFFFFFF,
- GDT_DESC_CODE_FLAGS)
- },
-
- /**
- * entry 1 for data segment
- * base: 0x0
- * limit: 0xFFFFFFFF
- * flag: 0x93, Present = 1, DPL = 0, data segment
- */
- {
- .dword_lo = GEN_GDT_DESC_LO(0x0, 0xFFFFFFFF,
- GDT_DESC_DATA_FLAGS),
-
- .dword_up = GEN_GDT_DESC_UP(0x0, 0xFFFFFFFF,
- GDT_DESC_DATA_FLAGS)
- }
-};
-
-
-/* shared data structure between main FW and aon task */
-struct ish_aon_share aon_share = {
- .magic_id = AON_MAGIC_ID,
- .error_count = 0,
- .last_error = AON_SUCCESS,
- .aon_tss = &aon_tss,
- .aon_ldt = &aon_ldt[0],
- .aon_ldt_size = sizeof(aon_ldt),
-};
-
-/* snowball structure */
-#if defined(CHIP_FAMILY_ISH3)
-/* on ISH3, reused ISH2PMC IPC message registers */
-#define SNOWBALL_BASE IPC_ISH2PMC_MSG_BASE
-#else
-/* from ISH4, used reserved rom part of AON memory */
-#define SNOWBALL_BASE (CONFIG_AON_PERSISTENT_BASE + 256)
-#endif
-
-struct snowball_struct *snowball = (void *)SNOWBALL_BASE;
-
-
-/* In IMR DDR, ISH FW image has a manifest header */
-#define ISH_FW_IMAGE_MANIFEST_HEADER_SIZE (0x1000)
-
-/* simple count based delay */
-static inline void delay(uint32_t count)
-{
- while (count)
- count--;
-}
-
-static int store_main_fw(void)
-{
- int ret;
- uint64_t imr_fw_addr;
- uint64_t imr_fw_rw_addr;
-
- imr_fw_addr = (((uint64_t)snowball->uma_base_hi << 32) +
- snowball->uma_base_lo +
- snowball->fw_offset +
- ISH_FW_IMAGE_MANIFEST_HEADER_SIZE);
-
- imr_fw_rw_addr = (imr_fw_addr
- + aon_share.main_fw_rw_addr
- - CONFIG_RAM_BASE);
-
- /* disable BCG (Block Clock Gating) for DMA, DMA can be accessed now */
- CCU_BCG_EN = CCU_BCG_EN & ~CCU_BCG_BIT_DMA;
-
- /* store main FW's read and write data region to IMR/UMA DDR */
- ret = ish_dma_copy(
- PAGING_CHAN,
- imr_fw_rw_addr,
- aon_share.main_fw_rw_addr,
- aon_share.main_fw_rw_size,
- SRAM_TO_UMA);
-
- /* enable BCG for DMA, DMA can't be accessed now */
- CCU_BCG_EN = CCU_BCG_EN | CCU_BCG_BIT_DMA;
-
- if (ret != DMA_RC_OK) {
-
- aon_share.last_error = AON_ERROR_DMA_FAILED;
- aon_share.error_count++;
-
- return AON_ERROR_DMA_FAILED;
- }
-
- return AON_SUCCESS;
-}
-
-static int restore_main_fw(void)
-{
- int ret;
- uint64_t imr_fw_addr;
- uint64_t imr_fw_ro_addr;
- uint64_t imr_fw_rw_addr;
-
- imr_fw_addr = (((uint64_t)snowball->uma_base_hi << 32) +
- snowball->uma_base_lo +
- snowball->fw_offset +
- ISH_FW_IMAGE_MANIFEST_HEADER_SIZE);
-
- imr_fw_ro_addr = (imr_fw_addr
- + aon_share.main_fw_ro_addr
- - CONFIG_RAM_BASE);
-
- imr_fw_rw_addr = (imr_fw_addr
- + aon_share.main_fw_rw_addr
- - CONFIG_RAM_BASE);
-
- /* disable BCG (Block Clock Gating) for DMA, DMA can be accessed now */
- CCU_BCG_EN = CCU_BCG_EN & ~CCU_BCG_BIT_DMA;
-
- /* restore main FW's read only code and data region from IMR/UMA DDR */
- ret = ish_dma_copy(
- PAGING_CHAN,
- aon_share.main_fw_ro_addr,
- imr_fw_ro_addr,
- aon_share.main_fw_ro_size,
- UMA_TO_SRAM);
-
- if (ret != DMA_RC_OK) {
-
- aon_share.last_error = AON_ERROR_DMA_FAILED;
- aon_share.error_count++;
-
- /* enable BCG for DMA, DMA can't be accessed now */
- CCU_BCG_EN = CCU_BCG_EN | CCU_BCG_BIT_DMA;
-
- return AON_ERROR_DMA_FAILED;
- }
-
- /* restore main FW's read and write data region from IMR/UMA DDR */
- ret = ish_dma_copy(
- PAGING_CHAN,
- aon_share.main_fw_rw_addr,
- imr_fw_rw_addr,
- aon_share.main_fw_rw_size,
- UMA_TO_SRAM
- );
-
- /* enable BCG for DMA, DMA can't be accessed now */
- CCU_BCG_EN = CCU_BCG_EN | CCU_BCG_BIT_DMA;
-
- if (ret != DMA_RC_OK) {
-
- aon_share.last_error = AON_ERROR_DMA_FAILED;
- aon_share.error_count++;
-
- return AON_ERROR_DMA_FAILED;
- }
-
- return AON_SUCCESS;
-}
-
-#if defined(CHIP_FAMILY_ISH3)
-/* on ISH3, the last SRAM bank is reserved for AON use */
-#define SRAM_POWER_OFF_BANKS (CONFIG_RAM_BANKS - 1)
-#elif defined(CHIP_FAMILY_ISH4) || defined(CHIP_FAMILY_ISH5)
-/* ISH4 and ISH5 have separate AON memory, can power off entire main SRAM */
-#define SRAM_POWER_OFF_BANKS CONFIG_RAM_BANKS
-#else
-#error "CHIP_FAMILY_ISH(3|4|5) must be defined"
-#endif
-
-/**
- * check SRAM bank i power gated status in PMU_SRAM_PG_EN register
- * 1: power gated 0: not power gated
- */
-#define BANK_PG_STATUS(i) (PMU_SRAM_PG_EN & (0x1 << (i)))
-
-/* enable power gate of a SRAM bank */
-#define BANK_PG_ENABLE(i) (PMU_SRAM_PG_EN |= (0x1 << (i)))
-
-/* disable power gate of a SRAM bank */
-#define BANK_PG_DISABLE(i) (PMU_SRAM_PG_EN &= ~(0x1 << (i)))
-
-/**
- * check SRAM bank i disabled status in ISH_SRAM_CTRL_CSFGR register
- * 1: disabled 0: enabled
- */
-#define BANK_DISABLE_STATUS(i) (ISH_SRAM_CTRL_CSFGR & (0x1 << ((i) + 4)))
-
-/* enable a SRAM bank in ISH_SRAM_CTRL_CSFGR register */
-#define BANK_ENABLE(i) (ISH_SRAM_CTRL_CSFGR &= ~(0x1 << ((i) + 4)))
-
-/* disable a SRAM bank in ISH_SRAM_CTRL_CSFGR register */
-#define BANK_DISABLE(i) (ISH_SRAM_CTRL_CSFGR |= (0x1 << ((i) + 4)))
-
-/* SRAM needs time to warm up after power on */
-#define SRAM_WARM_UP_DELAY_CNT 10
-
-/* SRAM needs time to enter retention mode */
-#define CYCLES_PER_US 100
-#define SRAM_RETENTION_US_DELAY 5
-#define SRAM_RETENTION_CYCLES_DELAY (SRAM_RETENTION_US_DELAY * CYCLES_PER_US)
-
-static void sram_power(int on)
-{
- int i;
- uint32_t bank_size;
- uint32_t sram_addr;
- uint32_t erase_cfg;
-
- bank_size = CONFIG_RAM_BANK_SIZE;
- sram_addr = CONFIG_RAM_BASE;
-
- /**
- * set erase size as one bank, erase control register using DWORD as
- * size unit, and using 0 based length, i.e if set 0, will erase one
- * DWORD
- */
- erase_cfg = (((bank_size - 4) >> 2) << 2) | 0x1;
-
- for (i = 0; i < SRAM_POWER_OFF_BANKS; i++) {
-
- if (on && (BANK_PG_STATUS(i) || BANK_DISABLE_STATUS(i))) {
-
- /* power on and enable a bank */
- BANK_PG_DISABLE(i);
-
- delay(SRAM_WARM_UP_DELAY_CNT);
-
- BANK_ENABLE(i);
-
- /* erase a bank */
- ISH_SRAM_CTRL_ERASE_ADDR = sram_addr + (i * bank_size);
- ISH_SRAM_CTRL_ERASE_CTRL = erase_cfg;
-
- /* wait erase complete */
- while (ISH_SRAM_CTRL_ERASE_CTRL & 0x1)
- continue;
-
- } else {
- /* disable and power off a bank */
- BANK_DISABLE(i);
- BANK_PG_ENABLE(i);
- }
-
- /**
- * clear interrupt status register, not allow generate SRAM
- * interrupts. Bringup already masked all SRAM interrupts when
- * booting ISH
- */
- ISH_SRAM_CTRL_INTR = 0xFFFFFFFF;
-
- }
-}
-
-static void handle_d0i2(void)
-{
- /* set main SRAM into retention mode*/
- PMU_LDO_CTRL = PMU_LDO_ENABLE_BIT
- | PMU_LDO_RETENTION_BIT;
-
- /* delay some cycles before halt */
- delay(SRAM_RETENTION_CYCLES_DELAY);
-
- ish_mia_halt();
- /* wakeup from PMU interrupt */
-
- /* set main SRAM intto normal mode */
- PMU_LDO_CTRL = PMU_LDO_ENABLE_BIT;
-
- /**
- * poll LDO_READY status to make sure SRAM LDO is on
- * (exited retention mode)
- */
- while (!(PMU_LDO_CTRL & PMU_LDO_READY_BIT))
- continue;
-}
-
-static void handle_d0i3(void)
-{
- int ret;
-
- /* store main FW 's context to IMR DDR from main SRAM */
- ret = store_main_fw();
-
- /* if store main FW failed, then switch back to main FW */
- if (ret != AON_SUCCESS)
- return;
-
- /* power off main SRAM */
- sram_power(0);
-
- ish_mia_halt();
- /* wakeup from PMU interrupt */
-
- /* power on main SRAM */
- sram_power(1);
-
- /* restore main FW 's context to main SRAM from IMR DDR */
- ret = restore_main_fw();
-
- if (ret != AON_SUCCESS) {
- /* we can't switch back to main FW now, reset ISH */
- handle_reset(ISH_PM_STATE_RESET);
- }
-}
-
-static void handle_d3(void)
-{
- /* handle D3 */
- handle_reset(ISH_PM_STATE_RESET);
-}
-
-static void handle_reset(enum ish_pm_state pm_state)
-{
- /* disable watch dog */
- WDT_CONTROL &= ~WDT_CONTROL_ENABLE_BIT;
-
- /* disable all gpio interrupts */
- ISH_GPIO_GRER = 0;
- ISH_GPIO_GFER = 0;
- ISH_GPIO_GIMR = 0;
-
- /* disable CSME CSR irq */
- IPC_PIMR &= ~IPC_PIMR_CSME_CSR_BIT;
-
- /* power off main SRAM */
- sram_power(0);
-
- while (1) {
- /**
- * check if host ish driver already set the DMA enable flag
- *
- * ISH FW and ISH ipc host driver using IPC_ISH_RMP2 register
- * for synchronization during ISH boot.
- * ISH ipc host driver will set DMA_ENABLED_MASK bit when it
- * is loaded and starts, and clear this bit when it is removed.
- *
- * see: https://github.com/torvalds/linux/blob/master/drivers/
- * hid/intel-ish-hid/ipc/ipc.c
- *
- * we have two kinds of reset situations need to handle here:
- * 1: reset ISH via uart console cmd or ectool host cmd
- * 2: S0 -> Sx (reset_prep interrupt)
- *
- * for #1, ISH ipc host driver no changed states,
- * DMA_ENABLED_MASK bit always set, so, will reset ISH directly
- *
- * for #2, ISH ipc host driver changed states, and cleared
- * DMA_ENABLED_MASK bit, then ISH FW received reset_prep
- * interrupt, ISH will stay in this while loop (most time in
- * halt state), waiting for DMA_ENABLED_MASK bit was set and
- * reset ISH then. Since ISH ROM have no power managment, stay
- * in aontask can save more power especially if system stay in
- * Sx for long time.
- *
- */
- if (IPC_ISH_RMP2 & DMA_ENABLED_MASK) {
-
- /* clear ISH2HOST doorbell register */
- *IPC_ISH2HOST_DOORBELL_ADDR = 0;
-
- /* clear error register in MISC space */
- MISC_ISH_ECC_ERR_SRESP = 1;
-
- /*
- * Disable power gating of RF(Cache) and ROMs.
- *
- * Before switch to aon task, RF and ROMs are already
- * power gated, so we need disable the power gating
- * before reset to ROM, to make sure ROM code runs
- * correctly.
- */
- PMU_RF_ROM_PWR_CTRL = 0;
-
- /* reset ISH minute-ia cpu core, will goto ISH ROM */
- ish_mia_reset();
-
- __builtin_unreachable();
- }
-
- ish_mia_halt();
- }
-
-}
-
-static void handle_unknown_state(void)
-{
- aon_share.last_error = AON_ERROR_NOT_SUPPORT_POWER_MODE;
- aon_share.error_count++;
-
- /* switch back to main FW */
-}
-
-void ish_aon_main(void)
-{
-
- /* set PMU wakeup interrupt gate using LDT code segment selector(0x4) */
- aon_idt[0].dword_lo = GEN_IDT_DESC_LO(&pmu_wakeup_isr, 0x4,
- IDT_DESC_FLAGS);
-
- aon_idt[0].dword_up = GEN_IDT_DESC_UP(&pmu_wakeup_isr, 0x4,
- IDT_DESC_FLAGS);
-
- if (IS_ENABLED(CONFIG_ISH_PM_RESET_PREP)) {
- /*
- * set reset prep interrupt gate using LDT code segment
- * selector(0x4)
- */
- aon_idt[AON_IDT_ENTRY_VEC_LAST - AON_IDT_ENTRY_VEC_FIRST]
- .dword_lo =
- GEN_IDT_DESC_LO(&reset_prep_isr, 0x4, IDT_DESC_FLAGS);
-
- aon_idt[AON_IDT_ENTRY_VEC_LAST - AON_IDT_ENTRY_VEC_FIRST]
- .dword_up =
- GEN_IDT_DESC_UP(&reset_prep_isr, 0x4, IDT_DESC_FLAGS);
- }
-
- while (1) {
-
- /**
- * will start to run from here when switched to aontask from
- * the second time
- */
-
- /* save main FW's IDT and load aontask's IDT */
- __asm__ volatile (
- "sidtl %0;\n"
- "lidtl %1;\n"
- :
- : "m" (aon_share.main_fw_idt_hdr),
- "m" (aon_idt_hdr)
- );
-
- aon_share.last_error = AON_SUCCESS;
-
- switch (aon_share.pm_state) {
- case ISH_PM_STATE_D0I2:
- handle_d0i2();
- break;
- case ISH_PM_STATE_D0I3:
- handle_d0i3();
- break;
- case ISH_PM_STATE_D3:
- handle_d3();
- break;
- case ISH_PM_STATE_RESET:
- case ISH_PM_STATE_RESET_PREP:
- handle_reset(aon_share.pm_state);
- break;
- default:
- handle_unknown_state();
- break;
- }
-
- /* check if D3 rising status */
- if (PMU_D3_STATUS &
- (PMU_D3_BIT_RISING_EDGE_STATUS | PMU_D3_BIT_SET)) {
- aon_share.pm_state = ISH_PM_STATE_D3;
- handle_d3();
- }
-
- /* restore main FW's IDT and switch back to main FW */
- __asm__ volatile(
- "lidtl %0;\n"
- "iret;"
- :
- : "m" (aon_share.main_fw_idt_hdr)
- );
- }
-}