summaryrefslogtreecommitdiffstats
path: root/spd_dump.c
blob: f45ef31e0725bf52666d82d665a461e83dce9163 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
 * acpi_reset.c: Reboot your LinuxBIOS system with ACPI software watchdo
 *
 *
 * Copyright 2000 Silicon Integrated System Corporation
 *
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation; either version 2 of the License, or
 *	(at your option) any later version.
 *
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with this program; if not, write to the Free Software
 *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *
 * Reference:
 *	1. SiS 630 Specification
 *
 * $Id$
 */

#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/io.h>
#include <unistd.h>
#include <stdio.h>

unsigned short acpi_base;

void
waitsmbus()
{
	unsigned short port = acpi_base;
	unsigned char val;

	//printf("waitsmb ..\n");

	for (val = inb(port); (val & 8) == 0; val = inb(port))
		;
	//printf("past first test\n");
}

void
setsmbus(unsigned char index, unsigned char value)
{
	unsigned short port = acpi_base + index;

	//printf("setsmbus: index 0x%02x, value 0x%02x\n", 
	//	index, value);

	outb(value, port);
}

unsigned char
getsmbus(unsigned char index)
{
	unsigned short port = acpi_base + index;
	unsigned char value;

	value = inb(port);

	//printf("getsmbus: index 0x%02x, value 0x%02x\n", 
	//	index, value);

	return value;
}

unsigned char
read_spd(unsigned char slot, unsigned char index)
{
	unsigned char value;

	setsmbus(0x03, 0x20);

	setsmbus(0x04, 0xA1 + (slot << 1));

	setsmbus(0x05, index);

	setsmbus(0x03, 0x12);

	waitsmbus();

	value = getsmbus(0x08);

	setsmbus(0x00, 0xFF);

	return value;
}

main()
{
	unsigned char b;
	unsigned short w;


	/* get io privilege access PCI configuration space */
	if (iopl(3) != 0) {
		perror("Can not set io priviliage");
		exit(1);
	}

	/* Enable ACPI by set B7 on Reg 0x40, LPC */
	outl(0x80000840, 0x0cf8);
	b = inb(0x0cfc) | 0x80;
	outb(b, 0xcfc);

	/* get the ACPI base address for register 0x74,0x75 of LPC */
	outl(0x80000874, 0x0cf8);
	w = inw(0x0cfc);
	acpi_base = w + 0x80;

	printf("Number of bytes used by module manufacturer 0x%02x\n",
	       read_spd(0x00, 0x00));

	printf("Memory Type 0x%02x\n",
	       read_spd(0x00, 0x02));

	printf("Number of Row Address bits 0x%02x\n",
	       read_spd(0x00, 0x03));

	printf("Number of Column Address bits 0x%02x\n",
	       read_spd(0x00, 0x04));

	printf("Number of Sides 0x%02x\n",
	       read_spd(0x00, 0x05));

	printf("Number of Banks 0x%02x\n",
	       read_spd(0x00, 0x11));
}
OpenPOWER on IntegriCloud