]>
git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/hwinfo/src/hd/memory.c
12 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
15 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
18 uint64_t kcore_mem(hd_data_t
*hd_data
);
19 uint64_t klog_mem(hd_data_t
*hd_data
, uint64_t *alt
);
20 uint64_t klog_mem2(hd_data_t
*hd_data
);
21 uint64_t meminfo_mem(hd_data_t
*hd_data
);
23 void hd_scan_memory(hd_data_t
*hd_data
)
26 uint64_t kcore
, klog
, klog_alt
, klog2
, meminfo
, msize0
, msize1
, u
;
31 if(!hd_probe_feature(hd_data
, pr_memory
)) return;
33 hd_data
->module
= mod_memory
;
36 remove_hd_entries(hd_data
);
38 PROGRESS(1, 0, "main memory size");
40 kcore
= kcore_mem(hd_data
);
41 klog
= klog_mem(hd_data
, &klog_alt
);
42 klog2
= klog_mem2(hd_data
);
43 if(klog2
> klog
) klog
= klog2
;
44 meminfo
= meminfo_mem(hd_data
);
46 msize0
= meminfo
> klog
? meminfo
: klog
;
47 if(!msize0
) msize0
= kcore
;
50 if(msize0
&& kcore
>= msize0
&& ((kcore
- msize0
) << 4) / msize0
== 0) {
51 /* trust kcore value if it's approx. msize0 */
56 if(meminfo
> msize1
) { msize1
= meminfo
; exact
= 0; }
57 if(klog_alt
> msize0
) msize0
= klog_alt
;
59 hd
= add_hd_entry(hd_data
, __LINE__
, 0);
60 hd
->base_class
.id
= bc_internal
;
61 hd
->sub_class
.id
= sc_int_main_mem
;
63 res
= add_res_entry(&hd
->res
, new_mem(sizeof *res
));
64 res
->mem
.type
= res_mem
;
65 res
->mem
.range
= msize0
;
66 res
->mem
.access
= acc_rw
;
69 /* round it somewhat */
70 for(i
= 0, u
= msize1
; u
; i
++) {
73 if(i
> 10) { /* We *do* have at least 1k memory, do we? */
74 msize1
>>= i
- (exact
? 8 : 5);
77 msize1
<<= i
- (exact
? 7 : 4);
80 res
= add_res_entry(&hd
->res
, new_mem(sizeof *res
));
81 res
->phys_mem
.type
= res_phys_mem
;
82 res
->phys_mem
.range
= msize1
;
85 uint64_t kcore_mem(hd_data_t
*hd_data
)
88 size_t ps
= getpagesize();
91 if(!stat(PROC_KCORE
, &sb
)) {
96 /* we'll assume no mem modules with less than 256k */
102 ADD2LOG(" kcore mem: 0x%"PRIx64
"\n", u
);
108 uint64_t klog_mem(hd_data_t
*hd_data
, uint64_t *alt
)
110 uint64_t u
= 0, u0
, u1
, u2
, u3
, mem0
= 0, mem1
= 0;
115 if(!hd_data
->klog
) read_klog(hd_data
);
117 for(sl
= hd_data
->klog
; sl
; sl
= sl
->next
) {
118 if(strstr(sl
->str
, "<6>Memory: ") == sl
->str
) {
119 if(sscanf(sl
->str
, "<6>Memory: %"SCNu64
"k/%"SCNu64
"k", &u0
, &u1
) == 2) {
123 (i
= sscanf(sl
->str
, "<6>Memory: %"SCNu64
"k available (%"SCNu64
"k kernel code, %"SCNu64
"k data, %"SCNu64
"k", &u0
, &u1
, &u2
, &u3
)) == 4 || i
== 1
125 mem0
= (i
== 1 ? u0
: u0
+ u1
+ u2
+ u3
) << 10;
128 (s
= strstr(sl
->str
, "[")) &&
129 sscanf(s
, "[%"SCNx64
",%"SCNx64
"]", &u0
, &u1
) == 2 &&
138 u
= mem0
? mem0
: mem1
;
141 /* round it somewhat */
142 for(i
= 0, u0
= u
; u0
; i
++) {
145 if(i
> 10) { /* We *do* have at least 1k memory, do we? */
153 ADD2LOG(" klog mem 0: 0x%"PRIx64
"\n", mem0
);
154 ADD2LOG(" klog mem 1: 0x%"PRIx64
"\n", mem1
);
155 ADD2LOG(" klog mem: 0x%"PRIx64
"\n", u
);
162 uint64_t klog_mem2(hd_data_t
*hd_data
)
164 uint64_t u0
, u1
, mem
= 0;
168 if(!hd_data
->klog
) read_klog(hd_data
);
170 for(sl
= hd_data
->klog
; sl
; sl
= sl
->next
) {
171 if(strstr(sl
->str
, "<6>BIOS-provided physical RAM map:") == sl
->str
) {
172 for(sl
= sl
->next
; sl
; sl
= sl
->next
) {
173 ADD2LOG(" -- %s", sl
->str
);
174 if(sscanf(sl
->str
, "<4> BIOS-e820: %"SCNx64
" - %"SCNx64
" (%63s", &u0
, &u1
, buf
) != 3) break;
175 if(strcmp(buf
, "usable)")) continue;
183 ADD2LOG(" bios mem: 0x%"PRIx64
"\n", mem
);
188 uint64_t meminfo_mem(hd_data_t
*hd_data
)
193 sl
= read_file(PROC_MEMINFO
, 0, 1);
195 if(sl
&& sscanf(sl
->str
, "MemTotal: %"SCNu64
"", &u0
) == 1) {
201 ADD2LOG(" meminfo: 0x%"PRIx64
"\n", u
);