From 6b698713d4e99e5a64e2d07f0df90545809227b9 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sat, 29 Aug 2020 10:00:40 +0200 Subject: [PATCH 01/18] fw_cfg: Add support for parisc architecture Signed-off-by: Helge Deller --- drivers/firmware/Kconfig | 2 +- drivers/firmware/qemu_fw_cfg.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index fbd785dd0513..25f51b60194b 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -187,7 +187,7 @@ config RASPBERRYPI_FIRMWARE config FW_CFG_SYSFS tristate "QEMU fw_cfg device support in sysfs" - depends on SYSFS && (ARM || ARM64 || PPC_PMAC || SPARC || X86) + depends on SYSFS && (ARM || ARM64 || PARISC || PPC_PMAC || SPARC || X86) depends on HAS_IOPORT_MAP default n help diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c index 6945c3c96637..0078260fbabe 100644 --- a/drivers/firmware/qemu_fw_cfg.c +++ b/drivers/firmware/qemu_fw_cfg.c @@ -215,6 +215,9 @@ static void fw_cfg_io_cleanup(void) # define FW_CFG_CTRL_OFF 0x08 # define FW_CFG_DATA_OFF 0x00 # define FW_CFG_DMA_OFF 0x10 +# elif defined(CONFIG_PARISC) /* parisc */ +# define FW_CFG_CTRL_OFF 0x00 +# define FW_CFG_DATA_OFF 0x04 # elif (defined(CONFIG_PPC_PMAC) || defined(CONFIG_SPARC32)) /* ppc/mac,sun4m */ # define FW_CFG_CTRL_OFF 0x00 # define FW_CFG_DATA_OFF 0x02 From 024f5b597564acced9e69305f7a9ef1202186a61 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sat, 29 Aug 2020 10:02:38 +0200 Subject: [PATCH 02/18] parisc: Add qemu fw_cfg interface When running on qemu, SeaBIOS-hppa stores the iomem address for the emulated fw_cfg port in PAGE0_>pad0[2/3]. Let the Linux driver auto-configure the fw_cfg interface with it, so that the fw_cfg info shows up in /sys/firmware/qemu_fw_cfg. Signed-off-by: Helge Deller --- arch/parisc/Kconfig | 1 + arch/parisc/kernel/inventory.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index cd4afe1e7a6c..087cbef348e6 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -376,5 +376,6 @@ config KEXEC_FILE endmenu +source "drivers/firmware/Kconfig" source "drivers/parisc/Kconfig" diff --git a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c index 9298f2285510..7ab2f2a54400 100644 --- a/arch/parisc/kernel/inventory.c +++ b/arch/parisc/kernel/inventory.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -641,4 +642,33 @@ void __init do_device_inventory(void) if (pa_serialize_tlb_flushes) pr_info("Merced bus found: Enable PxTLB serialization.\n"); #endif + +#if defined(CONFIG_FW_CFG_SYSFS) + if (running_on_qemu) { + struct resource res[3] = {0,}; + unsigned int base; + + base = ((unsigned long long) PAGE0->pad0[2] << 32) + | PAGE0->pad0[3]; /* SeaBIOS stored it here */ + + res[0].name = "fw_cfg"; + res[0].start = base; + res[0].end = base + 8 - 1; + res[0].flags = IORESOURCE_MEM; + + res[1].name = "ctrl"; + res[1].start = 0; + res[1].flags = IORESOURCE_REG; + + res[2].name = "data"; + res[2].start = 4; + res[2].flags = IORESOURCE_REG; + + if (base) { + pr_info("Found qemu fw_cfg interface at %#08x\n", base); + platform_device_register_simple("fw_cfg", + PLATFORM_DEVID_NONE, res, 3); + } + } +#endif } From f4d0d40cd1f19104e4f60537973ff5ac2f90123e Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Fri, 14 Aug 2020 15:14:12 +0200 Subject: [PATCH 03/18] parisc: Avoid external interrupts when IPI finishes No need to allow external interrupts when the IPI loop is going to finish now. Signed-off-by: Helge Deller --- arch/parisc/kernel/smp.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 6271139d2213..10227f667c8a 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -173,9 +173,12 @@ ipi_interrupt(int irq, void *dev_id) this_cpu, which); return IRQ_NONE; } /* Switch */ - /* let in any pending interrupts */ - local_irq_enable(); - local_irq_disable(); + + /* before doing more, let in any pending interrupts */ + if (ops) { + local_irq_enable(); + local_irq_disable(); + } } /* while (ops) */ } return IRQ_HANDLED; From 41f5a81c07cd410917c9ae3c165b9b761d48ba75 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sat, 29 Aug 2020 13:57:07 +0200 Subject: [PATCH 04/18] parisc: Drop HP-UX specific fcntl and signal flags Those flags are nowhere used in the Linux kernel and were added when we still wanted to support HP-UX in a compat mode. Since we never will support HP-UX, drop those flags. Signed-off-by: Helge Deller --- arch/parisc/include/uapi/asm/fcntl.h | 5 +---- arch/parisc/include/uapi/asm/signal.h | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/arch/parisc/include/uapi/asm/fcntl.h b/arch/parisc/include/uapi/asm/fcntl.h index 03ce20e5ad7d..e19adc65b1d0 100644 --- a/arch/parisc/include/uapi/asm/fcntl.h +++ b/arch/parisc/include/uapi/asm/fcntl.h @@ -3,7 +3,6 @@ #define _PARISC_FCNTL_H #define O_APPEND 000000010 -#define O_BLKSEEK 000000100 /* HPUX only */ #define O_CREAT 000000400 /* not fcntl */ #define O_EXCL 000002000 /* not fcntl */ #define O_LARGEFILE 000004000 @@ -11,14 +10,12 @@ #define O_SYNC (__O_SYNC|O_DSYNC) #define O_NONBLOCK 000200004 /* HPUX has separate NDELAY & NONBLOCK */ #define O_NOCTTY 000400000 /* not fcntl */ -#define O_DSYNC 001000000 /* HPUX only */ -#define O_RSYNC 002000000 /* HPUX only */ +#define O_DSYNC 001000000 #define O_NOATIME 004000000 #define O_CLOEXEC 010000000 /* set close_on_exec */ #define O_DIRECTORY 000010000 /* must be a directory */ #define O_NOFOLLOW 000000200 /* don't follow links */ -#define O_INVISIBLE 004000000 /* invisible I/O, for DMAPI/XDSM */ #define O_PATH 020000000 #define __O_TMPFILE 040000000 diff --git a/arch/parisc/include/uapi/asm/signal.h b/arch/parisc/include/uapi/asm/signal.h index d38563a394f2..045fde6d2fac 100644 --- a/arch/parisc/include/uapi/asm/signal.h +++ b/arch/parisc/include/uapi/asm/signal.h @@ -61,7 +61,6 @@ #define SA_NODEFER 0x00000020 #define SA_RESTART 0x00000040 #define SA_NOCLDWAIT 0x00000080 -#define _SA_SIGGFAULT 0x00000100 /* HPUX */ #define SA_NOMASK SA_NODEFER #define SA_ONESHOT SA_RESETHAND From 75ae04206a4d0e4f541c1d692b7febd1c0fdb814 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sat, 29 Aug 2020 14:11:35 +0200 Subject: [PATCH 05/18] parisc: Define O_NONBLOCK to become 000200000 HPUX has separate NDELAY & NONBLOCK values. In the past we wanted to be able to run HP-UX binaries natively on parisc Linux which is why we defined O_NONBLOCK to 000200004 to distinguish NDELAY & NONBLOCK bits. But with 2 bits set in this bitmask we often ran into compatibility issues with other Linux applications which often only test one bit (or even compare the values). To avoid such issues in the future, this patch changes O_NONBLOCK to become 000200000. That way old programs will still be functional, and for new programs we now have only one bit set. Update the comment about SOCK_NONBLOCK too. Signed-off-by: Helge Deller --- arch/parisc/include/asm/socket.h | 4 ++-- arch/parisc/include/uapi/asm/fcntl.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/parisc/include/asm/socket.h b/arch/parisc/include/asm/socket.h index 79feff1b0721..33500c9f6e5e 100644 --- a/arch/parisc/include/asm/socket.h +++ b/arch/parisc/include/asm/socket.h @@ -4,8 +4,8 @@ #include -/* O_NONBLOCK clashes with the bits used for socket types. Therefore we - * have to define SOCK_NONBLOCK to a different value here. +/* O_NONBLOCK clashed with the bits used for socket types. Therefore we + * had to define SOCK_NONBLOCK to a different value here. */ #define SOCK_NONBLOCK 0x40000000 diff --git a/arch/parisc/include/uapi/asm/fcntl.h b/arch/parisc/include/uapi/asm/fcntl.h index e19adc65b1d0..03dee816cb13 100644 --- a/arch/parisc/include/uapi/asm/fcntl.h +++ b/arch/parisc/include/uapi/asm/fcntl.h @@ -8,7 +8,7 @@ #define O_LARGEFILE 000004000 #define __O_SYNC 000100000 #define O_SYNC (__O_SYNC|O_DSYNC) -#define O_NONBLOCK 000200004 /* HPUX has separate NDELAY & NONBLOCK */ +#define O_NONBLOCK 000200000 #define O_NOCTTY 000400000 /* not fcntl */ #define O_DSYNC 001000000 #define O_NOATIME 004000000 From cd760704ee32a762029c08ca0702228c34846ffb Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sat, 29 Aug 2020 18:07:49 +0200 Subject: [PATCH 06/18] parisc: Drop useless comments in uapi/asm/signal.h Signed-off-by: Helge Deller --- arch/parisc/include/uapi/asm/signal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/parisc/include/uapi/asm/signal.h b/arch/parisc/include/uapi/asm/signal.h index 045fde6d2fac..e605197b462c 100644 --- a/arch/parisc/include/uapi/asm/signal.h +++ b/arch/parisc/include/uapi/asm/signal.h @@ -35,11 +35,11 @@ #define SIGURG 29 #define SIGXFSZ 30 #define SIGUNUSED 31 -#define SIGSYS 31 /* Linux doesn't use this */ +#define SIGSYS 31 /* These should not be considered constants from userland. */ #define SIGRTMIN 32 -#define SIGRTMAX _NSIG /* it's 44 under HP/UX */ +#define SIGRTMAX _NSIG /* * SA_FLAGS values: From 0b5d9a063f67e9f77edb7d372eab82f33bf6b407 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 11 Sep 2020 12:27:46 +0200 Subject: [PATCH 07/18] parisc: disable CONFIG_IDE in defconfigs Enable libata support for the Nat Semi NS87415 controller, and disable the soon to be removed legacy ide driver entirely. Signed-off-by: Christoph Hellwig Acked-by: Helge Deller Signed-off-by: Helge Deller --- arch/parisc/configs/generic-32bit_defconfig | 6 ++---- arch/parisc/configs/generic-64bit_defconfig | 6 +----- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/arch/parisc/configs/generic-32bit_defconfig b/arch/parisc/configs/generic-32bit_defconfig index 61bac8ff8f22..3cbcfad5f724 100644 --- a/arch/parisc/configs/generic-32bit_defconfig +++ b/arch/parisc/configs/generic-32bit_defconfig @@ -52,10 +52,6 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=6144 -CONFIG_IDE=y -CONFIG_BLK_DEV_IDECD=y -CONFIG_BLK_DEV_GENERIC=y -CONFIG_BLK_DEV_NS87415=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y @@ -65,6 +61,8 @@ CONFIG_SCSI_SYM53C8XX_2=y CONFIG_SCSI_ZALON=y CONFIG_SCSI_DH=y CONFIG_ATA=y +CONFIG_ATA_GENERIC=y +CONFIG_PATA_NS87415=y CONFIG_MD=y CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m diff --git a/arch/parisc/configs/generic-64bit_defconfig b/arch/parisc/configs/generic-64bit_defconfig index 59561e04e659..7e2d7026285e 100644 --- a/arch/parisc/configs/generic-64bit_defconfig +++ b/arch/parisc/configs/generic-64bit_defconfig @@ -58,11 +58,6 @@ CONFIG_PCI_IOV=y CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_BLK_DEV_LOOP=y -CONFIG_IDE=y -CONFIG_IDE_GD=m -CONFIG_IDE_GD_ATAPI=y -CONFIG_BLK_DEV_IDECD=m -CONFIG_BLK_DEV_NS87415=y # CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=y @@ -76,6 +71,7 @@ CONFIG_SCSI_ZALON=y CONFIG_SCSI_QLA_ISCSI=m CONFIG_SCSI_DH=y CONFIG_ATA=y +CONFIG_PATA_NS87415=y CONFIG_PATA_SIL680=y CONFIG_ATA_GENERIC=y CONFIG_MD=y From f15309d7ad5d12603941ef213ead0e7ebe6e8943 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Wed, 30 Sep 2020 17:24:47 +0200 Subject: [PATCH 08/18] parisc: Add ioread64_hi_lo() and iowrite64_hi_lo() The kernel test robot reports missing functions. Add them. hppa-linux-ld: drivers/firmware/arm_scmi/perf.o: in function `scmi_perf_fc_ring_db': (.text+0x610): undefined reference to `ioread64_hi_lo' (.text+0x63c): undefined reference to `iowrite64_hi_lo' Reported-by: kernel test robot Signed-off-by: Helge Deller --- arch/parisc/lib/iomap.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/parisc/lib/iomap.c b/arch/parisc/lib/iomap.c index ce400417d54e..f03adb1999e7 100644 --- a/arch/parisc/lib/iomap.c +++ b/arch/parisc/lib/iomap.c @@ -346,6 +346,16 @@ u64 ioread64be(const void __iomem *addr) return *((u64 *)addr); } +u64 ioread64_hi_lo(const void __iomem *addr) +{ + u32 low, high; + + high = ioread32(addr + sizeof(u32)); + low = ioread32(addr); + + return low + ((u64)high << 32); +} + void iowrite8(u8 datum, void __iomem *addr) { if (unlikely(INDIRECT_ADDR(addr))) { @@ -409,6 +419,12 @@ void iowrite64be(u64 datum, void __iomem *addr) } } +void iowrite64_hi_lo(u64 val, void __iomem *addr) +{ + iowrite32(val >> 32, addr + sizeof(u32)); + iowrite32(val, addr); +} + /* Repeating interfaces */ void ioread8_rep(const void __iomem *addr, void *dst, unsigned long count) @@ -511,6 +527,7 @@ EXPORT_SYMBOL(ioread32); EXPORT_SYMBOL(ioread32be); EXPORT_SYMBOL(ioread64); EXPORT_SYMBOL(ioread64be); +EXPORT_SYMBOL(ioread64_hi_lo); EXPORT_SYMBOL(iowrite8); EXPORT_SYMBOL(iowrite16); EXPORT_SYMBOL(iowrite16be); @@ -518,6 +535,7 @@ EXPORT_SYMBOL(iowrite32); EXPORT_SYMBOL(iowrite32be); EXPORT_SYMBOL(iowrite64); EXPORT_SYMBOL(iowrite64be); +EXPORT_SYMBOL(iowrite64_hi_lo); EXPORT_SYMBOL(ioread8_rep); EXPORT_SYMBOL(ioread16_rep); EXPORT_SYMBOL(ioread32_rep); From 6caf55e570efe53f161bf9af64f22b310e86032e Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Fri, 2 Oct 2020 19:55:04 +0200 Subject: [PATCH 09/18] parisc: Add alternative patching to synchronize_caches define This change allows the sync barrier instruction to be patched to a nop. Signed-off-by: John David Anglin Signed-off-by: Helge Deller --- arch/parisc/include/asm/barrier.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/parisc/include/asm/barrier.h b/arch/parisc/include/asm/barrier.h index 640d46edf32e..c705decf2bed 100644 --- a/arch/parisc/include/asm/barrier.h +++ b/arch/parisc/include/asm/barrier.h @@ -2,11 +2,15 @@ #ifndef __ASM_BARRIER_H #define __ASM_BARRIER_H +#include + #ifndef __ASSEMBLY__ /* The synchronize caches instruction executes as a nop on systems in which all memory references are performed in order. */ -#define synchronize_caches() __asm__ __volatile__ ("sync" : : : "memory") +#define synchronize_caches() asm volatile("sync" \ + ALTERNATIVE(ALT_COND_NO_SMP, INSN_NOP) \ + : : : "memory") #if defined(CONFIG_SMP) #define mb() do { synchronize_caches(); } while (0) From 4df82ce78a34b8f94f3a512ef93972f978713cbc Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Fri, 2 Oct 2020 20:03:27 +0200 Subject: [PATCH 10/18] parisc: Fix comments and enable interrupts later Correct the comments: The jump is forwards, not backwards. Enable the interrupts after %r29 (reference param area) was loaded. Signed-off-by: John David Anglin Signed-off-by: Helge Deller --- arch/parisc/kernel/entry.S | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 519f9056fd00..f6f28e41bb5e 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -899,20 +899,20 @@ intr_check_sig: * Only do signals if we are returning to user space */ LDREG PT_IASQ0(%r16), %r20 - cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* backward */ + cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* forward */ LDREG PT_IASQ1(%r16), %r20 - cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* backward */ - - /* NOTE: We need to enable interrupts if we have to deliver - * signals. We used to do this earlier but it caused kernel - * stack overflows. */ - ssm PSW_SM_I, %r0 + cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* forward */ copy %r0, %r25 /* long in_syscall = 0 */ #ifdef CONFIG_64BIT ldo -16(%r30),%r29 /* Reference param save area */ #endif + /* NOTE: We need to enable interrupts if we have to deliver + * signals. We used to do this earlier but it caused kernel + * stack overflows. */ + ssm PSW_SM_I, %r0 + BL do_notify_resume,%r2 copy %r16, %r26 /* struct pt_regs *regs */ From 2a7d4eed5720d163f50b26892abe45b8cf40e849 Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Fri, 2 Oct 2020 21:16:49 +0200 Subject: [PATCH 11/18] parisc: Mark pointers volatile in __xchg8(), __xchg32() and __xchg64() Let the complier treat the pointers volatile to ensure that they get accessed atomicly. Signed-off-by: John David Anglin Signed-off-by: Helge Deller --- arch/parisc/include/asm/cmpxchg.h | 14 +++++++------- arch/parisc/lib/bitops.c | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/parisc/include/asm/cmpxchg.h b/arch/parisc/include/asm/cmpxchg.h index 068958575871..cf5ee9b0b393 100644 --- a/arch/parisc/include/asm/cmpxchg.h +++ b/arch/parisc/include/asm/cmpxchg.h @@ -14,22 +14,22 @@ extern void __xchg_called_with_bad_pointer(void); /* __xchg32/64 defined in arch/parisc/lib/bitops.c */ -extern unsigned long __xchg8(char, char *); -extern unsigned long __xchg32(int, int *); +extern unsigned long __xchg8(char, volatile char *); +extern unsigned long __xchg32(int, volatile int *); #ifdef CONFIG_64BIT -extern unsigned long __xchg64(unsigned long, unsigned long *); +extern unsigned long __xchg64(unsigned long, volatile unsigned long *); #endif /* optimizer better get rid of switch since size is a constant */ static inline unsigned long -__xchg(unsigned long x, __volatile__ void *ptr, int size) +__xchg(unsigned long x, volatile void *ptr, int size) { switch (size) { #ifdef CONFIG_64BIT - case 8: return __xchg64(x, (unsigned long *) ptr); + case 8: return __xchg64(x, (volatile unsigned long *) ptr); #endif - case 4: return __xchg32((int) x, (int *) ptr); - case 1: return __xchg8((char) x, (char *) ptr); + case 4: return __xchg32((int) x, (volatile int *) ptr); + case 1: return __xchg8((char) x, (volatile char *) ptr); } __xchg_called_with_bad_pointer(); return x; diff --git a/arch/parisc/lib/bitops.c b/arch/parisc/lib/bitops.c index 2e4d1f05a926..9ac683bf6ae7 100644 --- a/arch/parisc/lib/bitops.c +++ b/arch/parisc/lib/bitops.c @@ -18,7 +18,7 @@ arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = { #endif #ifdef CONFIG_64BIT -unsigned long __xchg64(unsigned long x, unsigned long *ptr) +unsigned long __xchg64(unsigned long x, volatile unsigned long *ptr) { unsigned long temp, flags; @@ -30,7 +30,7 @@ unsigned long __xchg64(unsigned long x, unsigned long *ptr) } #endif -unsigned long __xchg32(int x, int *ptr) +unsigned long __xchg32(int x, volatile int *ptr) { unsigned long flags; long temp; @@ -43,7 +43,7 @@ unsigned long __xchg32(int x, int *ptr) } -unsigned long __xchg8(char x, char *ptr) +unsigned long __xchg8(char x, volatile char *ptr) { unsigned long flags; long temp; From 53a42b6324b8ddce1e9d2f34da2ca68ef21c2084 Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Fri, 2 Oct 2020 21:21:41 +0200 Subject: [PATCH 12/18] parisc: Switch to more fine grained lws locks Increase the number of lws locks to 256 entries (instead of 16) and choose lock entry based on bits 3-11 (instead of 4-7) of the relevant address. With this change we archieve more fine-grained locking in futex syscalls and thus reduce the number of possible stalls. Signed-off-by: John David Anglin Signed-off-by: Helge Deller --- arch/parisc/include/asm/futex.h | 4 ++-- arch/parisc/kernel/syscall.S | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h index c459f656c8c3..fceb9cf02fb3 100644 --- a/arch/parisc/include/asm/futex.h +++ b/arch/parisc/include/asm/futex.h @@ -16,7 +16,7 @@ static inline void _futex_spin_lock_irqsave(u32 __user *uaddr, unsigned long int *flags) { extern u32 lws_lock_start[]; - long index = ((long)uaddr & 0xf0) >> 2; + long index = ((long)uaddr & 0x3f8) >> 1; arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index]; local_irq_save(*flags); arch_spin_lock(s); @@ -26,7 +26,7 @@ static inline void _futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags) { extern u32 lws_lock_start[]; - long index = ((long)uaddr & 0xf0) >> 2; + long index = ((long)uaddr & 0x3f8) >> 1; arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index]; arch_spin_unlock(s); local_irq_restore(*flags); diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 3ad61a177f5b..322503780db6 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -571,8 +571,8 @@ lws_compare_and_swap: ldil L%lws_lock_start, %r20 ldo R%lws_lock_start(%r20), %r28 - /* Extract four bits from r26 and hash lock (Bits 4-7) */ - extru %r26, 27, 4, %r20 + /* Extract eight bits from r26 and hash lock (Bits 3-11) */ + extru %r26, 28, 8, %r20 /* Find lock to use, the hash is either one of 0 to 15, multiplied by 16 (keep it 16-byte aligned) @@ -761,8 +761,8 @@ cas2_lock_start: ldil L%lws_lock_start, %r20 ldo R%lws_lock_start(%r20), %r28 - /* Extract four bits from r26 and hash lock (Bits 4-7) */ - extru %r26, 27, 4, %r20 + /* Extract eight bits from r26 and hash lock (Bits 3-11) */ + extru %r26, 28, 8, %r20 /* Find lock to use, the hash is either one of 0 to 15, multiplied by 16 (keep it 16-byte aligned) @@ -950,7 +950,7 @@ END(sys_call_table64) .align L1_CACHE_BYTES ENTRY(lws_lock_start) /* lws locks */ - .rept 16 + .rept 256 /* Keep locks aligned at 16-bytes */ .word 1 .word 0 From a50d3d3ce0235fdc06cdb5cc2fb082964ecb56da Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Fri, 2 Oct 2020 21:28:31 +0200 Subject: [PATCH 13/18] parisc: Rewrite tlb flush threshold calculation Signed-off-by: John David Anglin Signed-off-by: Helge Deller --- arch/parisc/kernel/cache.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index b5e1d9f1b440..86a1a63563fd 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -383,12 +383,12 @@ EXPORT_SYMBOL(flush_kernel_icache_range_asm); static unsigned long parisc_cache_flush_threshold __ro_after_init = FLUSH_THRESHOLD; #define FLUSH_TLB_THRESHOLD (16*1024) /* 16 KiB minimum TLB threshold */ -static unsigned long parisc_tlb_flush_threshold __ro_after_init = FLUSH_TLB_THRESHOLD; +static unsigned long parisc_tlb_flush_threshold __ro_after_init = ~0UL; void __init parisc_setup_cache_timing(void) { unsigned long rangetime, alltime; - unsigned long size, start; + unsigned long size; unsigned long threshold; alltime = mfctl(16); @@ -422,14 +422,9 @@ void __init parisc_setup_cache_timing(void) goto set_tlb_threshold; } - size = 0; - start = (unsigned long) _text; + size = (unsigned long)_end - (unsigned long)_text; rangetime = mfctl(16); - while (start < (unsigned long) _end) { - flush_tlb_kernel_range(start, start + PAGE_SIZE); - start += PAGE_SIZE; - size += PAGE_SIZE; - } + flush_tlb_kernel_range((unsigned long)_text, (unsigned long)_end); rangetime = mfctl(16) - rangetime; alltime = mfctl(16); @@ -444,8 +439,11 @@ void __init parisc_setup_cache_timing(void) threshold/1024); set_tlb_threshold: - if (threshold > parisc_tlb_flush_threshold) + if (threshold > FLUSH_TLB_THRESHOLD) parisc_tlb_flush_threshold = threshold; + else + parisc_tlb_flush_threshold = FLUSH_TLB_THRESHOLD; + printk(KERN_INFO "TLB flush threshold set to %lu KiB\n", parisc_tlb_flush_threshold/1024); } From b47cf497469fae14fcbf63526150c8c71e636c20 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Fri, 2 Oct 2020 21:32:39 +0200 Subject: [PATCH 14/18] parisc: Install vmlinuz instead of zImage file Tested-by: John David Anglin Signed-off-by: Helge Deller --- arch/parisc/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/parisc/install.sh b/arch/parisc/install.sh index 6f68784fea25..056d588befdd 100644 --- a/arch/parisc/install.sh +++ b/arch/parisc/install.sh @@ -43,7 +43,7 @@ fi # Default install -if [ "$(basename $2)" = "zImage" ]; then +if [ "$(basename $2)" = "vmlinuz" ]; then # Compressed install echo "Installing compressed kernel" base=vmlinuz From f173e3a751708b7f5e0b77dcdd4ac3c2287b735e Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Fri, 2 Oct 2020 21:41:52 +0200 Subject: [PATCH 15/18] parisc: Improve spinlock handling Use READ_ONCE() to check if spinlock is locked. The other changes are cleanups. Signed-off-by: John David Anglin Signed-off-by: Helge Deller --- arch/parisc/include/asm/spinlock.h | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/arch/parisc/include/asm/spinlock.h b/arch/parisc/include/asm/spinlock.h index 51b6c47f802f..fa5ee8a45dbd 100644 --- a/arch/parisc/include/asm/spinlock.h +++ b/arch/parisc/include/asm/spinlock.h @@ -10,13 +10,21 @@ static inline int arch_spin_is_locked(arch_spinlock_t *x) { volatile unsigned int *a = __ldcw_align(x); - return *a == 0; + return READ_ONCE(*a) == 0; } -#define arch_spin_lock(lock) arch_spin_lock_flags(lock, 0) +static inline void arch_spin_lock(arch_spinlock_t *x) +{ + volatile unsigned int *a; + + a = __ldcw_align(x); + while (__ldcw(a) == 0) + while (*a == 0) + continue; +} static inline void arch_spin_lock_flags(arch_spinlock_t *x, - unsigned long flags) + unsigned long flags) { volatile unsigned int *a; @@ -25,10 +33,8 @@ static inline void arch_spin_lock_flags(arch_spinlock_t *x, while (*a == 0) if (flags & PSW_SM_I) { local_irq_enable(); - cpu_relax(); local_irq_disable(); - } else - cpu_relax(); + } } #define arch_spin_lock_flags arch_spin_lock_flags @@ -44,12 +50,9 @@ static inline void arch_spin_unlock(arch_spinlock_t *x) static inline int arch_spin_trylock(arch_spinlock_t *x) { volatile unsigned int *a; - int ret; a = __ldcw_align(x); - ret = __ldcw(a) != 0; - - return ret; + return __ldcw(a) != 0; } /* From 4a770b413fe91d5d271e29a50a1f23cf189b4d2e Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Mon, 12 Oct 2020 08:50:51 +0200 Subject: [PATCH 16/18] parisc: Add MAP_UNINITIALIZED define We will not allow unitialized anon mmaps, but we need this define to prevent build errors, e.g. the debian foot package. Suggested-by: John David Anglin Signed-off-by: Helge Deller --- arch/parisc/include/uapi/asm/mman.h | 1 + tools/arch/parisc/include/uapi/asm/mman.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/parisc/include/uapi/asm/mman.h b/arch/parisc/include/uapi/asm/mman.h index 6fd8871e4081..ab78cba446ed 100644 --- a/arch/parisc/include/uapi/asm/mman.h +++ b/arch/parisc/include/uapi/asm/mman.h @@ -25,6 +25,7 @@ #define MAP_STACK 0x40000 /* give out an address that is best suited for process/thread stacks */ #define MAP_HUGETLB 0x80000 /* create a huge page mapping */ #define MAP_FIXED_NOREPLACE 0x100000 /* MAP_FIXED which doesn't unmap underlying mapping */ +#define MAP_UNINITIALIZED 0 /* uninitialized anonymous mmap */ #define MS_SYNC 1 /* synchronous memory sync */ #define MS_ASYNC 2 /* sync memory asynchronously */ diff --git a/tools/arch/parisc/include/uapi/asm/mman.h b/tools/arch/parisc/include/uapi/asm/mman.h index f9fd1325f5bd..506c06a6536f 100644 --- a/tools/arch/parisc/include/uapi/asm/mman.h +++ b/tools/arch/parisc/include/uapi/asm/mman.h @@ -39,6 +39,5 @@ #define MADV_SOFT_OFFLINE 101 /* MAP_32BIT is undefined on parisc, fix it for perf */ #define MAP_32BIT 0 -/* MAP_UNINITIALIZED is undefined on parisc, fix it for perf */ #define MAP_UNINITIALIZED 0 #endif From 58a5c67aadde68d0d31c36adbabdec28c25bb6ab Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Mon, 12 Oct 2020 09:05:09 +0200 Subject: [PATCH 17/18] parisc/sticon: Always register sticon console driver If the ROM provides functional STI routines, always register the sticon driver, even if the serial console was choosen as boot device. Additionally, in that case, do not make the sticon driver the default output console device. Signed-off-by: Helge Deller --- drivers/video/console/sticon.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index e7fd995d3aea..7c1dcd526600 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -348,14 +348,13 @@ static int __init sticonsole_init(void) if (!sticon_sti) return -ENODEV; - if (conswitchp == &dummy_con) { - printk(KERN_INFO "sticon: Initializing STI text console.\n"); - console_lock(); - err = do_take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1, 1); - console_unlock(); - return err; - } - return 0; + pr_info("sticon: Initializing STI text console.\n"); + console_lock(); + err = do_take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1, + PAGE0->mem_cons.cl_class != CL_DUPLEX); + console_unlock(); + + return err; } module_init(sticonsole_init); From 7ff3f14ddc355bfbc94c766f43b90606b1f79e83 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Mon, 12 Oct 2020 10:44:52 +0200 Subject: [PATCH 18/18] parisc/sticon: Add user font support This is a major rework of the sticon (parisc text console) driver in order to support user font support. Usually one want to use the stifb (parisc framebuffer driver) which is based on fbcon and does support fonts and colors, but some old machines (e.g. HP 730 workstations) don't provide a supported stifb graphic card, and for those user fonts are preferred. This patch drops unused code for software cursor and scrollback, enhances the debug output and adds better documentation. The code was tested on various machines with byte-mode and word-mode graphic cards on GSC- and PCI-busses. Signed-off-by: Helge Deller --- drivers/video/console/Kconfig | 1 + drivers/video/console/sticon.c | 282 ++++++++++++++++++------------- drivers/video/console/sticore.c | 284 +++++++++++++++++--------------- drivers/video/fbdev/sticore.h | 27 ++- 4 files changed, 326 insertions(+), 268 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 39deb22a4180..ee33b8ec62bb 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -119,6 +119,7 @@ config STI_CONSOLE bool "STI text console" depends on PARISC && HAS_IOMEM select FONT_SUPPORT + select CRC32 default y help The STI console is the builtin display/keyboard on HP-PARISC diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index 7c1dcd526600..1b451165311c 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -2,7 +2,7 @@ * linux/drivers/video/console/sticon.c - console driver using HP's STI firmware * * Copyright (C) 2000 Philipp Rumpf - * Copyright (C) 2002 Helge Deller + * Copyright (C) 2002-2020 Helge Deller * * Based on linux/drivers/video/vgacon.c and linux/drivers/video/fbcon.c, * which were @@ -43,6 +43,9 @@ #include #include #include +#include +#include +#include #include @@ -52,28 +55,16 @@ #define BLANK 0 static int vga_is_gfx; +#define STI_DEF_FONT sticon_sti->font + +/* borrowed from fbcon.c */ +#define FNTREFCOUNT(fd) (fd->refcount) +#define FNTCRC(fd) (fd->crc) +static struct sti_cooked_font *font_data[MAX_NR_CONSOLES]; + /* this is the sti_struct used for this console */ static struct sti_struct *sticon_sti; -/* Software scrollback */ -static unsigned long softback_buf, softback_curr; -static unsigned long softback_in; -static unsigned long /* softback_top, */ softback_end; -static int softback_lines; - -/* software cursor */ -static int cursor_drawn; -#define CURSOR_DRAW_DELAY (1) -#define DEFAULT_CURSOR_BLINK_RATE (20) - -static int vbl_cursor_cnt; - -static inline void cursor_undrawn(void) -{ - vbl_cursor_cnt = 0; - cursor_drawn = 0; -} - static const char *sticon_startup(void) { return "STI console"; @@ -81,61 +72,43 @@ static const char *sticon_startup(void) static void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos) { - int redraw_cursor = 0; - if (vga_is_gfx || console_blanked) return; if (conp->vc_mode != KD_TEXT) return; -#if 0 - if ((p->cursor_x == xpos) && (p->cursor_y == ypos)) { - cursor_undrawn(); - redraw_cursor = 1; - } -#endif - sti_putc(sticon_sti, c, ypos, xpos); - - if (redraw_cursor) - vbl_cursor_cnt = CURSOR_DRAW_DELAY; + sti_putc(sticon_sti, c, ypos, xpos, font_data[conp->vc_num]); } static void sticon_putcs(struct vc_data *conp, const unsigned short *s, int count, int ypos, int xpos) { - int redraw_cursor = 0; - if (vga_is_gfx || console_blanked) return; if (conp->vc_mode != KD_TEXT) return; -#if 0 - if ((p->cursor_y == ypos) && (xpos <= p->cursor_x) && - (p->cursor_x < (xpos + count))) { - cursor_undrawn(); - redraw_cursor = 1; - } -#endif - while (count--) { - sti_putc(sticon_sti, scr_readw(s++), ypos, xpos++); + sti_putc(sticon_sti, scr_readw(s++), ypos, xpos++, + font_data[conp->vc_num]); } - - if (redraw_cursor) - vbl_cursor_cnt = CURSOR_DRAW_DELAY; } static void sticon_cursor(struct vc_data *conp, int mode) { unsigned short car1; + /* no cursor update if screen is blanked */ + if (vga_is_gfx || console_blanked) + return; + car1 = conp->vc_screenbuf[conp->state.x + conp->state.y * conp->vc_cols]; switch (mode) { case CM_ERASE: - sti_putc(sticon_sti, car1, conp->state.y, conp->state.x); + sti_putc(sticon_sti, car1, conp->state.y, conp->state.x, + font_data[conp->vc_num]); break; case CM_MOVE: case CM_DRAW: @@ -146,7 +119,7 @@ static void sticon_cursor(struct vc_data *conp, int mode) case CUR_TWO_THIRDS: case CUR_BLOCK: sti_putc(sticon_sti, (car1 & 255) + (0 << 8) + (7 << 11), - conp->state.y, conp->state.x); + conp->state.y, conp->state.x, font_data[conp->vc_num]); break; } break; @@ -165,42 +138,164 @@ static bool sticon_scroll(struct vc_data *conp, unsigned int t, switch (dir) { case SM_UP: - sti_bmove(sti, t + count, 0, t, 0, b - t - count, conp->vc_cols); - sti_clear(sti, b - count, 0, count, conp->vc_cols, conp->vc_video_erase_char); + sti_bmove(sti, t + count, 0, t, 0, b - t - count, conp->vc_cols, + font_data[conp->vc_num]); + sti_clear(sti, b - count, 0, count, conp->vc_cols, + conp->vc_video_erase_char, font_data[conp->vc_num]); break; case SM_DOWN: - sti_bmove(sti, t, 0, t + count, 0, b - t - count, conp->vc_cols); - sti_clear(sti, t, 0, count, conp->vc_cols, conp->vc_video_erase_char); + sti_bmove(sti, t, 0, t + count, 0, b - t - count, conp->vc_cols, + font_data[conp->vc_num]); + sti_clear(sti, t, 0, count, conp->vc_cols, + conp->vc_video_erase_char, font_data[conp->vc_num]); break; } return false; } +static int sticon_set_def_font(int unit, struct console_font *op) +{ + if (font_data[unit] != STI_DEF_FONT) { + if (--FNTREFCOUNT(font_data[unit]) == 0) { + kfree(font_data[unit]->raw_ptr); + kfree(font_data[unit]); + } + font_data[unit] = STI_DEF_FONT; + } + + return 0; +} + +static int sticon_set_font(struct vc_data *vc, struct console_font *op) +{ + struct sti_struct *sti = sticon_sti; + int vc_cols, vc_rows, vc_old_cols, vc_old_rows; + int unit = vc->vc_num; + int w = op->width; + int h = op->height; + int size, i, bpc, pitch; + struct sti_rom_font *new_font; + struct sti_cooked_font *cooked_font; + unsigned char *data = op->data, *p; + + if ((w < 6) || (h < 6) || (w > 32) || (h > 32) + || (op->charcount != 256 && op->charcount != 512)) + return -EINVAL; + pitch = ALIGN(w, 8) / 8; + bpc = pitch * h; + size = bpc * op->charcount; + + new_font = kmalloc(sizeof(*new_font) + size, STI_LOWMEM); + if (!new_font) + return -ENOMEM; + + new_font->first_char = 0; + new_font->last_char = op->charcount - 1; + new_font->width = w; + new_font->height = h; + new_font->font_type = STI_FONT_HPROMAN8; + new_font->bytes_per_char = bpc; + new_font->underline_height = 0; + new_font->underline_pos = 0; + + cooked_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL); + if (!cooked_font) { + kfree(new_font); + return -ENOMEM; + } + cooked_font->raw = new_font; + cooked_font->raw_ptr = new_font; + cooked_font->width = w; + cooked_font->height = h; + FNTREFCOUNT(cooked_font) = 0; /* usage counter */ + + p = (unsigned char *) new_font; + p += sizeof(*new_font); + for (i = 0; i < op->charcount; i++) { + memcpy(p, data, bpc); + data += pitch*32; + p += bpc; + } + FNTCRC(cooked_font) = crc32(0, new_font, size + sizeof(*new_font)); + sti_font_convert_bytemode(sti, cooked_font); + new_font = cooked_font->raw_ptr; + + /* check if font is already used by other console */ + for (i = 0; i < MAX_NR_CONSOLES; i++) { + if (font_data[i] != STI_DEF_FONT + && (FNTCRC(font_data[i]) == FNTCRC(cooked_font))) { + kfree(new_font); + kfree(cooked_font); + /* current font is the same as the new one */ + if (i == unit) + return 0; + cooked_font = font_data[i]; + new_font = cooked_font->raw_ptr; + break; + } + } + + /* clear screen with old font: we now may have less rows */ + vc_old_rows = vc->vc_rows; + vc_old_cols = vc->vc_cols; + sti_clear(sticon_sti, 0, 0, vc_old_rows, vc_old_cols, + vc->vc_video_erase_char, font_data[vc->vc_num]); + + /* delete old font in case it is a user font */ + sticon_set_def_font(unit, NULL); + + FNTREFCOUNT(cooked_font)++; + font_data[unit] = cooked_font; + + vc_cols = sti_onscreen_x(sti) / cooked_font->width; + vc_rows = sti_onscreen_y(sti) / cooked_font->height; + vc_resize(vc, vc_cols, vc_rows); + + /* need to repaint screen if cols & rows are same as old font */ + if (vc_cols == vc_old_cols && vc_rows == vc_old_rows) + update_screen(vc); + + return 0; +} + +static int sticon_font_default(struct vc_data *vc, struct console_font *op, char *name) +{ + return sticon_set_def_font(vc->vc_num, op); +} + +static int sticon_font_set(struct vc_data *vc, struct console_font *font, + unsigned int flags) +{ + return sticon_set_font(vc, font); +} + static void sticon_init(struct vc_data *c, int init) { struct sti_struct *sti = sticon_sti; int vc_cols, vc_rows; sti_set(sti, 0, 0, sti_onscreen_y(sti), sti_onscreen_x(sti), 0); - vc_cols = sti_onscreen_x(sti) / sti->font_width; - vc_rows = sti_onscreen_y(sti) / sti->font_height; + vc_cols = sti_onscreen_x(sti) / sti->font->width; + vc_rows = sti_onscreen_y(sti) / sti->font->height; c->vc_can_do_color = 1; if (init) { c->vc_cols = vc_cols; c->vc_rows = vc_rows; } else { - /* vc_rows = (c->vc_rows > vc_rows) ? vc_rows : c->vc_rows; */ - /* vc_cols = (c->vc_cols > vc_cols) ? vc_cols : c->vc_cols; */ vc_resize(c, vc_cols, vc_rows); -/* vc_resize_con(vc_rows, vc_cols, c->vc_num); */ } } static void sticon_deinit(struct vc_data *c) { + int i; + + /* free memory used by user font */ + for (i = 0; i < MAX_NR_CONSOLES; i++) + sticon_set_def_font(i, NULL); } static void sticon_clear(struct vc_data *conp, int sy, int sx, int height, @@ -209,7 +304,8 @@ static void sticon_clear(struct vc_data *conp, int sy, int sx, int height, if (!height || !width) return; - sti_clear(sticon_sti, sy, sx, height, width, conp->vc_video_erase_char); + sti_clear(sticon_sti, sy, sx, height, width, + conp->vc_video_erase_char, font_data[conp->vc_num]); } static int sticon_switch(struct vc_data *conp) @@ -224,64 +320,13 @@ static int sticon_blank(struct vc_data *c, int blank, int mode_switch) vga_is_gfx = 0; return 1; } - sti_clear(sticon_sti, 0,0, c->vc_rows, c->vc_cols, BLANK); + sti_clear(sticon_sti, 0, 0, c->vc_rows, c->vc_cols, BLANK, + font_data[c->vc_num]); if (mode_switch) vga_is_gfx = 1; return 1; } -static u16 *sticon_screen_pos(const struct vc_data *conp, int offset) -{ - int line; - unsigned long p; - - if (conp->vc_num != fg_console || !softback_lines) - return (u16 *)(conp->vc_origin + offset); - line = offset / conp->vc_size_row; - if (line >= softback_lines) - return (u16 *)(conp->vc_origin + offset - softback_lines * conp->vc_size_row); - p = softback_curr + offset; - if (p >= softback_end) - p += softback_buf - softback_end; - return (u16 *)p; -} - -static unsigned long sticon_getxy(struct vc_data *conp, unsigned long pos, - int *px, int *py) -{ - int x, y; - unsigned long ret; - if (pos >= conp->vc_origin && pos < conp->vc_scr_end) { - unsigned long offset = (pos - conp->vc_origin) / 2; - - x = offset % conp->vc_cols; - y = offset / conp->vc_cols; - if (conp->vc_num == fg_console) - y += softback_lines; - ret = pos + (conp->vc_cols - x) * 2; - } else if (conp->vc_num == fg_console && softback_lines) { - unsigned long offset = pos - softback_curr; - - if (pos < softback_curr) - offset += softback_end - softback_buf; - offset /= 2; - x = offset % conp->vc_cols; - y = offset / conp->vc_cols; - ret = pos + (conp->vc_cols - x) * 2; - if (ret == softback_end) - ret = softback_buf; - if (ret == softback_in) - ret = conp->vc_origin; - } else { - /* Should not happen */ - x = y = 0; - ret = conp->vc_origin; - } - if (px) *px = x; - if (py) *py = y; - return ret; -} - static u8 sticon_build_attr(struct vc_data *conp, u8 color, enum vc_intensity intens, bool blink, bool underline, bool reverse, @@ -312,10 +357,6 @@ static void sticon_invert_region(struct vc_data *conp, u16 *p, int count) } } -static void sticon_save_screen(struct vc_data *conp) -{ -} - static const struct consw sti_con = { .owner = THIS_MODULE, .con_startup = sticon_startup, @@ -328,18 +369,18 @@ static const struct consw sti_con = { .con_scroll = sticon_scroll, .con_switch = sticon_switch, .con_blank = sticon_blank, - .con_save_screen = sticon_save_screen, + .con_font_set = sticon_font_set, + .con_font_default = sticon_font_default, .con_build_attr = sticon_build_attr, .con_invert_region = sticon_invert_region, - .con_screen_pos = sticon_screen_pos, - .con_getxy = sticon_getxy, }; static int __init sticonsole_init(void) { - int err; + int err, i; + /* already initialized ? */ if (sticon_sti) return 0; @@ -348,6 +389,9 @@ static int __init sticonsole_init(void) if (!sticon_sti) return -ENODEV; + for (i = 0; i < MAX_NR_CONSOLES; i++) + font_data[i] = STI_DEF_FONT; + pr_info("sticon: Initializing STI text console.\n"); console_lock(); err = do_take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1, diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index 84c3ca37040a..6a26a364f9bd 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -4,7 +4,7 @@ * core code for console driver using HP's STI firmware * * Copyright (C) 2000 Philipp Rumpf - * Copyright (C) 2001-2013 Helge Deller + * Copyright (C) 2001-2020 Helge Deller * Copyright (C) 2001-2002 Thomas Bogendoerfer * * TODO: @@ -14,6 +14,8 @@ * */ +#define pr_fmt(fmt) "%s: " fmt, KBUILD_MODNAME + #include #include #include @@ -133,16 +135,17 @@ static const struct sti_font_flags default_font_flags = { }; void -sti_putc(struct sti_struct *sti, int c, int y, int x) +sti_putc(struct sti_struct *sti, int c, int y, int x, + struct sti_cooked_font *font) { struct sti_font_inptr *inptr = &sti->sti_data->font_inptr; struct sti_font_inptr inptr_default = { - .font_start_addr= STI_PTR(sti->font->raw), + .font_start_addr = STI_PTR(font->raw), .index = c_index(sti, c), .fg_color = c_fg(sti, c), .bg_color = c_bg(sti, c), - .dest_x = x * sti->font_width, - .dest_y = y * sti->font_height, + .dest_x = x * font->width, + .dest_y = y * font->height, }; struct sti_font_outptr *outptr = &sti->sti_data->font_outptr; s32 ret; @@ -193,18 +196,18 @@ sti_set(struct sti_struct *sti, int src_y, int src_x, void sti_clear(struct sti_struct *sti, int src_y, int src_x, - int height, int width, int c) + int height, int width, int c, struct sti_cooked_font *font) { struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr; struct sti_blkmv_inptr inptr_default = { .fg_color = c_fg(sti, c), .bg_color = c_bg(sti, c), - .src_x = src_x * sti->font_width, - .src_y = src_y * sti->font_height, - .dest_x = src_x * sti->font_width, - .dest_y = src_y * sti->font_height, - .width = width * sti->font_width, - .height = height* sti->font_height, + .src_x = src_x * font->width, + .src_y = src_y * font->height, + .dest_x = src_x * font->width, + .dest_y = src_y * font->height, + .width = width * font->width, + .height = height * font->height, }; struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr; s32 ret; @@ -225,16 +228,17 @@ static const struct sti_blkmv_flags default_blkmv_flags = { void sti_bmove(struct sti_struct *sti, int src_y, int src_x, - int dst_y, int dst_x, int height, int width) + int dst_y, int dst_x, int height, int width, + struct sti_cooked_font *font) { struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr; struct sti_blkmv_inptr inptr_default = { - .src_x = src_x * sti->font_width, - .src_y = src_y * sti->font_height, - .dest_x = dst_x * sti->font_width, - .dest_y = dst_y * sti->font_height, - .width = width * sti->font_width, - .height = height* sti->font_height, + .src_x = src_x * font->width, + .src_y = src_y * font->height, + .dest_x = dst_x * font->width, + .dest_y = dst_y * font->height, + .width = width * font->width, + .height = height * font->height, }; struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr; s32 ret; @@ -301,36 +305,32 @@ __setup("sti=", sti_setup); -static char *font_name[MAX_STI_ROMS]; -static int font_index[MAX_STI_ROMS], - font_height[MAX_STI_ROMS], - font_width[MAX_STI_ROMS]; +static char *font_name; +static int font_index, + font_height, + font_width; #ifndef MODULE static int sti_font_setup(char *str) { - char *x; - int i = 0; + /* + * The default font can be selected in various ways. + * a) sti_font=VGA8x16, sti_font=10x20, sti_font=10*20 selects + * an built-in Linux framebuffer font. + * b) sti_font=, where index is (1..x) with 1 selecting + * the first HP STI ROM built-in font.. + */ - /* we accept sti_font=VGA8x16, sti_font=10x20, sti_font=10*20 - * or sti_font=7 style command lines. */ + if (*str >= '0' && *str <= '9') { + char *x; - while (i='0' && *str<='9') { - if ((x = strchr(str, 'x')) || (x = strchr(str, '*'))) { - font_height[i] = simple_strtoul(str, NULL, 0); - font_width[i] = simple_strtoul(x+1, NULL, 0); - } else { - font_index[i] = simple_strtoul(str, NULL, 0); - } + if ((x = strchr(str, 'x')) || (x = strchr(str, '*'))) { + font_height = simple_strtoul(str, NULL, 0); + font_width = simple_strtoul(x+1, NULL, 0); } else { - font_name[i] = str; /* fb font name */ + font_index = simple_strtoul(str, NULL, 0); } - - if ((x = strchr(str, ','))) - *x++ = 0; - str = x; - - i++; + } else { + font_name = str; /* fb font name */ } return 1; @@ -344,7 +344,7 @@ static int sti_font_setup(char *str) * framebuffer font names (e.g. VGA8x16, SUN22x18). * This is only available if the fonts have been statically compiled * in with e.g. the CONFIG_FONT_8x16 or CONFIG_FONT_SUN12x22 options. - * - sti_font= + * - sti_font= ( = 1,2,3,...) * most STI ROMs have built-in HP specific fonts, which can be selected * by giving the desired number to the sticon driver. * NOTE: This number is machine and STI ROM dependend. @@ -364,8 +364,7 @@ static void sti_dump_globcfg(struct sti_glob_cfg *glob_cfg, { struct sti_glob_cfg_ext *cfg; - DPRINTK((KERN_INFO - "%d text planes\n" + pr_debug("%d text planes\n" "%4d x %4d screen resolution\n" "%4d x %4d offscreen\n" "%4d x %4d layout\n" @@ -382,12 +381,11 @@ static void sti_dump_globcfg(struct sti_glob_cfg *glob_cfg, glob_cfg->region_ptrs[4], glob_cfg->region_ptrs[5], glob_cfg->region_ptrs[6], glob_cfg->region_ptrs[7], glob_cfg->reent_lvl, - glob_cfg->save_addr)); + glob_cfg->save_addr); /* dump extended cfg */ cfg = PTR_STI((unsigned long)glob_cfg->ext_ptr); - DPRINTK(( KERN_INFO - "monitor %d\n" + pr_debug("monitor %d\n" "in friendly mode: %d\n" "power consumption %d watts\n" "freq ref %d\n" @@ -396,20 +394,19 @@ static void sti_dump_globcfg(struct sti_glob_cfg *glob_cfg, cfg->friendly_boot, cfg->power, cfg->freq_ref, - cfg->sti_mem_addr, sti_mem_request)); + cfg->sti_mem_addr, sti_mem_request); } static void sti_dump_outptr(struct sti_struct *sti) { - DPRINTK((KERN_INFO - "%d bits per pixel\n" + pr_debug("%d bits per pixel\n" "%d used bits\n" "%d planes\n" "attributes %08x\n", sti->sti_data->inq_outptr.bits_per_pixel, sti->sti_data->inq_outptr.bits_used, sti->sti_data->inq_outptr.planes, - sti->sti_data->inq_outptr.attributes)); + sti->sti_data->inq_outptr.attributes); } static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address, @@ -448,8 +445,7 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address, if (offs != PCI_ROM_ADDRESS && (offs < PCI_BASE_ADDRESS_0 || offs > PCI_BASE_ADDRESS_5)) { - printk (KERN_WARNING - "STI pci region mapping for region %d (%02x) can't be mapped\n", + pr_warn("STI pci region mapping for region %d (%02x) can't be mapped\n", i,sti->rm_entry[i]); continue; } @@ -464,14 +460,14 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address, if (len) glob_cfg->region_ptrs[i] = sti->regions_phys[i]; - DPRINTK(("region #%d: phys %08lx, region_ptr %08x, len=%lukB, " + pr_debug("region #%d: phys %08lx, region_ptr %08x, len=%lukB, " "btlb=%d, sysonly=%d, cache=%d, last=%d\n", i, sti->regions_phys[i], glob_cfg->region_ptrs[i], len/1024, sti->regions[i].region_desc.btlb, sti->regions[i].region_desc.sys_only, sti->regions[i].region_desc.cache, - sti->regions[i].region_desc.last)); + sti->regions[i].region_desc.last); /* last entry reached ? */ if (sti->regions[i].region_desc.last) @@ -479,8 +475,8 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address, } if (++i<8 && sti->regions[i].region) - printk(KERN_WARNING "%s: *future ptr (0x%8x) not yet supported !\n", - __FILE__, sti->regions[i].region); + pr_warn("future ptr (0x%8x) not yet supported !\n", + sti->regions[i].region); glob_cfg_ext->sti_mem_addr = STI_PTR(sti_mem_addr); @@ -538,6 +534,7 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) } cooked_font->raw = nf; + cooked_font->raw_ptr = nf; cooked_font->next_font = NULL; cooked_rom->font_start = cooked_font; @@ -552,24 +549,38 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) } #endif -static struct sti_cooked_font *sti_select_font(struct sti_cooked_rom *rom, - int (*search_font_fnc)(struct sti_cooked_rom *, int, int)) +static int sti_search_font(struct sti_cooked_rom *rom, int height, int width) +{ + struct sti_cooked_font *font; + int i = 0; + + for (font = rom->font_start; font; font = font->next_font, i++) { + if ((font->raw->width == width) && + (font->raw->height == height)) + return i; + } + return 0; +} + +static struct sti_cooked_font *sti_select_font(struct sti_cooked_rom *rom) { struct sti_cooked_font *font; int i; - int index = num_sti_roms; /* check for framebuffer-font first */ - if ((font = sti_select_fbfont(rom, font_name[index]))) - return font; + if (!font_index) { + font = sti_select_fbfont(rom, font_name); + if (font) + return font; + } - if (font_width[index] && font_height[index]) - font_index[index] = search_font_fnc(rom, - font_height[index], font_width[index]); + if (font_width && font_height) + font_index = sti_search_font(rom, + font_height, font_width); - for (font = rom->font_start, i = font_index[index]; - font && (i > 0); - font = font->next_font, i--); + for (font = rom->font_start, i = font_index - 1; + font && (i > 0); + font = font->next_font, i--); if (font) return font; @@ -578,20 +589,35 @@ static struct sti_cooked_font *sti_select_font(struct sti_cooked_rom *rom, } -static void sti_dump_rom(struct sti_rom *rom) +static void sti_dump_rom(struct sti_struct *sti) { - printk(KERN_INFO " id %04x-%04x, conforms to spec rev. %d.%02x\n", + struct sti_rom *rom = sti->rom->raw; + struct sti_cooked_font *font_start; + int nr; + + pr_info(" id %04x-%04x, conforms to spec rev. %d.%02x\n", rom->graphics_id[0], rom->graphics_id[1], rom->revno[0] >> 4, rom->revno[0] & 0x0f); - DPRINTK((" supports %d monitors\n", rom->num_mons)); - DPRINTK((" font start %08x\n", rom->font_start)); - DPRINTK((" region list %08x\n", rom->region_list)); - DPRINTK((" init_graph %08x\n", rom->init_graph)); - DPRINTK((" bus support %02x\n", rom->bus_support)); - DPRINTK((" ext bus support %02x\n", rom->ext_bus_support)); - DPRINTK((" alternate code type %d\n", rom->alt_code_type)); + pr_debug(" supports %d monitors\n", rom->num_mons); + pr_debug(" font start %08x\n", rom->font_start); + pr_debug(" region list %08x\n", rom->region_list); + pr_debug(" init_graph %08x\n", rom->init_graph); + pr_debug(" bus support %02x\n", rom->bus_support); + pr_debug(" ext bus support %02x\n", rom->ext_bus_support); + pr_debug(" alternate code type %d\n", rom->alt_code_type); + + font_start = sti->rom->font_start; + nr = 0; + while (font_start) { + struct sti_rom_font *f = font_start->raw; + + pr_info(" built-in font #%d: size %dx%d, chars %d-%d, bpc %d\n", ++nr, + f->width, f->height, + f->first_char, f->last_char, f->bytes_per_char); + font_start = font_start->next_font; + } } @@ -628,39 +654,34 @@ static int sti_cook_fonts(struct sti_cooked_rom *cooked_rom, return 1; } - -static int sti_search_font(struct sti_cooked_rom *rom, int height, int width) -{ - struct sti_cooked_font *font; - int i = 0; - - for (font = rom->font_start; font; font = font->next_font, i++) { - if ((font->raw->width == width) && - (font->raw->height == height)) - return i; - } - return 0; -} - #define BMODE_RELOCATE(offset) offset = (offset) / 4; #define BMODE_LAST_ADDR_OFFS 0x50 -static void *sti_bmode_font_raw(struct sti_cooked_font *f) +void sti_font_convert_bytemode(struct sti_struct *sti, struct sti_cooked_font *f) { unsigned char *n, *p, *q; - int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font); - + int size = f->raw->bytes_per_char * 256 + sizeof(struct sti_rom_font); + struct sti_rom_font *old_font; + + if (sti->wordmode) + return; + + old_font = f->raw_ptr; n = kcalloc(4, size, STI_LOWMEM); + f->raw_ptr = n; if (!n) - return NULL; + return; p = n + 3; - q = (unsigned char *)f->raw; + q = (unsigned char *) f->raw; while (size--) { *p = *q++; - p+=4; + p += 4; } - return n + 3; + /* store new ptr to byte-mode font and delete old font */ + f->raw = (struct sti_rom_font *) (n + 3); + kfree(old_font); } +EXPORT_SYMBOL(sti_font_convert_bytemode); static void sti_bmode_rom_copy(unsigned long base, unsigned long count, void *dest) @@ -747,7 +768,7 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti, goto out_err; if (!sti_cook_fonts(cooked, raw)) { - printk(KERN_ERR "No font found for STI at %08lx\n", address); + pr_warn("No font found for STI at %08lx\n", address); goto out_err; } @@ -756,7 +777,8 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti, address = (unsigned long) STI_PTR(raw); - pr_info("STI ROM supports 32 %sbit firmware functions.\n", + pr_info("STI %s ROM supports 32 %sbit firmware functions.\n", + wordmode ? "word mode" : "byte mode", raw->alt_code_type == ALT_CODE_TYPE_PA_RISC_64 ? "and 64 " : ""); @@ -767,18 +789,17 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti, sti->rom = cooked; sti->rom->raw = raw; - - sti->font = sti_select_font(sti->rom, sti_search_font); - sti->font_width = sti->font->raw->width; - sti->font_height = sti->font->raw->height; - if (!wordmode) - sti->font->raw = sti_bmode_font_raw(sti->font); + sti_dump_rom(sti); + + sti->wordmode = wordmode; + sti->font = sti_select_font(sti->rom); + sti->font->width = sti->font->raw->width; + sti->font->height = sti->font->raw->height; + sti_font_convert_bytemode(sti, sti->font); sti->sti_mem_request = raw->sti_mem_req; sti->graphics_id[0] = raw->graphics_id[0]; sti->graphics_id[1] = raw->graphics_id[1]; - - sti_dump_rom(raw); /* check if the ROM routines in this card are compatible */ if (wordmode || sti->graphics_id[1] != 0x09A02587) @@ -804,9 +825,9 @@ ok: return 1; msg_not_supported: - printk(KERN_ERR "Sorry, this GSC/STI card is not yet supported.\n"); - printk(KERN_ERR "Please see http://parisc-linux.org/faq/" - "graphics-howto.html for more info.\n"); + pr_warn("Sorry, this GSC/STI card is not yet supported.\n"); + pr_warn("Please see https://parisc.wiki.kernel.org/" + "index.php/Graphics_howto for more info.\n"); /* fall through */ out_err: kfree(raw); @@ -823,7 +844,7 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address, u32 sig; if (num_sti_roms >= MAX_STI_ROMS) { - printk(KERN_WARNING "maximum number of STI ROMS reached !\n"); + pr_warn("maximum number of STI ROMS reached !\n"); return NULL; } @@ -849,16 +870,15 @@ test_rom: if (i != 1) { /* The ROM could have multiple architecture * dependent images (e.g. i386, parisc,...) */ - printk(KERN_WARNING - "PCI ROM is not a STI ROM type image (0x%8x)\n", i); + pr_warn("PCI ROM is not a STI ROM type image (0x%8x)\n", i); goto out_err; } sti->pd = pd; i = gsc_readl(address+0x0c); - DPRINTK(("PCI ROM size (from header) = %d kB\n", - le16_to_cpu(i>>16)*512/1024)); + pr_debug("PCI ROM size (from header) = %d kB\n", + le16_to_cpu(i>>16)*512/1024); rm_offset = le16_to_cpu(i & 0xffff); if (rm_offset) { /* read 16 bytes from the pci region mapper array */ @@ -867,29 +887,24 @@ test_rom: *rm++ = gsc_readl(address+rm_offset+0x04); *rm++ = gsc_readl(address+rm_offset+0x08); *rm++ = gsc_readl(address+rm_offset+0x0c); - DPRINTK(("PCI region Mapper offset = %08x: ", - rm_offset)); - for (i=0; i<16; i++) - DPRINTK(("%02x ", sti->rm_entry[i])); - DPRINTK(("\n")); } address += le32_to_cpu(gsc_readl(address+8)); - DPRINTK(("sig %04x, PCI STI ROM at %08lx\n", sig, address)); + pr_debug("sig %04x, PCI STI ROM at %08lx\n", sig, address); goto test_rom; } ok = 0; if ((sig & 0xff) == 0x01) { - DPRINTK((" byte mode ROM at %08lx, hpa at %08lx\n", - address, hpa)); + pr_debug(" byte mode ROM at %08lx, hpa at %08lx\n", + address, hpa); ok = sti_read_rom(0, sti, address); } if ((sig & 0xffff) == 0x0303) { - DPRINTK((" word mode ROM at %08lx, hpa at %08lx\n", - address, hpa)); + pr_debug(" word mode ROM at %08lx, hpa at %08lx\n", + address, hpa); ok = sti_read_rom(1, sti, address); } @@ -906,7 +921,7 @@ test_rom: unsigned long rom_base; rom_base = pci_resource_start(sti->pd, PCI_ROM_RESOURCE); pci_write_config_dword(sti->pd, PCI_ROM_ADDRESS, rom_base & ~PCI_ROM_ADDRESS_ENABLE); - DPRINTK((KERN_DEBUG "STI PCI ROM disabled\n")); + pr_debug("STI PCI ROM disabled\n"); } if (sti_init_graph(sti)) @@ -981,14 +996,14 @@ static int sticore_pci_init(struct pci_dev *pd, const struct pci_device_id *ent) rom_len = pci_resource_len(pd, PCI_ROM_RESOURCE); if (rom_base) { pci_write_config_dword(pd, PCI_ROM_ADDRESS, rom_base | PCI_ROM_ADDRESS_ENABLE); - DPRINTK((KERN_DEBUG "STI PCI ROM enabled at 0x%08lx\n", rom_base)); + pr_debug("STI PCI ROM enabled at 0x%08lx\n", rom_base); } - printk(KERN_INFO "STI PCI graphic ROM found at %08lx (%u kB), fb at %08lx (%u MB)\n", + pr_info("STI PCI graphic ROM found at %08lx (%u kB), fb at %08lx (%u MB)\n", rom_base, rom_len/1024, fb_base, fb_len/1024/1024); - DPRINTK((KERN_DEBUG "Trying PCI STI ROM at %08lx, PCI hpa at %08lx\n", - rom_base, fb_base)); + pr_debug("Trying PCI STI ROM at %08lx, PCI hpa at %08lx\n", + rom_base, fb_base); sti = sti_try_rom_generic(rom_base, fb_base, pd); if (sti) { @@ -998,8 +1013,7 @@ static int sticore_pci_init(struct pci_dev *pd, const struct pci_device_id *ent) } if (!sti) { - printk(KERN_WARNING "Unable to handle STI device '%s'\n", - pci_name(pd)); + pr_warn("Unable to handle STI device '%s'\n", pci_name(pd)); return -ENODEV; } #endif /* CONFIG_PCI */ @@ -1058,7 +1072,7 @@ static void sti_init_roms(void) sticore_initialized = 1; - printk(KERN_INFO "STI GSC/PCI core graphics driver " + pr_info("STI GSC/PCI core graphics driver " STI_DRIVERVERSION "\n"); /* Register drivers for native & PCI cards */ diff --git a/drivers/video/fbdev/sticore.h b/drivers/video/fbdev/sticore.h index fb8f58f9867a..c338f7848ae2 100644 --- a/drivers/video/fbdev/sticore.h +++ b/drivers/video/fbdev/sticore.h @@ -4,12 +4,6 @@ /* generic STI structures & functions */ -#if 0 -#define DPRINTK(x) printk x -#else -#define DPRINTK(x) -#endif - #define MAX_STI_ROMS 4 /* max no. of ROMs which this driver handles */ #define STI_REGION_MAX 8 /* hardcoded STI constants */ @@ -246,8 +240,12 @@ struct sti_rom_font { /* sticore internal font handling */ struct sti_cooked_font { - struct sti_rom_font *raw; + struct sti_rom_font *raw; /* native ptr for STI functions */ + void *raw_ptr; /* kmalloc'ed font data */ struct sti_cooked_font *next_font; + int height, width; + int refcount; + u32 crc; }; struct sti_cooked_rom { @@ -341,9 +339,6 @@ struct sti_all_data { struct sti_struct { spinlock_t lock; - /* the following fields needs to be filled in by the word/byte routines */ - int font_width; - int font_height; /* char **mon_strings; */ int sti_mem_request; u32 graphics_id[2]; @@ -362,6 +357,7 @@ struct sti_struct { struct sti_glob_cfg *glob_cfg; /* points into sti_all_data */ + int wordmode; struct sti_cooked_font *font; /* ptr to selected font (cooked) */ struct pci_dev *pd; @@ -380,6 +376,7 @@ struct sti_struct { /* sticore interface functions */ struct sti_struct *sti_get_rom(unsigned int index); /* 0: default sti */ +void sti_font_convert_bytemode(struct sti_struct *sti, struct sti_cooked_font *f); /* sticore main function to call STI firmware */ @@ -391,12 +388,14 @@ int sti_call(const struct sti_struct *sti, unsigned long func, /* functions to call the STI ROM directly */ -void sti_putc(struct sti_struct *sti, int c, int y, int x); +void sti_putc(struct sti_struct *sti, int c, int y, int x, + struct sti_cooked_font *font); void sti_set(struct sti_struct *sti, int src_y, int src_x, - int height, int width, u8 color); + int height, int width, u8 color); void sti_clear(struct sti_struct *sti, int src_y, int src_x, - int height, int width, int c); + int height, int width, int c, struct sti_cooked_font *font); void sti_bmove(struct sti_struct *sti, int src_y, int src_x, - int dst_y, int dst_x, int height, int width); + int dst_y, int dst_x, int height, int width, + struct sti_cooked_font *font); #endif /* STICORE_H */