From beb220f8d6b011e59462cc240ab4350c8a47b681 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 26 Sep 2023 15:59:54 +0200 Subject: pci detection on astro works --- src/fw/pciinit.c | 9 +++------ src/hw/pci.c | 35 +++++++++++++++++++++++++++++++++++ src/parisc/hppa.h | 34 +++++++++++++++++++++++++++------- src/parisc/hppa_hardware.h | 15 +++++++++++++-- src/parisc/parisc.c | 7 ++++++- 5 files changed, 84 insertions(+), 16 deletions(-) diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c index 7f93a1f..abf5007 100644 --- a/src/fw/pciinit.c +++ b/src/fw/pciinit.c @@ -545,16 +545,13 @@ static int astro_pci_slot_get_irq(struct pci_device *pci, int pin) static void astro_mem_addr_setup(struct pci_device *dev, void *arg) { - pcimem_start = 0xf4000000ULL; - pcimem_end = pcimem_start + 0x4000000ULL; - -// outl(0x00000080, DINO_HPA + 0x038); /* IO_CONTROL - enable DINO PCI */ -// outl(0x7ffffffe, DINO_HPA + 0x060); /* Set DINO_IO_ADDR_EN */ + pcimem_start = LMMIO_DIST_BASE_ADDR; + pcimem_end = pcimem_start + LMMIO_DIST_BASE_SIZE / ROPES_PER_IOC; pci_slot_get_irq = astro_pci_slot_get_irq; /* setup io address space */ - pci_io_low_end = 0x40000; + pci_io_low_end = IOS_DIST_BASE_SIZE / ROPES_PER_IOC; } static void parisc_mem_addr_setup(struct pci_device *dev, void *arg) diff --git a/src/hw/pci.c b/src/hw/pci.c index ecc724b..7d8b19e 100644 --- a/src/hw/pci.c +++ b/src/hw/pci.c @@ -31,8 +31,23 @@ static u32 ioconfig_cmd(u16 bdf, u32 addr) return 0x80000000 | (bdf << 8) | (addr & 0xfc); } +/* + * Memory mapped I/O + * + * readX()/writeX() do byteswapping and take an ioremapped address + * __raw_readX()/__raw_writeX() don't byteswap and take an ioremapped address. + * gsc_*() don't byteswap and operate on physical addresses; + * eg dev->hpa or 0xfee00000. + */ + +#define _pciport(x) (void *)((unsigned long)(x)) + void pci_config_writel(u16 bdf, u32 addr, u32 val) { + if (has_astro) { + writel(_pciport(PORT_PCI_CMD), ioconfig_cmd(bdf, addr)); + writel(_pciport(PORT_PCI_DATA), val); + } else if (!MODESEGMENT && mmconfig) { writel(mmconfig_addr(bdf, addr), val); } else { @@ -43,6 +58,10 @@ void pci_config_writel(u16 bdf, u32 addr, u32 val) void pci_config_writew(u16 bdf, u32 addr, u16 val) { + if (has_astro) { + writel(_pciport(PORT_PCI_CMD), ioconfig_cmd(bdf, addr)); + writew(_pciport(PORT_PCI_DATA + (addr & 2)), val); + } else if (!MODESEGMENT && mmconfig) { writew(mmconfig_addr(bdf, addr), val); } else { @@ -53,6 +72,10 @@ void pci_config_writew(u16 bdf, u32 addr, u16 val) void pci_config_writeb(u16 bdf, u32 addr, u8 val) { + if (has_astro) { + writel(_pciport(PORT_PCI_CMD), ioconfig_cmd(bdf, addr)); + writeb(_pciport(PORT_PCI_DATA + (addr & 3)), val); + } else if (!MODESEGMENT && mmconfig) { writeb(mmconfig_addr(bdf, addr), val); } else { @@ -63,6 +86,10 @@ void pci_config_writeb(u16 bdf, u32 addr, u8 val) u32 pci_config_readl(u16 bdf, u32 addr) { + if (has_astro) { + writel(_pciport(PORT_PCI_CMD), ioconfig_cmd(bdf, addr)); + return readl(_pciport(PORT_PCI_DATA)); + } else if (!MODESEGMENT && mmconfig) { return readl(mmconfig_addr(bdf, addr)); } else { @@ -73,6 +100,10 @@ u32 pci_config_readl(u16 bdf, u32 addr) u16 pci_config_readw(u16 bdf, u32 addr) { + if (has_astro) { + writel(_pciport(PORT_PCI_CMD), ioconfig_cmd(bdf, addr)); + return readw(_pciport(PORT_PCI_DATA + (addr & 2))); + } else if (!MODESEGMENT && mmconfig) { return readw(mmconfig_addr(bdf, addr)); } else { @@ -83,6 +114,10 @@ u16 pci_config_readw(u16 bdf, u32 addr) u8 pci_config_readb(u16 bdf, u32 addr) { + if (has_astro) { + writel(_pciport(PORT_PCI_CMD), ioconfig_cmd(bdf, addr)); + return readb(_pciport(PORT_PCI_DATA + (addr & 3))); + } else if (!MODESEGMENT && mmconfig) { return readb(mmconfig_addr(bdf, addr)); } else { diff --git a/src/parisc/hppa.h b/src/parisc/hppa.h index 1a00288..d832514 100644 --- a/src/parisc/hppa.h +++ b/src/parisc/hppa.h @@ -205,10 +205,19 @@ static inline u32 ror(u32 word, unsigned int shift) } extern char has_astro; /* false for B160L machine with Dino PCI chip */ +extern unsigned long hppa_port_pci_cmd; +extern unsigned long hppa_port_pci_data; + #define pci_ioport_addr(port) ((port >= 0x1000) && (port < FIRMWARE_START)) +#define is_astro_ioport(port) (has_astro && (port < IOS_DIST_BASE_SIZE)) + +#define astro_ioport_addr(port) ((void *)(portaddr_t)(IOS_DIST_BASE_ADDR + port)) static inline void outl(u32 value, portaddr_t port) { + if (is_astro_ioport(port)) + *(volatile u32 *)(astro_ioport_addr(port)) = cpu_to_le32(value); + else if (!pci_ioport_addr(port)) { *(volatile u32 *)(port) = be32_to_cpu(value); } else { @@ -220,6 +229,9 @@ static inline void outl(u32 value, portaddr_t port) { } static inline void outw(u16 value, portaddr_t port) { + if (is_astro_ioport(port)) + *(volatile u16 *)(astro_ioport_addr(port)) = cpu_to_le16(value); + else if (!pci_ioport_addr(port)) { *(volatile u16 *)(port) = be16_to_cpu(value); } else { @@ -231,7 +243,7 @@ static inline void outw(u16 value, portaddr_t port) { } static inline void outb(u8 value, portaddr_t port) { - if (!pci_ioport_addr(port)) { + if (has_astro || !pci_ioport_addr(port)) { *(volatile u8 *)(port) = value; } else { /* write PCI I/O address to Dino's PCI_CONFIG_ADDR */ @@ -242,7 +254,7 @@ static inline void outb(u8 value, portaddr_t port) { } static inline u8 inb(portaddr_t port) { - if (!pci_ioport_addr(port)) { + if (has_astro || !pci_ioport_addr(port)) { return *(volatile u8 *)(port); } else { /* write PCI I/O address to Dino's PCI_CONFIG_ADDR */ @@ -253,6 +265,9 @@ static inline u8 inb(portaddr_t port) { } static inline u16 inw(portaddr_t port) { + if (is_astro_ioport(port)) + return le16_to_cpu(*(volatile u16 *)(astro_ioport_addr(port))); + else if (!pci_ioport_addr(port)) { return *(volatile u16 *)(port); } else { @@ -263,6 +278,9 @@ static inline u16 inw(portaddr_t port) { } } static inline u32 inl(portaddr_t port) { + if (is_astro_ioport(port)) + return (le32_to_cpu(*(volatile u32 *)(astro_ioport_addr(port)))); + else if (!pci_ioport_addr(port)) { return *(volatile u32 *)(port); } else { @@ -323,13 +341,15 @@ static inline void smp_wmb(void) { barrier(); } +/* readX()/writeX() do byteswapping */ + static inline void writel(void *addr, u32 val) { barrier(); - *(volatile u32 *)addr = val; + *(volatile u32 *)addr = cpu_to_le32(val); } static inline void writew(void *addr, u16 val) { barrier(); - *(volatile u16 *)addr = val; + *(volatile u16 *)addr = cpu_to_le16(val); } static inline void writeb(void *addr, u8 val) { barrier(); @@ -338,17 +358,17 @@ static inline void writeb(void *addr, u8 val) { static inline u64 readq(const void *addr) { u64 val = *(volatile const u64 *)addr; barrier(); - return val; + return le64_to_cpu(val); } static inline u32 readl(const void *addr) { u32 val = *(volatile const u32 *)addr; barrier(); - return val; + return le32_to_cpu(val); } static inline u16 readw(const void *addr) { u16 val = *(volatile const u16 *)addr; barrier(); - return val; + return le16_to_cpu(val); } static inline u8 readb(const void *addr) { u8 val = *(volatile const u8 *)addr; diff --git a/src/parisc/hppa_hardware.h b/src/parisc/hppa_hardware.h index c036d46..f363d9d 100644 --- a/src/parisc/hppa_hardware.h +++ b/src/parisc/hppa_hardware.h @@ -36,8 +36,8 @@ #define DINO_CONFIG_DATA 0x068 #define DINO_IO_DATA 0x06c -#define PORT_PCI_CMD (PCI_HPA + DINO_PCI_ADDR) -#define PORT_PCI_DATA (PCI_HPA + DINO_CONFIG_DATA) +#define PORT_PCI_CMD hppa_port_pci_cmd +#define PORT_PCI_DATA hppa_port_pci_data #define FW_CFG_IO_BASE 0xfffa0000 @@ -50,4 +50,15 @@ #define CPU_HPA_CR_REG 7 /* store CPU HPA in cr7 (SeaBIOS internal) */ #define PIM_STORAGE_SIZE 600 /* storage size of pdc_pim_toc_struct (64bit) */ + +/* ASTRO Memory and I/O regions */ +#define LMMIO_DIST_BASE_ADDR 0xf4000000ULL +#define LMMIO_DIST_BASE_SIZE 0x4000000ULL + +#define IOS_DIST_BASE_ADDR 0xfffee00000ULL +#define IOS_DIST_BASE_SIZE 0x10000ULL + +#define ROPES_PER_IOC 8 /* per Ike half or Pluto/Astro */ + + #endif diff --git a/src/parisc/parisc.c b/src/parisc/parisc.c index 8a97339..6739ce5 100644 --- a/src/parisc/parisc.c +++ b/src/parisc/parisc.c @@ -120,6 +120,9 @@ char qemu_version[16] = "unknown version"; char qemu_machine[16] = "B160L"; char cpu_bit_width; char has_astro; +unsigned long hppa_port_pci_cmd = (PCI_HPA + DINO_PCI_ADDR); +unsigned long hppa_port_pci_data = (PCI_HPA + DINO_CONFIG_DATA); + /* Want PDC boot menu? Enable via qemu "-boot menu=on" option. */ unsigned int show_boot_menu; @@ -2255,6 +2258,8 @@ void __VISIBLE start_parisc_firmware(void) if (strcmp(str, "C3700") == 0) { current_machine = &machine_C3700; has_astro = 1; + hppa_port_pci_cmd = 0xfed30000 + 0x040; + hppa_port_pci_data = hppa_port_pci_cmd + 8; } parisc_devices = current_machine->device_list; strtcpy(qemu_machine, str, sizeof(qemu_machine)); @@ -2392,7 +2397,7 @@ void __VISIBLE start_parisc_firmware(void) pci_setup(); serial_setup(); - block_setup(); +// block_setup(); PAGE0->vec_rendz = 0; /* No rendezvous yet. Add MEM_RENDEZ_HI later */ -- cgit v1.1