root / hw / lm32_hwsetup.h @ 51387f86
History | View | Annotate | Download (5 kB)
1 | e5f799a2 | Michael Walle | /*
|
---|---|---|---|
2 | e5f799a2 | Michael Walle | * LatticeMico32 hwsetup helper functions.
|
3 | e5f799a2 | Michael Walle | *
|
4 | e5f799a2 | Michael Walle | * Copyright (c) 2010 Michael Walle <michael@walle.cc>
|
5 | e5f799a2 | Michael Walle | *
|
6 | e5f799a2 | Michael Walle | * This library is free software; you can redistribute it and/or
|
7 | e5f799a2 | Michael Walle | * modify it under the terms of the GNU Lesser General Public
|
8 | e5f799a2 | Michael Walle | * License as published by the Free Software Foundation; either
|
9 | e5f799a2 | Michael Walle | * version 2 of the License, or (at your option) any later version.
|
10 | e5f799a2 | Michael Walle | *
|
11 | e5f799a2 | Michael Walle | * This library is distributed in the hope that it will be useful,
|
12 | e5f799a2 | Michael Walle | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | e5f799a2 | Michael Walle | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | e5f799a2 | Michael Walle | * Lesser General Public License for more details.
|
15 | e5f799a2 | Michael Walle | *
|
16 | e5f799a2 | Michael Walle | * You should have received a copy of the GNU Lesser General Public
|
17 | e5f799a2 | Michael Walle | * License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
18 | e5f799a2 | Michael Walle | */
|
19 | e5f799a2 | Michael Walle | |
20 | e5f799a2 | Michael Walle | /*
|
21 | e5f799a2 | Michael Walle | * These are helper functions for creating the hardware description blob used
|
22 | e5f799a2 | Michael Walle | * in the Theobroma's uClinux port.
|
23 | e5f799a2 | Michael Walle | */
|
24 | e5f799a2 | Michael Walle | |
25 | e5f799a2 | Michael Walle | #ifndef QEMU_HW_LM32_HWSETUP_H
|
26 | e5f799a2 | Michael Walle | #define QEMU_HW_LM32_HWSETUP_H
|
27 | e5f799a2 | Michael Walle | |
28 | e5f799a2 | Michael Walle | #include "qemu-common.h" |
29 | e5f799a2 | Michael Walle | #include "loader.h" |
30 | e5f799a2 | Michael Walle | |
31 | e5f799a2 | Michael Walle | typedef struct { |
32 | e5f799a2 | Michael Walle | void *data;
|
33 | e5f799a2 | Michael Walle | void *ptr;
|
34 | e5f799a2 | Michael Walle | } HWSetup; |
35 | e5f799a2 | Michael Walle | |
36 | e5f799a2 | Michael Walle | enum hwsetup_tag {
|
37 | e5f799a2 | Michael Walle | HWSETUP_TAG_EOL = 0,
|
38 | e5f799a2 | Michael Walle | HWSETUP_TAG_CPU = 1,
|
39 | e5f799a2 | Michael Walle | HWSETUP_TAG_ASRAM = 2,
|
40 | e5f799a2 | Michael Walle | HWSETUP_TAG_FLASH = 3,
|
41 | e5f799a2 | Michael Walle | HWSETUP_TAG_SDRAM = 4,
|
42 | e5f799a2 | Michael Walle | HWSETUP_TAG_OCM = 5,
|
43 | e5f799a2 | Michael Walle | HWSETUP_TAG_DDR_SDRAM = 6,
|
44 | e5f799a2 | Michael Walle | HWSETUP_TAG_DDR2_SDRAM = 7,
|
45 | e5f799a2 | Michael Walle | HWSETUP_TAG_TIMER = 8,
|
46 | e5f799a2 | Michael Walle | HWSETUP_TAG_UART = 9,
|
47 | e5f799a2 | Michael Walle | HWSETUP_TAG_GPIO = 10,
|
48 | e5f799a2 | Michael Walle | HWSETUP_TAG_TRISPEEDMAC = 11,
|
49 | e5f799a2 | Michael Walle | HWSETUP_TAG_I2CM = 12,
|
50 | e5f799a2 | Michael Walle | HWSETUP_TAG_LEDS = 13,
|
51 | e5f799a2 | Michael Walle | HWSETUP_TAG_7SEG = 14,
|
52 | e5f799a2 | Michael Walle | HWSETUP_TAG_SPI_S = 15,
|
53 | e5f799a2 | Michael Walle | HWSETUP_TAG_SPI_M = 16,
|
54 | e5f799a2 | Michael Walle | }; |
55 | e5f799a2 | Michael Walle | |
56 | e5f799a2 | Michael Walle | static inline HWSetup *hwsetup_init(void) |
57 | e5f799a2 | Michael Walle | { |
58 | e5f799a2 | Michael Walle | HWSetup *hw; |
59 | e5f799a2 | Michael Walle | |
60 | e5f799a2 | Michael Walle | hw = qemu_malloc(sizeof(HWSetup));
|
61 | e5f799a2 | Michael Walle | hw->data = qemu_mallocz(TARGET_PAGE_SIZE); |
62 | e5f799a2 | Michael Walle | hw->ptr = hw->data; |
63 | e5f799a2 | Michael Walle | |
64 | e5f799a2 | Michael Walle | return hw;
|
65 | e5f799a2 | Michael Walle | } |
66 | e5f799a2 | Michael Walle | |
67 | e5f799a2 | Michael Walle | static inline void hwsetup_free(HWSetup *hw) |
68 | e5f799a2 | Michael Walle | { |
69 | e5f799a2 | Michael Walle | qemu_free(hw->data); |
70 | e5f799a2 | Michael Walle | qemu_free(hw); |
71 | e5f799a2 | Michael Walle | } |
72 | e5f799a2 | Michael Walle | |
73 | e5f799a2 | Michael Walle | static inline void hwsetup_create_rom(HWSetup *hw, |
74 | e5f799a2 | Michael Walle | target_phys_addr_t base) |
75 | e5f799a2 | Michael Walle | { |
76 | e5f799a2 | Michael Walle | rom_add_blob("hwsetup", hw->data, TARGET_PAGE_SIZE, base);
|
77 | e5f799a2 | Michael Walle | } |
78 | e5f799a2 | Michael Walle | |
79 | e5f799a2 | Michael Walle | static inline void hwsetup_add_u8(HWSetup *hw, uint8_t u) |
80 | e5f799a2 | Michael Walle | { |
81 | e5f799a2 | Michael Walle | stb_p(hw->ptr, u); |
82 | e5f799a2 | Michael Walle | hw->ptr += 1;
|
83 | e5f799a2 | Michael Walle | } |
84 | e5f799a2 | Michael Walle | |
85 | e5f799a2 | Michael Walle | static inline void hwsetup_add_u32(HWSetup *hw, uint32_t u) |
86 | e5f799a2 | Michael Walle | { |
87 | e5f799a2 | Michael Walle | stl_p(hw->ptr, u); |
88 | e5f799a2 | Michael Walle | hw->ptr += 4;
|
89 | e5f799a2 | Michael Walle | } |
90 | e5f799a2 | Michael Walle | |
91 | e5f799a2 | Michael Walle | static inline void hwsetup_add_tag(HWSetup *hw, enum hwsetup_tag t) |
92 | e5f799a2 | Michael Walle | { |
93 | e5f799a2 | Michael Walle | stl_p(hw->ptr, t); |
94 | e5f799a2 | Michael Walle | hw->ptr += 4;
|
95 | e5f799a2 | Michael Walle | } |
96 | e5f799a2 | Michael Walle | |
97 | e5f799a2 | Michael Walle | static inline void hwsetup_add_str(HWSetup *hw, const char *str) |
98 | e5f799a2 | Michael Walle | { |
99 | e5f799a2 | Michael Walle | strncpy(hw->ptr, str, 31); /* make sure last byte is zero */ |
100 | e5f799a2 | Michael Walle | hw->ptr += 32;
|
101 | e5f799a2 | Michael Walle | } |
102 | e5f799a2 | Michael Walle | |
103 | e5f799a2 | Michael Walle | static inline void hwsetup_add_trailer(HWSetup *hw) |
104 | e5f799a2 | Michael Walle | { |
105 | e5f799a2 | Michael Walle | hwsetup_add_u32(hw, 8); /* size */ |
106 | e5f799a2 | Michael Walle | hwsetup_add_tag(hw, HWSETUP_TAG_EOL); |
107 | e5f799a2 | Michael Walle | } |
108 | e5f799a2 | Michael Walle | |
109 | e5f799a2 | Michael Walle | static inline void hwsetup_add_cpu(HWSetup *hw, |
110 | e5f799a2 | Michael Walle | const char *name, uint32_t frequency) |
111 | e5f799a2 | Michael Walle | { |
112 | e5f799a2 | Michael Walle | hwsetup_add_u32(hw, 44); /* size */ |
113 | e5f799a2 | Michael Walle | hwsetup_add_tag(hw, HWSETUP_TAG_CPU); |
114 | e5f799a2 | Michael Walle | hwsetup_add_str(hw, name); |
115 | e5f799a2 | Michael Walle | hwsetup_add_u32(hw, frequency); |
116 | e5f799a2 | Michael Walle | } |
117 | e5f799a2 | Michael Walle | |
118 | e5f799a2 | Michael Walle | static inline void hwsetup_add_flash(HWSetup *hw, |
119 | e5f799a2 | Michael Walle | const char *name, uint32_t base, uint32_t size) |
120 | e5f799a2 | Michael Walle | { |
121 | e5f799a2 | Michael Walle | hwsetup_add_u32(hw, 52); /* size */ |
122 | e5f799a2 | Michael Walle | hwsetup_add_tag(hw, HWSETUP_TAG_FLASH); |
123 | e5f799a2 | Michael Walle | hwsetup_add_str(hw, name); |
124 | e5f799a2 | Michael Walle | hwsetup_add_u32(hw, base); |
125 | e5f799a2 | Michael Walle | hwsetup_add_u32(hw, size); |
126 | e5f799a2 | Michael Walle | hwsetup_add_u8(hw, 8); /* read latency */ |
127 | e5f799a2 | Michael Walle | hwsetup_add_u8(hw, 8); /* write latency */ |
128 | e5f799a2 | Michael Walle | hwsetup_add_u8(hw, 25); /* address width */ |
129 | e5f799a2 | Michael Walle | hwsetup_add_u8(hw, 32); /* data width */ |
130 | e5f799a2 | Michael Walle | } |
131 | e5f799a2 | Michael Walle | |
132 | e5f799a2 | Michael Walle | static inline void hwsetup_add_ddr_sdram(HWSetup *hw, |
133 | e5f799a2 | Michael Walle | const char *name, uint32_t base, uint32_t size) |
134 | e5f799a2 | Michael Walle | { |
135 | e5f799a2 | Michael Walle | hwsetup_add_u32(hw, 48); /* size */ |
136 | e5f799a2 | Michael Walle | hwsetup_add_tag(hw, HWSETUP_TAG_DDR_SDRAM); |
137 | e5f799a2 | Michael Walle | hwsetup_add_str(hw, name); |
138 | e5f799a2 | Michael Walle | hwsetup_add_u32(hw, base); |
139 | e5f799a2 | Michael Walle | hwsetup_add_u32(hw, size); |
140 | e5f799a2 | Michael Walle | } |
141 | e5f799a2 | Michael Walle | |
142 | e5f799a2 | Michael Walle | static inline void hwsetup_add_timer(HWSetup *hw, |
143 | e5f799a2 | Michael Walle | const char *name, uint32_t base, uint32_t irq) |
144 | e5f799a2 | Michael Walle | { |
145 | e5f799a2 | Michael Walle | hwsetup_add_u32(hw, 56); /* size */ |
146 | e5f799a2 | Michael Walle | hwsetup_add_tag(hw, HWSETUP_TAG_TIMER); |
147 | e5f799a2 | Michael Walle | hwsetup_add_str(hw, name); |
148 | e5f799a2 | Michael Walle | hwsetup_add_u32(hw, base); |
149 | e5f799a2 | Michael Walle | hwsetup_add_u8(hw, 1); /* wr_tickcount */ |
150 | e5f799a2 | Michael Walle | hwsetup_add_u8(hw, 1); /* rd_tickcount */ |
151 | e5f799a2 | Michael Walle | hwsetup_add_u8(hw, 1); /* start_stop_control */ |
152 | e5f799a2 | Michael Walle | hwsetup_add_u8(hw, 32); /* counter_width */ |
153 | e5f799a2 | Michael Walle | hwsetup_add_u32(hw, 20); /* reload_ticks */ |
154 | e5f799a2 | Michael Walle | hwsetup_add_u8(hw, irq); |
155 | e5f799a2 | Michael Walle | hwsetup_add_u8(hw, 0); /* padding */ |
156 | e5f799a2 | Michael Walle | hwsetup_add_u8(hw, 0); /* padding */ |
157 | e5f799a2 | Michael Walle | hwsetup_add_u8(hw, 0); /* padding */ |
158 | e5f799a2 | Michael Walle | } |
159 | e5f799a2 | Michael Walle | |
160 | e5f799a2 | Michael Walle | static inline void hwsetup_add_uart(HWSetup *hw, |
161 | e5f799a2 | Michael Walle | const char *name, uint32_t base, uint32_t irq) |
162 | e5f799a2 | Michael Walle | { |
163 | e5f799a2 | Michael Walle | hwsetup_add_u32(hw, 56); /* size */ |
164 | e5f799a2 | Michael Walle | hwsetup_add_tag(hw, HWSETUP_TAG_UART); |
165 | e5f799a2 | Michael Walle | hwsetup_add_str(hw, name); |
166 | e5f799a2 | Michael Walle | hwsetup_add_u32(hw, base); |
167 | e5f799a2 | Michael Walle | hwsetup_add_u32(hw, 115200); /* baudrate */ |
168 | e5f799a2 | Michael Walle | hwsetup_add_u8(hw, 8); /* databits */ |
169 | e5f799a2 | Michael Walle | hwsetup_add_u8(hw, 1); /* stopbits */ |
170 | e5f799a2 | Michael Walle | hwsetup_add_u8(hw, 1); /* use_interrupt */ |
171 | e5f799a2 | Michael Walle | hwsetup_add_u8(hw, 1); /* block_on_transmit */ |
172 | e5f799a2 | Michael Walle | hwsetup_add_u8(hw, 1); /* block_on_receive */ |
173 | e5f799a2 | Michael Walle | hwsetup_add_u8(hw, 4); /* rx_buffer_size */ |
174 | e5f799a2 | Michael Walle | hwsetup_add_u8(hw, 4); /* tx_buffer_size */ |
175 | e5f799a2 | Michael Walle | hwsetup_add_u8(hw, irq); |
176 | e5f799a2 | Michael Walle | } |
177 | e5f799a2 | Michael Walle | |
178 | e5f799a2 | Michael Walle | #endif /* QEMU_HW_LM32_HWSETUP_H */ |