From 250f7b1570f37da541d1c0146bbad6babb50886e Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Tue, 22 Jan 2013 11:53:22 +0100 Subject: [PATCH] nova: update syscall assign_gsi/_pci for 32/64 bit --- base-nova/include/32bit/nova/syscalls.h | 28 +++++++++++++++++++-- base-nova/include/64bit/nova/syscalls.h | 21 ++++++---------- base-nova/src/core/irq_session_component.cc | 18 ++++++++++--- 3 files changed, 48 insertions(+), 19 deletions(-) diff --git a/base-nova/include/32bit/nova/syscalls.h b/base-nova/include/32bit/nova/syscalls.h index 6c179fa5bb..3ea64d5413 100644 --- a/base-nova/include/32bit/nova/syscalls.h +++ b/base-nova/include/32bit/nova/syscalls.h @@ -155,6 +155,21 @@ namespace Nova { return status; } + ALWAYS_INLINE + inline uint8_t syscall_5(Syscall s, uint8_t flags, mword_t sel, + mword_t &p1, mword_t &p2) + { + mword_t status = eax(s, flags, sel); + + asm volatile (" movl %%esp, %%ecx;" + " movl $1f, %%edx;" + "sysenter;" + "1:" + : "+a" (status), "+D" (p1), "+S" (p2) + : + : "ecx", "edx", "memory"); + return status; + } ALWAYS_INLINE inline uint8_t call(unsigned pt) @@ -257,9 +272,18 @@ namespace Nova { ALWAYS_INLINE - inline uint8_t assign_gsi(unsigned sm, mword_t dev, mword_t cpu) + inline uint8_t assign_pci(mword_t pd, mword_t mem, mword_t rid) { - return syscall_2(NOVA_ASSIGN_GSI, 0, sm, dev, cpu); + return syscall_2(NOVA_ASSIGN_PCI, 0, pd, mem, rid); + } + + ALWAYS_INLINE + inline uint8_t assign_gsi(mword_t sm, mword_t dev, mword_t cpu, mword_t &msi_addr, mword_t &msi_data) + { + msi_addr = dev; + msi_data = cpu; + + return syscall_5(NOVA_ASSIGN_GSI, 0, sm, msi_addr, msi_data); } } #endif /* _PLATFORM__NOVA_SYSCALLS_H_ */ diff --git a/base-nova/include/64bit/nova/syscalls.h b/base-nova/include/64bit/nova/syscalls.h index 4a4c8b9541..2ad00646ac 100644 --- a/base-nova/include/64bit/nova/syscalls.h +++ b/base-nova/include/64bit/nova/syscalls.h @@ -119,12 +119,12 @@ namespace Nova { ALWAYS_INLINE inline uint8_t syscall_5(Syscall s, uint8_t flags, mword_t sel, - mword_t p1, mword_t p2, mword_t &p3, mword_t &p4) + mword_t &p1, mword_t &p2) { mword_t status = rdi(s, flags, sel); asm volatile ("syscall" - : "+D" (status), "+S"(p3), "+d"(p4) + : "+D" (status), "+S"(p1), "+d"(p2) : : "rcx", "r11", "memory"); return status; @@ -226,7 +226,7 @@ namespace Nova { mword_t status = rdi(NOVA_SC_CTRL, op, sm); mword_t time_h; - uint8_t res = syscall_5(NOVA_SC_CTRL, op, sm, 0, 0, time_h, time); + uint8_t res = syscall_5(NOVA_SC_CTRL, op, sm, time_h, time); asm volatile ("syscall" : "+D" (status), "=S"(time_h), "=d"(time) : @@ -240,20 +240,15 @@ namespace Nova { ALWAYS_INLINE inline uint8_t assign_pci(mword_t pd, mword_t mem, mword_t rid) { - return syscall_2(NOVA_ASSIGN_GSI, 0, pd, mem, rid); + return syscall_2(NOVA_ASSIGN_PCI, 0, pd, mem, rid); } ALWAYS_INLINE - inline uint8_t assign_gsi(mword_t sm, mword_t dev, mword_t rid) + inline uint8_t assign_gsi(mword_t sm, mword_t dev, mword_t cpu, mword_t &msi_addr, mword_t &msi_data) { - mword_t dummy1 = 0, dummy2 = 0; - return syscall_5(NOVA_ASSIGN_GSI, 0, sm, dev, rid, dummy1, dummy2); - } - - ALWAYS_INLINE - inline uint8_t assign_gsi(mword_t sm, mword_t dev, mword_t rid, mword_t &msi_addr, mword_t &msi_data) - { - return syscall_5(NOVA_ASSIGN_GSI, 0, sm, dev, rid, msi_addr, msi_data); + msi_addr = dev; + msi_data = cpu; + return syscall_5(NOVA_ASSIGN_GSI, 0, sm, msi_addr, msi_data); } } #endif /* _PLATFORM__NOVA_SYSCALLS_H_ */ diff --git a/base-nova/src/core/irq_session_component.cc b/base-nova/src/core/irq_session_component.cc index 27deb94f28..55c5bd5df4 100644 --- a/base-nova/src/core/irq_session_component.cc +++ b/base-nova/src/core/irq_session_component.cc @@ -109,7 +109,8 @@ class Genode::Irq_proxy_component : public Irq_proxy { private: - long _irq_sel; /* IRQ cap selector */ + Genode::addr_t _irq_sel; /* IRQ cap selector */ + Genode::addr_t _dev_mem; /* used when MSI or HPET is used */ protected: @@ -134,9 +135,16 @@ class Genode::Irq_proxy_component : public Irq_proxy /* assign IRQ to CPU */ enum { CPU = 0 }; - Nova::assign_gsi(_irq_sel, 0, CPU); + addr_t msi_addr = 0; + addr_t msi_data = 0; + uint8_t res = Nova::assign_gsi(_irq_sel, _dev_mem, CPU, msi_addr, msi_data); - return true; + if (res != Nova::NOVA_OK) + PERR("Error: assign_pci failed -irq:dev:msi_addr:msi_data " + "%lx:%lx:%lx:%lx", _irq_number, _dev_mem, msi_addr, + msi_data); + + return res == Nova::NOVA_OK; } void _wait_for_irq() @@ -149,7 +157,9 @@ class Genode::Irq_proxy_component : public Irq_proxy public: - Irq_proxy_component(long irq_number) : Irq_proxy(irq_number) + Irq_proxy_component(long irq_number) + : + Irq_proxy(irq_number), _dev_mem(0) { _start(); }