mirror of
				https://gitlab.com/qemu-project/qemu-palcode.git
				synced 2024-02-13 08:32:59 +08:00 
			
		
		
		
	Beginnings of the SRM console prompt.
This commit is contained in:
		
							
								
								
									
										3
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								Makefile
									
									
									
									
									
								
							| @ -12,7 +12,7 @@ CPPFLAGS = -DSYSTEM_H='"sys-$(SYSTEM).h"' | ||||
|  | ||||
| CFLAGS += -mcpu=ev67 | ||||
|  | ||||
| OBJS = pal.o sys-$(SYSTEM).o init.o crb.o uart.o memset.o printf.o | ||||
| OBJS = pal.o sys-$(SYSTEM).o init.o crb.o uart.o console.o console-low.o memset.o printf.o | ||||
|  | ||||
| all: palcode-$(SYSTEM) | ||||
|  | ||||
| @ -28,3 +28,4 @@ init.o: init.c hwrpb.h osf.h uart.h sys-$(SYSTEM).h core-$(CORE).h | ||||
| printf.o: printf.c uart.h | ||||
| uart.o: uart.c uart.h protos.h | ||||
| crb.o: crb.c hwrpb.h protos.h console.h uart.h | ||||
| console.o: console.c console.h protos.h | ||||
|  | ||||
							
								
								
									
										126
									
								
								console-low.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								console-low.S
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,126 @@ | ||||
| /* Assembly helper routines for the emulation SRM console. | ||||
|  | ||||
|    Copyright (C) 2011 Richard Henderson | ||||
|  | ||||
|    This file is part of QEMU PALcode. | ||||
|  | ||||
|    This program is free software; you can redistribute it and/or modify | ||||
|    it under the terms of the GNU General Public License as published by | ||||
|    the Free Software Foundation; either version 2 of the License or | ||||
|    (at your option) any later version. | ||||
|  | ||||
|    This program is distributed in the hope that it will be useful, | ||||
|    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the text | ||||
|    of the GNU General Public License for more details. | ||||
|  | ||||
|    You should have received a copy of the GNU General Public License | ||||
|    along with this program; see the file COPYING.  If not see | ||||
|    <http://www.gnu.org/licenses/>.  */ | ||||
|  | ||||
| 	.set nomacro | ||||
| 	.set noat | ||||
| 	.text | ||||
| 	.cfi_sections .debug_frame | ||||
|  | ||||
| #define SAVE_ALL_SIZE	(18*8) | ||||
|  | ||||
| 	.globl	entInt | ||||
| 	.type	entInt, @function | ||||
| 	.cfi_startproc simple | ||||
| entInt: | ||||
| 	.cfi_return_column 64 | ||||
| 	.cfi_def_cfa	$sp, 48 | ||||
| 	.cfi_rel_offset	64, 8 | ||||
| 	.cfi_rel_offset	$gp, 16 | ||||
| 	.cfi_rel_offset	$16, 24 | ||||
| 	.cfi_rel_offset	$17, 32 | ||||
| 	.cfi_rel_offset	$18, 40 | ||||
| 	lda	$sp, -SAVE_ALL_SIZE($sp) | ||||
| 	.cfi_adjust_cfa_offset SAVE_ALL_SIZE | ||||
| 	stq	$0, 0*8($sp) | ||||
| 	stq	$1, 1*8($sp) | ||||
| 	stq	$2, 2*8($sp) | ||||
| 	stq	$3, 3*8($sp) | ||||
| 	stq	$4, 4*8($sp) | ||||
| 	stq	$5, 5*8($sp) | ||||
| 	stq	$6, 6*8($sp) | ||||
| 	stq	$7, 7*8($sp) | ||||
| 	stq	$8, 9*8($sp) | ||||
| 	stq	$19, 9*8($sp) | ||||
| 	stq	$20, 10*8($sp) | ||||
| 	stq	$21, 11*8($sp) | ||||
| 	stq	$22, 12*8($sp) | ||||
| 	stq	$23, 13*8($sp) | ||||
| 	stq	$24, 14*8($sp) | ||||
| 	stq	$25, 15*8($sp) | ||||
| 	stq	$26, 16*8($sp) | ||||
| 	stq	$27, 17*8($sp) | ||||
| 	stq	$28, 18*8($sp) | ||||
| 	.cfi_rel_offset $0, 0*8 | ||||
| 	.cfi_rel_offset $1, 1*8 | ||||
| 	.cfi_rel_offset $2, 2*8 | ||||
| 	.cfi_rel_offset $3, 3*8 | ||||
| 	.cfi_rel_offset $4, 4*8 | ||||
| 	.cfi_rel_offset $5, 5*8 | ||||
| 	.cfi_rel_offset $6, 6*8 | ||||
| 	.cfi_rel_offset $7, 7*8 | ||||
| 	.cfi_rel_offset $8, 8*8 | ||||
| 	.cfi_rel_offset $19, 9*8 | ||||
| 	.cfi_rel_offset $20, 10*8 | ||||
| 	.cfi_rel_offset $21, 11*8 | ||||
| 	.cfi_rel_offset $22, 12*8 | ||||
| 	.cfi_rel_offset $23, 13*8 | ||||
| 	.cfi_rel_offset $24, 14*8 | ||||
| 	.cfi_rel_offset $25, 15*8 | ||||
| 	.cfi_rel_offset $26, 16*8 | ||||
| 	.cfi_rel_offset $27, 17*8 | ||||
| 	.cfi_rel_offset $28, 18*8 | ||||
|  | ||||
| 	bsr	$26, do_entInt	!samegp | ||||
|  | ||||
| 	ldq	$0, 0*8($sp) | ||||
| 	ldq	$1, 1*8($sp) | ||||
| 	ldq	$2, 2*8($sp) | ||||
| 	ldq	$3, 3*8($sp) | ||||
| 	ldq	$4, 4*8($sp) | ||||
| 	ldq	$5, 5*8($sp) | ||||
| 	ldq	$6, 6*8($sp) | ||||
| 	ldq	$7, 7*8($sp) | ||||
| 	ldq	$8, 9*8($sp) | ||||
| 	ldq	$19, 9*8($sp) | ||||
| 	ldq	$20, 10*8($sp) | ||||
| 	ldq	$21, 11*8($sp) | ||||
| 	ldq	$22, 12*8($sp) | ||||
| 	ldq	$23, 13*8($sp) | ||||
| 	ldq	$24, 14*8($sp) | ||||
| 	ldq	$25, 15*8($sp) | ||||
| 	ldq	$26, 16*8($sp) | ||||
| 	ldq	$27, 17*8($sp) | ||||
| 	ldq	$28, 18*8($sp) | ||||
| 	lda	$sp, SAVE_ALL_SIZE($sp) | ||||
| 	.cfi_adjust_cfa_offset -SAVE_ALL_SIZE | ||||
| 	.cfi_restore	$0 | ||||
| 	.cfi_restore	$1 | ||||
| 	.cfi_restore	$2 | ||||
| 	.cfi_restore	$3 | ||||
| 	.cfi_restore	$4 | ||||
| 	.cfi_restore	$5 | ||||
| 	.cfi_restore	$6 | ||||
| 	.cfi_restore	$7 | ||||
| 	.cfi_restore	$8 | ||||
| 	.cfi_restore	$19 | ||||
| 	.cfi_restore	$20 | ||||
| 	.cfi_restore	$21 | ||||
| 	.cfi_restore	$22 | ||||
| 	.cfi_restore	$23 | ||||
| 	.cfi_restore	$24 | ||||
| 	.cfi_restore	$25 | ||||
| 	.cfi_restore	$26 | ||||
| 	.cfi_restore	$27 | ||||
| 	.cfi_restore	$28 | ||||
|  | ||||
| 	call_pal 0x3f // rti | ||||
|  | ||||
| 	.cfi_endproc | ||||
| 	.size	entInt, . - entInt | ||||
							
								
								
									
										132
									
								
								console.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								console.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,132 @@ | ||||
