summaryrefslogtreecommitdiff
path: root/usr/src/uts/sun4u/sys/mc.h
blob: 005ae1646728509aec0723a8cd2dd544243b8d74 (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
137
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_SYS_MC_H
#define	_SYS_MC_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * Interface of Memory Controller driver
 *
 * Logical view: memory -> segment -> bank -> device group -> device
 * physical view: mc -> device group -> device
 *
 * MCIOC_MEM, MCIOC_SEG, MCIOC_CTRLCONF, MCIOC_CONTROL are
 * associated with various length struct. If given number is less than the
 * number in kernel, kernel will update the number and return EINVAL so that
 * user could allocate enough space for the struct and fill the right number
 * of ids at the struct.
 *
 * All varaiable number ids will be paired, global and local. Global id is
 * unique in the same object list and local id is only unique to
 * its upper layer. For instance, one memory module group has N memory modules.
 * local ids of this memory module group is from 0 to N - 1, but global id
 * is unique in all memory modules. So global id will be the key in the list
 * and pass it to driver to search. Local id will be returned to user
 * application via ioctl.
 */

#define	MCIOC		('M' << 8)
#define	MCIOC_MEMCONF	(MCIOC|8)
#define	MCIOC_MEM	(MCIOC|9)
#define	MCIOC_SEG	(MCIOC|10)
#define	MCIOC_BANK	(MCIOC|11)
#define	MCIOC_DEVGRP	(MCIOC|12)
#define	MCIOC_CTRLCONF	(MCIOC|13)
#define	MCIOC_CONTROL	(MCIOC|14)
#define	MCIOC_ECFLUSH	(MCIOC|15)

/*
 * libdevinfo property name for exporting the Memory Address
 * Decode Registers for each Logical bank. An array of [NBANK]
 * uint64_t's is created for each memory-controller node.
 */
#define	MEM_CFG_PROP_NAME	"logical-bank-ma-regs"

struct mc_ids {
	int	globalid;
	int	localid;
};

/*
 * Enabled memory controller is able to get memory-layout property, and
 * it could be with or without memory.
 */
struct mc_memconf {
	int nmcs;	/* The number of enabled memory controllers */
	int nsegments;	/* The number of memory segments */
	int nbanks;	/* The max. number of banks per segment */
	int ndevgrps;	/* The max. number of device groups per mc */
	int ndevs;	/* The max. number of devices per device group */
	int len_dev;	/* The length of device label */
	int xfer_size;	/* Data transfer size in CPU cache line */
};

struct mc_memory {
	uint64_t size;		/* size of physical memory */
	int nsegments;		/* The number of memory segments */
	struct mc_ids segmentids[1]; /* segment ids for next iteration */
};

struct mc_segment {
	int id;			/* unique segment id */
	int ifactor;		/* interleave factor for this segment */
	uint64_t base;		/* starting physical address */
	uint64_t size;		/* in bytes */
	int nbanks;		/* The number of banks at this segment */
	struct mc_ids bankids[1]; /* logical bank ids for next iteration */
};

struct mc_bank {
	int id;			/* unique id for logic bank */
	struct mc_ids devgrpid;	/* Only one device group id per logical bank */
	uint64_t mask;		/* If (Physic Address & MASK) == MATCH, */
	uint64_t match;		/* Physic Address is located at this bank. */
	uint64_t size;		/* memory size per logical bank */
};

struct mc_ctrlconf {
	int nmcs;		/* The number of enabled memory controllers */
	struct mc_ids mcids[1];	/* mc ids for next iteration */
};

struct mc_control {
	int id;			/* unique id for memory controllers */
	int ndevgrps;		/* The number of device groups on this mc */
	struct mc_ids devgrpids[1]; /* device group ids for next iteration */
};

struct mc_devgrp {
	int id;		/* unique id for device groups */
	int ndevices;	/* The number of available devices on this dev group */
	uint64_t size;	/* memory size per physical dimm group */
};

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_MC_H */