1 /*
2 * Copyright (c) 2018 Travis Geiselbrecht
3 *
4 * Use of this source code is governed by a MIT-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/MIT
7 */
8 #include <lk/reg.h>
9 #include <lk/trace.h>
10 #include <kernel/thread.h>
11 #include <platform.h>
12 #include <platform/interrupts.h>
13 #include <platform/debug.h>
14 #include <platform/timer.h>
15 #include <platform/virt.h>
16 #include <sys/types.h>
17 #include <dev/virtio.h>
18 #include <dev/virtio/net.h>
19 #if WITH_LIB_MINIP
20 #include <lib/minip.h>
21 #endif
22 #if WITH_KERNEL_VM
23 #include <kernel/vm.h>
24 #else
25 #include <kernel/novm.h>
26 #endif
27 #if WITH_LIB_CONSOLE
28 #include <lib/console.h>
29 #endif
30
31 #include "platform_p.h"
32
33 #define LOCAL_TRACE 0
34
35 extern ulong lk_boot_args[4];
36
37 #if WITH_KERNEL_VM
38 #define DEFAULT_MEMORY_SIZE (MEMSIZE) /* try to fetch from the emulator via the fdt */
39
40 static pmm_arena_t arena = {
41 .name = "ram",
42 .base = MEMORY_BASE_PHYS,
43 .size = DEFAULT_MEMORY_SIZE,
44 .flags = PMM_ARENA_FLAG_KMAP,
45 };
46 #endif
47
platform_early_init(void)48 void platform_early_init(void) {
49 goldfish_tty_early_init();
50 pic_early_init();
51 goldfish_rtc_early_init();
52 #if 0
53 plic_early_init();
54
55 LTRACEF("starting FDT scan\n");
56
57 /* look for a flattened device tree in the second arg passed to us */
58 bool found_mem = false;
59 int cpu_count = 0;
60 const void *fdt = (void *)lk_boot_args[1];
61 #if WITH_KERNEL_VM
62 fdt = (const void *)((uintptr_t)fdt + PERIPHERAL_BASE_VIRT);
63 #endif
64
65 struct fdt_walk_callbacks cb = {
66 .mem = memcallback,
67 .memcookie = &found_mem,
68 .cpu = cpucallback,
69 .cpucookie = &cpu_count,
70 };
71
72 status_t err = fdt_walk(fdt, &cb);
73 LTRACEF("fdt_walk returns %d\n", err);
74
75 if (err != 0) {
76 printf("FDT: error finding FDT at %p, using default memory & cpu count\n", fdt);
77 }
78
79 if (!found_mem) {
80 #if WITH_KERNEL_VM
81 pmm_add_arena(&arena);
82 #else
83 novm_add_arena("default", MEMBASE, MEMSIZE);
84 #endif
85 }
86
87 if (cpu_count > 0) {
88 printf("FDT: found %d cpus\n", cpu_count);
89 riscv_set_secondary_count(cpu_count - 1);
90 }
91
92 #if WITH_KERNEL_VM
93 /* reserve the first 256K of ram which is marked protected by the PMP in firmware */
94 struct list_node list = LIST_INITIAL_VALUE(list);
95 pmm_alloc_range(MEMBASE, 0x40000 / PAGE_SIZE, &list);
96 #endif
97
98 LTRACEF("done scanning FDT\n");
99
100 /* save a copy of the pointer to the poweroff/reset register */
101 /* TODO: read it from the FDT */
102 #if WITH_KERNEL_VM
103 power_reset_reg = paddr_to_kvaddr(0x100000);
104 #else
105 power_reset_reg = (void *)0x100000;
106 #endif
107 #endif
108 }
109
platform_init(void)110 void platform_init(void) {
111 pic_init();
112 goldfish_tty_init();
113 goldfish_rtc_init();
114 #if 0
115 plic_init();
116 uart_init();
117
118 /* detect any virtio devices */
119 uint virtio_irqs[NUM_VIRTIO_TRANSPORTS];
120 for (int i = 0; i < NUM_VIRTIO_TRANSPORTS; i++) {
121 virtio_irqs[i] = IRQ_VIRTIO_BASE + i;
122 }
123
124 virtio_mmio_detect((void *)VIRTIO_BASE_VIRT, NUM_VIRTIO_TRANSPORTS, virtio_irqs, VIRTIO_STRIDE);
125
126 #if WITH_LIB_MINIP
127 if (virtio_net_found() > 0) {
128 uint8_t mac_addr[6];
129
130 virtio_net_get_mac_addr(mac_addr);
131
132 TRACEF("found virtio networking interface\n");
133
134 /* start minip */
135 minip_set_macaddr(mac_addr);
136
137 __UNUSED uint32_t ip_addr = IPV4(192, 168, 0, 99);
138 __UNUSED uint32_t ip_mask = IPV4(255, 255, 255, 0);
139 __UNUSED uint32_t ip_gateway = IPV4_NONE;
140
141 //minip_init(virtio_net_send_minip_pkt, NULL, ip_addr, ip_mask, ip_gateway);
142 minip_init_dhcp(virtio_net_send_minip_pkt, NULL);
143
144 virtio_net_start();
145 }
146 #endif
147 #endif
148 }
149
150 #if 0
151 void platform_halt(platform_halt_action suggested_action,
152 platform_halt_reason reason) {
153 switch (suggested_action) {
154 case HALT_ACTION_SHUTDOWN:
155 dprintf(ALWAYS, "Shutting down... (reason = %d)\n", reason);
156 *power_reset_reg = 0x5555;
157 break;
158 case HALT_ACTION_REBOOT:
159 dprintf(ALWAYS, "Rebooting... (reason = %d)\n", reason);
160 *power_reset_reg = 0x7777;
161 break;
162 case HALT_ACTION_HALT:
163 #if ENABLE_PANIC_SHELL
164 if (reason == HALT_REASON_SW_PANIC) {
165 dprintf(ALWAYS, "CRASH: starting debug shell... (reason = %d)\n", reason);
166 arch_disable_ints();
167 panic_shell_start();
168 }
169 #endif // ENABLE_PANIC_SHELL
170 dprintf(ALWAYS, "HALT: spinning forever... (reason = %d)\n", reason);
171 break;
172 }
173
174 arch_disable_ints();
175 for (;;)
176 arch_idle();
177 }
178 #endif
179