From 5e3916baeea5fceb1debbd27f5efb64c5b96968c Mon Sep 17 00:00:00 2001 From: Fredrik Holmqvist Date: Wed, 1 Mar 2017 18:32:18 +0100 Subject: [PATCH] FreeBSD compability layer optimized read and writes. FreeBSD has a simple inlined bus_space_read while Haikus had one with call overhead. This still needs cleanup as it is x86 specific, which it was already. Also it redefines inX and outX defines as arch/x86/arch_cpu.h has a C++ namespace so it can't be included from FreeBSD drivers C-files. The results of these changes should be worth it though. --- src/libs/compat/freebsd_network/bus.cpp | 36 ------- .../freebsd_network/compat/machine/bus.h | 96 ++++++++++++++++--- 2 files changed, 83 insertions(+), 49 deletions(-) diff --git a/src/libs/compat/freebsd_network/bus.cpp b/src/libs/compat/freebsd_network/bus.cpp index 288b604aa0..4a77a0af1c 100644 --- a/src/libs/compat/freebsd_network/bus.cpp +++ b/src/libs/compat/freebsd_network/bus.cpp @@ -501,42 +501,6 @@ bus_generic_driver_added(device_t dev, driver_t *driver) } -#define BUS_SPACE_READ(size, type, fun) \ - type bus_space_read_##size(bus_space_tag_t tag, \ - bus_space_handle_t handle, bus_size_t offset) \ - { \ - type value; \ - if (tag == I386_BUS_SPACE_IO) \ - value = fun(handle + offset); \ - else \ - value = *(volatile type *)(handle + offset); \ - if (tag == I386_BUS_SPACE_IO) \ - TRACE_BUS_SPACE_RW(("bus_space_read_%s(0x%lx, 0x%lx, 0x%lx) = 0x%lx\n", \ - #size, (uint32)tag, (uint32)handle, (uint32)offset, (uint32)value)); \ - return value; \ - } - -#define BUS_SPACE_WRITE(size, type, fun) \ - void bus_space_write_##size(bus_space_tag_t tag, \ - bus_space_handle_t handle, bus_size_t offset, type value) \ - { \ - if (tag == I386_BUS_SPACE_IO) \ - TRACE_BUS_SPACE_RW(("bus_space_write_%s(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", \ - #size, (uint32)tag, (uint32)handle, (uint32)offset, (uint32)value)); \ - if (tag == I386_BUS_SPACE_IO) \ - fun(value, handle + offset); \ - else \ - *(volatile type *)(handle + offset) = value; \ - } - -BUS_SPACE_READ(1, uint8_t, in8) -BUS_SPACE_READ(2, uint16_t, in16) -BUS_SPACE_READ(4, uint32_t, in32) - -BUS_SPACE_WRITE(1, uint8_t, out8) -BUS_SPACE_WRITE(2, uint16_t, out16) -BUS_SPACE_WRITE(4, uint32_t, out32) - int bus_child_present(device_t child) { diff --git a/src/libs/compat/freebsd_network/compat/machine/bus.h b/src/libs/compat/freebsd_network/compat/machine/bus.h index 9e0a49d815..a10ba9a928 100644 --- a/src/libs/compat/freebsd_network/compat/machine/bus.h +++ b/src/libs/compat/freebsd_network/compat/machine/bus.h @@ -110,7 +110,6 @@ #ifndef _FBSD_COMPAT_MACHINE_BUS_H_ #define _FBSD_COMPAT_MACHINE_BUS_H_ - #include #include @@ -138,18 +137,89 @@ struct resource; #define BUS_SPACE_BARRIER_WRITE 2 -uint8_t bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset); -uint16_t bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset); -uint32_t bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset); -void bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset, uint8_t value); -void bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset, uint16_t value); -void bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset, uint32_t value); +// Copied from arch/x86/arch_cpu.h +// Can't use the header as it inderictly includes arch/x86/arch_thread_types.h +// Which has a namespace, so can't be used in FreeBSD's C-code atm. +#define out8(value,port) \ + __asm__ ("outb %%al,%%dx" : : "a" (value), "d" (port)) + +#define out16(value,port) \ + __asm__ ("outw %%ax,%%dx" : : "a" (value), "d" (port)) + +#define out32(value,port) \ + __asm__ ("outl %%eax,%%dx" : : "a" (value), "d" (port)) + +#define in8(port) ({ \ + uint8 _v; \ + __asm__ volatile ("inb %%dx,%%al" : "=a" (_v) : "d" (port)); \ + _v; \ +}) + +#define in16(port) ({ \ + uint16 _v; \ + __asm__ volatile ("inw %%dx,%%ax":"=a" (_v) : "d" (port)); \ + _v; \ +}) + +#define in32(port) ({ \ + uint32 _v; \ + __asm__ volatile ("inl %%dx,%%eax":"=a" (_v) : "d" (port)); \ + _v; \ +}) + + +inline uint8_t +bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle, + bus_size_t offset) { + return tag == I386_BUS_SPACE_MEM ? + (*(volatile u_int8_t *)(handle + offset)) : + in8(handle + offset); +} + + +inline uint16_t +bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle, + bus_size_t offset) { + return tag == I386_BUS_SPACE_MEM ? + (*(volatile u_int16_t *)(handle + offset)) : + in16(handle + offset); +} + + +inline uint32_t +bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle, + bus_size_t offset) { + return tag == I386_BUS_SPACE_MEM ? + (*(volatile u_int32_t *)(handle + offset)) : + in32(handle + offset); +} + + +inline void bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t handle, + bus_size_t offset, uint8_t value) { + if (tag == I386_BUS_SPACE_MEM) + *(volatile uint8_t *)(handle + offset) = value; + else + out8(value, handle + offset); +} + + +inline void bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t handle, + bus_size_t offset, uint16_t value) { + if (tag == I386_BUS_SPACE_MEM) + *(volatile uint16_t *)(handle + offset) = value; + else + out16(value, handle + offset); +} + + +inline void bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t handle, + bus_size_t offset, uint32_t value) { + if (tag == I386_BUS_SPACE_MEM) + *(volatile uint32_t *)(handle + offset) = value; + else + out32(value, handle + offset); +} static inline void