blob: cf395bd712bf1eb793eef539edb55ef93c0ac0b5 [file] [log] [blame]
Angel Pons118a9c72020-04-02 23:48:34 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Patrick Rudolphbd4bcab2019-06-30 22:12:15 +02003
4#include <types.h>
5#include <symbols.h>
6#include <device/mmio.h>
7#include <ramdetect.h>
8#include <console/console.h>
9
10#define OVERLAP(a, b, s, e) ((b) > (s) && (a) < (e))
11
Asami Doi06993ee2019-08-07 13:40:53 +090012int __weak probe_mb(const uintptr_t dram_start, const uintptr_t size)
Patrick Rudolphbd4bcab2019-06-30 22:12:15 +020013{
14 uintptr_t addr = dram_start + (size * MiB) - sizeof(uint32_t);
15 static const uint32_t patterns[] = {
16 0x55aa55aa,
17 0x12345678
18 };
19 void *ptr = (void *) addr;
20 size_t i;
21
22 /* Don't accidentally clober oneself. */
23 if (OVERLAP(addr, addr + sizeof(uint32_t), (uintptr_t)_program, (uintptr_t) _eprogram))
24 return 1;
25
26 uint32_t old = read32(ptr);
27 for (i = 0; i < ARRAY_SIZE(patterns); i++) {
28 write32(ptr, patterns[i]);
29 if (read32(ptr) != patterns[i])
30 break;
31 }
32
33 write32(ptr, old);
34 return i == ARRAY_SIZE(patterns);
35}
36
37/* - 20 as probe_size is in MiB, - 1 as i is signed */
38#define MAX_ADDRESSABLE_SPACE (sizeof(size_t) * 8 - 20 - 1)
39
40/* Probe an area if it's read/writable. */
41size_t probe_ramsize(const uintptr_t dram_start, const size_t probe_size)
42{
43 ssize_t i;
44 size_t msb = 0;
45 size_t discovered = 0;
46
47 static size_t saved_result;
48 if (saved_result)
49 return saved_result;
50
51 /* Find the MSB + 1. */
52 size_t tmp = probe_size;
53 do {
54 msb++;
55 } while (tmp >>= 1);
56
57 /* Limit search to accessible address space */
58 msb = MIN(msb, MAX_ADDRESSABLE_SPACE);
59
60 /* Compact binary search. */
61 for (i = msb; i >= 0; i--)
62 if (probe_mb(dram_start, (discovered | (1ULL << i))))
63 discovered |= (1ULL << i);
64
65 saved_result = discovered;
66 printk(BIOS_DEBUG, "RAMDETECT: Found %zu MiB RAM\n", discovered);
67 return discovered;
68}