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 "smbios_patcher.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 | void dumpAllTablesOfType(int i)␊ |
67 | {␊ |
68 | char title[32];␊ |
69 | struct DMIHeader * dmihdr;␊ |
70 | for(dmihdr = FindFirstDmiTableOfType(i, 4);␊ |
71 | dmihdr;␊ |
72 | dmihdr = FindNextDmiTableOfType(i, 4)) {␊ |
73 | sprintf(title,"Table (type %d) :" , i); ␊ |
74 | dumpPhysAddr(title, dmihdr, dmihdr->length);␊ |
75 | }␊ |
76 | }␊ |
77 | void scan_memory(PlatformInfo_t *p)␊ |
78 | {␊ |
79 | int i=0;␊ |
80 | uint8_t bc=0;␊ |
81 | struct SMBEntryPoint* smbios = NULL;␊ |
82 | struct DMIHeader * dmihdr = NULL;␊ |
83 | ␊ |
84 | struct DMIMemoryControllerInfo* ctrlInfo = NULL;␊ |
85 | struct DMIMemoryModuleInfo* memInfo[MAX_RAM_SLOTS];␊ |
86 | ␊ |
87 | /*␊ |
88 | struct DMIPhysicalMemoryArray* physMemArray;␊ |
89 | struct DMIMemoryDevice* memDev;␊ |
90 | */␊ |
91 | ␊ |
92 | smbios = getSmbios(SMBIOS_ORIGINAL);␉/* checks for _SM_ anchor and table header checksum */␊ |
93 | if (smbios==NULL) return ; // getSmbios() return a non null value if smbios is found␊ |
94 | ␊ |
95 | ctrlInfo = (struct DMIMemoryControllerInfo*) FindFirstDmiTableOfType(5, 4);␊ |
96 | Platform.DMI.MaxMemorySlots = ctrlInfo ? ctrlInfo->numberOfMemorySlots : 0;␊ |
97 | printf("Number of smbios detected Slots: %02d\n", Platform.DMI.MaxMemorySlots);␊ |
98 | ␊ |
99 | Platform.DMI.MemoryModules = 0;␊ |
100 | for(dmihdr = FindFirstDmiTableOfType(6, 4);␊ |
101 | dmihdr;␊ |
102 | dmihdr = FindNextDmiTableOfType(6, 4) ) {␊ |
103 | memInfo[i] = (struct DMIMemoryModuleInfo*) dmihdr;␊ |
104 | bc = memInfo[i]->bankConnections;␊ |
105 | Platform.RAM.DIMM[i].BankConnCnt = 2;␊ |
106 | if ((bc & 0x0F) == 0x0F) Platform.RAM.DIMM[i].BankConnCnt--; // 0xF nibble means no connection (3.3.7)␊ |
107 | if ((bc & 0xF0) == 0xF0) Platform.RAM.DIMM[i].BankConnCnt--; // 0xF nibble means no connection (3.3.7)␊ |
108 | printf("Bank Connection code for Slot %d is %02x, so %d bank connections per slot deducted.\n", ␊ |
109 | i+1, bc, Platform.RAM.DIMM[i].BankConnCnt);␊ |
110 | ␊ |
111 | if ( memInfo[i]->installedSize < 0x7D) // >= 0x7D means error / not installed␊ |
112 | Platform.DMI.MemoryModules++;␊ |
113 | i++;␊ |
114 | }␊ |
115 | Platform.DMI.CntMemorySlots = i;␊ |
116 | getc();␊ |
117 | /*␊ |
118 | physMemArray = (struct DMIPhysicalMemoryArray*) getSmbiosTableStructure(smbios, 16, 0x1);␊ |
119 | memDev = (struct DMIMemoryDevice*) getSmbiosTableStructure(smbios, 17, 0x1);␊ |
120 | */␊ |
121 | /*␊ |
122 | dumpAllTablesOfType(5);␊ |
123 | dumpAllTablesOfType(6 );␊ |
124 | getc();␊ |
125 | dumpAllTablesOfType(16);␊ |
126 | dumpAllTablesOfType(17);␊ |
127 | getc();␊ |
128 | */␊ |
129 | }␊ |
130 | |