mirror of
https://github.com/qemu/qemu.git
synced 2026-04-05 21:46:25 +00:00
Merge tag 'hppa-more-v11-fixes-pull-request' of https://github.com/hdeller/qemu-hppa into staging
HPPA patches for qemu-v11 A few late fixes for the HPPA architecture for QEMU v11: - graphics support was broken for 64-bit machines. This series adds support for VGA graphics for Linux guests - the various memory ranges were not correctly implemented - TOC/NMI was not working on 64-bit machines - minor 64-bit HP-UX boot fixes (but HP-UX 64-bit still crashes) # -----BEGIN PGP SIGNATURE----- # # iHUEABYKAB0WIQS86RI+GtKfB8BJu973ErUQojoPXwUCacwXxAAKCRD3ErUQojoP # X7NxAQCBszDUKsNX5KiB+cxW1AfT1Gyzo4q9T0NNULO5v2Fn7gD/YVzgtZ6F+crK # 1eG1R0aVekPmx+NClsCLvy/dX1YmTww= # =L+6i # -----END PGP SIGNATURE----- # gpg: Signature made Tue Mar 31 19:51:48 2026 BST # gpg: using EDDSA key BCE9123E1AD29F07C049BBDEF712B510A23A0F5F # gpg: Good signature from "Helge Deller <deller@gmx.de>" [unknown] # gpg: aka "Helge Deller <deller@kernel.org>" [unknown] # gpg: aka "Helge Deller <deller@debian.org>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 4544 8228 2CD9 10DB EF3D 25F8 3E5F 3D04 A7A2 4603 # Subkey fingerprint: BCE9 123E 1AD2 9F07 C049 BBDE F712 B510 A23A 0F5F * tag 'hppa-more-v11-fixes-pull-request' of https://github.com/hdeller/qemu-hppa: target/hppa: Update SeaBIOS-hppa to version 24 hw/hppa: Implement memory ranges target/hppa: Fix TOC handler for 64-bit CPUs hw/pci-host/astro: Add GMMIO mapping hw/pci-host/astro: Fix LMMIO DIRECT mappings hw/pci-host/astro: Implement LMMIO registers hw/pci-host/astro: Fix initial addresses in IOC hw/pci-host/astro: Make astro address arrays accessible for other users Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -8,7 +8,8 @@
|
|||||||
#define FIRMWARE_END 0xf0100000
|
#define FIRMWARE_END 0xf0100000
|
||||||
#define FIRMWARE_HIGH 0xfffffff0 /* upper 32-bits of 64-bit firmware address */
|
#define FIRMWARE_HIGH 0xfffffff0 /* upper 32-bits of 64-bit firmware address */
|
||||||
|
|
||||||
#define RAM_MAP_HIGH 0x0100000000 /* memory above 3.75 GB is mapped here */
|
#define RAM_MAP_HIGH1 0x0100000000 /* memory above 4 GB */
|
||||||
|
#define RAM_MAP_HIGH2 0x4040000000 /* memory between 1 G and 3.75 GB */
|
||||||
|
|
||||||
#define MEM_PDC_ENTRY 0x4800 /* PDC entry address */
|
#define MEM_PDC_ENTRY 0x4800 /* PDC entry address */
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(HppaMachineState, HPPA_COMMON_MACHINE)
|
|||||||
|
|
||||||
struct HppaMachineState {
|
struct HppaMachineState {
|
||||||
MachineState parent_obj;
|
MachineState parent_obj;
|
||||||
|
|
||||||
|
uint64_t memsplit_addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MIN_SEABIOS_HPPA_VERSION 22 /* require at least this fw version */
|
#define MIN_SEABIOS_HPPA_VERSION 22 /* require at least this fw version */
|
||||||
@@ -208,6 +210,7 @@ static FWCfgState *create_fw_cfg(MachineState *ms, PCIBus *pci_bus,
|
|||||||
const char qemu_version[] = QEMU_VERSION;
|
const char qemu_version[] = QEMU_VERSION;
|
||||||
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||||
int btlb_entries = HPPA_BTLB_ENTRIES(&cpu[0]->env);
|
int btlb_entries = HPPA_BTLB_ENTRIES(&cpu[0]->env);
|
||||||
|
struct HppaMachineState *hpm = HPPA_COMMON_MACHINE(ms);
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
fw_cfg = fw_cfg_init_mem_nodma(addr, addr + 4, 1);
|
fw_cfg = fw_cfg_init_mem_nodma(addr, addr + 4, 1);
|
||||||
@@ -231,6 +234,10 @@ static FWCfgState *create_fw_cfg(MachineState *ms, PCIBus *pci_bus,
|
|||||||
fw_cfg_add_file(fw_cfg, "/etc/hppa/machine",
|
fw_cfg_add_file(fw_cfg, "/etc/hppa/machine",
|
||||||
g_memdup2(mc->name, len), len);
|
g_memdup2(mc->name, len), len);
|
||||||
|
|
||||||
|
val = cpu_to_le64(hpm->memsplit_addr);
|
||||||
|
fw_cfg_add_file(fw_cfg, "/etc/hppa/memsplit-addr",
|
||||||
|
g_memdup2(&val, sizeof(val)), sizeof(val));
|
||||||
|
|
||||||
val = cpu_to_le64(soft_power_reg);
|
val = cpu_to_le64(soft_power_reg);
|
||||||
fw_cfg_add_file(fw_cfg, "/etc/hppa/power-button-addr",
|
fw_cfg_add_file(fw_cfg, "/etc/hppa/power-button-addr",
|
||||||
g_memdup2(&val, sizeof(val)), sizeof(val));
|
g_memdup2(&val, sizeof(val)), sizeof(val));
|
||||||
@@ -287,6 +294,8 @@ static TranslateFn *machine_HP_common_init_cpus(MachineState *machine)
|
|||||||
TranslateFn *translate;
|
TranslateFn *translate;
|
||||||
MemoryRegion *cpu_region;
|
MemoryRegion *cpu_region;
|
||||||
uint64_t ram_max;
|
uint64_t ram_max;
|
||||||
|
struct HppaMachineState *hpm;
|
||||||
|
hwaddr splitaddr;
|
||||||
|
|
||||||
/* Create CPUs. */
|
/* Create CPUs. */
|
||||||
for (unsigned int i = 0; i < smp_cpus; i++) {
|
for (unsigned int i = 0; i < smp_cpus; i++) {
|
||||||
@@ -347,21 +356,36 @@ static TranslateFn *machine_HP_common_init_cpus(MachineState *machine)
|
|||||||
info_report("Max RAM size limited to %" PRIu64 " MB", ram_max / MiB);
|
info_report("Max RAM size limited to %" PRIu64 " MB", ram_max / MiB);
|
||||||
machine->ram_size = ram_max;
|
machine->ram_size = ram_max;
|
||||||
}
|
}
|
||||||
if (machine->ram_size <= FIRMWARE_START) {
|
|
||||||
/* contiguous memory up to 3.75 GB RAM */
|
hpm = HPPA_COMMON_MACHINE(machine);
|
||||||
memory_region_add_subregion_overlap(addr_space, 0, machine->ram, -1);
|
if (!hpm->memsplit_addr) {
|
||||||
} else {
|
|
||||||
/* non-contiguous: Memory above 3.75 GB is mapped at RAM_MAP_HIGH */
|
/* non-contiguous: Memory above 3.75 GB is mapped at RAM_MAP_HIGH */
|
||||||
MemoryRegion *mem_region;
|
hpm->memsplit_addr = FIRMWARE_START;
|
||||||
mem_region = g_new(MemoryRegion, 2);
|
}
|
||||||
memory_region_init_alias(&mem_region[0], &addr_space->parent_obj,
|
splitaddr = hpm->memsplit_addr;
|
||||||
"LowMem", machine->ram, 0, FIRMWARE_START);
|
|
||||||
memory_region_init_alias(&mem_region[1], &addr_space->parent_obj,
|
MemoryRegion *mem_region;
|
||||||
"HighMem", machine->ram, FIRMWARE_START,
|
mem_region = g_new(MemoryRegion, 1);
|
||||||
machine->ram_size - FIRMWARE_START);
|
memory_region_init_alias(&mem_region[0], &addr_space->parent_obj,
|
||||||
memory_region_add_subregion_overlap(addr_space, 0, &mem_region[0], -1);
|
"memory0", machine->ram, 0, splitaddr);
|
||||||
memory_region_add_subregion_overlap(addr_space, RAM_MAP_HIGH,
|
memory_region_add_subregion_overlap(addr_space, 0, &mem_region[0], -1);
|
||||||
&mem_region[1], -1);
|
if (hppa_is_pa20(&cpu[0]->env)) {
|
||||||
|
if (machine->ram_size > 4 * GiB) {
|
||||||
|
mem_region = g_new(MemoryRegion, 1);
|
||||||
|
memory_region_init_alias(&mem_region[0], &addr_space->parent_obj,
|
||||||
|
"memory1", machine->ram, 4 * GiB,
|
||||||
|
machine->ram_size - 4 * GiB);
|
||||||
|
memory_region_add_subregion_overlap(addr_space, RAM_MAP_HIGH1,
|
||||||
|
&mem_region[0], -1);
|
||||||
|
}
|
||||||
|
if (machine->ram_size > splitaddr) {
|
||||||
|
mem_region = g_new(MemoryRegion, 1);
|
||||||
|
memory_region_init_alias(&mem_region[0], &addr_space->parent_obj,
|
||||||
|
"memory2", machine->ram, splitaddr,
|
||||||
|
4 * GiB - splitaddr);
|
||||||
|
memory_region_add_subregion_overlap(addr_space, RAM_MAP_HIGH2,
|
||||||
|
&mem_region[0], -1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return translate;
|
return translate;
|
||||||
@@ -757,6 +781,10 @@ static void machine_HP_C3700_init(MachineState *machine)
|
|||||||
*/
|
*/
|
||||||
static void machine_HP_A400_init(MachineState *machine)
|
static void machine_HP_A400_init(MachineState *machine)
|
||||||
{
|
{
|
||||||
|
struct HppaMachineState *hpm;
|
||||||
|
|
||||||
|
hpm = HPPA_COMMON_MACHINE(machine);
|
||||||
|
hpm->memsplit_addr = 1 * GiB;
|
||||||
machine_HP_C3700_init(machine);
|
machine_HP_C3700_init(machine);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -815,7 +843,7 @@ static void hppa_machine_common_class_init(ObjectClass *oc, const void *data)
|
|||||||
mc->default_cpus = 1;
|
mc->default_cpus = 1;
|
||||||
mc->max_cpus = HPPA_MAX_CPUS;
|
mc->max_cpus = HPPA_MAX_CPUS;
|
||||||
mc->default_boot_order = "cd";
|
mc->default_boot_order = "cd";
|
||||||
mc->default_ram_id = "ram";
|
mc->default_ram_id = "hppa.ram";
|
||||||
mc->default_nic = "tulip";
|
mc->default_nic = "tulip";
|
||||||
|
|
||||||
nc->nmi_monitor_handler = hppa_nmi;
|
nc->nmi_monitor_handler = hppa_nmi;
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
* - All user-added devices are currently attached to the first
|
* - All user-added devices are currently attached to the first
|
||||||
* Elroy (PCI bus) only for now. To fix this additional work in
|
* Elroy (PCI bus) only for now. To fix this additional work in
|
||||||
* SeaBIOS and this driver is needed. See "user_creatable" flag below.
|
* SeaBIOS and this driver is needed. See "user_creatable" flag below.
|
||||||
* - GMMIO (Greater than 4 GB MMIO) register
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define TYPE_ASTRO_IOMMU_MEMORY_REGION "astro-iommu-memory-region"
|
#define TYPE_ASTRO_IOMMU_MEMORY_REGION "astro-iommu-memory-region"
|
||||||
@@ -37,6 +36,11 @@
|
|||||||
#include "qom/object.h"
|
#include "qom/object.h"
|
||||||
#include "exec/target_page.h"
|
#include "exec/target_page.h"
|
||||||
|
|
||||||
|
static const int elroy_hpa_offsets[ELROY_NUM] = {
|
||||||
|
0x30000, 0x32000, 0x38000, 0x3c000 };
|
||||||
|
static const char elroy_rope_nr[ELROY_NUM] = {
|
||||||
|
0, 1, 4, 6 }; /* busnum path, e.g. [10:6] */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper functions
|
* Helper functions
|
||||||
*/
|
*/
|
||||||
@@ -525,14 +529,90 @@ static ElroyState *elroy_init(int num)
|
|||||||
* Astro Runway chip.
|
* Astro Runway chip.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static void adjust_LMMIO_mapping(AstroState *s)
|
||||||
|
{
|
||||||
|
MemoryRegion *lmmio;
|
||||||
|
uint64_t map_addr, map_size, align_mask;
|
||||||
|
uint32_t map_route, map_enabled, i;
|
||||||
|
|
||||||
|
lmmio = &s->lmmio;
|
||||||
|
|
||||||
|
/* read LMMIO distributed route and calculate size */
|
||||||
|
map_route = s->ioc_ranges[(0x370 - 0x300) / 8] >> 58;
|
||||||
|
map_route = MIN(MAX(map_route, 20), 23);
|
||||||
|
|
||||||
|
/* calculate size of each mapping, sum of all is 8-64 MB */
|
||||||
|
map_size = 1ULL << map_route;
|
||||||
|
align_mask = ~(map_size - 1);
|
||||||
|
|
||||||
|
/* read LMMIO_DIST_BASE for mapping address */
|
||||||
|
map_addr = s->ioc_ranges[(0x360 - 0x300) / 8];
|
||||||
|
map_enabled = map_addr & 1;
|
||||||
|
map_addr &= MAKE_64BIT_MASK(24, 5);
|
||||||
|
map_addr |= MAKE_64BIT_MASK(29, 36);
|
||||||
|
map_addr &= align_mask;
|
||||||
|
s->ioc_ranges[(0x360 - 0x300) / 8] = map_addr | map_enabled;
|
||||||
|
|
||||||
|
/* make sure the lmmio region is initially turned off */
|
||||||
|
if (lmmio->enabled) {
|
||||||
|
memory_region_set_enabled(lmmio, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* exit if range is not enabled */
|
||||||
|
if (!map_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lmmio->name) {
|
||||||
|
memory_region_init_io(lmmio, OBJECT(s), &unassigned_io_ops, s,
|
||||||
|
"LMMIO", ROPES_PER_IOC * map_size);
|
||||||
|
memory_region_add_subregion_overlap(get_system_memory(),
|
||||||
|
map_addr, lmmio, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memory_region_set_address(lmmio, map_addr);
|
||||||
|
memory_region_set_size(lmmio, ROPES_PER_IOC * map_size);
|
||||||
|
memory_region_set_enabled(lmmio, true);
|
||||||
|
|
||||||
|
for (i = 0; i < ELROY_NUM; i++) {
|
||||||
|
MemoryRegion *alias;
|
||||||
|
ElroyState *elroy;
|
||||||
|
int rope;
|
||||||
|
|
||||||
|
elroy = s->elroy[i];
|
||||||
|
alias = &elroy->lmmio_alias;
|
||||||
|
rope = elroy_rope_nr[i];
|
||||||
|
if (alias->enabled) {
|
||||||
|
memory_region_set_enabled(alias, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!alias->name) {
|
||||||
|
memory_region_init_alias(alias, OBJECT(elroy),
|
||||||
|
"lmmio-alias", &elroy->pci_mmio, 0, map_size);
|
||||||
|
memory_region_add_subregion_overlap(lmmio, rope * map_size,
|
||||||
|
alias, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
memory_region_set_address(alias, rope * map_size);
|
||||||
|
memory_region_set_alias_offset(alias,
|
||||||
|
(uint32_t) (map_addr + rope * map_size));
|
||||||
|
memory_region_set_size(alias, map_size);
|
||||||
|
memory_region_set_enabled(alias, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void adjust_LMMIO_DIRECT_mapping(AstroState *s, unsigned int reg_index)
|
static void adjust_LMMIO_DIRECT_mapping(AstroState *s, unsigned int reg_index)
|
||||||
{
|
{
|
||||||
MemoryRegion *lmmio_alias;
|
MemoryRegion *lmmio_alias;
|
||||||
unsigned int lmmio_index, map_route;
|
unsigned int lmmio_index, map_route;
|
||||||
hwaddr map_addr;
|
hwaddr map_addr;
|
||||||
uint32_t map_size;
|
uint32_t map_size, map_enabled;
|
||||||
struct ElroyState *elroy;
|
struct ElroyState *elroy;
|
||||||
|
|
||||||
|
/* each LMMIO may access from 1 MB up to 64 MB */
|
||||||
|
const unsigned int lmmio_mask = ~(1 * MiB - 1);
|
||||||
|
const unsigned int lmmio_max_size = 64 * MiB;
|
||||||
|
|
||||||
/* pointer to LMMIO_DIRECT entry */
|
/* pointer to LMMIO_DIRECT entry */
|
||||||
lmmio_index = reg_index / 3;
|
lmmio_index = reg_index / 3;
|
||||||
lmmio_alias = &s->lmmio_direct[lmmio_index];
|
lmmio_alias = &s->lmmio_direct[lmmio_index];
|
||||||
@@ -545,30 +625,104 @@ static void adjust_LMMIO_DIRECT_mapping(AstroState *s, unsigned int reg_index)
|
|||||||
map_route &= (ELROY_NUM - 1);
|
map_route &= (ELROY_NUM - 1);
|
||||||
elroy = s->elroy[map_route];
|
elroy = s->elroy[map_route];
|
||||||
|
|
||||||
|
/* make sure the lmmio region is initially turned off */
|
||||||
if (lmmio_alias->enabled) {
|
if (lmmio_alias->enabled) {
|
||||||
memory_region_set_enabled(lmmio_alias, false);
|
memory_region_set_enabled(lmmio_alias, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* do sanity checks and calculate mmio size */
|
||||||
|
map_enabled = map_addr & 1;
|
||||||
|
map_addr &= lmmio_mask;
|
||||||
|
map_size &= lmmio_mask;
|
||||||
|
map_size = MIN(map_size, lmmio_max_size);
|
||||||
map_addr = F_EXTEND(map_addr);
|
map_addr = F_EXTEND(map_addr);
|
||||||
map_addr &= TARGET_PAGE_MASK;
|
|
||||||
map_size = (~map_size) + 1;
|
|
||||||
map_size &= TARGET_PAGE_MASK;
|
|
||||||
|
|
||||||
/* exit if disabled or zero map size */
|
/* exit if disabled or has zero size. */
|
||||||
if (!(map_addr & 1) || !map_size) {
|
if (!map_enabled || !map_size) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!memory_region_size(lmmio_alias)) {
|
if (!lmmio_alias->name) {
|
||||||
|
char lmmio_name[32];
|
||||||
|
snprintf(lmmio_name, sizeof(lmmio_name),
|
||||||
|
"LMMIO-DIRECT-%u", lmmio_index);
|
||||||
memory_region_init_alias(lmmio_alias, OBJECT(elroy),
|
memory_region_init_alias(lmmio_alias, OBJECT(elroy),
|
||||||
"pci-lmmmio-alias", &elroy->pci_mmio,
|
lmmio_name, &elroy->pci_mmio,
|
||||||
(uint32_t) map_addr, map_size);
|
(uint32_t) map_addr, map_size);
|
||||||
memory_region_add_subregion(get_system_memory(), map_addr,
|
memory_region_add_subregion_overlap(get_system_memory(),
|
||||||
lmmio_alias);
|
map_addr, lmmio_alias, 3);
|
||||||
} else {
|
}
|
||||||
memory_region_set_alias_offset(lmmio_alias, map_addr);
|
|
||||||
memory_region_set_size(lmmio_alias, map_size);
|
memory_region_set_address(lmmio_alias, map_addr);
|
||||||
memory_region_set_enabled(lmmio_alias, true);
|
memory_region_set_alias_offset(lmmio_alias, (uint32_t) map_addr);
|
||||||
|
memory_region_set_size(lmmio_alias, map_size);
|
||||||
|
memory_region_set_enabled(lmmio_alias, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void adjust_GMMIO_mapping(AstroState *s)
|
||||||
|
{
|
||||||
|
MemoryRegion *gmmio;
|
||||||
|
uint64_t map_addr, map_size, align_mask;
|
||||||
|
uint32_t map_route, map_enabled, i;
|
||||||
|
|
||||||
|
gmmio = &s->gmmio;
|
||||||
|
map_addr = s->ioc_ranges[(0x378 - 0x300) / 8]; /* GMMIO_DIST_BASE */
|
||||||
|
map_enabled = map_addr & 1;
|
||||||
|
map_addr &= MAKE_64BIT_MASK(32, 8);
|
||||||
|
s->ioc_ranges[(0x378 - 0x300) / 8] = map_addr | map_enabled;
|
||||||
|
|
||||||
|
map_route = s->ioc_ranges[(0x388 - 0x300) / 8] >> 58; /* GMMIO_DIST_ROUTE */
|
||||||
|
map_route = MIN(MAX(map_route, 29), 33); /* between 4-16 GB total */
|
||||||
|
map_size = 1ULL << map_route; /* size of each mapping */
|
||||||
|
align_mask = ~(map_size - 1);
|
||||||
|
|
||||||
|
/* make sure the lmmio region is initially turned off */
|
||||||
|
if (gmmio->enabled) {
|
||||||
|
memory_region_set_enabled(gmmio, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do sanity checks and calculate mmio size */
|
||||||
|
map_addr &= align_mask;
|
||||||
|
|
||||||
|
/* exit if disabled */
|
||||||
|
if (!map_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gmmio->name) {
|
||||||
|
memory_region_init_io(gmmio, OBJECT(s), &unassigned_io_ops, s,
|
||||||
|
"GMMIO", ROPES_PER_IOC * map_size);
|
||||||
|
memory_region_add_subregion_overlap(get_system_memory(),
|
||||||
|
map_addr, gmmio, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memory_region_set_address(gmmio, map_addr);
|
||||||
|
memory_region_set_size(gmmio, ROPES_PER_IOC * map_size);
|
||||||
|
memory_region_set_enabled(gmmio, true);
|
||||||
|
|
||||||
|
for (i = 0; i < ELROY_NUM; i++) {
|
||||||
|
MemoryRegion *alias;
|
||||||
|
ElroyState *elroy;
|
||||||
|
int rope;
|
||||||
|
|
||||||
|
elroy = s->elroy[i];
|
||||||
|
alias = &elroy->gmmio_alias;
|
||||||
|
rope = elroy_rope_nr[i];
|
||||||
|
if (alias->enabled) {
|
||||||
|
memory_region_set_enabled(alias, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!alias->name) {
|
||||||
|
memory_region_init_alias(alias, OBJECT(elroy),
|
||||||
|
"gmmio-alias", &elroy->pci_mmio, 0, map_size);
|
||||||
|
memory_region_add_subregion_overlap(gmmio, rope * map_size,
|
||||||
|
alias, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
memory_region_set_address(alias, rope * map_size);
|
||||||
|
memory_region_set_alias_offset(alias, map_addr + rope * map_size);
|
||||||
|
memory_region_set_size(alias, map_size);
|
||||||
|
memory_region_set_enabled(alias, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -684,6 +838,12 @@ static MemTxResult astro_chip_write_with_attrs(void *opaque, hwaddr addr,
|
|||||||
if (index < LMMIO_DIRECT_RANGES * 3) {
|
if (index < LMMIO_DIRECT_RANGES * 3) {
|
||||||
adjust_LMMIO_DIRECT_mapping(s, index);
|
adjust_LMMIO_DIRECT_mapping(s, index);
|
||||||
}
|
}
|
||||||
|
if (addr >= 0x360 && addr <= 0x370 + 7) {
|
||||||
|
adjust_LMMIO_mapping(s);
|
||||||
|
}
|
||||||
|
if (addr >= 0x378 && addr <= 0x388 + 7) {
|
||||||
|
adjust_GMMIO_mapping(s);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0x10200:
|
case 0x10200:
|
||||||
case 0x10220:
|
case 0x10220:
|
||||||
@@ -799,13 +959,13 @@ static void astro_reset(DeviceState *dev)
|
|||||||
* The LBA BASE/MASK registers control IO -> System routing (in Elroy)
|
* The LBA BASE/MASK registers control IO -> System routing (in Elroy)
|
||||||
*/
|
*/
|
||||||
memset(&s->ioc_ranges, 0, sizeof(s->ioc_ranges));
|
memset(&s->ioc_ranges, 0, sizeof(s->ioc_ranges));
|
||||||
s->ioc_ranges[(0x360 - 0x300) / 8] = LMMIO_DIST_BASE_ADDR | 0x01; /* LMMIO_DIST_BASE (SBA) */
|
s->ioc_ranges[(0x360 - 0x300) / 8] = F_EXTEND(LMMIO_DIST_BASE_ADDR) | 0x01;
|
||||||
s->ioc_ranges[(0x368 - 0x300) / 8] = 0xfc000000; /* LMMIO_DIST_MASK */
|
s->ioc_ranges[(0x368 - 0x300) / 8] = 0xfc000000; /* LMMIO_DIST_MASK */
|
||||||
s->ioc_ranges[(0x370 - 0x300) / 8] = 0; /* LMMIO_DIST_ROUTE */
|
s->ioc_ranges[(0x370 - 0x300) / 8] = 0; /* LMMIO_DIST_ROUTE */
|
||||||
s->ioc_ranges[(0x390 - 0x300) / 8] = IOS_DIST_BASE_ADDR | 0x01; /* IOS_DIST_BASE */
|
s->ioc_ranges[(0x390 - 0x300) / 8] = F_EXTEND(IOS_DIST_BASE_ADDR) | 0x01;
|
||||||
s->ioc_ranges[(0x398 - 0x300) / 8] = 0xffffff0000; /* IOS_DIST_MASK */
|
s->ioc_ranges[(0x398 - 0x300) / 8] = 0xffffff0000; /* IOS_DIST_MASK */
|
||||||
s->ioc_ranges[(0x3a0 - 0x300) / 8] = 0x3400000000000000ULL; /* IOS_DIST_ROUTE */
|
s->ioc_ranges[(0x3a0 - 0x300) / 8] = 0x3400000000000000ULL; /* IOS_DIST_ROUTE */
|
||||||
s->ioc_ranges[(0x3c0 - 0x300) / 8] = 0xfffee00000; /* IOS_DIRECT_BASE */
|
s->ioc_ranges[(0x3c0 - 0x300) / 8] = IOS_DIST_BASE_ADDR; /* IOS_DIRECT_BASE */
|
||||||
s->ioc_ranges[(0x3c8 - 0x300) / 8] = 0xffffff0000; /* IOS_DIRECT_MASK */
|
s->ioc_ranges[(0x3c8 - 0x300) / 8] = 0xffffff0000; /* IOS_DIRECT_MASK */
|
||||||
s->ioc_ranges[(0x3d0 - 0x300) / 8] = 0x0; /* IOS_DIRECT_ROUTE */
|
s->ioc_ranges[(0x3d0 - 0x300) / 8] = 0x0; /* IOS_DIRECT_ROUTE */
|
||||||
|
|
||||||
@@ -843,10 +1003,6 @@ static void astro_realize(DeviceState *obj, Error **errp)
|
|||||||
|
|
||||||
/* Create Elroys (PCI host bus chips). */
|
/* Create Elroys (PCI host bus chips). */
|
||||||
for (i = 0; i < ELROY_NUM; i++) {
|
for (i = 0; i < ELROY_NUM; i++) {
|
||||||
static const int elroy_hpa_offsets[ELROY_NUM] = {
|
|
||||||
0x30000, 0x32000, 0x38000, 0x3c000 };
|
|
||||||
static const char elroy_rope_nr[ELROY_NUM] = {
|
|
||||||
0, 1, 4, 6 }; /* busnum path, e.g. [10:6] */
|
|
||||||
int addr_offset;
|
int addr_offset;
|
||||||
ElroyState *elroy;
|
ElroyState *elroy;
|
||||||
hwaddr map_addr;
|
hwaddr map_addr;
|
||||||
@@ -891,15 +1047,6 @@ static void astro_realize(DeviceState *obj, Error **errp)
|
|||||||
elroy->mmio_base[(0x0240 - 0x200) / 8] = rope * map_size | 0x01;
|
elroy->mmio_base[(0x0240 - 0x200) / 8] = rope * map_size | 0x01;
|
||||||
elroy->mmio_base[(0x0248 - 0x200) / 8] = 0x0000e000;
|
elroy->mmio_base[(0x0248 - 0x200) / 8] = 0x0000e000;
|
||||||
|
|
||||||
/* map elroys mmio */
|
|
||||||
map_size = LMMIO_DIST_BASE_SIZE / ROPES_PER_IOC;
|
|
||||||
map_addr = F_EXTEND(LMMIO_DIST_BASE_ADDR + rope * map_size);
|
|
||||||
memory_region_init_alias(&elroy->pci_mmio_alias, OBJECT(elroy),
|
|
||||||
"pci-mmio-alias",
|
|
||||||
&elroy->pci_mmio, (uint32_t) map_addr, map_size);
|
|
||||||
memory_region_add_subregion(get_system_memory(), map_addr,
|
|
||||||
&elroy->pci_mmio_alias);
|
|
||||||
|
|
||||||
/* map elroys io */
|
/* map elroys io */
|
||||||
map_size = IOS_DIST_BASE_SIZE / ROPES_PER_IOC;
|
map_size = IOS_DIST_BASE_SIZE / ROPES_PER_IOC;
|
||||||
map_addr = F_EXTEND(IOS_DIST_BASE_ADDR + rope * map_size);
|
map_addr = F_EXTEND(IOS_DIST_BASE_ADDR + rope * map_size);
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(ElroyState, ELROY_PCI_HOST_BRIDGE)
|
|||||||
|
|
||||||
#define LMMIO_DIRECT_RANGES 4
|
#define LMMIO_DIRECT_RANGES 4
|
||||||
|
|
||||||
#define IOS_DIST_BASE_ADDR 0xfffee00000ULL
|
#define IOS_DIST_BASE_ADDR 0xffffee00000ULL
|
||||||
#define IOS_DIST_BASE_SIZE 0x10000ULL
|
#define IOS_DIST_BASE_SIZE 0x10000ULL
|
||||||
|
|
||||||
#define HF_ENABLE 0x40 /* enable HF mode (default is -1 mode) */
|
#define HF_ENABLE 0x40 /* enable HF mode (default is -1 mode) */
|
||||||
|
|
||||||
@@ -61,9 +61,10 @@ struct ElroyState {
|
|||||||
MemoryRegion this_mem;
|
MemoryRegion this_mem;
|
||||||
|
|
||||||
MemoryRegion pci_mmio;
|
MemoryRegion pci_mmio;
|
||||||
MemoryRegion pci_mmio_alias;
|
|
||||||
MemoryRegion pci_hole;
|
|
||||||
MemoryRegion pci_io;
|
MemoryRegion pci_io;
|
||||||
|
|
||||||
|
MemoryRegion gmmio_alias;
|
||||||
|
MemoryRegion lmmio_alias;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstroState {
|
struct AstroState {
|
||||||
@@ -89,6 +90,9 @@ struct AstroState {
|
|||||||
MemoryRegion this_mem;
|
MemoryRegion this_mem;
|
||||||
MemoryRegion lmmio_direct[LMMIO_DIRECT_RANGES];
|
MemoryRegion lmmio_direct[LMMIO_DIRECT_RANGES];
|
||||||
|
|
||||||
|
MemoryRegion lmmio;
|
||||||
|
MemoryRegion gmmio;
|
||||||
|
|
||||||
IOMMUMemoryRegion iommu;
|
IOMMUMemoryRegion iommu;
|
||||||
AddressSpace iommu_as;
|
AddressSpace iommu_as;
|
||||||
};
|
};
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Submodule roms/seabios-hppa updated: cf3a472f4d...d9560852a3
@@ -203,7 +203,12 @@ void hppa_cpu_do_interrupt(CPUState *cs)
|
|||||||
|
|
||||||
/* step 7 */
|
/* step 7 */
|
||||||
if (i == EXCP_TOC) {
|
if (i == EXCP_TOC) {
|
||||||
env->iaoq_f = hppa_form_gva(env, 0, FIRMWARE_START);
|
hwaddr pdc_toc_addr = FIRMWARE_START;
|
||||||
|
|
||||||
|
/* for 64-bit include the high bits of PDC */
|
||||||
|
pdc_toc_addr |= ((uint64_t) FIRMWARE_HIGH) << 32;
|
||||||
|
env->iaoq_f = hppa_form_gva(env, 0, pdc_toc_addr);
|
||||||
|
|
||||||
/* help SeaBIOS and provide iaoq_b and iasq_back in shadow regs */
|
/* help SeaBIOS and provide iaoq_b and iasq_back in shadow regs */
|
||||||
env->gr[24] = env->cr_back[0];
|
env->gr[24] = env->cr_back[0];
|
||||||
env->gr[25] = env->cr_back[1];
|
env->gr[25] = env->cr_back[1];
|
||||||
|
|||||||
Reference in New Issue
Block a user