Skip to content

Commit 580b2b2

Browse files
committed
Add amazfit target
1 parent eceb00d commit 580b2b2

File tree

2 files changed

+306
-0
lines changed

2 files changed

+306
-0
lines changed

hw/arm/Makefile.objs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,4 @@ obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
5454
obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o smmuv3.o
5555
obj-$(CONFIG_FSL_IMX6UL) += fsl-imx6ul.o mcimx6ul-evk.o
5656
obj-$(CONFIG_NRF51_SOC) += nrf51_soc.o
57+
obj-y += amazfit.o

hw/arm/amazfit.c

Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,305 @@
1+
2+
#include "qemu/osdep.h"
3+
#include "hw/misc/unimp.h"
4+
#include "hw/sysbus.h"
5+
#include "hw/arm/armv7m.h"
6+
#include "qapi/error.h"
7+
#include "hw/boards.h"
8+
#include "hw/arm/boot.h"
9+
#include "sysemu/sysemu.h"
10+
#include "exec/address-spaces.h"
11+
#include "hw/loader.h"
12+
#include "qemu/log.h"
13+
14+
bool POWER_IS_UP = 1;
15+
bool DBG_IS_ACTIVE = 0;
16+
bool COM_IS_UP = 0;
17+
bool COM_IS_DOWN = 1;
18+
bool TIM_IS_UP = 0;
19+
bool TIM_IS_DOWN = 1;
20+
bool MEM_IS_UP = 1;
21+
bool MEM_IS_DOWN = 0;
22+
bool SYS_IS_UP = 1;
23+
bool SYS_IS_DOWN = 0;
24+
bool PER_IS_UP = 1;
25+
bool PER_IS_DOWN = 0;
26+
bool RAD_IS_UP = 1;
27+
bool RAD_IS_DOWN = 0;
28+
29+
#define SYS_STAT_OFFSET 0x28
30+
31+
#define SYS_STAT_POWER_IS_UP_BIT 13
32+
#define SYS_STAT_DBG_IS_ACTIVE_BIT 12
33+
#define SYS_STAT_COM_IS_UP_BIT 11
34+
#define SYS_STAT_COM_IS_DOWN_BIT 10
35+
#define SYS_STAT_TIM_IS_UP_BIT 9
36+
#define SYS_STAT_TIM_IS_DOWN_BIT 8
37+
#define SYS_STAT_MEM_IS_UP_BIT 7
38+
#define SYS_STAT_MEM_IS_DOWN_BIT 6
39+
#define SYS_STAT_SYS_IS_UP_BIT 5
40+
#define SYS_STAT_SYS_IS_DOWN_BIT 4
41+
#define SYS_STAT_PER_IS_UP_BIT 3
42+
#define SYS_STAT_PER_IS_DOWN_BIT 2
43+
#define SYS_STAT_RAD_IS_UP_BIT 1
44+
#define SYS_STAT_RAD_IS_DOWN_BIT 0
45+
46+
#define SYS_STAT_POWER_IS_UP (1U << SYS_STAT_POWER_IS_UP_BIT)
47+
#define SYS_STAT_DBG_IS_ACTIVE (1U << SYS_STAT_DBG_IS_ACTIVE_BIT)
48+
#define SYS_STAT_COM_IS_UP (1U << SYS_STAT_COM_IS_UP_BIT)
49+
#define SYS_STAT_COM_IS_DOWN (1U << SYS_STAT_COM_IS_DOWN_BIT)
50+
#define SYS_STAT_TIM_IS_UP (1U << SYS_STAT_TIM_IS_UP_BIT)
51+
#define SYS_STAT_TIM_IS_DOWN (1U << SYS_STAT_TIM_IS_DOWN_BIT)
52+
#define SYS_STAT_MEM_IS_UP (1U << SYS_STAT_MEM_IS_UP_BIT)
53+
#define SYS_STAT_MEM_IS_DOWN (1U << SYS_STAT_MEM_IS_DOWN_BIT)
54+
#define SYS_STAT_SYS_IS_UP (1U << SYS_STAT_SYS_IS_UP_BIT)
55+
#define SYS_STAT_SYS_IS_DOWN (1U << SYS_STAT_SYS_IS_DOWN_BIT)
56+
#define SYS_STAT_PER_IS_UP (1U << SYS_STAT_PER_IS_UP_BIT)
57+
#define SYS_STAT_PER_IS_DOWN (1U << SYS_STAT_PER_IS_DOWN_BIT)
58+
#define SYS_STAT_RAD_IS_UP (1U << SYS_STAT_RAD_IS_UP_BIT)
59+
#define SYS_STAT_RAD_IS_DOWN (1U << SYS_STAT_RAD_IS_DOWN_BIT)
60+
61+
#define PMU_CTRL_OFFSET 0x20
62+
63+
#define PMU_CTRL_ENABLE_CLKLESS_BIT 8
64+
#define PMU_CTRL_RETAIN_CACHE_BIT 7
65+
#define PMU_CTRL_SYS_SLEEP_BIT 6
66+
#define PMU_CTRL_RESET_ON_WAKEUP_BIT 5
67+
#define PMU_CTRL_MAP_BANDGAP_EN_BIT 4
68+
#define PMU_CTRL_COM_SLEEP_BIT 3
69+
#define PMU_CTRL_TIM_SLEEP_BIT 2
70+
#define PMU_CTRL_RADIO_SLEEP_BIT 1
71+
#define PMU_CTRL_PERIPH_SLEEP_BIT 0
72+
#define PMU_CTRL_ENABLE_CLKLESS (1U << PMU_CTRL_ENABLE_CLKLESS_BIT)
73+
#define PMU_CTRL_RETAIN_CACHE (1U << PMU_CTRL_RETAIN_CACHE_BIT)
74+
#define PMU_CTRL_SYS_SLEEP (1U << PMU_CTRL_SYS_SLEEP_BIT)
75+
#define PMU_CTRL_RESET_ON_WAKEUP (1U << PMU_CTRL_RESET_ON_WAKEUP_BIT)
76+
#define PMU_CTRL_MAP_BANDGAP_EN (1U << PMU_CTRL_MAP_BANDGAP_EN_BIT)
77+
#define PMU_CTRL_COM_SLEEP (1U << PMU_CTRL_COM_SLEEP_BIT)
78+
#define PMU_CTRL_TIM_SLEEP (1U << PMU_CTRL_TIM_SLEEP_BIT)
79+
#define PMU_CTRL_RADIO_SLEEP (1U << PMU_CTRL_RADIO_SLEEP_BIT)
80+
#define PMU_CTRL_PERIPH_SLEEP (1U << PMU_CTRL_PERIPH_SLEEP_BIT)
81+
82+
#define CLK_CTRL_OFFSET 0x14
83+
#define CLK_CTRL_SYS_RUNNING_AT_PLL96M_BIT 15
84+
#define CLK_CTRL_SYS_RUNNING_AT_RC32M_BIT 14
85+
#define CLK_CTRL_SYS_RUNNING_AT_XTAL32M_BIT 13
86+
#define CLK_CTRL_SYS_RUNNING_AT_LP_CLK_BIT 12
87+
#define CLK_CTRL_SYS_CLK_SEL_BIT 0
88+
89+
#define CLK_SWITCH2XTAL_OFFSET 0x1C
90+
#define CLK_SWITCH2XTAL_SWITCH2XTAL_BIT 0
91+
#define CLK_SWITCH2XTAL_SWITCH2XTAL (1U << CLK_SWITCH2XTAL_SWITCH2XTAL_BIT)
92+
93+
bool pd_power = true;
94+
bool pd_com = false;
95+
bool pd_tim = false;
96+
bool pd_mem = true;
97+
bool pd_sys = true;
98+
bool pd_per = false;
99+
bool pd_rad = false;
100+
101+
typedef enum sys_clk_is_type {
102+
XTAL32M = 0,
103+
RC32M = 1,
104+
LowPower = 2,
105+
PLL96Mhz = 3,
106+
} sys_clk_is_t;
107+
108+
sys_clk_is_t syc_clk = RC32M;
109+
110+
static uint32_t getValue(hwaddr offset) {
111+
switch (offset) {
112+
113+
case CLK_CTRL_OFFSET: {
114+
uint32_t out = 0;
115+
out |= syc_clk << CLK_CTRL_SYS_CLK_SEL_BIT;
116+
out |= 1 << 6;
117+
118+
if (syc_clk == PLL96Mhz)
119+
out |= 1U << CLK_CTRL_SYS_RUNNING_AT_PLL96M_BIT;
120+
if (syc_clk == XTAL32M)
121+
out |= 1U << CLK_CTRL_SYS_RUNNING_AT_XTAL32M_BIT;
122+
if (syc_clk == RC32M)
123+
out |= 1U << CLK_CTRL_SYS_RUNNING_AT_RC32M_BIT;
124+
if (syc_clk == LowPower)
125+
out |= 1U << CLK_CTRL_SYS_RUNNING_AT_LP_CLK_BIT;
126+
127+
return out;
128+
}
129+
130+
case SYS_STAT_OFFSET: {
131+
uint32_t out = 0;
132+
133+
out |= pd_power ? SYS_STAT_POWER_IS_UP : 0;
134+
out |= pd_com ? SYS_STAT_COM_IS_UP : SYS_STAT_COM_IS_DOWN;
135+
out |= pd_tim ? SYS_STAT_TIM_IS_UP : SYS_STAT_TIM_IS_DOWN;
136+
out |= pd_mem ? SYS_STAT_MEM_IS_UP : SYS_STAT_MEM_IS_DOWN;
137+
out |= pd_sys ? SYS_STAT_SYS_IS_UP : SYS_STAT_SYS_IS_DOWN;
138+
out |= pd_per ? SYS_STAT_PER_IS_UP : SYS_STAT_PER_IS_DOWN;
139+
out |= pd_rad ? SYS_STAT_RAD_IS_UP : SYS_STAT_RAD_IS_DOWN;
140+
return out;
141+
}
142+
143+
case PMU_CTRL_OFFSET: {
144+
uint32_t out = 0;
145+
146+
out |= pd_com == false ? PMU_CTRL_COM_SLEEP : 0;
147+
out |= pd_tim == false ? PMU_CTRL_TIM_SLEEP : 0;
148+
out |= pd_rad == false ? PMU_CTRL_RADIO_SLEEP : 0;
149+
out |= pd_per == false ? PMU_CTRL_PERIPH_SLEEP : 0;
150+
return out;
151+
}
152+
}
153+
154+
return 0;
155+
}
156+
157+
static uint64_t pxa2xx_pic_mem_read(void *opaque, hwaddr offset,
158+
unsigned size) {
159+
160+
switch (offset) {
161+
case SYS_STAT_OFFSET:
162+
case PMU_CTRL_OFFSET:
163+
case CLK_CTRL_OFFSET:
164+
return getValue(offset);
165+
166+
default:
167+
qemu_log_mask(LOG_UNIMP, "Read from 0x%llX\n", offset + 0x50000000);
168+
}
169+
return 0;
170+
}
171+
172+
static void pxa2xx_pic_mem_write(void *opaque, hwaddr offset,
173+
uint64_t value, unsigned size) {
174+
175+
switch (offset) {
176+
case SYS_STAT_OFFSET:
177+
case PMU_CTRL_OFFSET:
178+
case CLK_CTRL_OFFSET: {
179+
uint32_t current = getValue(offset);;
180+
printf("Write 0x%08llX to 0x%llX (was 0x%08X)\n", value, offset + 0x50000000, current);
181+
break;
182+
}
183+
184+
default:
185+
printf("Write 0x%llX to 0x%llX\n", value, offset + 0x50000000);
186+
break;
187+
}
188+
189+
switch (offset) {
190+
case PMU_CTRL_OFFSET:
191+
pd_com = (value & PMU_CTRL_COM_SLEEP) ? false : true;
192+
pd_rad = (value & PMU_CTRL_RADIO_SLEEP) ? false : true;
193+
pd_per = (value & PMU_CTRL_PERIPH_SLEEP) ? false : true;
194+
pd_tim = (value & PMU_CTRL_TIM_SLEEP) ? false : true;
195+
break;
196+
197+
case CLK_CTRL_OFFSET:
198+
// syc_clk = (value >> CLK_CTRL_SYS_CLK_SEL_BIT) & 0b11;
199+
break;
200+
201+
case CLK_SWITCH2XTAL_OFFSET:
202+
if (value & CLK_SWITCH2XTAL_SWITCH2XTAL)
203+
syc_clk = XTAL32M;
204+
break;
205+
206+
}
207+
}
208+
209+
static const MemoryRegionOps crg_aon_ops = {
210+
.read = pxa2xx_pic_mem_read,
211+
.write = pxa2xx_pic_mem_write,
212+
.endianness = DEVICE_NATIVE_ENDIAN,
213+
};
214+
215+
/**
216+
* Machine
217+
*/
218+
219+
typedef struct {
220+
MachineState parent;
221+
222+
ARMv7MState armv7m;
223+
MemoryRegion flash;
224+
MemoryRegion sysram;
225+
226+
MemoryRegion crg_aon;
227+
} BipSMachineState;
228+
229+
#define TYPE_BIP_S_MACHINE MACHINE_TYPE_NAME("bip-s")
230+
231+
#define BIPS_MACHINE(obj) \
232+
OBJECT_CHECK(BipSMachineState, obj, TYPE_BIP_S_MACHINE)
233+
234+
static inline void create_unimplemented_layer(const char *name, hwaddr base, hwaddr size) {
235+
DeviceState *dev = qdev_create(NULL, TYPE_UNIMPLEMENTED_DEVICE);
236+
237+
qdev_prop_set_string(dev, "name", name);
238+
qdev_prop_set_uint64(dev, "size", size);
239+
qdev_init_nofail(dev);
240+
241+
sysbus_mmio_map_overlap(SYS_BUS_DEVICE(dev), 0, base, -900);
242+
}
243+
244+
static void bip_s_init(MachineState *machine) {
245+
Error * err = NULL;
246+
BipSMachineState *bip = BIPS_MACHINE(machine);
247+
248+
MemoryRegion *system_memory = get_system_memory();
249+
250+
sysbus_init_child_obj(OBJECT(bip), "armv7m", &bip->armv7m, sizeof(bip->armv7m), TYPE_ARMV7M);
251+
DeviceState *armv7m = DEVICE(&bip->armv7m);
252+
qdev_prop_set_string(armv7m, "cpu-type", machine->cpu_type);
253+
object_property_set_link(OBJECT(armv7m), OBJECT(system_memory),
254+
"memory", &error_abort);
255+
object_property_set_bool(OBJECT(armv7m), true, "realized", &err);
256+
if (err != NULL) {
257+
return;
258+
}
259+
260+
memory_region_init_ram(&bip->flash, NULL, "flash", 0x20000000, &err);
261+
if (err != NULL) {
262+
return;
263+
}
264+
memory_region_set_readonly(&bip->flash, true);
265+
memory_region_add_subregion(system_memory, 0x00000000, &bip->flash);
266+
267+
memory_region_init_ram(&bip->sysram, NULL, "system", 512 * 1024, &error_fatal);
268+
memory_region_add_subregion(system_memory, 0x20000000, &bip->sysram);
269+
270+
create_unimplemented_device("PSRAM", 0x00000000, 0xFFFFFFFF);
271+
272+
// Power Domains Controller
273+
create_unimplemented_layer("PDC", 0x50000200, 0x100);
274+
275+
static uint32_t crg_aon_val = 0xffffffff;
276+
memory_region_init_io(&bip->crg_aon, NULL, &crg_aon_ops, &crg_aon_val, "crc", 0x100);
277+
memory_region_add_subregion(system_memory, 0x50000000, &bip->crg_aon);
278+
279+
load_image_targphys("/Users/Marijn/Downloads/tonlesap_202006191826_2.1.1.16_tonlesap.img", 0x0, 0x8192 * 1024);
280+
281+
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
282+
0x8192 * 1024);
283+
}
284+
285+
static void bip_s_machine_class_init(ObjectClass *oc, void *data) {
286+
MachineClass *mc = MACHINE_CLASS(oc);
287+
288+
mc->desc = "Amazfit Bip S";
289+
mc->init = bip_s_init;
290+
mc->max_cpus = 1;
291+
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
292+
}
293+
294+
static const TypeInfo bip_s_info = {
295+
.name = TYPE_BIP_S_MACHINE,
296+
.parent = TYPE_MACHINE,
297+
.instance_size = sizeof(BipSMachineState),
298+
.class_init = bip_s_machine_class_init,
299+
};
300+
301+
static void bip_s_machine_init(void) {
302+
type_register_static(&bip_s_info);
303+
}
304+
305+
type_init(bip_s_machine_init);

0 commit comments

Comments
 (0)