blob: 048d396ffeedb1727034bf93d0c4484b3b93887f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <arch/exception.h>
#include <types.h>
#include <console/console.h>
#include <device/mmio.h>
#include <ramdetect.h>
#include <arch/smp/spinlock.h>
#include <vm.h>
static enum {
ABORT_CHECKER_NOT_TRIGGERED,
ABORT_CHECKER_TRIGGERED,
} abort_state = ABORT_CHECKER_NOT_TRIGGERED;
extern void (*trap_handler)(struct trapframe *tf);
static int get_instruction_len(uintptr_t addr)
{
uint16_t ins = read16p(addr);
/*
* 16-bit or 32-bit instructions supported
*/
if ((ins & 0x3) != 3) {
return 2;
} else if ((ins & 0x1f) != 0x1f) {
return 4;
}
die("Not a 16bit or 32bit instruction 0x%x\n", ins);
}
static void ramcheck_trap_handler(struct trapframe *tf)
{
abort_state = ABORT_CHECKER_TRIGGERED;
/*
* skip read instruction.
*/
int insn_size = get_instruction_len(tf->epc);
write_csr(mepc, read_csr(mepc) + insn_size);
}
int probe_mb(const uintptr_t dram_start, const uintptr_t size)
{
uintptr_t addr = dram_start + (size * MiB) - sizeof(uint32_t);
void *ptr = (void *)addr;
abort_state = ABORT_CHECKER_NOT_TRIGGERED;
trap_handler = ramcheck_trap_handler;
barrier();
read32(ptr);
trap_handler = default_trap_handler;
barrier();
printk(BIOS_DEBUG, "%lx is %s DRAM\n", dram_start + size * MiB,
abort_state == ABORT_CHECKER_NOT_TRIGGERED ? "" : "not");
return abort_state == ABORT_CHECKER_NOT_TRIGGERED;
}
|