Cleanup and rename sbi_hart_boot_next()

Cleanup sbi_hart_boot_nexti() code, adding messages for clarity and
rename the function to sbi_hart_switch_mode() to reflect what the
function actually does.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
This commit is contained in:
Damien Le Moal 2018-12-21 16:44:53 +09:00
parent 4fb23c49eb
commit 426adf9f60
3 changed files with 32 additions and 17 deletions

View file

@ -20,10 +20,10 @@ void sbi_hart_pmp_dump(struct sbi_scratch *scratch);
void __attribute__((noreturn)) sbi_hart_hang(void);
void __attribute__((noreturn)) sbi_hart_boot_next(unsigned long arg0,
unsigned long arg1,
unsigned long next_addr,
unsigned long next_mode);
void __attribute__((noreturn)) sbi_hart_switch_mode(unsigned long arg0,
unsigned long arg1,
unsigned long next_addr,
unsigned long next_mode);
void sbi_hart_mark_available(u32 hartid);

View file

@ -205,37 +205,52 @@ void __attribute__((noreturn)) sbi_hart_hang(void)
__builtin_unreachable();
}
void __attribute__((noreturn)) sbi_hart_boot_next(unsigned long arg0,
unsigned long arg1,
unsigned long next_addr,
unsigned long next_mode)
void __attribute__((noreturn)) sbi_hart_switch_mode(unsigned long arg0,
unsigned long arg1,
unsigned long next_addr,
unsigned long next_mode)
{
unsigned long val;
char mode = 'M';
if (next_mode != PRV_S && next_mode != PRV_M && next_mode != PRV_U)
sbi_hart_hang();
if (next_mode == PRV_S && !misa_extension('S'))
sbi_hart_hang();
if (next_mode == PRV_U && !misa_extension('U'))
switch (next_mode) {
case PRV_M:
break;
case PRV_S:
if (!misa_extension('S'))
sbi_hart_hang();
break;
case PRV_U:
if (!misa_extension('U'))
sbi_hart_hang();
break;
default:
sbi_printf("\nTrying to switch to unsupported mode\n");
sbi_hart_hang();
}
val = csr_read(mstatus);
val = INSERT_FIELD(val, MSTATUS_MPP, next_mode);
val = INSERT_FIELD(val, MSTATUS_MPIE, 0);
csr_write(mstatus, val);
csr_write(mepc, next_addr);
if (next_mode == PRV_S) {
mode = 'S';
csr_write(stvec, next_addr);
csr_write(sscratch, 0);
csr_write(sie, 0);
csr_write(satp, 0);
} else if (next_mode == PRV_U) {
mode = 'U';
csr_write(utvec, next_addr);
csr_write(uscratch, 0);
csr_write(uie, 0);
}
sbi_printf("\nSwitching to %c-mode...\n\n", mode);
register unsigned long a0 asm ("a0") = arg0;
register unsigned long a1 asm ("a1") = arg1;
__asm__ __volatile__ ("mret" : : "r" (a0), "r" (a1));

View file

@ -111,8 +111,8 @@ static void __attribute__((noreturn)) init_coldboot(struct sbi_scratch *scratch,
if (!sbi_platform_has_hart_hotplug(plat))
sbi_hart_wake_coldboot_harts(scratch, hartid);
sbi_hart_boot_next(hartid, scratch->next_arg1,
scratch->next_addr, scratch->next_mode);
sbi_hart_switch_mode(hartid, scratch->next_arg1,
scratch->next_addr, scratch->next_mode);
}
static void __attribute__((noreturn)) init_warmboot(struct sbi_scratch *scratch,
@ -154,8 +154,8 @@ static void __attribute__((noreturn)) init_warmboot(struct sbi_scratch *scratch,
/* TODO: To be implemented in-future. */
sbi_hart_hang();
else
sbi_hart_boot_next(hartid, scratch->next_arg1,
scratch->next_addr, scratch->next_mode);
sbi_hart_switch_mode(hartid, scratch->next_arg1,
scratch->next_addr, scratch->next_mode);
}
static atomic_t coldboot_lottery = ATOMIC_INITIALIZER(0);