1 | /*␊ |
2 | * Copyright 2010 AsereBLN. All rights reserved. <aserebln@googlemail.com>␊ |
3 | *␊ |
4 | * mem.c - obtain system memory information␊ |
5 | */␊ |
6 | ␊ |
7 | #include "libsaio.h"␊ |
8 | #include "pci.h"␊ |
9 | #include "platform.h"␊ |
10 | #include "cpu.h"␊ |
11 | #include "mem.h"␊ |
12 | #include "fake_efi.h"␊ |
13 | ␊ |
14 | #ifndef DEBUG_MEM␊ |
15 | #define DEBUG_MEM 0␊ |
16 | #endif␊ |
17 | ␊ |
18 | #if DEBUG_MEM␊ |
19 | #define DBG(x...)␉␉printf(x)␊ |
20 | #else␊ |
21 | #define DBG(x...)␊ |
22 | #endif␊ |
23 | ␊ |
24 | #define DC(c) (c >= 0x20 && c < 0x7f ? (char) c : '.')␊ |
25 | #define STEP 16␊ |
26 | ␊ |
27 | void dumpPhysAddr(const char * title, void * a, int len)␊ |
28 | {␊ |
29 | int i,j;␊ |
30 | u_int8_t* ad = (u_int8_t*) a;␊ |
31 | char buffer[80];␊ |
32 | char str[16];␊ |
33 | ␊ |
34 | if(ad==NULL) return;␊ |
35 | ␊ |
36 | printf("%s addr=0x%08x len=%04d\n",title ? title : "Dump of ", a, len);␊ |
37 | printf("Ofs-00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F ASCII\n");␊ |
38 | i = (len/STEP)*STEP;␊ |
39 | for (j=0; j < i; j+=STEP)␊ |
40 | {␊ |
41 | printf("%02x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",␊ |
42 | j, ␊ |
43 | ad[j], ad[j+1], ad[j+2], ad[j+3] , ad[j+4], ad[j+5], ad[j+6], ad[j+7],␊ |
44 | ad[j+8], ad[j+9], ad[j+10], ad[j+11] , ad[j+12], ad[j+13], ad[j+14], ad[j+15],␊ |
45 | DC(ad[j]), DC(ad[j+1]), DC(ad[j+2]), DC(ad[j+3]) , DC(ad[j+4]), DC(ad[j+5]), DC(ad[j+6]), DC(ad[j+7]),␊ |
46 | DC(ad[j+8]), DC(ad[j+9]), DC(ad[j+10]), DC(ad[j+11]) , DC(ad[j+12]), DC(ad[j+13]), DC(ad[j+14]), DC(ad[j+15])␊ |
47 | ); ␊ |
48 | }␊ |
49 | ␊ |
50 | if (len%STEP==0) return;␊ |
51 | sprintf(buffer,"%02x:", i);␊ |
52 | for (j=0; j < STEP; j++) {␊ |
53 | if (j<(len%STEP))␊ |
54 | sprintf(str, " %02x", ad[i+j]);␊ |
55 | else␊ |
56 | strcpy(str, " " ); ␊ |
57 | strncat(buffer, str, sizeof(buffer));␊ |
58 | }␊ |
59 | strncat(buffer," ", sizeof(buffer));␊ |
60 | for (j=0; j < (len%STEP); j++) {␊ |
61 | sprintf(str, "%c", DC(ad[i+j])); ␊ |
62 | strncat(buffer, str, sizeof(buffer));␊ |
63 | }␊ |
64 | printf("%s\n",buffer);␊ |
65 | }␊ |
66 | ␊ |
67 | const char * getDMIString(struct DMIHeader * dmihdr, uint8_t strNum)␊ |
68 | {␊ |
69 | const char * ret =NULL;␊ |
70 | const char * startAddr = (const char *) dmihdr;␊ |
71 | const char * limit = NULL;␊ |
72 | ␊ |
73 | if (!dmihdr || dmihdr->length<4 || strNum==0) return NULL;␊ |
74 | startAddr += dmihdr->length;␊ |
75 | limit = startAddr + 256;␊ |
76 | for(; strNum; strNum--) {␊ |
77 | if ((*startAddr)==0 && *(startAddr+1)==0) break;␊ |
78 | if (*startAddr && strNum<=1) {␊ |
79 | ret = startAddr; // current str␊ |
80 | break;␊ |
81 | }␊ |
82 | while(*startAddr && startAddr<limit) startAddr++;␊ |
83 | if (startAddr==limit) break; // no terminator found␊ |
84 | else if((*startAddr==0) && *(startAddr+1)==0) break;␊ |
85 | else startAddr++;␊ |
86 | }␊ |
87 | ␊ |
88 | return ret;␊ |
89 | }␊ |
90 | #if UNUSED␊ |
91 | ␊ |
92 | void dumpAllTablesOfType(int i)␊ |
93 | {␊ |
94 | char title[32];␊ |
95 | ␉struct DMIHeader * dmihdr;␊ |
96 | ␉for(dmihdr = FindFirstDmiTableOfType(i, 4);␊ |
97 | ␉␉dmihdr;␊ |
98 | ␉␉dmihdr = FindNextDmiTableOfType(i, 4)) {␊ |
99 | ␉␉sprintf(title,"Table (type %d) :" , i); ␊ |
100 | ␉␉dumpPhysAddr(title, dmihdr, dmihdr->length+32);␊ |
101 | ␉}␊ |
102 | }␊ |
103 | ␊ |
104 | void scan_memory(PlatformInfo_t *p)␊ |
105 | {␉␉ ␊ |
106 | int i=0;␊ |
107 | struct DMIHeader * dmihdr = NULL;␊ |
108 | ␊ |
109 | struct DMIMemoryModuleInfo* memInfo[MAX_RAM_SLOTS]; // 6␊ |
110 | struct DMIPhysicalMemoryArray* physMemArray; // 16␊ |
111 | struct DMIMemoryDevice* memDev[MAX_RAM_SLOTS]; //17␊ |
112 | ␊ |
113 | /* We mainly don't use obsolete tables 5,6 because most of computers don't handle it anymore */␊ |
114 | Platform->DMI.MemoryModules = 0;␊ |
115 | /* Now lets peek info rom table 16,17 as for some bios, table 5 & 6 are not used */␊ |
116 | physMemArray = (struct DMIPhysicalMemoryArray*) FindFirstDmiTableOfType(16, 4);␊ |
117 | Platform->DMI.MaxMemorySlots = physMemArray ? physMemArray->numberOfMemoryDevices : 0;␊ |
118 | ␊ |
119 | i = 0;␊ |
120 | for(dmihdr = FindFirstDmiTableOfType(17, 4);␊ |
121 | dmihdr;␊ |
122 | dmihdr = FindNextDmiTableOfType(17, 4) ) {␊ |
123 | memDev[i] = (struct DMIMemoryDevice*) dmihdr;␊ |
124 | if (memDev[i]->size !=0 ) Platform->DMI.MemoryModules++;␊ |
125 | if (memDev[i]->speed>0) Platform->RAM.DIMM[i].Frequency = memDev[i]->speed; // take it here for now but we'll check spd and dmi table 6 as well␊ |
126 | i++;␊ |
127 | }␊ |
128 | // for table 6, we only have a look at the current speed␊ |
129 | i = 0;␊ |
130 | for(dmihdr = FindFirstDmiTableOfType(6, 4);␊ |
131 | dmihdr;␊ |
132 | dmihdr = FindNextDmiTableOfType(6, 4) ) {␊ |
133 | memInfo[i] = (struct DMIMemoryModuleInfo*) dmihdr;␊ |
134 | if (memInfo[i]->currentSpeed > Platform->RAM.DIMM[i].Frequency) ␊ |
135 | Platform->RAM.DIMM[i].Frequency = memInfo[i]->currentSpeed; // favor real overclocked speed if any␊ |
136 | i++;␊ |
137 | }␊ |
138 | #if 0␊ |
139 | dumpAllTablesOfType(17);␊ |
140 | getc();␊ |
141 | #endif␊ |
142 | }␊ |
143 | #endif␊ |
144 | |