2 #include <l4/cxx/minmax>
8 scan_ram_size(unsigned long base_addr, unsigned long max_scan_size_mb)
10 // scan the RAM to find out the RAM size, note that at this point we have
11 // two regions in RAM that we cannot touch, &_start - &_end and the
14 // assume that the image is loaded correctly and we need to start
15 // probing for memory wraparounds beyond the end of our image
18 extern char _module_data_end[];
20 = l4_round_size((l4_addr_t)cxx::max(_end, _module_data_end), 20);
22 l4_addr_t lower_bound = l4_round_size((l4_addr_t)_end, 20);
25 assert(base_addr <= lower_bound);
26 lower_bound -= base_addr;
28 // must be a power of 2 and >= (1 << 20)
29 unsigned long increment;
30 unsigned long max_scan_size = max_scan_size_mb << 20;
32 // push the initial probe point beyond lower_bound
33 for (increment = 1 << 20;
34 increment < lower_bound && increment < max_scan_size;
38 printf(" Scanning up to %ld MB RAM, starting at offset %ldMB\n",
39 max_scan_size_mb, increment >> 20);
41 // initialize memory probe points
42 for (unsigned long offset = increment;
43 offset < max_scan_size;
45 *(unsigned long *)(base_addr + offset) = 0;
47 // avoid gcc/clang optimization figuring out that base_addr might
48 // always be 0 and generating a trap here
49 asm("" : "+r" (base_addr));
50 // write something at offset 0, does it appear elsewhere?
51 *(unsigned long *)base_addr = 0x12345678;
52 asm volatile("" : : : "memory");
53 for (unsigned long offset = increment;
54 offset < max_scan_size;
56 if (*(unsigned long *)(base_addr + offset) == 0x12345678)
57 return offset >> 20; // detected a wrap around at offset
59 return max_scan_size_mb;
63 Platform_single_region_ram::setup_memory_map()
65 unsigned long ram_size_mb = scan_ram_size(RAM_BASE, RAM_SIZE_MB);
66 printf(" Memory size is %ldMB%s (%08lx - %08lx)\n",
67 ram_size_mb, ram_size_mb != RAM_SIZE_MB ? " (Limited by Scan)" : "",
68 (unsigned long)RAM_BASE, RAM_BASE + (ram_size_mb << 20) - 1);
69 mem_manager->ram->add(
71 (unsigned long long)RAM_BASE + (ram_size_mb << 20),
72 ".ram", Region::Ram));