 9997771bc1
			
		
	
	
		9997771bc1
		
	
	
	
	
		
			
			See commit 9ba1caf510 ("MAINTAINERS: Mark the Nios II CPU as orphan"),
last contribution from Chris was in 2012 [1] and Marek in 2018 [2].
[1] https://lore.kernel.org/qemu-devel/1352607539-10455-2-git-send-email-crwulff@gmail.com/
[2] https://lore.kernel.org/qemu-devel/805fc7b5-03f0-56d4-abfd-ed010d4fa769@denx.de/
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: Marek Vasut <marex@denx.de>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20231117070250.32932-1-philmd@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20231120150833.2552739-6-alex.bennee@linaro.org>
		
	
			
		
			
				
	
	
		
			182 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			182 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Altera 10M50 Nios2 GHRD
 | |
|  *
 | |
|  * Copyright (c) 2016 Marek Vasut <marek.vasut@gmail.com>
 | |
|  *
 | |
|  * Based on LabX device code
 | |
|  *
 | |
|  * Copyright (c) 2012 Chris Wulff <crwulff@gmail.com>
 | |
|  *
 | |
|  * This library is free software; you can redistribute it and/or
 | |
|  * modify it under the terms of the GNU Lesser General Public
 | |
|  * License as published by the Free Software Foundation; either
 | |
|  * version 2.1 of the License, or (at your option) any later version.
 | |
|  *
 | |
|  * This library is distributed in the hope that it will be useful,
 | |
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|  * Lesser General Public License for more details.
 | |
|  *
 | |
|  * You should have received a copy of the GNU Lesser General Public
 | |
|  * License along with this library; if not, see
 | |
|  * <http://www.gnu.org/licenses/lgpl-2.1.html>
 | |
|  */
 | |
| 
 | |
| #include "qemu/osdep.h"
 | |
| #include "qapi/error.h"
 | |
| 
 | |
| #include "hw/sysbus.h"
 | |
| #include "hw/char/serial.h"
 | |
| #include "hw/intc/nios2_vic.h"
 | |
| #include "hw/qdev-properties.h"
 | |
| #include "sysemu/sysemu.h"
 | |
| #include "hw/boards.h"
 | |
| #include "exec/memory.h"
 | |
| #include "exec/address-spaces.h"
 | |
| #include "qemu/config-file.h"
 | |
| 
 | |
| #include "boot.h"
 | |
| 
 | |
| struct Nios2MachineState {
 | |
|     MachineState parent_obj;
 | |
| 
 | |
|     MemoryRegion phys_tcm;
 | |
|     MemoryRegion phys_tcm_alias;
 | |
|     MemoryRegion phys_ram;
 | |
|     MemoryRegion phys_ram_alias;
 | |
| 
 | |
|     bool vic;
 | |
| };
 | |
| 
 | |
| #define TYPE_NIOS2_MACHINE  MACHINE_TYPE_NAME("10m50-ghrd")
 | |
| OBJECT_DECLARE_TYPE(Nios2MachineState, MachineClass, NIOS2_MACHINE)
 | |
| 
 | |
| #define BINARY_DEVICE_TREE_FILE    "10m50-devboard.dtb"
 | |
| 
 | |
| static void nios2_10m50_ghrd_init(MachineState *machine)
 | |
