aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2023-09-26 15:59:54 +0200
committerHelge Deller <deller@gmx.de>2023-09-26 15:59:54 +0200
commitbeb220f8d6b011e59462cc240ab4350c8a47b681 (patch)
tree3076df5259bb26b4dc98cfd2e4d80c4e48de84c3
parent0ab8a0c6b3ae05cc3be993b4e19f7b1774c2f023 (diff)
downloadseabios-hppa-beb220f8d6b011e59462cc240ab4350c8a47b681.zip
seabios-hppa-beb220f8d6b011e59462cc240ab4350c8a47b681.tar.gz
seabios-hppa-beb220f8d6b011e59462cc240ab4350c8a47b681.tar.bz2
pci detection on astro works
-rw-r--r--src/fw/pciinit.c9
-rw-r--r--src/hw/pci.c35
-rw-r--r--src/parisc/hppa.h34
-rw-r--r--src/parisc/hppa_hardware.h15
-rw-r--r--src/parisc/parisc.c7
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 */