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;
}
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_ */

View File

@ -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_ */

View File

@ -109,7 +109,8 @@ class Genode::Irq_proxy_component : public Irq_proxy<Irq_thread>
{
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<Irq_thread>
/* 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<Irq_thread>
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();
}