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_hang(void);
void __attribute__((noreturn)) sbi_hart_boot_next(unsigned long arg0, void __attribute__((noreturn)) sbi_hart_switch_mode(unsigned long arg0,
unsigned long arg1, unsigned long arg1,
unsigned long next_addr, unsigned long next_addr,
unsigned long next_mode); unsigned long next_mode);
void sbi_hart_mark_available(u32 hartid); void sbi_hart_mark_available(u32 hartid);

View file

@ -205,37 +205,52 @@ void __attribute__((noreturn)) sbi_hart_hang(void)
__builtin_unreachable(); __builtin_unreachable();
} }
void __attribute__((noreturn)) sbi_hart_boot_next(unsigned long arg0, void __attribute__((noreturn)) sbi_hart_switch_mode(unsigned long arg0,
unsigned long arg1, unsigned long arg1,
unsigned long next_addr, unsigned long next_addr,
unsigned long next_mode) unsigned long next_mode)
{ {
unsigned long val; unsigned long val;
char mode = 'M';
if (next_mode != PRV_S && next_mode != PRV_M && next_mode != PRV_U) switch (next_mode) {
sbi_hart_hang(); case PRV_M:
if (next_mode == PRV_S && !misa_extension('S')) break;
sbi_hart_hang(); case PRV_S:
if (next_mode == PRV_U && !misa_extension('U')) 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(); sbi_hart_hang();
}
val = csr_read(mstatus); val = csr_read(mstatus);
val = INSERT_FIELD(val, MSTATUS_MPP, next_mode); val = INSERT_FIELD(val, MSTATUS_MPP, next_mode);
val = INSERT_FIELD(val, MSTATUS_MPIE, 0); val = INSERT_FIELD(val, MSTATUS_MPIE, 0);
csr_write(mstatus, val); csr_write(mstatus, val);
csr_write(mepc, next_addr); csr_write(mepc, next_addr);
if (next_mode == PRV_S) { if (next_mode == PRV_S) {
mode = 'S';
csr_write(stvec, next_addr); csr_write(stvec, next_addr);
csr_write(sscratch, 0); csr_write(sscratch, 0);
csr_write(sie, 0); csr_write(sie, 0);
csr_write(satp, 0); csr_write(satp, 0);
} else if (next_mode == PRV_U) { } else if (next_mode == PRV_U) {
mode = 'U';
csr_write(utvec, next_addr); csr_write(utvec, next_addr);
csr_write(uscratch, 0); csr_write(uscratch, 0);
csr_write(uie, 0); csr_write(uie, 0);
} }
sbi_printf("\nSwitching to %c-mode...\n\n", mode);
register unsigned long a0 asm ("a0") = arg0; register unsigned long a0 asm ("a0") = arg0;
register unsigned long a1 asm ("a1") = arg1; register unsigned long a1 asm ("a1") = arg1;
__asm__ __volatile__ ("mret" : : "r" (a0), "r" (a1)); __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)) if (!sbi_platform_has_hart_hotplug(plat))
sbi_hart_wake_coldboot_harts(scratch, hartid); sbi_hart_wake_coldboot_harts(scratch, hartid);
sbi_hart_boot_next(hartid, scratch->next_arg1, sbi_hart_switch_mode(hartid, scratch->next_arg1,
scratch->next_addr, scratch->next_mode); scratch->next_addr, scratch->next_mode);
} }
static void __attribute__((noreturn)) init_warmboot(struct sbi_scratch *scratch, 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. */ /* TODO: To be implemented in-future. */
sbi_hart_hang(); sbi_hart_hang();
else else
sbi_hart_boot_next(hartid, scratch->next_arg1, sbi_hart_switch_mode(hartid, scratch->next_arg1,
scratch->next_addr, scratch->next_mode); scratch->next_addr, scratch->next_mode);
} }
static atomic_t coldboot_lottery = ATOMIC_INITIALIZER(0); static atomic_t coldboot_lottery = ATOMIC_INITIALIZER(0);