From 45a7c5cf8ff59a917bd7dda6ccd3f14dbab2c4dd Mon Sep 17 00:00:00 2001 From: Leifu Zhao Date: Fri, 24 Apr 2020 18:59:12 +0800 Subject: 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 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2164091 Reviewed-by: Leifu Zhao Reviewed-by: Jack Rosenthal Tested-by: Leifu Zhao Commit-Queue: Jack Rosenthal Auto-Submit: Leifu Zhao --- chip/ish/aontaskfw/ipapg.S | 130 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100755 chip/ish/aontaskfw/ipapg.S (limited to 'chip/ish/aontaskfw/ipapg.S') 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 -- cgit v1.2.1