master
c 616 lines 22.7 KB
Raw
1 /*
2 * Tenstorrent Atlantis RISC-V System on Chip
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 *
6 * Copyright 2025 Tenstorrent, Joel Stanley <joel@jms.id.au>
7 */
8
9 #include "qemu/osdep.h"
10 #include "qemu/cutils.h"
11 #include "qemu/error-report.h"
12 #include "qemu/guest-random.h"
13 #include "qemu/units.h"
14
15 #include "hw/core/boards.h"
16 #include "hw/core/loader.h"
17 #include "hw/core/sysbus.h"
18
19 #include "target/riscv/cpu.h"
20
21 #include "hw/riscv/boot.h"
22 #include "hw/riscv/fdt-common.h"
23 #include "hw/riscv/machines-qom.h"
24 #include "hw/riscv/riscv_hart.h"
25
26 #include "hw/char/serial-mm.h"
27 #include "hw/intc/riscv_aclint.h"
28 #include "hw/misc/unimp.h"
29
30 #include "system/system.h"
31 #include "system/device_tree.h"
32
33 #include "hw/riscv/tt_atlantis.h"
34
35 #include "aia.h"
36
37 #define TT_IRQCHIP_NUM_MSIS 255
38 #define TT_IRQCHIP_NUM_SOURCES 128
39 #define TT_IRQCHIP_NUM_PRIO_BITS 3
40 #define TT_IRQCHIP_GUESTS 63 /* aia_guests, gives guest_index_bits=6 */
41 #define TT_IRQCHIP_MIMSIC_STRIDE 0x40000
42
43 #define TT_ACLINT_MTIME_SIZE 0x8050
44 #define TT_ACLINT_MTIME 0x0
45 #define TT_ACLINT_MTIMECMP 0x8000
46 #define TT_ACLINT_TIMEBASE_FREQ 1000000000
47
48 static const MemMapEntry tt_atlantis_memmap[] = {
49 /* Keep sorted with :'<,'>!sort -g -k 4 */
50 [TT_ATL_DDR_LO] = { 0x00000000, 0x80000000 },
51 [TT_ATL_BOOTROM] = { 0x80000000, 0x2000 },
52 [TT_ATL_MIMSIC] = { 0xa0000000, 0x200000 },
53 [TT_ATL_ACLINT] = { 0xa2180000, 0x10000 },
54 [TT_ATL_SIMSIC] = { 0xa4000000, 0x200000 },
55 [TT_ATL_MAPLIC] = { 0xcc000000, 0x4000000 },
56 [TT_ATL_I2C0] = { 0xd4040000, 0x10000 },
57 [TT_ATL_I2C1] = { 0xd4050000, 0x10000 },
58 [TT_ATL_I2C2] = { 0xd4060000, 0x10000 },
59 [TT_ATL_I2C3] = { 0xd4070000, 0x10000 },
60 [TT_ATL_I2C4] = { 0xd4080000, 0x10000 },
61 [TT_ATL_UART1] = { 0xd4110000, 0x10000 },
62 [TT_ATL_SAPLIC] = { 0xe8000000, 0x4000000 },
63 [TT_ATL_DDR_HI] = { 0x100000000, 0x1000000000 },
64 };
65
66 static I2CBus *i2c_get_bus(TTAtlantisState *s, unsigned busnr)
67 {
68 assert(busnr < TT_ATL_NUM_I2C);
69
70 return s->i2c[busnr].bus;
71 }
72
73 static uint32_t fdt_phandle = 1;
74 static uint32_t next_phandle(void)
75 {
76 return fdt_phandle++;
77 }
78
79 static void create_fdt_memory(TTAtlantisState *s)
80 {
81 void *fdt = MACHINE(s)->fdt;
82 hwaddr size_lo = MACHINE(s)->ram_size;
83 hwaddr size_hi = 0;
84
85 if (size_lo > s->memmap[TT_ATL_DDR_LO].size) {
86 size_lo = s->memmap[TT_ATL_DDR_LO].size;
87 size_hi = MACHINE(s)->ram_size - size_lo;
88 }
89
90 create_fdt_socket_memory(fdt, s->memmap[TT_ATL_DDR_LO].base, size_lo,
91 0, false);
92 if (size_hi) {
93 /*
94 * The first part of the HI address is aliased at the LO address
95 * so do not include that as usable memory. Is there any way
96 * (or good reason) to describe that aliasing 2GB with DT?
97 */
98 create_fdt_socket_memory(fdt, s->memmap[TT_ATL_DDR_HI].base + size_lo,
99 size_hi, 0, false);
100 }
101 }
102
103 static void create_fdt_aclint(TTAtlantisState *s, uint32_t *intc_phandles)
104 {
105 void *fdt = MACHINE(s)->fdt;
106 g_autofree char *name = NULL;
107 g_autofree uint32_t *aclint_mtimer_cells = NULL;
108 uint32_t aclint_cells_size;
109 hwaddr addr;
110
111 aclint_mtimer_cells = g_new0(uint32_t, s->soc.num_harts * 2);
112
113 for (int cpu = 0; cpu < s->soc.num_harts; cpu++) {
114 aclint_mtimer_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
115 aclint_mtimer_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_TIMER);
116 }
117 aclint_cells_size = s->soc.num_harts * sizeof(uint32_t) * 2;
118
119 addr = s->memmap[TT_ATL_ACLINT].base;
120
121 name = g_strdup_printf("/soc/mtimer@%"HWADDR_PRIX, addr);
122 qemu_fdt_add_subnode(fdt, name);
123 qemu_fdt_setprop_string(fdt, name, "compatible", "riscv,aclint-mtimer");
124 qemu_fdt_setprop_sized_cells(fdt, name, "reg",
125 2, addr + TT_ACLINT_MTIME,
126 2, 0x1000,
127 2, addr + TT_ACLINT_MTIMECMP,
128 2, 0x1000);
129 qemu_fdt_setprop(fdt, name, "interrupts-extended",
130 aclint_mtimer_cells, aclint_cells_size);
131 }
132
133 static void create_fdt_one_imsic(void *fdt, const MemMapEntry *mem, int cpus,
134 uint32_t *intc_phandles, uint32_t msi_phandle,
135 int irq_line, uint32_t imsic_guest_bits)
136 {
137 g_autofree char *name = NULL;
138 g_autofree uint32_t *imsic_cells = g_new0(uint32_t, cpus * 2);
139
140 for (int cpu = 0; cpu < cpus; cpu++) {
141 imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
142 imsic_cells[cpu * 2 + 1] = cpu_to_be32(irq_line);
143 }
144
145 name = g_strdup_printf("/soc/interrupt-controller@%"HWADDR_PRIX, mem->base);
146 qemu_fdt_add_subnode(fdt, name);
147 qemu_fdt_setprop_string(fdt, name, "compatible", "riscv,imsics");
148
149 qemu_fdt_setprop_cell(fdt, name, "#interrupt-cells", 0);
150 qemu_fdt_setprop(fdt, name, "interrupt-controller", NULL, 0);
151 qemu_fdt_setprop(fdt, name, "msi-controller", NULL, 0);
152 qemu_fdt_setprop(fdt, name, "interrupts-extended",
153 imsic_cells, sizeof(uint32_t) * cpus * 2);
154 qemu_fdt_setprop_sized_cells(fdt, name, "reg", 2, mem->base, 2, mem->size);
155 qemu_fdt_setprop_cell(fdt, name, "riscv,num-ids", TT_IRQCHIP_NUM_MSIS);
156
157 if (imsic_guest_bits) {
158 qemu_fdt_setprop_cell(fdt, name, "riscv,guest-index-bits",
159 imsic_guest_bits);
160 }
161 qemu_fdt_setprop_cell(fdt, name, "phandle", msi_phandle);
162 }
163
164 static void create_fdt_one_aplic(void *fdt,
165 const MemMapEntry *mem,
166 uint32_t msi_phandle,
167 uint32_t *intc_phandles,
168 uint32_t aplic_phandle,
169 uint32_t aplic_child_phandle,
170 int irq_line, int num_harts)
171 {
172 g_autofree char *name =
173 g_strdup_printf("/soc/interrupt-controller@%"HWADDR_PRIX, mem->base);
174 g_autofree uint32_t *aplic_cells = g_new0(uint32_t, num_harts * 2);
175
176 for (int cpu = 0; cpu < num_harts; cpu++) {
177 aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
178 aplic_cells[cpu * 2 + 1] = cpu_to_be32(irq_line);
179 }
180
181 qemu_fdt_add_subnode(fdt, name);
182 qemu_fdt_setprop_string(fdt, name, "compatible", "riscv,aplic");
183 qemu_fdt_setprop_cell(fdt, name, "#address-cells", 0);
184 qemu_fdt_setprop_cell(fdt, name, "#interrupt-cells", 2);
185 qemu_fdt_setprop(fdt, name, "interrupt-controller", NULL, 0);
186
187 qemu_fdt_setprop(fdt, name, "interrupts-extended",
188 aplic_cells, num_harts * sizeof(uint32_t) * 2);
189 qemu_fdt_setprop_cell(fdt, name, "msi-parent", msi_phandle);
190
191 qemu_fdt_setprop_sized_cells(fdt, name, "reg", 2, mem->base, 2, mem->size);
192 qemu_fdt_setprop_cell(fdt, name, "riscv,num-sources",
193 TT_IRQCHIP_NUM_SOURCES);
194
195 if (aplic_child_phandle) {
196 qemu_fdt_setprop_cell(fdt, name, "riscv,children",
197 aplic_child_phandle);
198 qemu_fdt_setprop_cells(fdt, name, "riscv,delegation",
199 aplic_child_phandle, 1, TT_IRQCHIP_NUM_SOURCES);
200 }
201
202 qemu_fdt_setprop_cell(fdt, name, "phandle", aplic_phandle);
203 }
204
205 static void create_fdt_pmu(TTAtlantisState *s)
206 {
207 char pmu_name[] = "/pmu";
208 void *fdt = MACHINE(s)->fdt;
209 RISCVCPU *hart = &s->soc.harts[0];
210
211 qemu_fdt_add_subnode(fdt, pmu_name);
212 qemu_fdt_setprop_string(fdt, pmu_name, "compatible", "riscv,pmu");
213 riscv_pmu_generate_fdt_node(fdt, hart->pmu_avail_ctrs, pmu_name);
214 }
215
216 static void create_fdt_cpu(TTAtlantisState *s, const MemMapEntry *memmap,
217 uint32_t aplic_s_phandle,
218 uint32_t imsic_s_phandle)
219 {
220 MachineState *ms = MACHINE(s);
221 void *fdt = MACHINE(s)->fdt;
222 g_autofree uint32_t *intc_phandles = g_new0(uint32_t, ms->smp.cpus);
223
224 fdt_create_cpu_socket_subnode(fdt, TT_ACLINT_TIMEBASE_FREQ);
225
226 create_fdt_socket_cpus(fdt, s->soc.harts, 0, s->soc.num_harts,
227 s->soc.hartid_base, &fdt_phandle, intc_phandles,
228 false, false);
229
230 create_fdt_memory(s);
231
232 create_fdt_aclint(s, intc_phandles);
233
234 uint32_t imsic_guest_bits = imsic_num_bits(TT_IRQCHIP_GUESTS + 1);
235
236 /* M-level IMSIC node */
237 uint32_t msi_m_phandle = next_phandle();
238 create_fdt_one_imsic(fdt, &s->memmap[TT_ATL_MIMSIC], ms->smp.cpus,
239 intc_phandles, msi_m_phandle,
240 IRQ_M_EXT, imsic_guest_bits);
241
242 /* S-level IMSIC node */
243 create_fdt_one_imsic(fdt, &s->memmap[TT_ATL_SIMSIC], ms->smp.cpus,
244 intc_phandles, imsic_s_phandle,
245 IRQ_S_EXT, imsic_guest_bits);
246
247 uint32_t aplic_m_phandle = next_phandle();
248
249 /* M-level APLIC node */
250 create_fdt_one_aplic(fdt, &s->memmap[TT_ATL_MAPLIC],
251 msi_m_phandle, intc_phandles,
252 aplic_m_phandle, aplic_s_phandle,
253 IRQ_M_EXT, s->soc.num_harts);
254
255 /* S-level APLIC node */
256 create_fdt_one_aplic(fdt, &s->memmap[TT_ATL_SAPLIC],
257 imsic_s_phandle, intc_phandles,
258 aplic_s_phandle, 0,
259 IRQ_S_EXT, s->soc.num_harts);
260 }
261
262 static void create_fdt_uart(void *fdt, const MemMapEntry *mem, int irq,
263 int irqchip_phandle)
264 {
265 g_autofree char *name = g_strdup_printf("/soc/serial@%"HWADDR_PRIX,
266 mem->base);
267
268 qemu_fdt_add_subnode(fdt, name);
269 qemu_fdt_setprop_string(fdt, name, "compatible", "ns16550a");
270 qemu_fdt_setprop_sized_cells(fdt, name, "reg", 2, mem->base, 2, mem->size);
271 qemu_fdt_setprop_cell(fdt, name, "reg-shift", 2);
272 qemu_fdt_setprop_cell(fdt, name, "reg-io-width", 4);
273 qemu_fdt_setprop_cell(fdt, name, "clock-frequency", 3686400);
274 qemu_fdt_setprop_cell(fdt, name, "interrupt-parent", irqchip_phandle);
275 qemu_fdt_setprop_cells(fdt, name, "interrupts", irq, 0x4);
276
277 qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", name);
278 qemu_fdt_setprop_string(fdt, "/aliases", "serial0", name);
279 }
280
281 static void create_fdt_rng(void *fdt)
282 {
283 uint8_t rng_seed[32];
284
285 qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
286 qemu_fdt_setprop(fdt, "/chosen", "rng-seed", rng_seed, sizeof(rng_seed));
287 }
288
289 static void create_fdt_clk(void *fdt, const char *clock_name,
290 uint32_t freq, uint32_t phandle)
291 {
292 g_autofree char *name = g_strdup_printf("/clocks/%s", clock_name);
293
294 qemu_fdt_add_path(fdt, name);
295 qemu_fdt_setprop_string(fdt, name, "compatible", "fixed-clock");
296 qemu_fdt_setprop_string(fdt, name, "clock-output-names", clock_name);
297 qemu_fdt_setprop_cell(fdt, name, "#clock-cells", 0);
298 qemu_fdt_setprop_cell(fdt, name, "clock-frequency", freq);
299 qemu_fdt_setprop_cell(fdt, name, "phandle", phandle);
300 }
301
302 static void create_fdt_i2c(void *fdt, const MemMapEntry *mem, uint32_t irq,
303 uint32_t irqchip_phandle, uint32_t clk_phandle)
304 {
305 g_autofree char *name = g_strdup_printf("/soc/i2c@%"HWADDR_PRIX, mem->base);
306
307 qemu_fdt_add_subnode(fdt, name);
308 qemu_fdt_setprop_string(fdt, name, "compatible", "snps,designware-i2c");
309 qemu_fdt_setprop_sized_cells(fdt, name, "reg", 2, mem->base, 2, mem->size);
310 qemu_fdt_setprop_cell(fdt, name, "interrupt-parent", irqchip_phandle);
311 qemu_fdt_setprop_cells(fdt, name, "interrupts", irq, 0x4);
312 qemu_fdt_setprop_cell(fdt, name, "clocks", clk_phandle);
313 qemu_fdt_setprop_cell(fdt, name, "clock-frequency", 100000);
314 qemu_fdt_setprop_cell(fdt, name, "#address-cells", 1);
315 qemu_fdt_setprop_cell(fdt, name, "#size-cells", 0);
316 }
317
318 static void create_fdt_i2c_device(TTAtlantisState *s, int bus,
319 const char *compat, int addr)
320 {
321 void *fdt = MACHINE(s)->fdt;
322 hwaddr base = s->memmap[TT_ATL_I2C0 + bus].base;
323 g_autofree char *name = g_strdup_printf("/soc/i2c@%"HWADDR_PRIX"/sensor@%x",
324 base, addr);
325
326 qemu_fdt_add_subnode(fdt, name);
327 qemu_fdt_setprop_string(fdt, name, "compatible", compat);
328 qemu_fdt_setprop_cell(fdt, name, "reg", addr);
329 }
330
331 static void finalize_fdt(TTAtlantisState *s)
332 {
333 uint32_t aplic_s_phandle = next_phandle();
334 uint32_t imsic_s_phandle = next_phandle();
335 uint32_t periph_clk_phandle = next_phandle();
336 void *fdt = MACHINE(s)->fdt;
337
338 create_fdt_cpu(s, s->memmap, aplic_s_phandle, imsic_s_phandle);
339
340 /*
341 * We want to do this, but the Linux aplic driver was broken before v6.16
342 *
343 * qemu_fdt_setprop_cell(MACHINE(s)->fdt, "/soc", "interrupt-parent",
344 * aplic_s_phandle);
345 */
346
347 create_fdt_uart(fdt, &s->memmap[TT_ATL_UART1], TT_ATL_UART1_IRQ,
348 aplic_s_phandle);
349
350 create_fdt_clk(fdt, "periph-clk", 100000000, periph_clk_phandle);
351
352 for (int i = 0; i < TT_ATL_NUM_I2C; i++) {
353 create_fdt_i2c(fdt,
354 &s->memmap[TT_ATL_I2C0 + i],
355 TT_ATL_I2C0_IRQ + i,
356 aplic_s_phandle, periph_clk_phandle);
357 }
358
359 create_fdt_i2c_device(s, 0, "dallas,ds1338", 0x6f);
360 create_fdt_i2c_device(s, 4, "ti,tmp105", 0x48);
361 }
362
363 static void create_fdt(TTAtlantisState *s)
364 {
365 MachineState *ms = MACHINE(s);
366
367 ms->fdt = create_board_device_tree("Tenstorrent Atlantis RISC-V Machine",
368 "tenstorrent,atlantis", &s->fdt_size);
369
370 qemu_fdt_add_subnode(ms->fdt, "/chosen");
371
372 create_fdt_rng(ms->fdt);
373
374 qemu_fdt_add_subnode(ms->fdt, "/aliases");
375
376 create_fdt_pmu(s);
377 }
378
379 static void load_fdt(TTAtlantisState *s)
380 {
381 MachineState *ms = MACHINE(s);
382 char **node_path;
383 Error *err = NULL;
384
385 ms->fdt = load_device_tree(ms->dtb, &s->fdt_size);
386 if (!ms->fdt) {
387 error_report("load_device_tree() failed");
388 exit(1);
389 }
390
391 qemu_fdt_add_path(ms->fdt, "/chosen");
392
393 /* Clear memory nodes and update with the specified RAM size */
394 node_path = qemu_fdt_node_unit_path(ms->fdt, "memory", &err);
395 if (err) {
396 warn_report_err(err);
397 } else {
398 for (int i = 0; node_path[i]; i++) {
399 warn_report("Replacing device tree %s with the requested RAM size",
400 node_path[i]);
401 qemu_fdt_nop_node(ms->fdt, node_path[i]);
402 }
403 g_strfreev(node_path);
404 }
405
406 create_fdt_memory(s);
407 }
408
409 static void tt_atlantis_machine_done(Notifier *notifier, void *data)
410 {
411 TTAtlantisState *s = container_of(notifier, TTAtlantisState, machine_done);
412 MachineState *machine = MACHINE(s);
413 hwaddr start_addr = s->memmap[TT_ATL_DDR_LO].base;
414 hwaddr mem_size;
415 target_ulong firmware_end_addr, kernel_start_addr;
416 const char *firmware_name = riscv_default_firmware_name(&s->soc);
417 uint64_t fdt_load_addr;
418 uint64_t kernel_entry;
419 RISCVBootInfo boot_info;
420
421 /*
422 * A user provided dtb must include everything, including
423 * dynamic sysbus devices. Our FDT needs to be finalized.
424 */
425 if (machine->dtb == NULL) {
426 finalize_fdt(s);
427 }
428
429 mem_size = machine->ram_size;
430 if (mem_size > s->memmap[TT_ATL_DDR_LO].size) {
431 mem_size = s->memmap[TT_ATL_DDR_LO].size;
432 }
433 riscv_boot_info_init_discontig_mem(&boot_info, &s->soc,
434 s->memmap[TT_ATL_DDR_LO].base,
435 mem_size);
436
437 firmware_end_addr = riscv_find_and_load_firmware(machine, &boot_info,
438 firmware_name,
439 &start_addr, NULL);
440
441 kernel_start_addr = riscv_calc_kernel_start_addr(&boot_info,
442 firmware_end_addr);
443 if (machine->kernel_filename) {
444 riscv_load_kernel(machine, &boot_info, kernel_start_addr,
445 true, NULL);
446 kernel_entry = boot_info.image_low_addr;
447 } else {
448 /* If we aren't loading a payload, OpenSBI thinks we are trying to boot
449 * address 0, which fails `sbi_domain_check_addr()` as that is where
450 * OpenSBI is running. Instead point OpenSBI to the end of the region
451 * where it was loaded, which avoids the early hang, allowing the
452 * system to proceed with the OpenSBI boot output.
453 */
454 kernel_entry = kernel_start_addr;
455 }
456
457 fdt_load_addr = riscv_compute_fdt_addr(s->memmap[TT_ATL_DDR_LO].base,
458 s->memmap[TT_ATL_DDR_LO].size,
459 machine, &boot_info);
460 riscv_load_fdt(fdt_load_addr, machine->fdt);
461
462 /* load the reset vector */
463 riscv_setup_rom_reset_vec(machine, &s->soc, start_addr,
464 s->memmap[TT_ATL_BOOTROM].base,
465 s->memmap[TT_ATL_BOOTROM].size,
466 kernel_entry,
467 fdt_load_addr);
468 }
469
470 static void tt_atlantis_machine_init(MachineState *machine)
471 {
472 TTAtlantisState *s = TT_ATLANTIS_MACHINE(machine);
473
474 MemoryRegion *system_memory = get_system_memory();
475 MemoryRegion *ram_hi = g_new(MemoryRegion, 1);
476 MemoryRegion *ram_lo = g_new(MemoryRegion, 1);
477 MemoryRegion *bootrom = g_new(MemoryRegion, 1);
478 ram_addr_t lo_ram_size;
479 int hart_count = machine->smp.cpus;
480
481 s->memmap = tt_atlantis_memmap;
482
483 object_initialize_child(OBJECT(machine), "soc", &s->soc,
484 TYPE_RISCV_HART_ARRAY);
485 object_property_set_str(OBJECT(&s->soc), "cpu-type", machine->cpu_type,
486 &error_abort);
487 object_property_set_int(OBJECT(&s->soc), "hartid-base", 0,
488 &error_abort);
489 object_property_set_int(OBJECT(&s->soc), "num-harts", hart_count,
490 &error_abort);
491 object_property_set_int(OBJECT(&s->soc), "resetvec",
492 s->memmap[TT_ATL_BOOTROM].base,
493 &error_abort);
494 sysbus_realize(SYS_BUS_DEVICE(&s->soc), &error_fatal);
495
496 s->irqchip = riscv_create_aia(true, TT_IRQCHIP_GUESTS,
497 TT_IRQCHIP_MIMSIC_STRIDE,
498 TT_IRQCHIP_NUM_SOURCES,
499 &s->memmap[TT_ATL_MAPLIC],
500 &s->memmap[TT_ATL_SAPLIC],
501 &s->memmap[TT_ATL_MIMSIC],
502 &s->memmap[TT_ATL_SIMSIC],
503 0, 0, hart_count,
504 TT_IRQCHIP_NUM_MSIS,
505 TT_IRQCHIP_NUM_PRIO_BITS);
506
507 riscv_aclint_mtimer_create(s->memmap[TT_ATL_ACLINT].base,
508 TT_ACLINT_MTIME_SIZE,
509 0, hart_count,
510 TT_ACLINT_MTIMECMP,
511 TT_ACLINT_MTIME,
512 TT_ACLINT_TIMEBASE_FREQ, true);
513
514 /*
515 * DDR
516 *
517 * The high address is where RAM lives. It is always present and may be
518 * up to 64GB. The low address is an alias of the first 2GB of that RAM.
519 */
520 if (machine->ram_size > s->memmap[TT_ATL_DDR_HI].size) {
521 char *sz = size_to_str(s->memmap[TT_ATL_DDR_HI].size);
522 error_report("RAM size is too large, maximum is %s", sz);
523 g_free(sz);
524 exit(EXIT_FAILURE);
525 }
526
527 memory_region_init_alias(ram_hi, OBJECT(machine), "ram.high", machine->ram,
528 0, machine->ram_size);
529 memory_region_add_subregion(system_memory,
530 s->memmap[TT_ATL_DDR_HI].base, ram_hi);
531
532 lo_ram_size = MIN(machine->ram_size, s->memmap[TT_ATL_DDR_LO].size);
533 memory_region_init_alias(ram_lo, OBJECT(machine), "ram.low", machine->ram,
534 0, lo_ram_size);
535 memory_region_add_subregion(system_memory,
536 s->memmap[TT_ATL_DDR_LO].base, ram_lo);
537
538 /* Boot ROM */
539 memory_region_init_rom(bootrom, NULL, "tt-atlantis.bootrom",
540 s->memmap[TT_ATL_BOOTROM].size, &error_fatal);
541 memory_region_add_subregion(system_memory, s->memmap[TT_ATL_BOOTROM].base,
542 bootrom);
543
544 /* UART1, the soc console (UART0 is for the boot microcontroller) */
545 serial_mm_init(system_memory, s->memmap[TT_ATL_UART1].base, 2,
546 qdev_get_gpio_in(s->irqchip, TT_ATL_UART1_IRQ),
547 115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
548 /*
549 * Atlantis contains a DesignWare uart while the QEMU machine
550 * uses the serial_mm model with the base ns16550 register set.
551 * Linux's dw driver writes outside of serial_mm's 0x20 sized
552 * mapping and faults.
553 *
554 * Create an unimplemented device region so writes don't fault
555 * and reads return zero, which keeps Linux happy.
556 */
557 create_unimplemented_device("tt-atlantis.uart0",
558 s->memmap[TT_ATL_UART1].base,
559 s->memmap[TT_ATL_UART1].size);
560
561 /* I2C */
562 for (int i = 0; i < TT_ATL_NUM_I2C; i++) {
563 SysBusDevice *sbd;
564
565 object_initialize_child(OBJECT(s), "i2c[*]", &s->i2c[i],
566 TYPE_DESIGNWARE_I2C);
567 sbd = SYS_BUS_DEVICE(&s->i2c[i]);
568 sysbus_realize(sbd, &error_fatal);
569 memory_region_add_subregion(system_memory,
570 s->memmap[TT_ATL_I2C0 + i].base,
571 sysbus_mmio_get_region(sbd, 0));
572 sysbus_connect_irq(sbd, 0,
573 qdev_get_gpio_in(s->irqchip, TT_ATL_I2C0_IRQ + i));
574 }
575
576 /* I2C peripherals: qemu specific */
577 i2c_slave_create_simple(i2c_get_bus(s, 0), "ds1338", 0x6f);
578 i2c_slave_create_simple(i2c_get_bus(s, 4), "tmp105", 0x48);
579
580 /* Load or create device tree */
581 if (machine->dtb) {
582 load_fdt(s);
583 } else {
584 create_fdt(s);
585 }
586
587 s->machine_done.notify = tt_atlantis_machine_done;
588 qemu_add_machine_init_done_notifier(&s->machine_done);
589 }
590
591 static void tt_atlantis_machine_class_init(ObjectClass *oc, const void *data)
592 {
593 MachineClass *mc = MACHINE_CLASS(oc);
594
595 mc->desc = "Tenstorrent Atlantis RISC-V SoC (Experimental)";
596 mc->init = tt_atlantis_machine_init;
597 mc->max_cpus = 8;
598 mc->default_cpus = 8;
599 mc->default_ram_size = 4 * GiB;
600 mc->default_cpu_type = TYPE_RISCV_CPU_TT_ASCALON;
601 mc->block_default_type = IF_VIRTIO;
602 mc->no_cdrom = 1;
603 mc->default_ram_id = "tt_atlantis.ram";
604 }
605
606 static const TypeInfo tt_atlantis_types[] = {
607 {
608 .name = MACHINE_TYPE_NAME("tt-atlantis"),
609 .parent = TYPE_MACHINE,
610 .class_init = tt_atlantis_machine_class_init,
611 .instance_size = sizeof(TTAtlantisState),
612 .interfaces = riscv64_machine_interfaces,
613 },
614 };
615
616 DEFINE_TYPES(tt_atlantis_types)