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