summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2011-04-20 15:20:43 -0700
committerRichard Henderson <rth@twiddle.net>2011-04-22 07:04:56 -0700
commit6d3e153cf8b83306b8faa5e969d3f784a4d2b372 (patch)
tree710f9f4d9e5dfc80d219109c6477958e6dc56ded
parent71b4db6096ad4f82bb297f2419e83301a41b0f95 (diff)
downloadqemu-palcode-6d3e153cf8b83306b8faa5e969d3f784a4d2b372.tar.gz
Implement CallPal_Cserve.
This is just good enough to handle the cserve_ena/dis used by the Linux kernel for managing interrupts.
-rw-r--r--Makefile6
-rw-r--r--pal.S63
-rw-r--r--uart.h5
3 files changed, 68 insertions, 6 deletions
diff --git a/Makefile b/Makefile
index 03a78a1..ea2eac2 100644
--- a/Makefile
+++ b/Makefile
@@ -18,5 +18,9 @@ clean:
rm -f *.o
rm -f palcode palcode.map
-pal.o: pal.S osf.h
+pal.o: pal.S osf.h uart.h
$(CC) $(CFLAGS) -c -Wa,-m21264 -Wa,--noexecstack -o $@ $<
+
+init.o: init.c hwrpb.h osf.h uart.h
+printf.o: printf.c uart.h
+uart.o: uart.c uart.h io.h cia.h
diff --git a/pal.S b/pal.S
index dc4aecf..c3f100d 100644
--- a/pal.S
+++ b/pal.S
@@ -3,6 +3,7 @@
.text
#include "osf.h"
+#include "uart.h"
/* General Purpose Registers. */
#define v0 $0
@@ -532,8 +533,8 @@ ENDFN CallPal_OpcDec08
*
* INPUT PARAMETERS:
*
- * r0 (v0) = Option selector
- * r16..r21 (a0..a5) = Implementation specific entry parameters
+ * r16 (a0) = Option selector
+ * r17..r21 (a1..a5) = Implementation specific entry parameters
*
* SIDE EFFECTS:
*
@@ -541,9 +542,64 @@ ENDFN CallPal_OpcDec08
*/
ORG_CALL_PAL_PRIV(0x09)
CallPal_Cserve:
- br Sys_Cserve
+ cmpeq a0, 15, v0
+ bne v0, Cserve_putc
+ cmpeq a0, 52, v0
+ bne v0, Cserve_ena
+ cmpeq a0, 53, v0
+ bne v0, Cserve_dis
+ hw_rei
ENDFN CallPal_Cserve
+ .text 1
+Cserve_putc:
+ // Load CIA_BW_IO. Note that this is the KSEG address,
+ // since there is no hw_stb with physical address access.
+ lda p0, -887
+ sll p0, 32, p0
+
+ ldbu v0, com1Lsr(p0) // Get Transmit Holding Register Empty
+ and v0, 0x20, v0
+ beq v0, 1f
+
+ stb a1, com1Thr(p0) // Output the byte
+ mov 1, v0
+1: hw_rei
+ENDFN Cserve_putc
+
+Cserve_ena:
+ lda p0, 0x87a // Load PYXIS INT REG base.
+ sll p0, 28, p0
+
+ lda p1, 1 // Shift the interrupt line in place.
+ sll p1, a1, p1
+
+ ldq_p p2, 0x40(p0) // Load PYXIS_INT_MASK
+ sll p2, a1, v0 // Return the current setting
+ and v0, 1, v0
+ andnot p2, p1, p2 // Clear the bit
+ stq_p p2, 0x40(p0) // Store PYXIS_INT_MASK
+
+ hw_rei
+ENDFN Cserve_ena
+
+Cserve_dis:
+ lda p0, 0x87a // Load PYXIS INT REG base.
+ sll p0, 28, p0
+
+ lda p1, 1 // Shift the interrupt line in place.
+ sll p1, a1, p1
+
+ ldq_p p2, 0x40(p0) // Load PYXIS_INT_MASK
+ sll p2, a1, v0 // Return the current setting
+ and v0, 1, v0
+ or p2, p1, p2 // Set the bit
+ stq_p p2, 0x40(p0) // Store PYXIS_INT_MASK
+
+ hw_rei
+ENDFN Cserve_dis
+ .previous
+
/*
* Swap PALcode
*
@@ -2068,7 +2124,6 @@ ENDFN UpdatePCB
* FIXME
*/
Sys_EnterConsole:
-Sys_Cserve:
halt
/*
diff --git a/uart.h b/uart.h
index b5f018d..48cceef 100644
--- a/uart.h
+++ b/uart.h
@@ -53,10 +53,13 @@ your own risk.
#define COM1 (com1Rbr - com2Rbr)
#define COM2 0
+#ifndef __ASSEMBLER__
+
extern int uart_charav(int port);
extern int uart_getchar(int port);
extern void uart_putchar(int port, char c);
extern void uart_puts(int port, const char *s);
extern void uart_init(void);
-#endif /* __UART_H_LOADED */
+#endif /* __ASSEMBLER__ */
+#endif /* __UART_H_LOADED */