mirror of
https://gitlab.com/qemu-project/SLOF.git
synced 2024-06-25 11:36:33 +08:00

When running a pseries guest in PR KVM on top of pHyp, sc 1 instructions are handled directly by pHyp, so we don't get to see them. That means we need to get inventive. Invent a new instruction that behaves like sc 1, but really is a reserved instruction that traps. This instruction can be used by KVM to emulate sc 1 behavior. This patch adds the SLOF support for it. With this, SLOF detects whether it's running on such a broken setup and if so patches itself to execute the fake sc 1 instruction instead of the real one. Furthermore, we also hook into "quiesce" which Linux calls when it boots. This gives us the chance to also patch Linux when it boots up, so it uses the fake sc 1 too. Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
60 lines
1.7 KiB
ArmAsm
60 lines
1.7 KiB
ArmAsm
/******************************************************************************
|
|
* Copyright (c) 2004, 2011 IBM Corporation
|
|
* All rights reserved.
|
|
* This program and the accompanying materials
|
|
* are made available under the terms of the BSD License
|
|
* which accompanies this distribution, and is available at
|
|
* http://www.opensource.org/licenses/bsd-license.php
|
|
*
|
|
* Contributors:
|
|
* IBM Corporation - initial implementation
|
|
*****************************************************************************/
|
|
|
|
#include <cpu.h>
|
|
#include <xvect.h>
|
|
|
|
.section ".slof.loader","ax"
|
|
|
|
/* this only works if paflof is running below 4GB */
|
|
lis r31, fdt_start@h /* save address of */
|
|
ori r31, r31, fdt_start@l /* flattened device */
|
|
std r3, 0(r31) /* tree */
|
|
|
|
/* this only works if paflof is running below 4GB */
|
|
lis r31, romfs_base@h /* save address of */
|
|
ori r31, r31, romfs_base@l /* the romfs */
|
|
std r4, 0(r31)
|
|
|
|
/* this only works if paflof is running below 4GB */
|
|
lis r31, epapr_magic@h /* if it is an epapr compliant */
|
|
ori r31, r31, epapr_magic@l /* low level firmware; then r6 */
|
|
std r6, 0(r31) /* contains the epapr magic */
|
|
|
|
/* this only works if paflof is running below 4GB */
|
|
lis r31, epapr_ima_size@h
|
|
ori r31, r31, epapr_ima_size@l
|
|
std r7, 0(r31) /* r7 contains the IMA size */
|
|
|
|
/* fill in handler address */
|
|
|
|
/* this only works if paflof is running below 4GB */
|
|
mfmsr r0
|
|
mtsrr1 r0
|
|
lis r3, _slof_text@h
|
|
ori r3, r3, _slof_text@l
|
|
ld r3, 0(r3)
|
|
std r3, XVECT_M_HANDLER(0)
|
|
|
|
#ifdef BROKEN_SC1
|
|
/* Patch potentially broken sc 1 instructions */
|
|
lis r3, _slof_text@h
|
|
ori r3, r3, _slof_text@l
|
|
lis r4, _slof_text_end@h
|
|
ori r4, r4, _slof_text_end@l
|
|
li r5, 0
|
|
bl .patch_broken_sc1
|
|
#endif
|
|
|
|
/* GO! */
|
|
ba 0x100
|