| /* The SRM console prompt. | ||||
|  | ||||
|    Copyright (C) 2011 Richard Henderson | ||||
|  | ||||
|    This file is part of QEMU PALcode. | ||||
|  | ||||
|    This program is free software; you can redistribute it and/or modify | ||||
|    it under the terms of the GNU General Public License as published by | ||||
|    the Free Software Foundation; either version 2 of the License or | ||||
|    (at your option) any later version. | ||||
|  | ||||
|    This program is distributed in the hope that it will be useful, | ||||
|    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the text | ||||
|    of the GNU General Public License for more details. | ||||
|  | ||||
|    You should have received a copy of the GNU General Public License | ||||
|    along with this program; see the file COPYING.  If not see | ||||
|    <http://www.gnu.org/licenses/>.  */ | ||||
|  | ||||
| #include "protos.h" | ||||
| #include "console.h" | ||||
|  | ||||
|  | ||||
| static void | ||||
| output_crnl(void) | ||||
| { | ||||
|   crb_puts(0, "\r\n", 2); | ||||
| } | ||||
|  | ||||
| static void | ||||
| output_bell(void) | ||||
| { | ||||
|   crb_puts(0, "\a", 1); | ||||
| } | ||||
|  | ||||
| static void | ||||
| backspace_and_erase(void) | ||||
| { | ||||
|   crb_puts(0, "\b \b", 3); | ||||
| } | ||||
|  | ||||
| static unsigned long | ||||
| getline(char *buf, unsigned long bufsize) | ||||
| { | ||||
|   unsigned long len = 0; | ||||
|   long c; | ||||
|  | ||||
|   while (1) | ||||
|     { | ||||
|       c = crb_getc(0); | ||||
|       if (c < 0) | ||||
| 	continue; | ||||
|       switch ((int)c) | ||||
| 	{ | ||||
| 	case '\r': | ||||
| 	case '\n': | ||||
| 	  output_crnl(); | ||||
| 	  buf[len] = 0; | ||||
| 	  return len; | ||||
|  | ||||
|         case '\b': | ||||
| 	case 0x7f: /* Delete */ | ||||
|           if (len > 0) | ||||
| 	    { | ||||
| 	      backspace_and_erase(); | ||||
|               len--; | ||||
|             } | ||||
| 	  else | ||||
| 	    output_bell(); | ||||
|           break; | ||||
|  | ||||
|         default: | ||||
| 	  if (len + 1 < bufsize) | ||||
| 	    { | ||||
| 	      buf[len] = c; | ||||
|               crb_puts(0, buf+len, 1); | ||||
| 	      len++; | ||||
| 	    } | ||||
| 	  else | ||||
| 	    output_bell(); | ||||
| 	  break; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| static inline void set_console_alarm(void) | ||||
| { | ||||
|   /* Just set a new timeout for 10ms = 10M ns.  */ | ||||
|   set_alarm_rel(10 * 1000 * 1000); | ||||
| } | ||||
|  | ||||
| void | ||||
| do_entInt(unsigned long type, unsigned long vector) | ||||
| { | ||||
|   switch (type) | ||||
|     { | ||||
|     case 0: | ||||
|       /* ??? SMP interrupt.  We're going to need this for starting up | ||||
|          secondary cpus.  */ | ||||
|       break; | ||||
|     case 1: | ||||
|       /* Timer interrupt.  */ | ||||
|       set_console_alarm(); | ||||
|       break; | ||||
|     case 2: | ||||
|       /* ??? Device interrupt.  We're going to need this for virtio disk | ||||
|          operations at minimum.  */ | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void | ||||
| do_console(void) | ||||
| { | ||||
|   char line[256]; | ||||
|   unsigned long len; | ||||
|  | ||||
|   wrkgp(); | ||||
|   wrent(entInt, 0); | ||||
|   set_console_alarm(); | ||||
|   swpipl(0); | ||||
|  | ||||
|   while (1) | ||||
|     { | ||||
|       crb_puts(0, ">>> ", 4); | ||||
|       len = getline(line, sizeof(line)); | ||||
|       crb_puts(0, "got: ", 5); | ||||
|       crb_puts(0, line, len); | ||||
|       output_crnl(); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										10
									
								
								init.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								init.c
									
									
									
									
									
								
							| @ -230,14 +230,6 @@ init_pcb (void) | ||||
|   pcb.flags = 1; /* FEN */ | ||||
| } | ||||
|  | ||||
| void | ||||
| do_hello(void) | ||||
| { | ||||
|   uart_puts(COM1, "Hello, World!\n"); | ||||
|   asm ("halt"); | ||||
|   __builtin_unreachable (); | ||||
| } | ||||
|  | ||||
| void | ||||
| do_start(unsigned long memsize, void (*kernel_entry)(void), long cpus) | ||||
| { | ||||
| @ -254,7 +246,7 @@ do_start(unsigned long memsize, void (*kernel_entry)(void), long cpus) | ||||
|     register unsigned long pa_pcb __asm__("$18"); | ||||
|     register unsigned long vptptr __asm__("$19"); | ||||
|  | ||||
|     pc = (kernel_entry ? kernel_entry : do_hello); | ||||
|     pc = (kernel_entry ? kernel_entry : do_console); | ||||
|     pa_pcb = PA(&pcb); | ||||
|     vptptr = VPTPTR; | ||||
|     asm("call_pal 0x0a" : : "r"(variant), "r"(pc), "r"(pa_pcb), "r"(vptptr)); | ||||
|  | ||||
							
								
								
									
										102
									
								
								protos.h
									
									
									
									
									
								
							
							
						
						
									
										102
									
								
								protos.h
									
									
									
									
									
								
							| @ -21,6 +21,60 @@ | ||||
| #ifndef PROTOS_H | ||||
| #define PROTOS_H 1 | ||||
|  | ||||
| /* | ||||
|  * Call_Pal functions. | ||||
|  */ | ||||
|  | ||||
| static inline void wrent(void *cb, unsigned long which) | ||||
| { | ||||
|   register void *a0 __asm__("$16") = cb; | ||||
|   register unsigned long a1 __asm__("$17") = which; | ||||
|  | ||||
|   asm volatile ("call_pal 0x34" | ||||
| 		: "+r"(a0), "+r"(a1) | ||||
| 		: : "$1", "$22", "$23", "$24", "$25"); | ||||
| } | ||||
|  | ||||
| static inline unsigned long swpipl(unsigned long newipl) | ||||
| { | ||||
|   register unsigned long v0 __asm__("$0"); | ||||
|   register unsigned long a0 __asm__("$16") = newipl; | ||||
|  | ||||
|   asm volatile ("call_pal 0x35" | ||||
| 		: "=r"(v0), "+r"(a0) | ||||
| 		: : "$1", "$22", "$23", "$24", "$25"); | ||||
|  | ||||
|   return v0; | ||||
| } | ||||
|  | ||||
| static inline unsigned long rdps(void) | ||||
| { | ||||
|   register unsigned long v0 __asm__("$0"); | ||||
|  | ||||
|   asm volatile ("call_pal 0x36" | ||||
| 		: "=r"(v0) : : "$1", "$22", "$23", "$24", "$25"); | ||||
|  | ||||
|   return v0; | ||||
| } | ||||
|  | ||||
| static inline void wrkgp(void) | ||||
| { | ||||
|   asm volatile ("mov $29, $16\n\tcall_pal 0x37" | ||||
| 		: : : "$16", "$1", "$22", "$23", "$24", "$25"); | ||||
| } | ||||
|  | ||||
| static inline unsigned long wtint(unsigned long skip) | ||||
| { | ||||
|   register unsigned long v0 __asm__("$0"); | ||||
|   register unsigned long a0 __asm__("$16") = skip; | ||||
|  | ||||
|   asm volatile ("call_pal 0x3e" | ||||
| 		: "=r"(v0), "+r"(a0) | ||||
| 		: : "$1", "$22", "$23", "$24", "$25"); | ||||
|  | ||||
|   return v0; | ||||
| } | ||||
|  | ||||
| /*  | ||||
|  * Cserve functions. | ||||
|  */ | ||||
| @ -41,7 +95,7 @@ static inline unsigned long ldq_p(unsigned long addr) | ||||
| static inline unsigned long stq_p(unsigned long port, unsigned long val) | ||||
| { | ||||
|   register unsigned long v0 __asm__("$0"); | ||||
|   register unsigned long a0 __asm__("$16") = 4; | ||||
|   register unsigned long a0 __asm__("$16") = 2; | ||||
|   register unsigned long a1 __asm__("$17") = port; | ||||
|   register unsigned long a2 __asm__("$18") = val; | ||||
|  | ||||
| @ -52,6 +106,46 @@ static inline unsigned long stq_p(unsigned long port, unsigned long val) | ||||
|   return v0; | ||||
| } | ||||
|  | ||||
| static inline unsigned long get_wall_time(void) | ||||
| { | ||||
|   register unsigned long v0 __asm__("$0"); | ||||
|   register unsigned long a0 __asm__("$16") = 3; | ||||
|  | ||||
|   asm("call_pal 9" : "=r"(v0), "+r"(a0) : : "$17", "$18", "$19", "$20", "$21"); | ||||
|  | ||||
|   return v0; | ||||
| } | ||||
|  | ||||
| static inline unsigned long get_alarm(void) | ||||
| { | ||||
|   register unsigned long v0 __asm__("$0"); | ||||
|   register unsigned long a0 __asm__("$16") = 4; | ||||
|  | ||||
|   asm("call_pal 9" : "=r"(v0), "+r"(a0) : : "$17", "$18", "$19", "$20", "$21"); | ||||
|  | ||||
|   return v0; | ||||
| } | ||||
|  | ||||
| static inline void set_alarm_rel(unsigned long nsec) | ||||
| { | ||||
|   register unsigned long a0 __asm__("$16") = 5; | ||||
|   register unsigned long a1 __asm__("$17") = nsec; | ||||
|  | ||||
|   asm volatile ("call_pal 9" | ||||
| 		: "+r"(a0), "+r"(a1) | ||||
| 		: : "$0", "$18", "$19", "$20", "$21"); | ||||
| } | ||||
|  | ||||
| static inline void set_alarm_abs(unsigned long nsec) | ||||
| { | ||||
|   register unsigned long a0 __asm__("$16") = 6; | ||||
|   register unsigned long a1 __asm__("$17") = nsec; | ||||
|  | ||||
|   asm volatile ("call_pal 9" | ||||
| 		: "+r"(a0), "+r"(a1) | ||||
| 		: : "$0", "$18", "$19", "$20", "$21"); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * I/O functions | ||||
|  */ | ||||
| @ -67,4 +161,10 @@ extern unsigned long crb_dispatch(long select, long a1, long a2, | ||||
|                                   long a3, long a4); | ||||
| extern unsigned long crb_fixup(unsigned long vptptr, unsigned long hwrpb); | ||||
|  | ||||
| /* | ||||
|  * The Console | ||||
|  */ | ||||
| extern void do_console(void); | ||||
| extern void entInt(void); | ||||
|  | ||||
| #endif /* PROTOS_H */ | ||||
|  | ||||
							
								
								
									
										13
									
								
								uart.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								uart.c
									
									
									
									
									
								
							| @ -46,8 +46,17 @@ uart_charav(int offset) | ||||
| int | ||||
| uart_getchar(int offset) | ||||
| { | ||||
| 	while (!uart_charav(offset)) | ||||
| 		continue; | ||||
| 	/* If interrupts are enabled, use wtint assuming that either the | ||||
| 	   device itself will wake us, or that a clock interrupt will.  */ | ||||
| 	if ((rdps() & 7) == 0) { | ||||
| 	    while (!uart_charav(offset)) { | ||||
| 		wtint(0); | ||||
| 	    } | ||||
| 	} else { | ||||
| 	    while (!uart_charav(offset)) | ||||
| 	        continue; | ||||
| 	} | ||||
|  | ||||
| 	return inb(com2Rbr + offset); | ||||
| } | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Richard Henderson
					Richard Henderson