summaryrefslogtreecommitdiff
path: root/chip/ish/aontaskfw/ipapg.S
diff options
context:
space:
mode:
authorLeifu Zhao <leifu.zhao@intel.com>2020-04-24 18:59:12 +0800
committerCommit Bot <commit-bot@chromium.org>2020-05-15 19:20:48 +0000
commit45a7c5cf8ff59a917bd7dda6ccd3f14dbab2c4dd (patch)
treee6a355c05fc0ae6f6bf5a21ffcbb2ddd9d500d33 /chip/ish/aontaskfw/ipapg.S
parentc828740d6050fc40cf1b881374679ebf0e4b5666 (diff)
downloadchrome-ec-45a7c5cf8ff59a917bd7dda6ccd3f14dbab2c4dd.tar.gz
ish: enable IPAPG for ish 5.4 on tgl rvp platform
Enable ip accessible power gating for ish 5.4 on tgl rvp platform. BUG=b:154891699 BRANCH=none TEST=ISH can successfully enter into IPAPG on tgl rvp. Change-Id: Iee30124a0928389f4c75dffff065fab7a5a2d970 Signed-off-by: Leifu Zhao <leifu.zhao@intel.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2164091 Reviewed-by: Leifu Zhao <leifu.zhao@intel.corp-partner.google.com> Reviewed-by: Jack Rosenthal <jrosenth@chromium.org> Tested-by: Leifu Zhao <leifu.zhao@intel.corp-partner.google.com> Commit-Queue: Jack Rosenthal <jrosenth@chromium.org> Auto-Submit: Leifu Zhao <leifu.zhao@intel.corp-partner.google.com>
Diffstat (limited to 'chip/ish/aontaskfw/ipapg.S')
-rwxr-xr-xchip/ish/aontaskfw/ipapg.S130
1 files changed, 130 insertions, 0 deletions
diff --git a/chip/ish/aontaskfw/ipapg.S b/chip/ish/aontaskfw/ipapg.S
new file mode 100755
index 0000000000..f0d3f8c554
--- /dev/null
+++ b/chip/ish/aontaskfw/ipapg.S
@@ -0,0 +1,130 @@
+/* Copyright 2020 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.
+ */
+
+#include "registers.h"
+
+ .equ PMU_STATUS_PG, (1 << 4)
+ .equ PMU_STATUS_PG_AON, (1 << 5)
+
+ .equ PMU_PG_EN, (1 << 0)
+ .equ PMU_PG_EXIT_COMPLETE, (1 << 8)
+
+ .equ FWST_AON_STATE_MASK, (0x7 << 24)
+ .equ FWST_AON_STATE_HALT, (0x2 << 24)
+
+ .equ EFLAGS_NT, (1 << 14)
+
+ .equ TSS_ESP0_OFFSET, 0x4
+ .equ TSS_LDT_SEG_SEL_OFFSET, 0x60
+
+ .equ AON_CS, 0x4
+ .equ AON_DS, 0xc
+
+
+ .global ipapg
+ipapg:
+ push %ebp
+ push %edi
+ push %esi
+ push %ebx
+ mov %cr0, %eax
+ push %eax
+ mov %cr4, %eax
+ push %eax
+
+ clts
+
+ #write down return address for ROM
+ movl $(PMU_STATUS_PG|PMU_STATUS_PG_AON), PMU_STATUS_REG_ADDR
+ movl $out_of_pg, %eax
+ movl %eax, PMU_SCRATCHPAD0_REG_ADDR
+ movl (%eax), %eax
+ movl %eax, PMU_SCRATCHPAD1_REG_ADDR
+
+ #enable IPAPG, we will actually enter PG on the next halt
+ movl $(PMU_PG_EN|PMU_PG_EXIT_COMPLETE), PMU_PG_EN_REG_ADDR
+
+ #save esp so we can restore stack after returning from ROM
+ lea aon_tss, %eax
+ movl %esp, TSS_ESP0_OFFSET(%eax)
+
+ sti
+ hlt
+
+ #unreachable
+
+
+ #got out of IPAPG, jumped here from ROM if there was no abort condition
+out_of_pg:
+ cli
+
+ #restore stack
+ lea aon_tss, %eax
+ movl TSS_ESP0_OFFSET(%eax), %esp
+
+ #set the nested task bit in eflags
+ pushfl
+ orl $EFLAGS_NT, (%esp)
+ popfl
+
+ clts
+ fninit
+
+ #restore non-volatile registers and CR0 & CR4
+ pop %eax
+ mov %eax, %cr4
+ pop %eax
+ mov %eax, %cr0
+ pop %ebx
+ pop %esi
+ pop %edi
+ pop %ebp
+
+ #check if we're indeed after IPAPG exit
+ testl $PMU_STATUS_PG, PMU_STATUS_REG_ADDR
+ jz after_pg
+
+ #we didn't go through ROM, clear PG_EN bit and return an abort condition to AON
+ movl $0, PMU_PG_EN_REG_ADDR
+ movl $0, %eax
+ jmp return_to_aon
+
+after_pg:
+ #return to caller that we got ouf of PG
+ movl $1, %eax
+
+return_to_aon:
+ movl $0, PMU_STATUS_REG_ADDR
+
+ #return to AON task (still with ROM GDT and segments in case of PG exit)
+ ret
+
+ .global pg_exit_save_ctx
+pg_exit_save_ctx:
+ sgdtl mainfw_gdt
+ str tr
+ ret
+
+ .global pg_exit_restore_ctx
+pg_exit_restore_ctx:
+
+ #load RTOS GDT and AON task
+ lgdtl mainfw_gdt
+ ltr tr
+
+ #load AON LDT and segments
+ lea aon_tss, %eax
+ lldt TSS_LDT_SEG_SEL_OFFSET(%eax)
+ mov $AON_DS, %ax
+ mov %ax, %ds
+ mov %ax, %es
+ mov %ax, %fs
+ mov %ax, %gs
+ mov %ax, %ss
+ ljmpl $AON_CS, $cont
+
+cont:
+ nop
+ ret