@@ -212,6 +212,152 @@ static const MemoryRegionOps crg_aon_ops = {
212
212
.endianness = DEVICE_NATIVE_ENDIAN ,
213
213
};
214
214
215
+ /**
216
+ * OTPC
217
+ */
218
+
219
+ #define OTPC 0x30070000
220
+
221
+ typedef enum {
222
+ HW_OTPC_MODE_PDOWN = 0 , /**< OTP cell and LDO are inactive*/
223
+ HW_OTPC_MODE_DSTBY = 1 , /**< OTP cell is powered on LDO is inactive*/
224
+ HW_OTPC_MODE_STBY = 2 , /**< OTP cell and LDO are powered on, chip select is deactivated*/
225
+ HW_OTPC_MODE_READ = 3 , /**< OTP cell can be read*/
226
+ HW_OTPC_MODE_PROG = 4 , /**< OTP cell can be programmed*/
227
+ HW_OTPC_MODE_PVFY = 5 , /**< OTP cell can be read in PVFY margin read mode*/
228
+ HW_OTPC_MODE_RINI = 6 /**< OTP cell can be read in RINI margin read mode*/
229
+ } HW_OTPC_MODE ;
230
+
231
+ // Mode register
232
+ #define OTPC_MODE_REG 0x00
233
+ #define OTPC_MODE_MODE_BIT 0
234
+
235
+ // Status register
236
+ #define OTPC_STAT_REG 0x04
237
+
238
+ // The address of the word that will be programmed, when the PROG mode is used.
239
+ #define OTPC_PADDR_REG 0x08
240
+
241
+ // The 32-bit word that will be programmed, when the PROG mode is used.
242
+ #define OTPC_PWORD_REG 0x0C
243
+
244
+ // Various timing parameters of the OTP cell.
245
+ #define OTPC_TIM1_REG 0x10
246
+
247
+ // Various timing parameters of the OTP cell.
248
+ #define OTPC_TIM2_REG 0x14
249
+
250
+ HW_OTPC_MODE otpc_mode ;
251
+
252
+ static uint64_t otpc_mem_read (void * opaque , hwaddr offset , unsigned size ) {
253
+
254
+ switch (offset ) {
255
+ case OTPC_MODE_REG :
256
+ return otpc_mode ;
257
+
258
+ case OTPC_STAT_REG : {
259
+ uint32_t out = 0 ;
260
+ out |= 1 << 0 ;
261
+ out |= 1 << 1 ;
262
+ out |= 1 << 2 ;
263
+
264
+ return out ;
265
+ }
266
+ }
267
+
268
+ return 0 ;
269
+ }
270
+
271
+ static void otpc_mem_write (void * opaque , hwaddr offset ,
272
+ uint64_t value , unsigned size ) {
273
+ switch (offset ) {
274
+ case OTPC_MODE_REG :
275
+ otpc_mode = (value >> OTPC_MODE_MODE_BIT ) & 0b111 ;
276
+ break ;
277
+ }
278
+ }
279
+
280
+ static const MemoryRegionOps otpc_ops = {
281
+ .read = otpc_mem_read ,
282
+ .write = otpc_mem_write ,
283
+ .endianness = DEVICE_NATIVE_ENDIAN ,
284
+ };
285
+
286
+
287
+ /**
288
+ * CRG_XTAL
289
+ */
290
+
291
+ #define PLL_SYS_CTRL1_REG 0x60
292
+ #define CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_SEL_MIN_CUR_INT_BIT 14
293
+ #define CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_PRE_DIV_BIT 11
294
+ #define CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_N_DIV_BIT 4
295
+ #define CRG_XTAL_PLL_SYS_CTRL1_REG_LDO_PLL_VREF_HOLD_BIT 3
296
+ #define CRG_XTAL_PLL_SYS_CTRL1_REG_LDO_PLL_ENABLE_BIT 2
297
+ #define CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_EN_BIT 1
298
+ #define CRG_XTAL_PLL_SYS_CTRL1_REG_LDO_PLL_ENABLE (1U << CRG_XTAL_PLL_SYS_CTRL1_REG_LDO_PLL_ENABLE_BIT)
299
+ #define CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_EN (1U << CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_EN_BIT)
300
+
301
+ #define PLL_SYS_STATUS_REG 0x70
302
+ #define CRG_XTAL_PLL_SYS_STATUS_REG_LDO_PLL_OK_BIT 15
303
+ #define CRG_XTAL_PLL_SYS_STATUS_REG_PLL_CALIBRATION_END_BIT 11
304
+ #define CRG_XTAL_PLL_SYS_STATUS_REG_PLL_BEST_MIN_CUR_BIT 5
305
+ #define CRG_XTAL_PLL_SYS_STATUS_REG_PLL_LOCK_FINE_BIT 0
306
+
307
+ bool ldoPllOn = false;
308
+ bool pllOn = false;
309
+
310
+ static uint64_t crg_xtal_mem_read (void * opaque , hwaddr offset , unsigned size ) {
311
+
312
+ switch (offset ) {
313
+ case PLL_SYS_CTRL1_REG : {
314
+ uint32_t out = 0 ;
315
+ out |= 1 << CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_SEL_MIN_CUR_INT_BIT ;
316
+ out |= 2 << 12 ;
317
+ out |= 1 << CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_PRE_DIV_BIT ;
318
+ out |= 6 << CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_N_DIV_BIT ;
319
+ out |= 0 << CRG_XTAL_PLL_SYS_CTRL1_REG_LDO_PLL_VREF_HOLD_BIT ;
320
+ if (ldoPllOn )
321
+ out |= 1 << CRG_XTAL_PLL_SYS_CTRL1_REG_LDO_PLL_ENABLE_BIT ;
322
+ if (pllOn )
323
+ out |= 1 << CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_EN_BIT ;
324
+
325
+ return out ;
326
+ }
327
+ case PLL_SYS_STATUS_REG : {
328
+ uint32_t out = 0 ;
329
+ if (ldoPllOn )
330
+ out |= 1 << CRG_XTAL_PLL_SYS_STATUS_REG_LDO_PLL_OK_BIT ;
331
+ if (false) {
332
+ out |= 1 << CRG_XTAL_PLL_SYS_STATUS_REG_PLL_CALIBRATION_END_BIT ;
333
+ out |= 1 << CRG_XTAL_PLL_SYS_STATUS_REG_PLL_BEST_MIN_CUR_BIT ;
334
+ out |= 1 << CRG_XTAL_PLL_SYS_STATUS_REG_PLL_LOCK_FINE_BIT ;
335
+ }
336
+
337
+ return out ;
338
+ }
339
+ }
340
+
341
+ return 0 ;
342
+ }
343
+
344
+ static void crg_xtal_mem_write (void * opaque , hwaddr offset , uint64_t value , unsigned size ) {
345
+ switch (offset ) {
346
+ case PLL_SYS_CTRL1_REG :
347
+ if (value & CRG_XTAL_PLL_SYS_CTRL1_REG_LDO_PLL_ENABLE ) {
348
+ ldoPllOn = true;
349
+ } else {
350
+ ldoPllOn = false;
351
+ }
352
+ break ;
353
+ }
354
+ }
355
+ static const MemoryRegionOps crg_xtal_ops = {
356
+ .read = crg_xtal_mem_read ,
357
+ .write = crg_xtal_mem_write ,
358
+ .endianness = DEVICE_NATIVE_ENDIAN ,
359
+ };
360
+
215
361
/**
216
362
* Machine
217
363
*/
@@ -224,6 +370,8 @@ typedef struct {
224
370
MemoryRegion sysram ;
225
371
226
372
MemoryRegion crg_aon ;
373
+ MemoryRegion crg_xtal ;
374
+ MemoryRegion otpc_c ;
227
375
} BipSMachineState ;
228
376
229
377
#define TYPE_BIP_S_MACHINE MACHINE_TYPE_NAME("bip-s")
@@ -276,6 +424,14 @@ static void bip_s_init(MachineState *machine) {
276
424
memory_region_init_io (& bip -> crg_aon , NULL , & crg_aon_ops , & crg_aon_val , "crc" , 0x100 );
277
425
memory_region_add_subregion (system_memory , 0x50000000 , & bip -> crg_aon );
278
426
427
+ static uint32_t crg_xtal_val = 0xffffffff ;
428
+ memory_region_init_io (& bip -> crg_xtal , NULL , & crg_xtal_ops , & crg_xtal_val , "crg_xtal" , 0x100 );
429
+ memory_region_add_subregion (system_memory , 0x50010000U , & bip -> crg_xtal );
430
+
431
+ static uint32_t otpc_val = 0xffffffff ;
432
+ memory_region_init_io (& bip -> otpc_c , NULL , & otpc_ops , & otpc_val , "otpc" , 0x80000 );
433
+ memory_region_add_subregion (system_memory , 0x30070000 , & bip -> otpc_c );
434
+
279
435
load_image_targphys ("/Users/Marijn/Downloads/tonlesap_202006191826_2.1.1.16_tonlesap.img" , 0x0 , 0x8192 * 1024 );
280
436
281
437
armv7m_load_kernel (ARM_CPU (first_cpu ), machine -> kernel_filename ,
0 commit comments