2015-08-27 00:28:04 +02:00
|
|
|
/*
|
|
|
|
* Early initialization code for riscv virtual memory
|
|
|
|
*
|
|
|
|
* Copyright 2015 Google Inc.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
|
|
|
* published by the Free Software Foundation; version 2 of
|
|
|
|
* the License.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <arch/encoding.h>
|
2016-07-26 01:54:34 +02:00
|
|
|
#include <stdint.h>
|
|
|
|
#include <vm.h>
|
2015-08-27 00:28:04 +02:00
|
|
|
|
2016-11-12 16:31:16 +01:00
|
|
|
/* Delegate controls which traps are delegated to the payload. If you
|
|
|
|
* wish to temporarily disable some or all delegation you can, in a
|
|
|
|
* debugger, set it to a different value (e.g. 0 to have all traps go
|
|
|
|
* to M-mode). In practice, this variable has been a lifesaver. It is
|
|
|
|
* still not quite determined which delegation might by unallowed by
|
|
|
|
* the spec so for now we enumerate and set them all. */
|
|
|
|
static int delegate = 0
|
|
|
|
| (1 << CAUSE_MISALIGNED_FETCH)
|
2018-02-16 13:36:46 +01:00
|
|
|
| (1 << CAUSE_FETCH_ACCESS)
|
2016-11-12 16:31:16 +01:00
|
|
|
| (1 << CAUSE_ILLEGAL_INSTRUCTION)
|
|
|
|
| (1 << CAUSE_BREAKPOINT)
|
2018-02-16 13:36:46 +01:00
|
|
|
| (1 << CAUSE_LOAD_ACCESS)
|
|
|
|
| (1 << CAUSE_STORE_ACCESS)
|
2016-11-12 16:31:16 +01:00
|
|
|
| (1 << CAUSE_USER_ECALL)
|
2018-02-16 13:36:46 +01:00
|
|
|
| (1 << CAUSE_FETCH_PAGE_FAULT)
|
|
|
|
| (1 << CAUSE_LOAD_PAGE_FAULT)
|
|
|
|
| (1 << CAUSE_STORE_PAGE_FAULT)
|
2016-11-12 16:31:16 +01:00
|
|
|
;
|
2016-11-04 19:27:25 +01:00
|
|
|
|
2015-08-27 00:28:04 +02:00
|
|
|
void mstatus_init(void)
|
|
|
|
{
|
|
|
|
uintptr_t ms = 0;
|
2016-12-13 00:09:42 +01:00
|
|
|
|
2015-08-27 00:28:04 +02:00
|
|
|
ms = INSERT_FIELD(ms, MSTATUS_FS, 3);
|
|
|
|
ms = INSERT_FIELD(ms, MSTATUS_XS, 3);
|
|
|
|
write_csr(mstatus, ms);
|
|
|
|
|
2016-12-13 00:09:42 +01:00
|
|
|
// clear any pending timer interrupts.
|
|
|
|
clear_csr(mip, MIP_STIP | MIP_SSIP);
|
|
|
|
|
|
|
|
// enable machine and supervisor timer and
|
|
|
|
// all other supervisor interrupts.
|
|
|
|
set_csr(mie, MIP_MTIP | MIP_STIP | MIP_SSIP);
|
|
|
|
|
|
|
|
// Delegate supervisor timer and other interrupts
|
|
|
|
// to supervisor mode.
|
|
|
|
set_csr(mideleg, MIP_STIP | MIP_SSIP);
|
2016-08-22 19:37:15 +02:00
|
|
|
|
2016-11-12 16:31:16 +01:00
|
|
|
set_csr(medeleg, delegate);
|
2016-10-19 17:07:13 +02:00
|
|
|
|
2016-12-19 18:06:00 +01:00
|
|
|
// Enable all user/supervisor-mode counters using
|
2017-06-06 10:50:46 +02:00
|
|
|
// v1.10 register addresses.
|
2016-12-19 18:06:00 +01:00
|
|
|
// They moved from the earlier spec.
|
|
|
|
// Until we trust our toolchain use the hardcoded constants.
|
|
|
|
// These were in flux and people who get the older toolchain
|
|
|
|
// will have difficult-to-debug failures.
|
2017-06-06 10:50:46 +02:00
|
|
|
write_csr(/*mcounteren*/0x306, 7);
|
2015-08-27 00:28:04 +02:00
|
|
|
}
|