| {
 | |
|     Nios2MachineState *nms = NIOS2_MACHINE(machine);
 | |
|     Nios2CPU *cpu;
 | |
|     DeviceState *dev;
 | |
|     MemoryRegion *address_space_mem = get_system_memory();
 | |
|     ram_addr_t tcm_base = 0x0;
 | |
|     ram_addr_t tcm_size = 0x1000;    /* 1 kiB, but QEMU limit is 4 kiB */
 | |
|     ram_addr_t ram_base = 0x08000000;
 | |
|     ram_addr_t ram_size = 0x08000000;
 | |
|     qemu_irq irq[32];
 | |
|     int i;
 | |
| 
 | |
|     /* Physical TCM (tb_ram_1k) with alias at 0xc0000000 */
 | |
|     memory_region_init_ram(&nms->phys_tcm, NULL, "nios2.tcm", tcm_size,
 | |
|                            &error_abort);
 | |
|     memory_region_init_alias(&nms->phys_tcm_alias, NULL, "nios2.tcm.alias",
 | |
|                              &nms->phys_tcm, 0, tcm_size);
 | |
|     memory_region_add_subregion(address_space_mem, tcm_base, &nms->phys_tcm);
 | |
|     memory_region_add_subregion(address_space_mem, 0xc0000000 + tcm_base,
 | |
|                                 &nms->phys_tcm_alias);
 | |
| 
 | |
|     /* Physical DRAM with alias at 0xc0000000 */
 | |
|     memory_region_init_ram(&nms->phys_ram, NULL, "nios2.ram", ram_size,
 | |
|                            &error_abort);
 | |
|     memory_region_init_alias(&nms->phys_ram_alias, NULL, "nios2.ram.alias",
 | |
|                              &nms->phys_ram, 0, ram_size);
 | |
|     memory_region_add_subregion(address_space_mem, ram_base, &nms->phys_ram);
 | |
|     memory_region_add_subregion(address_space_mem, 0xc0000000 + ram_base,
 | |
|                                 &nms->phys_ram_alias);
 | |
| 
 | |
|     /* Create CPU.  We need to set eic_present between init and realize. */
 | |
|     cpu = NIOS2_CPU(object_new(TYPE_NIOS2_CPU));
 | |
| 
 | |
|     /* Enable the External Interrupt Controller within the CPU. */
 | |
|     cpu->eic_present = nms->vic;
 | |
| 
 | |
|     /* Configure new exception vectors. */
 | |
|     cpu->reset_addr = 0xd4000000;
 | |
|     cpu->exception_addr = 0xc8000120;
 | |
|     cpu->fast_tlb_miss_addr = 0xc0000100;
 | |
| 
 | |
|     qdev_realize_and_unref(DEVICE(cpu), NULL, &error_fatal);
 | |
| 
 | |
|     if (nms->vic) {
 | |
|         dev = qdev_new(TYPE_NIOS2_VIC);
 | |
|         MemoryRegion *dev_mr;
 | |
|         qemu_irq cpu_irq;
 | |
| 
 | |
|         object_property_set_link(OBJECT(dev), "cpu", OBJECT(cpu), &error_fatal);
 | |
|         sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
 | |
| 
 | |
|         cpu_irq = qdev_get_gpio_in_named(DEVICE(cpu), "EIC", 0);
 | |
|         sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, cpu_irq);
 | |
|         for (i = 0; i < 32; i++) {
 | |
|             irq[i] = qdev_get_gpio_in(dev, i);
 | |
|         }
 | |
| 
 | |
|         dev_mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
 | |
|         memory_region_add_subregion(address_space_mem, 0x18002000, dev_mr);
 | |
|     } else {
 | |
|         for (i = 0; i < 32; i++) {
 | |
|             irq[i] = qdev_get_gpio_in_named(DEVICE(cpu), "IRQ", i);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* Register: Altera 16550 UART */
 | |
|     serial_mm_init(address_space_mem, 0xf8001600, 2, irq[1], 115200,
 | |
|                    serial_hd(0), DEVICE_NATIVE_ENDIAN);
 | |
| 
 | |
|     /* Register: Timer sys_clk_timer  */
 | |
|     dev = qdev_new("ALTR.timer");
 | |
|     qdev_prop_set_uint32(dev, "clock-frequency", 75 * 1000000);
 | |
|     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
 | |
|     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xf8001440);
 | |
|     sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[0]);
 | |
| 
 | |
|     /* Register: Timer sys_clk_timer_1  */
 | |
|     dev = qdev_new("ALTR.timer");
 | |
|     qdev_prop_set_uint32(dev, "clock-frequency", 75 * 1000000);
 | |
|     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
 | |
|     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xe0000880);
 | |
|     sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[5]);
 | |
| 
 | |
|     nios2_load_kernel(cpu, ram_base, ram_size, machine->initrd_filename,
 | |
|                       BINARY_DEVICE_TREE_FILE, NULL);
 | |
| }
 | |
| 
 | |
| static bool get_vic(Object *obj, Error **errp)
 | |
| {
 | |
|     Nios2MachineState *nms = NIOS2_MACHINE(obj);
 | |
|     return nms->vic;
 | |
| }
 | |
| 
 | |
| static void set_vic(Object *obj, bool value, Error **errp)
 | |
| {
 | |
|     Nios2MachineState *nms = NIOS2_MACHINE(obj);
 | |
|     nms->vic = value;
 | |
| }
 | |
| 
 | |
| static void nios2_10m50_ghrd_class_init(ObjectClass *oc, void *data)
 | |
| {
 | |
|     MachineClass *mc = MACHINE_CLASS(oc);
 | |
| 
 | |
|     mc->desc = "Altera 10M50 GHRD Nios II design";
 | |
|     mc->init = nios2_10m50_ghrd_init;
 | |
|     mc->is_default = true;
 | |
|     mc->deprecation_reason = "Nios II architecture is deprecated";
 | |
| 
 | |
|     object_class_property_add_bool(oc, "vic", get_vic, set_vic);
 | |
|     object_class_property_set_description(oc, "vic",
 | |
|         "Set on/off to enable/disable the Vectored Interrupt Controller");
 | |
| }
 | |
| 
 | |
| static const TypeInfo nios2_10m50_ghrd_type_info = {
 | |
|     .name          = TYPE_NIOS2_MACHINE,
 | |
|     .parent        = TYPE_MACHINE,
 | |
|     .instance_size = sizeof(Nios2MachineState),
 | |
|     .class_init    = nios2_10m50_ghrd_class_init,
 | |
| };
 | |
| 
 | |
| static void nios2_10m50_ghrd_type_init(void)
 | |
| {
 | |
|     type_register_static(&nios2_10m50_ghrd_type_info);
 | |
| }
 | |
| type_init(nios2_10m50_ghrd_type_init);
 |