nova: update syscall assign_gsi/_pci for 32/64 bit

This commit is contained in:
Alexander Boettcher 2013-01-22 11:53:22 +01:00 committed by Norman Feske
parent ff062f24ff
commit 250f7b1570
3 changed files with 48 additions and 19 deletions

View File

@ -155,6 +155,21 @@ namespace Nova {
return status; 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 ALWAYS_INLINE
inline uint8_t call(unsigned pt) inline uint8_t call(unsigned pt)
@ -257,9 +272,18 @@ namespace Nova {
ALWAYS_INLINE 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_ */ #endif /* _PLATFORM__NOVA_SYSCALLS_H_ */

View File

@ -119,12 +119,12 @@ namespace Nova {
ALWAYS_INLINE ALWAYS_INLINE
inline uint8_t syscall_5(Syscall s, uint8_t flags, mword_t sel, 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); mword_t status = rdi(s, flags, sel);
asm volatile ("syscall" asm volatile ("syscall"
: "+D" (status), "+S"(p3), "+d"(p4) : "+D" (status), "+S"(p1), "+d"(p2)
: :
: "rcx", "r11", "memory"); : "rcx", "r11", "memory");
return status; return status;
@ -226,7 +226,7 @@ namespace Nova {
mword_t status = rdi(NOVA_SC_CTRL, op, sm); mword_t status = rdi(NOVA_SC_CTRL, op, sm);
mword_t time_h; 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" asm volatile ("syscall"
: "+D" (status), "=S"(time_h), "=d"(time) : "+D" (status), "=S"(time_h), "=d"(time)
: :
@ -240,20 +240,15 @@ namespace Nova {
ALWAYS_INLINE ALWAYS_INLINE
inline uint8_t assign_pci(mword_t pd, mword_t mem, mword_t rid) 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 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; msi_addr = dev;
return syscall_5(NOVA_ASSIGN_GSI, 0, sm, dev, rid, dummy1, dummy2); msi_data = cpu;
} return syscall_5(NOVA_ASSIGN_GSI, 0, sm, msi_addr, msi_data);
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);
} }
} }
#endif /* _PLATFORM__NOVA_SYSCALLS_H_ */ #endif /* _PLATFORM__NOVA_SYSCALLS_H_ */

View File

@ -109,7 +109,8 @@ class Genode::Irq_proxy_component : public Irq_proxy<Irq_thread>
{ {
private: 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: protected:
@ -134,9 +135,16 @@ class Genode::Irq_proxy_component : public Irq_proxy<Irq_thread>
/* assign IRQ to CPU */ /* assign IRQ to CPU */
enum { CPU = 0 }; 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() void _wait_for_irq()
@ -149,7 +157,9 @@ class Genode::Irq_proxy_component : public Irq_proxy<Irq_thread>
public: 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(); _start();
} }