21
#include "qemu/osdep.h"
22
#include "qemu/units.h"
23
#include "qemu/cutils.h"
26
#include "hw/mips/loongson3_bootp.h"
28
static void init_cpu_info(void *g_cpuinfo, uint64_t cpu_freq)
30
struct efi_cpuinfo_loongson *c = g_cpuinfo;
32
c->cputype = cpu_to_le32(Loongson_3A);
33
c->processor_id = cpu_to_le32(MIPS_CPU(first_cpu)->env.CP0_PRid);
34
if (cpu_freq > UINT_MAX) {
35
c->cpu_clock_freq = cpu_to_le32(UINT_MAX);
37
c->cpu_clock_freq = cpu_to_le32(cpu_freq);
40
c->cpu_startup_core_id = cpu_to_le16(0);
41
c->nr_cpus = cpu_to_le32(current_machine->smp.cpus);
42
c->total_node = cpu_to_le32(DIV_ROUND_UP(current_machine->smp.cpus,
43
LOONGSON3_CORE_PER_NODE));
46
static void init_memory_map(void *g_map, uint64_t ram_size)
48
struct efi_memory_map_loongson *emap = g_map;
50
emap->nr_map = cpu_to_le32(2);
51
emap->mem_freq = cpu_to_le32(300000000);
53
emap->map[0].node_id = cpu_to_le32(0);
54
emap->map[0].mem_type = cpu_to_le32(1);
55
emap->map[0].mem_start = cpu_to_le64(0x0);
56
emap->map[0].mem_size = cpu_to_le32(240);
58
emap->map[1].node_id = cpu_to_le32(0);
59
emap->map[1].mem_type = cpu_to_le32(2);
60
emap->map[1].mem_start = cpu_to_le64(0x90000000);
61
emap->map[1].mem_size = cpu_to_le32((ram_size / MiB) - 256);
64
static void init_system_loongson(void *g_system)
66
struct system_loongson *s = g_system;
68
s->ccnuma_smp = cpu_to_le32(0);
69
s->sing_double_channel = cpu_to_le32(1);
70
s->nr_uarts = cpu_to_le32(1);
71
s->uarts[0].iotype = cpu_to_le32(2);
72
s->uarts[0].int_offset = cpu_to_le32(2);
73
s->uarts[0].uartclk = cpu_to_le32(25000000);
74
s->uarts[0].uart_base = cpu_to_le64(virt_memmap[VIRT_UART].base);
77
static void init_irq_source(void *g_irq_source)
79
struct irq_source_routing_table *irq_info = g_irq_source;
81
irq_info->node_id = cpu_to_le32(0);
82
irq_info->PIC_type = cpu_to_le32(0);
83
irq_info->dma_mask_bits = cpu_to_le16(64);
84
irq_info->pci_mem_start_addr = cpu_to_le64(virt_memmap[VIRT_PCIE_MMIO].base);
85
irq_info->pci_mem_end_addr = cpu_to_le64(virt_memmap[VIRT_PCIE_MMIO].base +
86
virt_memmap[VIRT_PCIE_MMIO].size - 1);
87
irq_info->pci_io_start_addr = cpu_to_le64(virt_memmap[VIRT_PCIE_PIO].base);
90
static void init_interface_info(void *g_interface)
92
struct interface_info *interface = g_interface;
94
interface->vers = cpu_to_le16(0x01);
95
strpadcpy(interface->description, 64, "UEFI_Version_v1.0", '\0');
98
static void board_devices_info(void *g_board)
100
struct board_devices *bd = g_board;
102
strpadcpy(bd->name, 64, "Loongson-3A-VIRT-1w-V1.00-demo", '\0');
105
static void init_special_info(void *g_special)
107
struct loongson_special_attribute *special = g_special;
109
strpadcpy(special->special_name, 64, "2018-05-01", '\0');
112
void init_loongson_params(struct loongson_params *lp, void *p,
113
uint64_t cpu_freq, uint64_t ram_size)
115
init_cpu_info(p, cpu_freq);
116
lp->cpu_offset = cpu_to_le64((uintptr_t)p - (uintptr_t)lp);
117
p += ROUND_UP(sizeof(struct efi_cpuinfo_loongson), 64);
119
init_memory_map(p, ram_size);
120
lp->memory_offset = cpu_to_le64((uintptr_t)p - (uintptr_t)lp);
121
p += ROUND_UP(sizeof(struct efi_memory_map_loongson), 64);
123
init_system_loongson(p);
124
lp->system_offset = cpu_to_le64((uintptr_t)p - (uintptr_t)lp);
125
p += ROUND_UP(sizeof(struct system_loongson), 64);
128
lp->irq_offset = cpu_to_le64((uintptr_t)p - (uintptr_t)lp);
129
p += ROUND_UP(sizeof(struct irq_source_routing_table), 64);
131
init_interface_info(p);
132
lp->interface_offset = cpu_to_le64((uintptr_t)p - (uintptr_t)lp);
133
p += ROUND_UP(sizeof(struct interface_info), 64);
135
board_devices_info(p);
136
lp->boarddev_table_offset = cpu_to_le64((uintptr_t)p - (uintptr_t)lp);
137
p += ROUND_UP(sizeof(struct board_devices), 64);
139
init_special_info(p);
140
lp->special_offset = cpu_to_le64((uintptr_t)p - (uintptr_t)lp);
141
p += ROUND_UP(sizeof(struct loongson_special_attribute), 64);
144
void init_reset_system(struct efi_reset_system_t *reset)
146
reset->Shutdown = cpu_to_le64(0xffffffffbfc000a8);
147
reset->ResetCold = cpu_to_le64(0xffffffffbfc00080);
148
reset->ResetWarm = cpu_to_le64(0xffffffffbfc00080);
149
reset->DoSuspend = cpu_to_le64(0xffffffffbfc000d0);