ELF: Redone the .mmcu section
[simavr] / include / avr_mcu_section.h
1 /*
2         avr_mcu_section.h
3
4         Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
5
6         This file is part of simavr.
7
8         simavr is free software: you can redistribute it and/or modify
9         it under the terms of the GNU General Public License as published by
10         the Free Software Foundation, either version 3 of the License, or
11         (at your option) any later version.
12
13         simavr is distributed in the hope that it will be useful,
14         but WITHOUT ANY WARRANTY; without even the implied warranty of
15         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16         GNU General Public License for more details.
17
18         You should have received a copy of the GNU General Public License
19         along with simavr.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #ifndef __AVR_MCU_SECTION_H__
23 #define __AVR_MCU_SECTION_H__
24
25 /*
26  * This header is used to pass "parameters" to the programmer or the simulator,
27  * it tags the ELF file with a section that contains parameters about the physical
28  * AVR this was compiled for, including the speed, model, and signature bytes.
29  *
30  * A programmer software can read this and verify fuses values for example, and a
31  * simulator can instanciate the proper "model" of AVR, the speed and so on without
32  * command line parameters.
33  *
34  * Exemple of use:
35  *
36  * #include "avr_mcu_section.h"
37  * AVR_MCU(F_CPU, "atmega88");
38  *
39  */
40
41 #include <stdint.h>
42
43 enum {
44         AVR_MMCU_TAG = 0,
45         AVR_MMCU_TAG_NAME,
46         AVR_MMCU_TAG_FREQUENCY,
47         AVR_MMCU_TAG_LFUSE,
48         AVR_MMCU_TAG_HFUSE,
49         AVR_MMCU_TAG_EFUSE,
50         AVR_MMCU_TAG_SIGNATURE,
51         AVR_MMCU_TAG_VCD_FILENAME,
52         AVR_MMCU_TAG_VCD_PERIOD,        
53         AVR_MMCU_TAG_VCD_TRACE,
54 };
55
56 #if __AVR__
57
58 #define _MMCU_ __attribute__((section(".mmcu")))
59 struct avr_mmcu_long_t {
60         uint8_t tag;
61         uint8_t len;
62         uint32_t val; 
63 } __attribute__((__packed__));
64
65 struct avr_mmcu_string_t {
66         uint8_t tag;
67         uint8_t len;
68         char string[]; 
69 } __attribute__((__packed__));
70
71 struct avr_mmcu_vcd_trace_t {
72         uint8_t tag;
73         uint8_t len;
74         uint8_t mask;
75         void * what;
76         char name[]; 
77 } __attribute__((__packed__));
78
79 #define AVR_MCU_STRING(_tag, _str) \
80 const struct avr_mmcu_string_t _##_tag _MMCU_ = {\
81         .tag = _tag,\
82         .len = sizeof(_str),\
83         .string = _str,\
84 }
85
86 #define AVR_MCU_LONG(_tag, _val) \
87 const struct avr_mmcu_long_t _##_tag _MMCU_ = {\
88         .tag = _tag,\
89         .len = sizeof(uint32_t),\
90         .val = _val,\
91 }
92
93 #define AVR_MCU_BYTE(_tag, _val) \
94 const uint8_t _##_tag _MMCU_ = { _tag, 1, _val }
95
96 #define AVR_MCU_VCD_SYMBOL(_name) \
97         .tag = AVR_MMCU_TAG_VCD_TRACE, \
98         .len = sizeof(struct avr_mmcu_vcd_trace_t) - 2 + sizeof(_name),\
99         .name = _name
100
101 // specified the nane and wanted period (usec) for a VCD file
102 // thid is not mandatory, a default one will be created if
103 // symbols are declared themselves
104 #define AVR_MCU_VCD_FILE(_name, _period) \
105         AVR_MCU_STRING(AVR_MMCU_TAG_VCD_FILENAME, _name);\
106         AVR_MCU_LONG(AVR_MMCU_TAG_VCD_PERIOD, _period)
107
108 /*
109  * This the has to be used if you want to add other tags to the .mmcu section
110  * the _mmcu symbol is used as an anchor to make sure it stays linked in.
111  */
112 #define AVR_MCU(_speed, _name) \
113         const uint8_t _mmcu[2] _MMCU_ = { AVR_MMCU_TAG, 0 }; \
114         AVR_MCU_STRING(AVR_MMCU_TAG_NAME, _name);\
115         AVR_MCU_LONG(AVR_MMCU_TAG_FREQUENCY, _speed)
116
117 #endif /* __AVR__ */
118
119
120 #endif