diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2007-05-15 17:03:54 -0700 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-05-15 20:23:02 -0700 |
commit | c7754d465b1feade85b5f1c4492781a30f6652a2 (patch) | |
tree | 9a3b6ccb18983c1ea389377028ca51c8170730ef /arch/sparc64/kernel/entry.S | |
parent | 7b104bcb8e460e45a1aebe3da9b86aacdb4cab12 (diff) | |
download | blackbird-op-linux-c7754d465b1feade85b5f1c4492781a30f6652a2.tar.gz blackbird-op-linux-c7754d465b1feade85b5f1c4492781a30f6652a2.zip |
[SPARC64]: Add hypervisor API negotiation and fix console bugs.
Hypervisor interfaces need to be negotiated in order to use
some API calls reliably. So add a small set of interfaces
to request API versions and query current settings.
This allows us to fix some bugs in the hypervisor console:
1) If we can negotiate API group CORE of at least major 1
minor 1 we can use con_read and con_write which can improve
console performance quite a bit.
2) When we do a console write request, we should hold the
spinlock around the whole request, not a byte at a time.
What would happen is that it's easy for output from
different cpus to get mixed with each other.
3) Use consistent udelay() based polling, udelay(1) each
loop with a limit of 1000 polls to handle stuck hypervisor
console.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/entry.S')
-rw-r--r-- | arch/sparc64/kernel/entry.S | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index c15a3edcb826..732b77cb71f8 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -1843,3 +1843,97 @@ sun4v_cpu_state: mov %o1, %o0 1: retl nop + + /* %o0: API group number + * %o1: pointer to unsigned long major number storage + * %o2: pointer to unsigned long minor number storage + * + * returns %o0: status + */ + .globl sun4v_get_version +sun4v_get_version: + mov HV_CORE_GET_VER, %o5 + mov %o1, %o3 + mov %o2, %o4 + ta HV_CORE_TRAP + stx %o1, [%o3] + retl + stx %o2, [%o4] + + /* %o0: API group number + * %o1: desired major number + * %o2: desired minor number + * %o3: pointer to unsigned long actual minor number storage + * + * returns %o0: status + */ + .globl sun4v_set_version +sun4v_set_version: + mov HV_CORE_SET_VER, %o5 + mov %o3, %o4 + ta HV_CORE_TRAP + retl + stx %o1, [%o4] + + /* %o0: pointer to unsigned long status + * + * returns %o0: signed character + */ + .globl sun4v_con_getchar +sun4v_con_getchar: + mov %o0, %o4 + mov HV_FAST_CONS_GETCHAR, %o5 + clr %o0 + clr %o1 + ta HV_FAST_TRAP + stx %o0, [%o4] + retl + sra %o1, 0, %o0 + + /* %o0: signed long character + * + * returns %o0: status + */ + .globl sun4v_con_putchar +sun4v_con_putchar: + mov HV_FAST_CONS_PUTCHAR, %o5 + ta HV_FAST_TRAP + retl + sra %o0, 0, %o0 + + /* %o0: buffer real address + * %o1: buffer size + * %o2: pointer to unsigned long bytes_read + * + * returns %o0: status + */ + .globl sun4v_con_read +sun4v_con_read: + mov %o2, %o4 + mov HV_FAST_CONS_READ, %o5 + ta HV_FAST_TRAP + brnz %o0, 1f + cmp %o1, -1 /* break */ + be,a,pn %icc, 1f + mov %o1, %o0 + cmp %o1, -2 /* hup */ + be,a,pn %icc, 1f + mov %o1, %o0 + stx %o1, [%o4] +1: retl + nop + + /* %o0: buffer real address + * %o1: buffer size + * %o2: pointer to unsigned long bytes_written + * + * returns %o0: status + */ + .globl sun4v_con_write +sun4v_con_write: + mov %o2, %o4 + mov HV_FAST_CONS_WRITE, %o5 + ta HV_FAST_TRAP + stx %o1, [%o4] + retl + nop |