| 
									
										
										
										
											2011-06-02 13:53:40 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * QEMU PowerPC MPC8544 global util pseudo-device | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (C) 2011 Freescale Semiconductor, Inc. All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Author: Alexander Graf, <alex@csgraf.de> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This is free software; you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of  the GNU General  Public License as published by | 
					
						
							|  |  |  |  * the Free Software Foundation;  either version 2 of the  License, or | 
					
						
							|  |  |  |  * (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***************************************************************** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The documentation for this device is noted in the MPC8544 documentation, | 
					
						
							|  |  |  |  * file name "MPC8544ERM.pdf". You can easily find it on the web. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-26 18:16:58 +00:00
										 |  |  | #include "qemu/osdep.h"
 | 
					
						
							| 
									
										
										
										
											2019-05-23 16:35:07 +02:00
										 |  |  | #include "qemu/module.h"
 | 
					
						
							| 
									
										
										
										
											2022-01-04 07:55:34 +01:00
										 |  |  | #include "qemu/log.h"
 | 
					
						
							| 
									
										
										
										
											2019-08-12 07:23:59 +02:00
										 |  |  | #include "sysemu/runstate.h"
 | 
					
						
							| 
									
										
										
										
											2016-01-19 21:51:44 +01:00
										 |  |  | #include "cpu.h"
 | 
					
						
							| 
									
										
										
										
											2013-02-04 15:40:22 +01:00
										 |  |  | #include "hw/sysbus.h"
 | 
					
						
							| 
									
										
										
										
											2020-09-03 16:43:22 -04:00
										 |  |  | #include "qom/object.h"
 | 
					
						
							| 
									
										
										
										
											2011-06-02 13:53:40 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_MMIO_SIZE        0x1000
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_RSTCR_RESET      0x02
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_PORPLLSR    0x00
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_PORBMSR     0x04
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_PORIMPSCR   0x08
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_PORDEVSR    0x0C
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_PORDBGMSR   0x10
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_PORDEVSR2   0x14
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_GPPORCR     0x20
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_GPIOCR      0x30
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_GPOUTDR     0x40
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_GPINDR      0x50
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_PMUXCR      0x60
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_DEVDISR     0x70
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_POWMGTCSR   0x80
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_MCPSUMR     0x90
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_RSTRSCR     0x94
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_PVR         0xA0
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_SVR         0xA4
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_RSTCR       0xB0
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_IOVSELSR    0xC0
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_DDRCSR      0xB20
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_DDRCDR      0xB24
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_DDRCLKDR    0xB28
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_CLKOCR      0xE00
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_SRDS1CR1    0xF04
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_SRDS2CR1    0xF10
 | 
					
						
							|  |  |  | #define MPC8544_GUTS_ADDR_SRDS2CR3    0xF18
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-09 22:47:34 +02:00
										 |  |  | #define TYPE_MPC8544_GUTS "mpc8544-guts"
 | 
					
						
							| 
									
										
										
										
											2020-09-16 14:25:19 -04:00
										 |  |  | OBJECT_DECLARE_SIMPLE_TYPE(GutsState, MPC8544_GUTS) | 
					
						
							| 
									
										
										
										
											2013-06-09 22:47:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-02 13:53:40 +02:00
										 |  |  | struct GutsState { | 
					
						
							| 
									
										
										
										
											2013-06-09 22:47:34 +02:00
										 |  |  |     /*< private >*/ | 
					
						
							|  |  |  |     SysBusDevice parent_obj; | 
					
						
							|  |  |  |     /*< public >*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-13 15:05:28 +02:00
										 |  |  |     MemoryRegion iomem; | 
					
						
							| 
									
										
										
										
											2011-06-02 13:53:40 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static uint64_t mpc8544_guts_read(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-11-13 15:05:28 +02:00
										 |  |  |                                   unsigned size) | 
					
						
							| 
									
										
										
										
											2011-06-02 13:53:40 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     uint32_t value = 0; | 
					
						
							| 
									
										
										
										
											2024-01-29 17:45:03 +01:00
										 |  |  |     CPUPPCState *env = cpu_env(current_cpu); | 
					
						
							| 
									
										
										
										
											2011-06-02 13:53:40 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     addr &= MPC8544_GUTS_MMIO_SIZE - 1; | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case MPC8544_GUTS_ADDR_PVR: | 
					
						
							|  |  |  |         value = env->spr[SPR_PVR]; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case MPC8544_GUTS_ADDR_SVR: | 
					
						
							|  |  |  |         value = env->spr[SPR_E500_SVR]; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2022-01-04 07:55:34 +01:00
										 |  |  |         qemu_log_mask(LOG_GUEST_ERROR, | 
					
						
							|  |  |  |                       "%s: Unknown register 0x%" HWADDR_PRIx "\n", | 
					
						
							|  |  |  |                       __func__, addr); | 
					
						
							| 
									
										
										
										
											2011-06-02 13:53:40 +02:00
										 |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return value; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static void mpc8544_guts_write(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-11-13 15:05:28 +02:00
										 |  |  |                                uint64_t value, unsigned size) | 
					
						
							| 
									
										
										
										
											2011-06-02 13:53:40 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     addr &= MPC8544_GUTS_MMIO_SIZE - 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (addr) { | 
					
						
							|  |  |  |     case MPC8544_GUTS_ADDR_RSTCR: | 
					
						
							|  |  |  |         if (value & MPC8544_GUTS_RSTCR_RESET) { | 
					
						
							| 
									
										
										
										
											2017-05-15 16:41:13 -05:00
										 |  |  |             qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); | 
					
						
							| 
									
										
										
										
											2011-06-02 13:53:40 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2022-01-04 07:55:34 +01:00
										 |  |  |         qemu_log_mask(LOG_GUEST_ERROR, "%s: Unknown register 0x%" HWADDR_PRIx | 
					
						
							|  |  |  |                        " = 0x%" PRIx64 "\n", __func__, addr, value); | 
					
						
							| 
									
										
										
										
											2011-06-02 13:53:40 +02:00
										 |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-13 15:05:28 +02:00
										 |  |  | static const MemoryRegionOps mpc8544_guts_ops = { | 
					
						
							|  |  |  |     .read = mpc8544_guts_read, | 
					
						
							|  |  |  |     .write = mpc8544_guts_write, | 
					
						
							|  |  |  |     .endianness = DEVICE_BIG_ENDIAN, | 
					
						
							|  |  |  |     .valid = { | 
					
						
							|  |  |  |         .min_access_size = 4, | 
					
						
							|  |  |  |         .max_access_size = 4, | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2011-06-02 13:53:40 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-09 22:47:35 +02:00
										 |  |  | static void mpc8544_guts_initfn(Object *obj) | 
					
						
							| 
									
										
										
										
											2011-06-02 13:53:40 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-06-09 22:47:35 +02:00
										 |  |  |     SysBusDevice *d = SYS_BUS_DEVICE(obj); | 
					
						
							|  |  |  |     GutsState *s = MPC8544_GUTS(obj); | 
					
						
							| 
									
										
										
										
											2011-06-02 13:53:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-06 21:25:08 -04:00
										 |  |  |     memory_region_init_io(&s->iomem, OBJECT(s), &mpc8544_guts_ops, s, | 
					
						
							| 
									
										
										
										
											2013-06-09 22:47:33 +02:00
										 |  |  |                           "mpc8544.guts", MPC8544_GUTS_MMIO_SIZE); | 
					
						
							| 
									
										
										
										
											2013-06-09 22:47:35 +02:00
										 |  |  |     sysbus_init_mmio(d, &s->iomem); | 
					
						
							| 
									
										
										
										
											2012-01-24 13:12:29 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-10 16:19:07 +01:00
										 |  |  | static const TypeInfo mpc8544_guts_info = { | 
					
						
							| 
									
										
										
										
											2013-06-09 22:47:34 +02:00
										 |  |  |     .name          = TYPE_MPC8544_GUTS, | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     .parent        = TYPE_SYS_BUS_DEVICE, | 
					
						
							|  |  |  |     .instance_size = sizeof(GutsState), | 
					
						
							| 
									
										
										
										
											2013-06-09 22:47:35 +02:00
										 |  |  |     .instance_init = mpc8544_guts_initfn, | 
					
						
							| 
									
										
										
										
											2011-06-02 13:53:40 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 15:20:55 +01:00
										 |  |  | static void mpc8544_guts_register_types(void) | 
					
						
							| 
									
										
										
										
											2011-06-02 13:53:40 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-12-07 21:34:16 -06:00
										 |  |  |     type_register_static(&mpc8544_guts_info); | 
					
						
							| 
									
										
										
										
											2011-06-02 13:53:40 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2012-02-09 15:20:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | type_init(mpc8544_guts_register_types) |