aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlessandro Rubini <rubini@gnudd.com>2013-06-12 03:13:36 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-06-17 19:38:57 -0400
commite34fae7841b12d77f2621bd28fd41929879ef951 (patch)
treebdaefafd01ed704886d1d99badce309a902a2ece
parent9c9f32eddee56888c7acd0d69134a5dcae09e1a8 (diff)
FMC: add needed headers
This set of headers comes from commit ab23167f (current master of the project on ohwr.org). They define the basic data structures for FMC and its SDB support. Signed-off-by: Alessandro Rubini <rubini@gnudd.com> Acked-by: Juan David Gonzalez Cobas <dcobas@cern.ch> Acked-by: Emilio G. Cota <cota@braap.org> Acked-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--include/linux/fmc-sdb.h36
-rw-r--r--include/linux/fmc.h237
-rw-r--r--include/linux/ipmi-fru.h135
-rw-r--r--include/linux/sdb.h159
4 files changed, 567 insertions, 0 deletions
diff --git a/include/linux/fmc-sdb.h b/include/linux/fmc-sdb.h
new file mode 100644
index 000000000000..1974317a9b3d
--- /dev/null
+++ b/include/linux/fmc-sdb.h
@@ -0,0 +1,36 @@
1/*
2 * This file is separate from sdb.h, because I want that one to remain
3 * unchanged (as far as possible) from the official sdb distribution
4 *
5 * This file and associated functionality are a playground for me to
6 * understand stuff which will later be implemented in more generic places.
7 */
8#include <linux/sdb.h>
9
10/* This is the union of all currently defined types */
11union sdb_record {
12 struct sdb_interconnect ic;
13 struct sdb_device dev;
14 struct sdb_bridge bridge;
15 struct sdb_integration integr;
16 struct sdb_empty empty;
17};
18
19struct fmc_device;
20
21/* Every sdb table is turned into this structure */
22struct sdb_array {
23 int len;
24 int level;
25 unsigned long baseaddr;
26 struct fmc_device *fmc; /* the device that hosts it */
27 struct sdb_array *parent; /* NULL at root */
28 union sdb_record *record; /* copies of the struct */
29 struct sdb_array **subtree; /* only valid for bridge items */
30};
31
32extern int fmc_scan_sdb_tree(struct fmc_device *fmc, unsigned long address);
33extern void fmc_show_sdb_tree(const struct fmc_device *fmc);
34extern signed long fmc_find_sdb_device(struct sdb_array *tree, uint64_t vendor,
35 uint32_t device, unsigned long *sz);
36extern int fmc_free_sdb_tree(struct fmc_device *fmc);
diff --git a/include/linux/fmc.h b/include/linux/fmc.h
new file mode 100644
index 000000000000..a3c498503983
--- /dev/null
+++ b/include/linux/fmc.h
@@ -0,0 +1,237 @@
1/*
2 * Copyright (C) 2012 CERN (www.cern.ch)
3 * Author: Alessandro Rubini <rubini@gnudd.com>
4 *
5 * Released according to the GNU GPL, version 2 or any later version.
6 *
7 * This work is part of the White Rabbit project, a research effort led
8 * by CERN, the European Institute for Nuclear Research.
9 */
10#ifndef __LINUX_FMC_H__
11#define __LINUX_FMC_H__
12#include <linux/types.h>
13#include <linux/moduleparam.h>
14#include <linux/device.h>
15#include <linux/list.h>
16#include <linux/interrupt.h>
17#include <linux/io.h>
18
19struct fmc_device;
20struct fmc_driver;
21
22/*
23 * This bus abstraction is developed separately from drivers, so we need
24 * to check the version of the data structures we receive.
25 */
26
27#define FMC_MAJOR 3
28#define FMC_MINOR 0
29#define FMC_VERSION ((FMC_MAJOR << 16) | FMC_MINOR)
30#define __FMC_MAJOR(x) ((x) >> 16)
31#define __FMC_MINOR(x) ((x) & 0xffff)
32
33/*
34 * The device identification, as defined by the IPMI FRU (Field Replaceable
35 * Unit) includes four different strings to describe the device. Here we
36 * only match the "Board Manufacturer" and the "Board Product Name",
37 * ignoring the "Board Serial Number" and "Board Part Number". All 4 are
38 * expected to be strings, so they are treated as zero-terminated C strings.
39 * Unspecified string (NULL) means "any", so if both are unspecified this
40 * is a catch-all driver. So null entries are allowed and we use array
41 * and length. This is unlike pci and usb that use null-terminated arrays
42 */
43struct fmc_fru_id {
44 char *manufacturer;
45 char *product_name;
46};
47
48/*
49 * If the FPGA is already programmed (think Etherbone or the second
50 * SVEC slot), we can match on SDB devices in the memory image. This
51 * match uses an array of devices that must all be present, and the
52 * match is based on vendor and device only. Further checks are expected
53 * to happen in the probe function. Zero means "any" and catch-all is allowed.
54 */
55struct fmc_sdb_one_id {
56 uint64_t vendor;
57 uint32_t device;
58};
59struct fmc_sdb_id {
60 struct fmc_sdb_one_id *cores;
61 int cores_nr;
62};
63
64struct fmc_device_id {
65 struct fmc_fru_id *fru_id;
66 int fru_id_nr;
67 struct fmc_sdb_id *sdb_id;
68 int sdb_id_nr;
69};
70
71/* This sizes the module_param_array used by generic module parameters */
72#define FMC_MAX_CARDS 32
73
74/* The driver is a pretty simple thing */
75struct fmc_driver {
76 unsigned long version;
77 struct device_driver driver;
78 int (*probe)(struct fmc_device *);
79 int (*remove)(struct fmc_device *);
80 const struct fmc_device_id id_table;
81 /* What follows is for generic module parameters */
82 int busid_n;
83 int busid_val[FMC_MAX_CARDS];
84 int gw_n;
85 char *gw_val[FMC_MAX_CARDS];
86};
87#define to_fmc_driver(x) container_of((x), struct fmc_driver, driver)
88
89/* These are the generic parameters, that drivers may instantiate */
90#define FMC_PARAM_BUSID(_d) \
91 module_param_array_named(busid, _d.busid_val, int, &_d.busid_n, 0444)
92#define FMC_PARAM_GATEWARE(_d) \
93 module_param_array_named(gateware, _d.gw_val, charp, &_d.gw_n, 0444)
94
95/*
96 * Drivers may need to configure gpio pins in the carrier. To read input
97 * (a very uncommon operation, and definitely not in the hot paths), just
98 * configure one gpio only and get 0 or 1 as retval of the config method
99 */
100struct fmc_gpio {
101 char *carrier_name; /* name or NULL for virtual pins */
102 int gpio;
103 int _gpio; /* internal use by the carrier */
104 int mode; /* GPIOF_DIR_OUT etc, from <linux/gpio.h> */
105 int irqmode; /* IRQF_TRIGGER_LOW and so on */
106};
107
108/* The numbering of gpio pins allows access to raw pins or virtual roles */
109#define FMC_GPIO_RAW(x) (x) /* 4096 of them */
110#define __FMC_GPIO_IS_RAW(x) ((x) < 0x1000)
111#define FMC_GPIO_IRQ(x) ((x) + 0x1000) /* 256 of them */
112#define FMC_GPIO_LED(x) ((x) + 0x1100) /* 256 of them */
113#define FMC_GPIO_KEY(x) ((x) + 0x1200) /* 256 of them */
114#define FMC_GPIO_TP(x) ((x) + 0x1300) /* 256 of them */
115#define FMC_GPIO_USER(x) ((x) + 0x1400) /* 256 of them */
116/* We may add SCL and SDA, or other roles if the need arises */
117
118/* GPIOF_DIR_IN etc are missing before 3.0. copy from <linux/gpio.h> */
119#ifndef GPIOF_DIR_IN
120# define GPIOF_DIR_OUT (0 << 0)
121# define GPIOF_DIR_IN (1 << 0)
122# define GPIOF_INIT_LOW (0 << 1)
123# define GPIOF_INIT_HIGH (1 << 1)
124#endif
125
126/*
127 * The operations are offered by each carrier and should make driver
128 * design completely independent of the carrier. Named GPIO pins may be
129 * the exception.
130 */
131struct fmc_operations {
132 uint32_t (*readl)(struct fmc_device *fmc, int offset);
133 void (*writel)(struct fmc_device *fmc, uint32_t value, int offset);
134 int (*validate)(struct fmc_device *fmc, struct fmc_driver *drv);
135 int (*reprogram)(struct fmc_device *f, struct fmc_driver *d, char *gw);
136 int (*irq_request)(struct fmc_device *fmc, irq_handler_t h,
137 char *name, int flags);
138 void (*irq_ack)(struct fmc_device *fmc);
139 int (*irq_free)(struct fmc_device *fmc);
140 int (*gpio_config)(struct fmc_device *fmc, struct fmc_gpio *gpio,
141 int ngpio);
142 int (*read_ee)(struct fmc_device *fmc, int pos, void *d, int l);
143 int (*write_ee)(struct fmc_device *fmc, int pos, const void *d, int l);
144};
145
146/* Prefer this helper rather than calling of fmc->reprogram directly */
147extern int fmc_reprogram(struct fmc_device *f, struct fmc_driver *d, char *gw,
148 int sdb_entry);
149
150/*
151 * The device reports all information needed to access hw.
152 *
153 * If we have eeprom_len and not contents, the core reads it.
154 * Then, parsing of identifiers is done by the core which fills fmc_fru_id..
155 * Similarly a device that must be matched based on SDB cores must
156 * fill the entry point and the core will scan the bus (FIXME: sdb match)
157 */
158struct fmc_device {
159 unsigned long version;
160 unsigned long flags;
161 struct module *owner; /* char device must pin it */
162 struct fmc_fru_id id; /* for EEPROM-based match */
163 struct fmc_operations *op; /* carrier-provided */
164 int irq; /* according to host bus. 0 == none */
165 int eeprom_len; /* Usually 8kB, may be less */
166 int eeprom_addr; /* 0x50, 0x52 etc */
167 uint8_t *eeprom; /* Full contents or leading part */
168 char *carrier_name; /* "SPEC" or similar, for special use */
169 void *carrier_data; /* "struct spec *" or equivalent */
170 __iomem void *fpga_base; /* May be NULL (Etherbone) */
171 __iomem void *slot_base; /* Set by the driver */
172 struct fmc_device **devarray; /* Allocated by the bus */
173 int slot_id; /* Index in the slot array */
174 int nr_slots; /* Number of slots in this carrier */
175 unsigned long memlen; /* Used for the char device */
176 struct device dev; /* For Linux use */
177 struct device *hwdev; /* The underlying hardware device */
178 unsigned long sdbfs_entry;
179 struct sdb_array *sdb;
180 uint32_t device_id; /* Filled by the device */
181 char *mezzanine_name; /* Defaults to ``fmc'' */
182 void *mezzanine_data;
183};
184#define to_fmc_device(x) container_of((x), struct fmc_device, dev)
185
186#define FMC_DEVICE_HAS_GOLDEN 1
187#define FMC_DEVICE_HAS_CUSTOM 2
188#define FMC_DEVICE_NO_MEZZANINE 4
189#define FMC_DEVICE_MATCH_SDB 8 /* fmc-core must scan sdb in fpga */
190
191/*
192 * If fpga_base can be used, the carrier offers no readl/writel methods, and
193 * this expands to a single, fast, I/O access.
194 */
195static inline uint32_t fmc_readl(struct fmc_device *fmc, int offset)
196{
197 if (unlikely(fmc->op->readl))
198 return fmc->op->readl(fmc, offset);
199 return readl(fmc->fpga_base + offset);
200}
201static inline void fmc_writel(struct fmc_device *fmc, uint32_t val, int off)
202{
203 if (unlikely(fmc->op->writel))
204 fmc->op->writel(fmc, val, off);
205 else
206 writel(val, fmc->fpga_base + off);
207}
208
209/* pci-like naming */
210static inline void *fmc_get_drvdata(const struct fmc_device *fmc)
211{
212 return dev_get_drvdata(&fmc->dev);
213}
214
215static inline void fmc_set_drvdata(struct fmc_device *fmc, void *data)
216{
217 dev_set_drvdata(&fmc->dev, data);
218}
219
220/* The 4 access points */
221extern int fmc_driver_register(struct fmc_driver *drv);
222extern void fmc_driver_unregister(struct fmc_driver *drv);
223extern int fmc_device_register(struct fmc_device *tdev);
224extern void fmc_device_unregister(struct fmc_device *tdev);
225
226/* Two more for device sets, all driven by the same FPGA */
227extern int fmc_device_register_n(struct fmc_device **devs, int n);
228extern void fmc_device_unregister_n(struct fmc_device **devs, int n);
229
230/* Internal cross-calls between files; not exported to other modules */
231extern int fmc_match(struct device *dev, struct device_driver *drv);
232extern int fmc_fill_id_info(struct fmc_device *fmc);
233extern void fmc_free_id_info(struct fmc_device *fmc);
234extern void fmc_dump_eeprom(const struct fmc_device *fmc);
235extern void fmc_dump_sdb(const struct fmc_device *fmc);
236
237#endif /* __LINUX_FMC_H__ */
diff --git a/include/linux/ipmi-fru.h b/include/linux/ipmi-fru.h
new file mode 100644
index 000000000000..4d3a76380e32
--- /dev/null
+++ b/include/linux/ipmi-fru.h
@@ -0,0 +1,135 @@
1/*
2 * Copyright (C) 2012 CERN (www.cern.ch)
3 * Author: Alessandro Rubini <rubini@gnudd.com>
4 *
5 * Released according to the GNU GPL, version 2 or any later version.
6 *
7 * This work is part of the White Rabbit project, a research effort led
8 * by CERN, the European Institute for Nuclear Research.
9 */
10#ifndef __LINUX_IPMI_FRU_H__
11#define __LINUX_IPMI_FRU_H__
12#ifdef __KERNEL__
13# include <linux/types.h>
14# include <linux/string.h>
15#else
16# include <stdint.h>
17# include <string.h>
18#endif
19
20/*
21 * These structures match the unaligned crap we have in FRU1011.pdf
22 * (http://download.intel.com/design/servers/ipmi/FRU1011.pdf)
23 */
24
25/* chapter 8, page 5 */
26struct fru_common_header {
27 uint8_t format; /* 0x01 */
28 uint8_t internal_use_off; /* multiple of 8 bytes */
29 uint8_t chassis_info_off; /* multiple of 8 bytes */
30 uint8_t board_area_off; /* multiple of 8 bytes */
31 uint8_t product_area_off; /* multiple of 8 bytes */
32 uint8_t multirecord_off; /* multiple of 8 bytes */
33 uint8_t pad; /* must be 0 */
34 uint8_t checksum; /* sum modulo 256 must be 0 */
35};
36
37/* chapter 9, page 5 -- internal_use: not used by us */
38
39/* chapter 10, page 6 -- chassis info: not used by us */
40
41/* chapter 13, page 9 -- used by board_info_area below */
42struct fru_type_length {
43 uint8_t type_length;
44 uint8_t data[0];
45};
46
47/* chapter 11, page 7 */
48struct fru_board_info_area {
49 uint8_t format; /* 0x01 */
50 uint8_t area_len; /* multiple of 8 bytes */
51 uint8_t language; /* I hope it's 0 */
52 uint8_t mfg_date[3]; /* LSB, minutes since 1996-01-01 */
53 struct fru_type_length tl[0]; /* type-length stuff follows */
54
55 /*
56 * the TL there are in order:
57 * Board Manufacturer
58 * Board Product Name
59 * Board Serial Number
60 * Board Part Number
61 * FRU File ID (may be null)
62 * more manufacturer-specific stuff
63 * 0xc1 as a terminator
64 * 0x00 pad to a multiple of 8 bytes - 1
65 * checksum (sum of all stuff module 256 must be zero)
66 */
67};
68
69enum fru_type {
70 FRU_TYPE_BINARY = 0x00,
71 FRU_TYPE_BCDPLUS = 0x40,
72 FRU_TYPE_ASCII6 = 0x80,
73 FRU_TYPE_ASCII = 0xc0, /* not ascii: depends on language */
74};
75
76/*
77 * some helpers
78 */
79static inline struct fru_board_info_area *fru_get_board_area(
80 const struct fru_common_header *header)
81{
82 /* we know for sure that the header is 8 bytes in size */
83 return (struct fru_board_info_area *)(header + header->board_area_off);
84}
85
86static inline int fru_type(struct fru_type_length *tl)
87{
88 return tl->type_length & 0xc0;
89}
90
91static inline int fru_length(struct fru_type_length *tl)
92{
93 return (tl->type_length & 0x3f) + 1; /* len of whole record */
94}
95
96/* assume ascii-latin1 encoding */
97static inline int fru_strlen(struct fru_type_length *tl)
98{
99 return fru_length(tl) - 1;
100}
101
102static inline char *fru_strcpy(char *dest, struct fru_type_length *tl)
103{
104 int len = fru_strlen(tl);
105 memcpy(dest, tl->data, len);
106 dest[len] = '\0';
107 return dest;
108}
109
110static inline struct fru_type_length *fru_next_tl(struct fru_type_length *tl)
111{
112 return tl + fru_length(tl);
113}
114
115static inline int fru_is_eof(struct fru_type_length *tl)
116{
117 return tl->type_length == 0xc1;
118}
119
120/*
121 * External functions defined in fru-parse.c.
122 */
123extern int fru_header_cksum_ok(struct fru_common_header *header);
124extern int fru_bia_cksum_ok(struct fru_board_info_area *bia);
125
126/* All these 4 return allocated strings by calling fru_alloc() */
127extern char *fru_get_board_manufacturer(struct fru_common_header *header);
128extern char *fru_get_product_name(struct fru_common_header *header);
129extern char *fru_get_serial_number(struct fru_common_header *header);
130extern char *fru_get_part_number(struct fru_common_header *header);
131
132/* This must be defined by the caller of the above functions */
133extern void *fru_alloc(size_t size);
134
135#endif /* __LINUX_IMPI_FRU_H__ */
diff --git a/include/linux/sdb.h b/include/linux/sdb.h
new file mode 100644
index 000000000000..fbb76a46c8a5
--- /dev/null
+++ b/include/linux/sdb.h
@@ -0,0 +1,159 @@
1/*
2 * This is the official version 1.1 of sdb.h
3 */
4#ifndef __SDB_H__
5#define __SDB_H__
6#ifdef __KERNEL__
7#include <linux/types.h>
8#else
9#include <stdint.h>
10#endif
11
12/*
13 * All structures are 64 bytes long and are expected
14 * to live in an array, one for each interconnect.
15 * Most fields of the structures are shared among the
16 * various types, and most-specific fields are at the
17 * beginning (for alignment reasons, and to keep the
18 * magic number at the head of the interconnect record
19 */
20
21/* Product, 40 bytes at offset 24, 8-byte aligned
22 *
23 * device_id is vendor-assigned; version is device-specific,
24 * date is hex (e.g 0x20120501), name is UTF-8, blank-filled
25 * and not terminated with a 0 byte.
26 */
27struct sdb_product {
28 uint64_t vendor_id; /* 0x18..0x1f */
29 uint32_t device_id; /* 0x20..0x23 */
30 uint32_t version; /* 0x24..0x27 */
31 uint32_t date; /* 0x28..0x2b */
32 uint8_t name[19]; /* 0x2c..0x3e */
33 uint8_t record_type; /* 0x3f */
34};
35
36/*
37 * Component, 56 bytes at offset 8, 8-byte aligned
38 *
39 * The address range is first to last, inclusive
40 * (for example 0x100000 - 0x10ffff)
41 */
42struct sdb_component {
43 uint64_t addr_first; /* 0x08..0x0f */
44 uint64_t addr_last; /* 0x10..0x17 */
45 struct sdb_product product; /* 0x18..0x3f */
46};
47
48/* Type of the SDB record */
49enum sdb_record_type {
50 sdb_type_interconnect = 0x00,
51 sdb_type_device = 0x01,
52 sdb_type_bridge = 0x02,
53 sdb_type_integration = 0x80,
54 sdb_type_repo_url = 0x81,
55 sdb_type_synthesis = 0x82,
56 sdb_type_empty = 0xFF,
57};
58
59/* Type 0: interconnect (first of the array)
60 *
61 * sdb_records is the length of the table including this first
62 * record, version is 1. The bus type is enumerated later.
63 */
64#define SDB_MAGIC 0x5344422d /* "SDB-" */
65struct sdb_interconnect {
66 uint32_t sdb_magic; /* 0x00-0x03 */
67 uint16_t sdb_records; /* 0x04-0x05 */
68 uint8_t sdb_version; /* 0x06 */
69 uint8_t sdb_bus_type; /* 0x07 */
70 struct sdb_component sdb_component; /* 0x08-0x3f */
71};
72
73/* Type 1: device
74 *
75 * class is 0 for "custom device", other values are
76 * to be standardized; ABI version is for the driver,
77 * bus-specific bits are defined by each bus (see below)
78 */
79struct sdb_device {
80 uint16_t abi_class; /* 0x00-0x01 */
81 uint8_t abi_ver_major; /* 0x02 */
82 uint8_t abi_ver_minor; /* 0x03 */
83 uint32_t bus_specific; /* 0x04-0x07 */
84 struct sdb_component sdb_component; /* 0x08-0x3f */
85};
86
87/* Type 2: bridge
88 *
89 * child is the address of the nested SDB table
90 */
91struct sdb_bridge {
92 uint64_t sdb_child; /* 0x00-0x07 */
93 struct sdb_component sdb_component; /* 0x08-0x3f */
94};
95
96/* Type 0x80: integration
97 *
98 * all types with bit 7 set are meta-information, so
99 * software can ignore the types it doesn't know. Here we
100 * just provide product information for an aggregate device
101 */
102struct sdb_integration {
103 uint8_t reserved[24]; /* 0x00-0x17 */
104 struct sdb_product product; /* 0x08-0x3f */
105};
106
107/* Type 0x81: Top module repository url
108 *
109 * again, an informative field that software can ignore
110 */
111struct sdb_repo_url {
112 uint8_t repo_url[63]; /* 0x00-0x3e */
113 uint8_t record_type; /* 0x3f */
114};
115
116/* Type 0x82: Synthesis tool information
117 *
118 * this informative record
119 */
120struct sdb_synthesis {
121 uint8_t syn_name[16]; /* 0x00-0x0f */
122 uint8_t commit_id[16]; /* 0x10-0x1f */
123 uint8_t tool_name[8]; /* 0x20-0x27 */
124 uint32_t tool_version; /* 0x28-0x2b */
125 uint32_t date; /* 0x2c-0x2f */
126 uint8_t user_name[15]; /* 0x30-0x3e */
127 uint8_t record_type; /* 0x3f */
128};
129
130/* Type 0xff: empty
131 *
132 * this allows keeping empty slots during development,
133 * so they can be filled later with minimal efforts and
134 * no misleading description is ever shipped -- hopefully.
135 * It can also be used to pad a table to a desired length.
136 */
137struct sdb_empty {
138 uint8_t reserved[63]; /* 0x00-0x3e */
139 uint8_t record_type; /* 0x3f */
140};
141
142/* The type of bus, for bus-specific flags */
143enum sdb_bus_type {
144 sdb_wishbone = 0x00,
145 sdb_data = 0x01,
146};
147
148#define SDB_WB_WIDTH_MASK 0x0f
149#define SDB_WB_ACCESS8 0x01
150#define SDB_WB_ACCESS16 0x02
151#define SDB_WB_ACCESS32 0x04
152#define SDB_WB_ACCESS64 0x08
153#define SDB_WB_LITTLE_ENDIAN 0x80
154
155#define SDB_DATA_READ 0x04
156#define SDB_DATA_WRITE 0x02
157#define SDB_DATA_EXEC 0x01
158
159#endif /* __SDB_H__ */