-diff -ruN proll_18.orig/Makefile proll-patch4/Makefile
+diff -ruN proll_18.orig/Makefile proll-patch7/Makefile
--- proll_18.orig/Makefile 2002-09-13 14:16:59.000000000 +0000
-+++ proll-patch4/Makefile 2004-11-13 15:50:49.000000000 +0000
++++ proll-patch7/Makefile 2004-11-13 15:50:49.000000000 +0000
@@ -4,6 +4,7 @@
make -C krups-ser all
make -C espresso all
make -C espresso clean
make -C espresso-ser clean
+ make -C qemu clean
-diff -ruN proll_18.orig/qemu/head.S proll-patch4/qemu/head.S
+diff -ruN proll_18.orig/qemu/Makefile proll-patch7/qemu/Makefile
+--- proll_18.orig/qemu/Makefile 1970-01-01 00:00:00.000000000 +0000
++++ proll-patch7/qemu/Makefile 2005-03-02 16:41:50.000000000 +0000
+@@ -0,0 +1,122 @@
++#
++# proll:
++# qemu/Makefile - make PROLL for QEMU
++# $Id: proll.patch,v 1.3 2005-03-13 09:43:36 bellard Exp $
++#
++# Copyright 1999 Pete Zaitcev
++# This is Free Software is licensed under terms of GNU General Public License.
++#
++
++CC = gcc
++
++#CROSS = /usr/local/sparc/bin/sparc-sun-linux-
++CROSS = sparc-unknown-linux-gnu-
++
++CROSSCC = $(CROSS)gcc
++CROSSLD = $(CROSS)ld
++CROSSNM = $(CROSS)nm
++
++RM = /bin/rm -f
++ELFTOAOUT = elftoaout
++
++#
++SRC = ../src
++
++# Due to remapping algorithm PROLBASE should be algned on PMD.
++# We make PROLBASE a define instead of using _start because we
++# want to shift it to form a PGD entry. A relocatable label will not work.
++# Linux kernel expects us to be at LINUX_OPPROM_BEGVM <asm-sparc/openprom.h>.
++PROLBASE = 0xffd00000
++PROLRODATA = 0xffd07000
++PROLDATA = 0xffd09000
++PROLSIZE = 240*1024
++
++# Linux
++# Fixed %g6 is for arch/sparc/kernel/head.S, it seems ok w/o -ffixed-g6.
++# Kernel uses -fcall-used-g5 -fcall-used-g7, we probably do not need them.
++# __ANSI__ is supposed to be on by default but it is not.
++CFLAGS = -O2 -Wall -DPROLBASE=$(PROLBASE) -DPROLDATA=$(PROLDATA) -DPROLRODATA=$(PROLRODATA) -D__ANSI__=1 -I$(SRC) -mcpu=hypersparc -g -DQEMU
++ASFLAGS = -D__ASSEMBLY__ -I$(SRC) -DPROLRODATA=$(PROLRODATA) -DPROLDATA=$(PROLDATA) -DPROLSIZE=$(PROLSIZE) -g
++# Solaris or Linux/i386 cross compilation
++#CFLAGS = -Iinclude -O
++
++LDFLAGS = -N -Ttext $(PROLBASE) --section-start .rodata=$(PROLRODATA) -Tdata $(PROLDATA) -Tbss $(PROLDATA)
++
++ALL = proll.aout
++PROLLEXE = proll.elf
++
++OBJS = head.o wuf.o wof.o main.o $(CONSOLE) \
++ printf.o le.o system_qemu.o iommu.o \
++ arp.o netinit.o bootp.o packet.o tftp.o udp.o sched_4m.o openprom.o \
++ vconsole.o hconsole.o rconsole.o vcons_zs.o
++
++all: $(ALL)
++
++$(PROLLEXE): $(OBJS)
++ $(CROSSLD) $(LDFLAGS) -o $(PROLLEXE) $(OBJS)
++
++head.o: head.S $(SRC)/phys_jj.h \
++ $(SRC)/asi.h $(SRC)/psr.h $(SRC)/crs.h
++ $(CROSSCC) $(ASFLAGS) -DPROLBASE=$(PROLBASE) -o $*.o -c $*.S
++
++main.o: main.c $(SRC)/asi.h $(SRC)/pgtsrmmu.h $(SRC)/iommu.h \
++ $(SRC)/phys_jj.h $(SRC)/vconsole.h $(SRC)/version.h $(SRC)/general.h \
++ $(SRC)/net.h $(SRC)/romlib.h $(SRC)/netpriv.h $(SRC)/arpa.h $(SRC)/system.h
++ $(CROSSCC) $(CFLAGS) -c $*.c
++openprom.o: openprom.c $(SRC)/openprom.h $(SRC)/general.h $(SRC)/romlib.h \
++ $(SRC)/vconsole.h $(SRC)/system.h $(SRC)/phys_jj.h
++ $(CROSSCC) $(CFLAGS) -c $*.c
++
++system_qemu.o: system_qemu.c $(SRC)/vconsole.h $(SRC)/pgtsrmmu.h \
++ $(SRC)/timer.h $(SRC)/general.h $(SRC)/net.h $(SRC)/romlib.h $(SRC)/asi.h \
++ $(SRC)/netpriv.h $(SRC)/arpa.h $(SRC)/system.h $(SRC)/crs.h
++ $(CROSSCC) $(CFLAGS) -c $*.c
++iommu.o: $(SRC)/iommu.c $(SRC)/pgtsrmmu.h $(SRC)/phys_jj.h $(SRC)/iommu.h \
++ $(SRC)/vconsole.h $(SRC)/general.h $(SRC)/romlib.h $(SRC)/system.h $(SRC)/asi.h
++ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
++vconsole.o: $(SRC)/vconsole.c $(SRC)/vconsole.h $(SRC)/hconsole.h
++ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
++vcons_zs.o: $(SRC)/vcons_zs.c $(SRC)/vconsole.h $(SRC)/system.h
++ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
++hconsole.o: $(SRC)/hconsole.c $(SRC)/hconsole.h $(SRC)/rconsole.h $(SRC)/phys_jj.h
++ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
++rconsole.o: $(SRC)/rconsole.c $(SRC)/rconsole.h
++ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
++printf.o: $(SRC)/printf.c
++ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
++le.o: $(SRC)/le.c $(SRC)/dma.h $(SRC)/system.h $(SRC)/netpriv.h $(SRC)/romlib.h $(SRC)/general.h $(SRC)/net.h $(SRC)/phys_jj.h
++ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
++
++arp.o: $(SRC)/arp.c $(SRC)/general.h $(SRC)/net.h $(SRC)/romlib.h $(SRC)/netpriv.h $(SRC)/arp.h
++ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
++netinit.o: $(SRC)/netinit.c $(SRC)/general.h $(SRC)/net.h $(SRC)/romlib.h $(SRC)/netpriv.h $(SRC)/arp.h $(SRC)/ip.h $(SRC)/udp.h
++ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
++tftp.o: $(SRC)/tftp.c $(SRC)/general.h $(SRC)/net.h $(SRC)/arpa.h $(SRC)/romlib.h $(SRC)/tftp.h
++ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
++udp.o: $(SRC)/udp.c $(SRC)/general.h $(SRC)/net.h $(SRC)/romlib.h $(SRC)/netpriv.h $(SRC)/arp.h $(SRC)/ip.h $(SRC)/udp.h
++ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
++packet.o: $(SRC)/packet.c $(SRC)/general.h $(SRC)/net.h $(SRC)/romlib.h $(SRC)/netpriv.h
++ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
++sched_4m.o: $(SRC)/sched_4m.c $(SRC)/system.h $(SRC)/general.h $(SRC)/romlib.h $(SRC)/phys_jj.h
++ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
++bootp.o: $(SRC)/bootp.c $(SRC)/general.h $(SRC)/net.h \
++ $(SRC)/arpa.h $(SRC)/romlib.h $(SRC)/system.h $(SRC)/bootp.h
++ $(CROSSCC) $(CFLAGS) -DNOBPEXT=1 -c $(SRC)/$*.c
++
++wuf.o: $(SRC)/wuf.S
++ $(CROSSCC) $(ASFLAGS) -o $*.o -c $(SRC)/$*.S
++wof.o: $(SRC)/wof.S
++ $(CROSSCC) $(ASFLAGS) -o $*.o -c $(SRC)/$*.S
++
++#genlab.o: genlab.c
++# $(CC) -c $*.c
++#
++#genlab: genlab.o
++# $(CC) -o genlab genlab.o
++
++clean:
++ $(RM) $(OBJS)
++ $(RM) $(PROLLEXE) proll.aout
++
++proll.aout: $(PROLLEXE)
++ $(ELFTOAOUT) -o proll.aout $(PROLLEXE)
+diff -ruN proll_18.orig/qemu/head.S proll-patch7/qemu/head.S
--- proll_18.orig/qemu/head.S 1970-01-01 00:00:00.000000000 +0000
-+++ proll-patch4/qemu/head.S 2004-11-13 15:50:49.000000000 +0000
-@@ -0,0 +1,515 @@
++++ proll-patch7/qemu/head.S 2005-03-02 15:30:47.000000000 +0000
+@@ -0,0 +1,539 @@
+/**
+ ** Standalone startup code for Linux PROM emulator.
+ ** Copyright 1999 Pete A. Zaitcev
+ ** This code is licensed under GNU General Public License.
+ **/
+/*
-+ * $Id: proll.patch,v 1.2 2004-12-19 23:18:01 bellard Exp $
++ * $Id: proll.patch,v 1.3 2005-03-13 09:43:36 bellard Exp $
+ */
+
+#include <psr.h>
+_start:
+start:
+ .globl spill_window_entry, fill_window_entry
++
++#define EXPORT_TRAP(trap) \
++ .globl trap; \
++ .type trap,function; \
++ .size trap, 16
++
++EXPORT_TRAP(t_zero)
++EXPORT_TRAP(t_wovf)
++EXPORT_TRAP(t_wunf)
++EXPORT_TRAP(t_irq1)
++EXPORT_TRAP(t_irq2)
++EXPORT_TRAP(t_irq3)
++EXPORT_TRAP(t_irq4)
++EXPORT_TRAP(t_irq5)
++EXPORT_TRAP(t_irq6)
++EXPORT_TRAP(t_irq7)
++EXPORT_TRAP(t_irq8)
++EXPORT_TRAP(t_irq9)
++EXPORT_TRAP(t_irq10)
++EXPORT_TRAP(t_irq11)
++EXPORT_TRAP(t_irq12)
++EXPORT_TRAP(t_irq13)
++EXPORT_TRAP(t_irq14)
++EXPORT_TRAP(t_irq15)
++
+C_LABEL(trapbase):
+t_zero: b goprol; nop; nop; nop;
+t_tflt: SRMMU_TFAULT /* Inst. Access Exception */
+
+goprol:
+ ! %g1 contains end of memory
++ set PHYS_JJ_EEPROM + 0x30, %g1
++ lda [%g1] ASI_M_BYPASS, %g1
+ ! map PROLDATA to PROLBASE+PROLSIZE to end of ram
+ set PROLSIZE+0x1000-PROLDATA+PROLBASE, %g2 ! add 0x1000 for temp tables
+ sub %g1, %g2, %g2 ! start of private memory
+ bl 1b
+ add %o0, 0x4, %o0
+
-+ sethi %hi( C_LABEL(ram_size) ), %o0
-+ st %g3, [%o0 + %lo( C_LABEL(ram_size) )]
-+
+ mov 2, %g1
+ wr %g1, 0x0, %wim ! make window 1 invalid
+ WRITE_PAUSE
+C_LABEL(ldb_bypass):
+ retl
+ lduba [%o0] ASI_M_BYPASS, %o0
-diff -ruN proll_18.orig/qemu/main.c proll-patch4/qemu/main.c
+diff -ruN proll_18.orig/qemu/main.c proll-patch7/qemu/main.c
--- proll_18.orig/qemu/main.c 1970-01-01 00:00:00.000000000 +0000
-+++ proll-patch4/qemu/main.c 2004-11-23 19:05:34.000000000 +0000
-@@ -0,0 +1,178 @@
++++ proll-patch7/qemu/main.c 2005-03-02 20:08:23.000000000 +0000
+@@ -0,0 +1,173 @@
+/**
+ ** Proll (PROM replacement)
+ ** Copyright 1999 Pete Zaitcev
+#include <arpa.h>
+#include <system.h> /* our own prototypes */
+
++void *init_openprom_qemu(int bankc, struct bank *bankv, unsigned hiphybas, const char *cmdline, char boot_device, int nographic);
++int vcon_zs_init(struct vconterm *t, unsigned int a0);
++int vcon_zs_write(struct vconterm *t, char *data, int leng);
++
+static void init_idprom(void);
-+static void makepages_q(struct phym *t, unsigned int highbase);
+
+struct vconterm dp0;
+struct mem cmem; /* Current memory, virtual */
+struct phym pmem; /* Current phys. mem. */
+struct iommu ciommu; /* Our IOMMU on sun4m */
+
-+static char *hw_idprom;
-+int ignore_fault, fault_ignored, ram_size;
++static struct {
++ const char id[16];
++ unsigned int version;
++ char pad1[0x1c]; // Pad to 0x30
++ unsigned int ram_size;
++ char boot_device;
++ unsigned int load_addr, kernel_size;
++ unsigned int cmdline, cmdline_len;
++ char pad2[0x0c]; // Pad to 0x54
++ unsigned short width, height, depth;
++} *hw_idprom;
++
++int ignore_fault, fault_ignored;
++void *printk_fn;
++unsigned int q_height, q_width;
+
+/*
+ */
+void prolmain()
+{
-+ //static const char fname[14] = "00000000.PROL";
++ static char fname[14];
+ static struct banks bb;
+ unsigned int hiphybas;
+ const void *romvec;
++ unsigned int ram_size;
++ char nographic;
++
++ nographic = ldb_bypass(PHYS_JJ_EEPROM + 0x2F);
++ if (!nographic) {
++ q_width = ldh_bypass(PHYS_JJ_EEPROM + 0x54);
++ q_height = ldh_bypass(PHYS_JJ_EEPROM + 0x56);
++ vcon_init(&dp0, PHYS_JJ_TCX_FB);
++ printk_fn = vcon_write;
++ }
++ else {
++ vcon_zs_init(&dp0, 0x71100000);
++ printk_fn = vcon_zs_write;
++ }
++
+
-+ vcon_init(&dp0, PHYS_JJ_TCX_FB);
+ printk("PROLL %s QEMU\n", PROLL_VERSION_STRING);
++ ram_size = ld_bypass(PHYS_JJ_EEPROM + 0x30);
+ printk("%d MB total\n", ram_size/(1024*1024));
+
+ bb.nbanks = 1;
+ hiphybas = ram_size - PROLSIZE;
+
+ mem_init(&cmem, (char *) &_end, (char *)(PROLBASE+PROLSIZE));
-+ makepages_q(&pmem, hiphybas);
++ makepages(&pmem, hiphybas);
+ init_mmu_swift((unsigned int)pmem.pctp - PROLBASE + hiphybas);
+
+ mem_init(&cio, (char *)(PROLBASE+PROLSIZE),
+ /*
+ */
+ init_idprom();
++ printk("NVRAM: id %s version %d\n", hw_idprom->id, hw_idprom->version);
++ if (!nographic)
++ printk("Prom console: TCX %dx%d\n", q_width, q_height);
++ else
++ printk("Prom console: serial\n");
+ sched_init();
+ le_probe();
+ init_net();
+
-+#if 0
-+#if 0 /* RARP */
-+ if (rarp() != 0) fatal();
-+ /* printrarp(); */
-+ xtoa(myipaddr, fname, 8);
-+ if (load(servaddr, fname) != 0) fatal();
-+#else
-+ if (bootp() != 0) fatal();
-+ /*
-+ * boot_rec.bp_file cannot be used because system PROM
-+ * uses it to locate ourselves. If we load from boot_rec.bp_file,
-+ * we will loop reloading PROLL over and over again.
-+ * Thus we use traditional PROLL scheme HEXIPADDR.PROL (single L).
-+ */
-+ xtoa(myipaddr, fname, 8);
-+ if (load(boot_rec.bp_siaddr, fname) != 0) fatal();
-+#endif
-+#endif
++ printk("Boot device: %c\n", hw_idprom->boot_device);
++ if (hw_idprom->boot_device == 'n') {
++ if (bootp() != 0) fatal();
++ /*
++ * boot_rec.bp_file cannot be used because system PROM
++ * uses it to locate ourselves. If we load from boot_rec.bp_file,
++ * we will loop reloading PROLL over and over again.
++ * Thus we use traditional PROLL scheme HEXIPADDR.PROL (single L).
++ */
++ xtoa(myipaddr, fname, 8);
++ fname[9] = '.';
++ fname[10] = 'P';
++ fname[11] = 'R';
++ fname[12] = 'O';
++ fname[13] = 'L';
++ fname[14] = 0;
++
++ if (load(boot_rec.bp_siaddr, fname) != 0) fatal();
++ }
+
-+ romvec = init_openprom(bb.nbanks, bb.bankv, hiphybas);
++ romvec = init_openprom_qemu(bb.nbanks, bb.bankv, hiphybas,
++ (void *)hw_idprom->cmdline, hw_idprom->boot_device, nographic);
+
+ printk("Memory used: virt 0x%x:0x%x[%dK] iomap 0x%x:0x%x\n",
+ PROLBASE, (int)cmem.curp, ((unsigned) cmem.curp - PROLBASE)/1024,
+ (int)cio.start, (int)cio.curp);
-+ //set_timeout(5); while (!chk_timeout()) { } /* P3: let me read */
+
+ {
-+ void (*entry)(const void *, int, int, int, int) = (void (*)(const void*, int, int, int, int)) LOADBASE;
++ void (*entry)(const void *, int, int, int, int) = (void *) hw_idprom->load_addr;
++ printk("Kernel loaded at 0x%x, size %dK, command line = '%s'\n",
++ *entry, hw_idprom->kernel_size/1024, hw_idprom->cmdline);
+ entry(romvec, 0, 0, 0, 0);
+ }
+
+ */
+void udelay(unsigned long usecs)
+{
-+ int i, n;
-+ n = usecs*50;
-+ for (i = 0; i < n; i++) { }
++ // Qemu hardware is perfect and does not need any delays!
+}
+
+static void init_idprom()
+{
-+ char *va_prom;
++ void *va_prom;
+
+ if ((va_prom = map_io(PHYS_JJ_EEPROM, PHYS_JJ_EEPROM_SIZE)) == NULL) {
+ printk("init_idprom: cannot map eeprom\n");
+ hw_idprom = va_prom;
+}
+
+diff -ruN proll_18.orig/qemu/openprom.c proll-patch7/qemu/openprom.c
+--- proll_18.orig/qemu/openprom.c 1970-01-01 00:00:00.000000000 +0000
++++ proll-patch7/qemu/openprom.c 2005-03-02 20:09:57.000000000 +0000
+@@ -0,0 +1,646 @@
+/*
-+ * Make CPU page tables.
-+ * Returns pointer to context table.
-+ * Here we ignore memory allocation errors which "should not happen"
-+ * because we cannot print anything anyways if memory initialization fails.
++ * PROM interface support
++ * Copyright 1996 The Australian National University.
++ * Copyright 1996 Fujitsu Laboratories Limited
++ * Copyright 1999 Pete A. Zaitcev
++ * This software may be distributed under the terms of the Gnu
++ * Public License version 2 or later
+ */
-+void makepages_q(struct phym *t, unsigned int highbase)
-+{
-+ unsigned int *ctp, *l1, pte;
-+ int i;
-+ unsigned int pa, va;
+
-+ ctp = mem_zalloc(&cmem, NCTX_SWIFT*sizeof(int), NCTX_SWIFT*sizeof(int));
-+ l1 = mem_zalloc(&cmem, 256*sizeof(int), 256*sizeof(int));
++#include <openprom.h>
++#include <general.h>
++#include <romlib.h>
++#include <system.h>
++#include <vconsole.h>
++#include "phys_jj.h"
+
-+ pte = SRMMU_ET_PTD | (((unsigned int)l1 - PROLBASE + highbase) >> 4);
-+ for (i = 0; i < NCTX_SWIFT; i++) {
-+ ctp[i] = pte;
-+ }
++//#define DEBUG_OBP
+
-+ pa = PROLBASE;
-+ for (va = PROLBASE; va < PROLDATA; va += PAGE_SIZE) {
-+ map_page(l1, va, pa, 0, highbase);
-+ pa += PAGE_SIZE;
-+ }
-+ pa = highbase + PROLDATA - PROLBASE;
-+ for (va = PROLDATA; va < PROLBASE + PROLSIZE; va += PAGE_SIZE) {
-+ map_page(l1, va, pa, 0, highbase);
-+ pa += PAGE_SIZE;
-+ }
++struct property {
++ const char *name;
++ const char *value;
++ const int length;
++};
+
-+ /* We need to start from LOADBASE, but kernel wants PAGE_SIZE. */
-+ pa = 0;
-+ for (va = 0; va < LOWMEMSZ; va += PAGE_SIZE) {
-+ map_page(l1, va, pa, 0, highbase);
-+ pa += PAGE_SIZE;
-+ }
++struct node {
++ const struct property *properties;
++ /* short */ const int sibling;
++ /* short */ const int child;
++};
+
-+ t->pctp = ctp;
-+ t->pl1 = l1;
-+ t->pbas = highbase;
-+}
-diff -ruN proll_18.orig/qemu/Makefile proll-patch4/qemu/Makefile
---- proll_18.orig/qemu/Makefile 1970-01-01 00:00:00.000000000 +0000
-+++ proll-patch4/qemu/Makefile 2004-11-13 15:50:49.000000000 +0000
-@@ -0,0 +1,119 @@
-+#
-+# proll:
-+# qemu/Makefile - make PROLL for QEMU
-+# $Id: proll.patch,v 1.2 2004-12-19 23:18:01 bellard Exp $
-+#
-+# Copyright 1999 Pete Zaitcev
-+# This is Free Software is licensed under terms of GNU General Public License.
-+#
++static int obp_nextnode(int node);
++static int obp_child(int node);
++static int obp_proplen(int node, char *name);
++static int obp_getprop(int node, char *name, char *val);
++static int obp_setprop(int node, char *name, char *val, int len);
++static const char *obp_nextprop(int node, char *name);
+
-+CC = gcc
++static char obp_idprom[IDPROM_SIZE];
++static const struct property null_properties = { NULL, NULL, -1 };
++static const int prop_true = -1;
+
-+#CROSS = /usr/local/sparc/bin/sparc-sun-linux-
-+CROSS = sparc-unknown-linux-gnu-
++static const struct property propv_root[] = {
++ {"name", "SUNW,JavaStation-1", sizeof("SUNW,JavaStation-1") },
++ {"idprom", obp_idprom, IDPROM_SIZE},
++ {"banner-name", "JavaStation", sizeof("JavaStation")},
++ {"compatible", "sun4m", 6},
++ {NULL, NULL, -1}
++};
+
-+CROSSCC = $(CROSS)gcc
-+CROSSLD = $(CROSS)ld
-+CROSSNM = $(CROSS)nm
++static const int prop_iommu_reg[] = {
++ 0x0, 0x10000000, 0x00000300,
++};
++static const struct property propv_iommu[] = {
++ {"name", "iommu", sizeof("iommu")},
++ {"reg", (char*)&prop_iommu_reg[0], sizeof(prop_iommu_reg) },
++ {NULL, NULL, -1}
++};
+
-+RM = /bin/rm -f
-+ELFTOAOUT = elftoaout
++static const int prop_sbus_ranges[] = {
++ 0x0, 0x0, 0x0, 0x30000000, 0x10000000,
++ 0x1, 0x0, 0x0, 0x40000000, 0x10000000,
++ 0x2, 0x0, 0x0, 0x50000000, 0x10000000,
++ 0x3, 0x0, 0x0, 0x60000000, 0x10000000,
++ 0x4, 0x0, 0x0, 0x70000000, 0x10000000,
++};
++static const struct property propv_sbus[] = {
++ {"name", "sbus", 5},
++ {"ranges", (char*)&prop_sbus_ranges[0], sizeof(prop_sbus_ranges)},
++ {"device_type", "hierarchical", sizeof("hierarchical") },
++ {NULL, NULL, -1}
++};
+
-+#
-+SRC = ../src
-+
-+# Due to remapping algorithm PROLBASE should be algned on PMD.
-+# We make PROLBASE a define instead of using _start because we
-+# want to shift it to form a PGD entry. A relocatable label will not work.
-+# Linux kernel expects us to be at LINUX_OPPROM_BEGVM <asm-sparc/openprom.h>.
-+PROLBASE = 0xffd00000
-+PROLRODATA = 0xffd07000
-+PROLDATA = 0xffd09000
-+PROLSIZE = (240*1024)
-+
-+# Linux
-+# Fixed %g6 is for arch/sparc/kernel/head.S, it seems ok w/o -ffixed-g6.
-+# Kernel uses -fcall-used-g5 -fcall-used-g7, we probably do not need them.
-+# __ANSI__ is supposed to be on by default but it is not.
-+CFLAGS = -O2 -Wall -DPROLBASE=$(PROLBASE) -DPROLDATA=$(PROLDATA) -DPROLRODATA=$(PROLRODATA) -D__ANSI__=1 -I$(SRC) -mcpu=hypersparc -g
-+ASFLAGS = -D__ASSEMBLY__ -I$(SRC) -DPROLRODATA=$(PROLRODATA) -DPROLDATA=$(PROLDATA) -DPROLSIZE=$(PROLSIZE) -g
-+# Solaris or Linux/i386 cross compilation
-+#CFLAGS = -Iinclude -O
-+
-+LDFLAGS = -N -Ttext $(PROLBASE) --section-start .rodata=$(PROLRODATA) -Tdata $(PROLDATA) -Tbss $(PROLDATA)
-+
-+ALL = proll.aout
-+PROLLEXE = proll.elf
-+
-+OBJS = head.o wuf.o wof.o main.o vconsole.o hconsole.o rconsole.o \
-+ printf.o le.o system.o iommu.o \
-+ arp.o netinit.o bootp.o packet.o tftp.o udp.o sched_4m.o openprom.o
-+
-+all: $(ALL)
-+
-+$(PROLLEXE): $(OBJS)
-+ $(CROSSLD) $(LDFLAGS) -o $(PROLLEXE) $(OBJS)
-+
-+head.o: head.S $(SRC)/phys_jj.h \
-+ $(SRC)/asi.h $(SRC)/psr.h $(SRC)/crs.h
-+ $(CROSSCC) $(ASFLAGS) -DPROLBASE=$(PROLBASE) -o $*.o -c $*.S
-+
-+main.o: main.c $(SRC)/asi.h $(SRC)/pgtsrmmu.h $(SRC)/iommu.h \
-+ $(SRC)/phys_jj.h $(SRC)/vconsole.h $(SRC)/version.h $(SRC)/general.h \
-+ $(SRC)/net.h $(SRC)/romlib.h $(SRC)/netpriv.h $(SRC)/arpa.h $(SRC)/system.h
-+ $(CROSSCC) $(CFLAGS) -c $*.c
-+openprom.o: openprom.c $(SRC)/openprom.h $(SRC)/general.h $(SRC)/romlib.h \
-+ $(SRC)/vconsole.h $(SRC)/system.h $(SRC)/phys_jj.h
-+ $(CROSSCC) $(CFLAGS) -c $*.c
-+
-+system.o: $(SRC)/system.c $(SRC)/vconsole.h $(SRC)/pgtsrmmu.h \
-+ $(SRC)/timer.h $(SRC)/general.h $(SRC)/net.h $(SRC)/romlib.h $(SRC)/asi.h \
-+ $(SRC)/netpriv.h $(SRC)/arpa.h $(SRC)/system.h $(SRC)/crs.h
-+ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
-+iommu.o: $(SRC)/iommu.c $(SRC)/pgtsrmmu.h $(SRC)/phys_jj.h $(SRC)/iommu.h \
-+ $(SRC)/vconsole.h $(SRC)/general.h $(SRC)/romlib.h $(SRC)/system.h $(SRC)/asi.h
-+ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
-+vconsole.o: $(SRC)/vconsole.c $(SRC)/vconsole.h $(SRC)/hconsole.h
-+ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
-+hconsole.o: $(SRC)/hconsole.c $(SRC)/hconsole.h $(SRC)/rconsole.h $(SRC)/phys_jj.h
-+ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
-+rconsole.o: $(SRC)/rconsole.c $(SRC)/rconsole.h
-+ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
-+printf.o: $(SRC)/printf.c
-+ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
-+le.o: $(SRC)/le.c $(SRC)/dma.h $(SRC)/system.h $(SRC)/netpriv.h $(SRC)/romlib.h $(SRC)/general.h $(SRC)/net.h $(SRC)/phys_jj.h
-+ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
-+
-+arp.o: $(SRC)/arp.c $(SRC)/general.h $(SRC)/net.h $(SRC)/romlib.h $(SRC)/netpriv.h $(SRC)/arp.h
-+ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
-+netinit.o: $(SRC)/netinit.c $(SRC)/general.h $(SRC)/net.h $(SRC)/romlib.h $(SRC)/netpriv.h $(SRC)/arp.h $(SRC)/ip.h $(SRC)/udp.h
-+ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
-+tftp.o: $(SRC)/tftp.c $(SRC)/general.h $(SRC)/net.h $(SRC)/arpa.h $(SRC)/romlib.h $(SRC)/tftp.h
-+ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
-+udp.o: $(SRC)/udp.c $(SRC)/general.h $(SRC)/net.h $(SRC)/romlib.h $(SRC)/netpriv.h $(SRC)/arp.h $(SRC)/ip.h $(SRC)/udp.h
-+ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
-+packet.o: $(SRC)/packet.c $(SRC)/general.h $(SRC)/net.h $(SRC)/romlib.h $(SRC)/netpriv.h
-+ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
-+sched_4m.o: $(SRC)/sched_4m.c $(SRC)/system.h $(SRC)/general.h $(SRC)/romlib.h $(SRC)/phys_jj.h
-+ $(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
-+bootp.o: $(SRC)/bootp.c $(SRC)/general.h $(SRC)/net.h \
-+ $(SRC)/arpa.h $(SRC)/romlib.h $(SRC)/system.h $(SRC)/bootp.h
-+ $(CROSSCC) $(CFLAGS) -DNOBPEXT=1 -c $(SRC)/$*.c
-+
-+wuf.o: $(SRC)/wuf.S
-+ $(CROSSCC) $(ASFLAGS) -o $*.o -c $(SRC)/$*.S
-+wof.o: $(SRC)/wof.S
-+ $(CROSSCC) $(ASFLAGS) -o $*.o -c $(SRC)/$*.S
-+
-+#genlab.o: genlab.c
-+# $(CC) -c $*.c
-+#
-+#genlab: genlab.o
-+# $(CC) -o genlab genlab.o
-+
-+clean:
-+ $(RM) $(OBJS)
-+ $(RM) $(PROLLEXE) proll.aout
-+
-+proll.aout: $(PROLLEXE)
-+ $(ELFTOAOUT) -o proll.aout $(PROLLEXE)
-diff -ruN proll_18.orig/qemu/openprom.c proll-patch4/qemu/openprom.c
---- proll_18.orig/qemu/openprom.c 1970-01-01 00:00:00.000000000 +0000
-+++ proll-patch4/qemu/openprom.c 2004-11-23 19:14:05.000000000 +0000
-@@ -0,0 +1,596 @@
-+/*
-+ * PROM interface support
-+ * Copyright 1996 The Australian National University.
-+ * Copyright 1996 Fujitsu Laboratories Limited
-+ * Copyright 1999 Pete A. Zaitcev
-+ * This software may be distributed under the terms of the Gnu
-+ * Public License version 2 or later
-+ */
-+
-+#include <openprom.h>
-+#include <general.h>
-+#include <romlib.h>
-+#include <system.h>
-+#include <vconsole.h>
-+#include "phys_jj.h"
-+
-+struct property {
-+ const char *name;
-+ const char *value;
-+ const int length;
-+};
-+
-+struct node {
-+ const struct property *properties;
-+ /* short */ const int sibling;
-+ /* short */ const int child;
-+};
-+
-+static int obp_nextnode(int node);
-+static int obp_child(int node);
-+static int obp_proplen(int node, char *name);
-+static int obp_getprop(int node, char *name, char *val);
-+static int obp_setprop(int node, char *name, char *val, int len);
-+static const char *obp_nextprop(int node, char *name);
-+
-+static char obp_idprom[IDPROM_SIZE];
-+static const struct property null_properties = { NULL, NULL, -1 };
-+static const int prop_true = -1;
-+
-+static const struct property propv_root[] = {
-+ {"name", "SUNW,JavaStation-1", sizeof("SUNW,JavaStation-1") },
-+ {"idprom", obp_idprom, IDPROM_SIZE},
-+ {"banner-name", "JavaStation", sizeof("JavaStation")},
-+ {"compatible", "sun4m", 6},
-+ {NULL, NULL, -1}
-+};
-+
-+static const int prop_iommu_reg[] = {
-+ 0x0, 0x10000000, 0x00000300,
-+};
-+static const struct property propv_iommu[] = {
-+ {"name", "iommu", sizeof("iommu")},
-+ {"reg", (char*)&prop_iommu_reg[0], sizeof(prop_iommu_reg) },
-+ {NULL, NULL, -1}
-+};
-+
-+static const int prop_sbus_ranges[] = {
-+ 0x0, 0x0, 0x0, 0x30000000, 0x10000000,
-+ 0x1, 0x0, 0x0, 0x40000000, 0x10000000,
-+ 0x2, 0x0, 0x0, 0x50000000, 0x10000000,
-+ 0x3, 0x0, 0x0, 0x60000000, 0x10000000,
-+ 0x4, 0x0, 0x0, 0x70000000, 0x10000000,
-+};
-+static const struct property propv_sbus[] = {
-+ {"name", "sbus", 5},
-+ {"ranges", (char*)&prop_sbus_ranges[0], sizeof(prop_sbus_ranges)},
-+ {NULL, NULL, -1}
-+};
-+
-+static const int prop_tcx_regs[] = {
-+ 0x2, 0x00800000, 0x00100000,
-+ 0x2, 0x02000000, 0x00000001,
-+ 0x2, 0x04000000, 0x00800000,
-+ 0x2, 0x06000000, 0x00800000,
-+ 0x2, 0x0a000000, 0x00000001,
-+ 0x2, 0x0c000000, 0x00000001,
-+ 0x2, 0x0e000000, 0x00000001,
-+ 0x2, 0x00700000, 0x00001000,
-+ 0x2, 0x00200000, 0x00000004,
-+ 0x2, 0x00300000, 0x0000081c,
-+ 0x2, 0x00000000, 0x00010000,
-+ 0x2, 0x00240000, 0x00000004,
-+ 0x2, 0x00280000, 0x00000001,
-+};
++static const int prop_tcx_regs[] = {
++ 0x2, 0x00800000, 0x00100000,
++ 0x2, 0x02000000, 0x00000001,
++ 0x2, 0x04000000, 0x00800000,
++ 0x2, 0x06000000, 0x00800000,
++ 0x2, 0x0a000000, 0x00000001,
++ 0x2, 0x0c000000, 0x00000001,
++ 0x2, 0x0e000000, 0x00000001,
++ 0x2, 0x00700000, 0x00001000,
++ 0x2, 0x00200000, 0x00000004,
++ 0x2, 0x00300000, 0x0000081c,
++ 0x2, 0x00000000, 0x00010000,
++ 0x2, 0x00240000, 0x00000004,
++ 0x2, 0x00280000, 0x00000001,
++};
+
+#if 1 /* Zaitcev */
+static const int pixfreq = 0x03dfd240;
+static const struct property propv_obio[] = {
+ {"name", "obio", 5 },
+ {"ranges", (char*)&prop_obio_ranges[0], sizeof(prop_obio_ranges) },
++ {"device_type", "hierarchical", sizeof("hierarchical") },
+ {NULL, NULL, -1}
+};
+
+ {NULL, NULL, -1}
+};
+
-+static const int prop_zs_intr[] = { 0x26, 0x0 };
++static const int prop_zs_intr[] = { 12, 0x0 };
+static const int prop_zs_reg[] = {
-+ 0x4, 0x00000000, 0x0000000f,
++ 0x0, 0x00000000, 0x00000008,
+};
-+static const int prop_zs_slave[] = { 0x1 };
++static const int prop_zs_addr = { 0x70000000 };
++static const int prop_zs_slave[] = { 1 };
+static const struct property propv_obio_zs[] = {
+ {"name", "zs", sizeof("zs")},
+ {"reg", (char*)&prop_zs_reg[0], sizeof(prop_zs_reg) },
-+ {"reg", (char*)&prop_zs_slave[0], sizeof(prop_zs_slave) },
++ {"slave", (char*)&prop_zs_slave[0], sizeof(prop_zs_slave) },
+ {"device_type", "serial", sizeof("serial") },
++ {"intr", (char*)&prop_zs_intr[0], sizeof(prop_zs_intr) },
++ // {"address", (char*)&prop_zs_addr, sizeof(prop_zs_addr) },
+ {NULL, NULL, -1}
+};
+
-+static const int prop_zs1_intr[] = { 0x26, 0x0 };
++static const int prop_zs1_intr[] = { 12, 0x0 };
+static const int prop_zs1_reg[] = {
-+ 0x4, 0x00100000, 0x0000000f,
++ 0x0, 0x00100000, 0x00000008,
+};
-+static const int prop_zs1_slave[] = { 0x0 };
++static const int prop_zs1_addr = { 0x70100000 };
++static const int prop_zs1_slave[] = { 0 };
+static const struct property propv_obio_zs1[] = {
+ {"name", "zs", sizeof("zs")},
+ {"reg", (char*)&prop_zs1_reg[0], sizeof(prop_zs1_reg) },
-+ {"reg", (char*)&prop_zs1_slave[0], sizeof(prop_zs1_slave) },
++ {"slave", (char*)&prop_zs1_slave[0], sizeof(prop_zs1_slave) },
+ {"device_type", "serial", sizeof("serial") },
++ {"intr", (char*)&prop_zs1_intr[0], sizeof(prop_zs1_intr) },
++ // {"address", (char*)&prop_zs1_addr, sizeof(prop_zs1_addr) },
+ {NULL, NULL, -1}
+};
+
+ {NULL, NULL, -1}
+};
+
++static const int prop_espdma_reg[] = {
++ 0x4, 0x08400000, 0x00000010,
++};
++// Disabled, not implemented yet
++static const struct property propv_sbus_espdma[] = {
++ {"name", "xxxespdma", sizeof("xxxespdma")},
++ {"reg", (char*)&prop_espdma_reg[0], sizeof(prop_espdma_reg) },
++ {NULL, NULL, -1}
++};
++
++static const int prop_esp_reg[] = {
++ 0x4, 0x08800000, 0x00000040,
++};
++static const int prop_esp_intr[] = { 0x24, 0x0 };
++static const struct property propv_sbus_espdma_esp[] = {
++ {"name", "esp", sizeof("esp")},
++ {"reg", (char*)&prop_esp_reg[0], sizeof(prop_esp_reg) },
++ {"intr", (char*)&prop_esp_intr[0], sizeof(prop_esp_intr) },
++ {NULL, NULL, -1}
++};
++
++static const int prop_bpp_reg[] = {
++ 0x4, 0x0c800000, 0x0000001c,
++};
++static const int prop_bpp_intr[] = { 0x33, 0x0 };
++static const struct property propv_sbus_bpp[] = {
++ {"name", "SUNW,bpp", sizeof("SUNW,bpp")},
++ {"reg", (char*)&prop_bpp_reg[0], sizeof(prop_bpp_reg) },
++ {"intr", (char*)&prop_bpp_intr[0], sizeof(prop_bpp_intr) },
++ {NULL, NULL, -1}
++};
++
++static const int prop_fd_intr[] = { 0x2b, 0x0 };
++static const int prop_fd_reg[] = {
++ 0x0, 0x00400000, 0x0000000f,
++};
++static const struct property propv_obio_fd[] = {
++ {"name", "SUNW,fdtwo", sizeof("SUNW,fdtwo")},
++ {"reg", (char*)&prop_fd_reg[0], sizeof(prop_fd_reg) },
++ {"device_type", "block", sizeof("block") },
++ {"intr", (char*)&prop_fd_intr[0], sizeof(prop_fd_intr) },
++ {NULL, NULL, -1}
++};
++
++static const int prop_pw_intr[] = { 0x22, 0x0 };
++static const int prop_pw_reg[] = {
++ 0x0, 0x00910000, 0x00000001,
++};
++static const struct property propv_obio_pw[] = {
++ {"name", "power", sizeof("power")},
++ {"reg", (char*)&prop_pw_reg[0], sizeof(prop_pw_reg) },
++ {"intr", (char*)&prop_pw_intr[0], sizeof(prop_pw_intr) },
++ {NULL, NULL, -1}
++};
++
++static const int prop_cf_reg[] = {
++ 0x0, 0x00800000, 0x00000001,
++};
++static const struct property propv_obio_cf[] = {
++ {"name", "slavioconfig", sizeof("slavioconfig")},
++ {"reg", (char*)&prop_cf_reg[0], sizeof(prop_cf_reg) },
++ {NULL, NULL, -1}
++};
++
+static const struct node nodes[] = {
+ { &null_properties, 1, 0 }, /* 0 = big brother of root */
+ { propv_root, 0, 2 }, /* 1 "/" */
-+ { propv_iommu, 8, 3 }, /* 2 "/iommu" */
++ { propv_iommu, 11, 3 }, /* 2 "/iommu" */
+ { propv_sbus, 0, 4 }, /* 3 "/iommu/sbus" */
+ { propv_sbus_tcx, 5, 0 }, /* 4 "/iommu/sbus/SUNW,tcx" */
+ { propv_sbus_ledma, 7, 6 }, /* 5 "/iommu/sbus/ledma" */
+ { propv_sbus_ledma_le, 0, 0 }, /* 6 "/iommu/sbus/ledma/le" */
-+ { propv_sbus_cs4231, 0, 0 }, /* 7 "/iommu/sbus/SUNW,CS4231 */
-+ { propv_cpu, 9, 0 }, /* 8 "/STP1012PGA" */
-+ { propv_obio, 0, 10 }, /* 9 "/obio" */
-+ { propv_obio_int, 11, 0 }, /* 10 "/obio/interrupt" */
-+ { propv_obio_cnt, 12, 0 }, /* 11 "/obio/counter" */
-+ { propv_obio_eep, 13, 0 }, /* 12 "/obio/eeprom" */
++ { propv_sbus_cs4231, 8, 0 }, /* 7 "/iommu/sbus/SUNW,CS4231 */
++ { propv_sbus_bpp, 9, 0 }, /* 8 "/iommu/sbus/SUNW,bpp */
++ { propv_sbus_espdma, 0, 10 }, /* 9 "/iommu/sbus/espdma" */
++ { propv_sbus_espdma_esp, 0, 0 }, /* 10 "/iommu/sbus/espdma/esp" */
++ { propv_cpu, 12, 0 }, /* 11 "/STP1012PGA" */
++ { propv_obio, 0, 13 }, /* 12 "/obio" */
++ { propv_obio_int, 14, 0 }, /* 13 "/obio/interrupt" */
++ { propv_obio_cnt, 15, 0 }, /* 14 "/obio/counter" */
++ { propv_obio_eep, 16, 0 }, /* 15 "/obio/eeprom" */
++ { propv_obio_auxio, 17, 0 }, /* 16 "/obio/auxio" */
++ { propv_obio_zs, 18, 0 }, /* 17 "/obio/zs@0,0" */
++ { propv_obio_zs1, 19, 0 }, /* 18 "/obio/zs@0,100000" */
++ { propv_obio_fd, 20, 0 }, /* 19 "/obio/SUNW,fdtwo" */
++ { propv_obio_pw, 21, 0 }, /* 20 "/obio/power" */
++ { propv_obio_cf, 0, 0 }, /* 21 "/obio/slavioconfig@0,800000" */
++#if 0
+ { propv_obio_su, 14, 0 }, /* 13 "/obio/su" */
-+ { propv_obio_auxio, 0, 0 }, /* 14 "/obio/auxio" */
-+ { propv_obio_zs, 0, 0 }, /* 14 "/obio/zs@0,0" */
-+ { propv_obio_zs1, 0, 0 }, /* 14 "/obio/zs@0,100000" */
++ { propv_cpu, 18, 0 }, /* 17 "/STP1012PGA" */
++ { propv_cpu, 19, 0 }, /* 18 "/STP1012PGA" */
++
++ { propv_cpu, 20, 0 }, /* 19 "/STP1012PGA" */
++ { propv_cpu, 21, 0 }, /* 20 "/STP1012PGA" */
++ { propv_cpu, 22, 0 }, /* 21 "/STP1012PGA" */
++ { propv_cpu, 23, 0 }, /* 22 "/STP1012PGA" */
++ { propv_cpu, 24, 0 }, /* 23 "/STP1012PGA" */
++ { propv_cpu, 25, 0 }, /* 24 "/STP1012PGA" */
++ { propv_cpu, 26, 0 }, /* 25 "/STP1012PGA" */
++ { propv_cpu, 27, 0 }, /* 26 "/STP1012PGA" */
++ { propv_cpu, 28, 0 }, /* 27 "/STP1012PGA" */
++ { propv_cpu, 29, 0 }, /* 28 "/STP1012PGA" */
++ { propv_cpu, 30, 0 }, /* 29 "/STP1012PGA" */
++#endif
+};
+
+static struct linux_mlist_v0 totphys[MAX_BANKS];
+ obp_nextprop /* char * (*no_nextprop)(int node, char *name); */
+};
+
-+static const char arg_nfsroot[] = "console=ttyS0 ip=bootp root=nfs";
-+
-+static const struct linux_arguments_v0 obp_arg = {
-+ { "le()", arg_nfsroot, NULL, NULL, NULL, NULL, NULL, NULL },
-+ { "" },
-+ { 'l', 'e' }, 0, 0, 0, NULL,
-+ NULL
-+};
++static struct linux_arguments_v0 obp_arg;
+static const struct linux_arguments_v0 * const obp_argp = &obp_arg;
+
-+static const void * const synch_hook = NULL;
-+#if 0
-+static const char obp_stdin = PROMDEV_KBD;
-+static const char obp_stdout = PROMDEV_SCREEN;
-+#else
-+static const char obp_stdin = PROMDEV_TTYA;
-+static const char obp_stdout = PROMDEV_TTYA;
-+#endif
++static void (*synch_hook)(void);
++static char obp_stdin, obp_stdout;
++
++static int obp_nbgetchar(void);
++static int obp_nbputchar(int ch);
++static void obp_reboot(char *);
++static void obp_abort(void);
++static void obp_halt(void);
++static int obp_devopen(char *str);
++static int obp_devclose(int dev_desc);
++static int obp_rdblkdev(int dev_desc, int num_blks, int blk_st, char *buf);
++
++static void doublewalk(unsigned ptab1, unsigned va)
++{
++unsigned int proc_tablewalk(int ctx, unsigned int va);
++unsigned int mem_tablewalk(unsigned int pa, unsigned int va);
++
++ proc_tablewalk(0, va);
++ if (ptab1 != 0) mem_tablewalk(ptab1, va);
++}
++
++static struct linux_romvec romvec0;
++
++void *
++init_openprom_qemu(int bankc, struct bank *bankv, unsigned hiphybas,
++ const char *cmdline, char boot_device, int nographic)
++{
++ int i;
++
++ /*
++ * Avoid data segment allocations
++ */
++ ptphys = totphys;
++ ptmap = totmap;
++ ptavail = totavail;
++ /*
++ * Form memory descriptors.
++ */
++ for (i = 0; i < bankc; i++) {
++ totphys[i].theres_more = &totphys[i+1];
++ totphys[i].start_adr = (char*) bankv[i].start;
++ totphys[i].num_bytes = bankv[i].length;
++ }
++ totphys[i-1].theres_more = 0;
++
++ /*
++ * XXX Merged in normal PROM when full banks touch.
++ */
++ for (i = 0; i < bankc; i++) {
++ unsigned bankbase = bankv[i].start;
++ unsigned banksize = bankv[i].length;
++ if (hiphybas > bankbase &&
++ hiphybas < bankbase + banksize) {
++ banksize = hiphybas - bankbase;
++ }
++ totavail[i].theres_more = &totavail[i+1];
++ totavail[i].start_adr = (char*) bankbase;
++ totavail[i].num_bytes = banksize;
++ }
++ totavail[i-1].theres_more = 0;
++
++ totmap[0].theres_more = 0;
++ totmap[0].start_adr = (char*) PROLBASE;
++ totmap[0].num_bytes = PROLSIZE;
++
++ /*
++ * idprom
++ */
++ bcopy(idprom, obp_idprom, IDPROM_SIZE);
++
++ // Linux wants a R/W romvec table
++ romvec0.pv_magic_cookie = LINUX_OPPROM_MAGIC;
++ romvec0.pv_plugin_revision = 77;
++ romvec0.pv_printrev = 0x10203;
++ romvec0.pv_v0mem.v0_totphys = &ptphys;
++ romvec0.pv_v0mem.v0_prommap = &ptmap;
++ romvec0.pv_v0mem.v0_available = &ptavail;
++ romvec0.pv_nodeops = &nodeops0;
++ romvec0.pv_bootstr = (void *)doublewalk;
++ romvec0.pv_v0devops.v0_devopen = &obp_devopen;
++ romvec0.pv_v0devops.v0_devclose = &obp_devclose;
++ romvec0.pv_v0devops.v0_rdblkdev = &obp_rdblkdev;
++ romvec0.pv_stdin = &obp_stdin;
++ romvec0.pv_stdout = &obp_stdout;
++ romvec0.pv_getchar = obp_nbgetchar;
++ romvec0.pv_putchar = (void (*)(int))obp_nbputchar;
++ romvec0.pv_nbgetchar = obp_nbgetchar;
++ romvec0.pv_nbputchar = obp_nbputchar;
++ romvec0.pv_reboot = obp_reboot;
++ romvec0.pv_abort = obp_abort;
++ romvec0.pv_halt = obp_halt;
++ romvec0.pv_synchook = &synch_hook;
++ romvec0.pv_v0bootargs = &obp_argp;
++ switch(boot_device) {
++ default:
++ case 'a':
++ obp_arg.argv[0] = "fd()";
++ break;
++ case 'c':
++ obp_arg.argv[0] = "sd()";
++ break;
++ case 'n':
++ obp_arg.argv[0] = "le()";
++ break;
++ }
++ obp_arg.argv[1] = cmdline;
++
++ if (nographic) {
++ obp_stdin = PROMDEV_TTYA;
++ obp_stdout = PROMDEV_TTYA;
++ } else {
++ obp_stdin = PROMDEV_KBD;
++ obp_stdout = PROMDEV_SCREEN;
++ }
++ return &romvec0;
++}
++
++static const struct property *find_property(int node,char *name)
++{
++ const struct property *prop = &nodes[node].properties[0];
++ while (prop && prop->name) {
++ if (bcmp(prop->name, name, 128) == 0) return prop;
++ prop++;
++ }
++ return NULL;
++}
++
++static int obp_nextnode(int node)
++{
++#ifdef DEBUG_OBP
++ printk("obp_nextnode(%d) = %d\n", node, nodes[node].sibling);
++#endif
++ return nodes[node].sibling;
++}
++
++static int obp_child(int node)
++{
++#ifdef DEBUG_OBP
++ printk("obp_child(%d) = %d\n", node, nodes[node].child);
++#endif
++ return nodes[node].child;
++}
++
++static int obp_proplen(int node, char *name)
++{
++ const struct property *prop = find_property(node,name);
++ if (prop) {
++#ifdef DEBUG_OBP
++ printk("obp_proplen(%d, %s) = %d\n", node, name, prop->length);
++#endif
++ return prop->length;
++ }
++#ifdef DEBUG_OBP
++ printk("obp_proplen(%d, %s) (no prop)\n", node, name);
++#endif
++ return -1;
++}
++
++static int obp_getprop(int node, char *name, char *value)
++{
++ const struct property *prop;
++
++ prop = find_property(node,name);
++ if (prop) {
++ memcpy(value,prop->value,prop->length);
++#ifdef DEBUG_OBP
++ printk("obp_getprop(%d, %s) = %s\n", node, name, value);
++#endif
++ return prop->length;
++ }
++#ifdef DEBUG_OBP
++ printk("obp_getprop(%d, %s): not found\n", node, name);
++#endif
++ return -1;
++}
++
++static int obp_setprop(int node, char *name, char *value, int len)
++{
++#ifdef DEBUG_OBP
++ printk("obp_setprop(%d, %s) = %s (%d)\n", node, name, value, len);
++#endif
++ return -1;
++}
++
++static const char *obp_nextprop(int node,char *name)
++{
++ const struct property *prop = find_property(node,name);
++ if (prop) {
++#ifdef DEBUG_OBP
++ printk("obp_nextprop(%d, %s) = %s\n", node, name, prop[1].name);
++#endif
++ return prop[1].name;
++ }
++#ifdef DEBUG_OBP
++ printk("obp_nextprop(%d, %s): not found\n", node, name);
++#endif
++ return NULL;
++}
++
++static int obp_nbgetchar(void) {
++ extern struct vconterm dp0;
++ return vcon_getch(&dp0);
++}
++
++static int obp_nbputchar(int ch) {
++ printk("%c", ch);
++ return 0;
++}
++
++static void obp_reboot(char *str) {
++ printk("rebooting (%s): not implemented, freezing\n", str);
++ for (;;) {}
++}
++
++static void obp_abort() {
++ printk("abort, freezing\n");
++ for (;;) {}
++}
++
++static void obp_halt() {
++ printk("halt, freezing\n");
++ for (;;) {}
++}
++
++static int obp_devopen(char *str) {
++#ifdef DEBUG_OBP
++ printk("open %s\n", str);
++#endif
++ return 0;
++}
++
++static int obp_devclose(int dev_desc) {
++#ifdef DEBUG_OBP
++ printk("close %d\n", dev_desc);
++#endif
++ return 0;
++}
++
++static int obp_rdblkdev(int dev_desc, int num_blks, int blk_st, char *buf) {
++#ifdef DEBUG_OBP
++ printk("rdblkdev: fd %d, num_blks %d, blk_st %d, buf 0x%x\n", dev_desc, num_blks, blk_st, buf);
++#endif
++ //buf[8] = 'L';
++ return num_blks;
++}
+diff -ruN proll_18.orig/qemu/system_qemu.c proll-patch7/qemu/system_qemu.c
+--- proll_18.orig/qemu/system_qemu.c 1970-01-01 00:00:00.000000000 +0000
++++ proll-patch7/qemu/system_qemu.c 2005-03-02 16:10:20.000000000 +0000
+@@ -0,0 +1,416 @@
++/**
++ ** Proll (PROM replacement)
++ ** system.c: shared miscallenea.
++ ** Copyright 1999 Pete Zaitcev
++ ** This code is licensed under GNU General Public License.
++ **/
++#include <stdarg.h>
++#include <asi.h>
++#include <crs.h>
++#ifndef NULL
++#define NULL ((void*)0)
++#endif
++
++#include "pgtsrmmu.h"
++
++#include "vconsole.h"
++#include <timer.h> /* Local copy of 2.2 style include */
++#include <general.h> /* __P() */
++#include <net.h> /* init_net() */
++#include <romlib.h> /* we are a provider for part of this. */
++#include <netpriv.h> /* myipaddr */
++#include <arpa.h>
++#include <system.h> /* our own prototypes */
++
++/*
++ * We export this.
++ */
++char idprom[IDPROM_SIZE];
++
++
++/*
++ * Create an I/O mapping to pa[size].
++ * Returns va of the mapping or 0 if unsuccessful.
++ */
++void *
++map_io(unsigned pa, int size)
++{
++ void *va;
++ unsigned int npages;
++ unsigned int off;
++ unsigned int mva;
++
++ off = pa & (PAGE_SIZE-1);
++ npages = (off + size + (PAGE_SIZE-1)) / PAGE_SIZE;
++ pa &= ~(PAGE_SIZE-1);
++
++ va = mem_alloc(&cio, npages*PAGE_SIZE, PAGE_SIZE);
++ if (va == 0) return va;
++
++ mva = (unsigned int) va;
++ /* printk("map_io: va 0x%x pa 0x%x off 0x%x npages %d\n", va, pa, off, npages); */ /* P3 */
++ while (npages-- != 0) {
++ map_page(pmem.pl1, mva, pa, 1, pmem.pbas);
++ mva += PAGE_SIZE;
++ pa += PAGE_SIZE;
++ }
++
++ return (void *)((unsigned int)va + off);
++}
++
++/*
++ * Tablewalk routine used for testing.
++ * Returns PTP/PTE.
++ */
++unsigned int
++proc_tablewalk(int ctx, unsigned int va)
++{
++ unsigned int pa1;
++
++ __asm__ __volatile__ ("lda [%1] %2, %0" :
++ "=r" (pa1) :
++ "r" (AC_M_CTPR), "i" (ASI_M_MMUREGS));
++ /* printk(" ctpr %x ctx %x\n", pa1, ctx); */ /* P3 */
++ pa1 <<= 4;
++ pa1 = ld_bypass(pa1 + (ctx << 2));
++ if ((pa1 & 0x03) == 0) goto invalid;
++ return mem_tablewalk((pa1 & 0xFFFFFFF0) << 4, va);
++
++invalid:
++ printk(" invalid %x\n", pa1);
++ return 0;
++}
++
++/*
++ * Walk the tables in memory, starting at physical address pa.
++ */
++unsigned int
++mem_tablewalk(unsigned int pa, unsigned int va)
++{
++ unsigned int pa1;
++
++ printk("pa %x va %x", pa, va);
++ pa1 = ld_bypass(pa + (((va&0xFF000000)>>24) << 2));
++ if ((pa1 & 0x03) == 0) goto invalid;
++ printk(" l1 %x", pa1);
++ pa1 <<= 4; pa1 &= 0xFFFFFF00;
++ pa1 = ld_bypass(pa1 + (((va&0x00FC0000)>>18) << 2));
++ if ((pa1 & 0x03) == 0) goto invalid;
++ printk(" l2 %x", pa1);
++ pa1 <<= 4; pa1 &= 0xFFFFFF00;
++ pa1 = ld_bypass(pa1 + (((va&0x0003F000)>>12) << 2));
++ if ((pa1 & 0x03) == 0) goto invalid;
++ printk(" l3 %x", pa1);
++ printk(" off %x\n", va&0x00000FFF);
++ return pa1;
++invalid:
++ printk(" invalid %x\n", pa1);
++ return 0;
++}
++
++/*
++ * Make CPU page tables.
++ * Returns pointer to context table.
++ * Here we ignore memory allocation errors which "should not happen"
++ * because we cannot print anything anyways if memory initialization fails.
++ */
++void makepages(struct phym *t, unsigned int highbase)
++{
++ unsigned int *ctp, *l1, pte;
++ int i;
++ unsigned int pa, va;
++
++ ctp = mem_zalloc(&cmem, NCTX_SWIFT*sizeof(int), NCTX_SWIFT*sizeof(int));
++ l1 = mem_zalloc(&cmem, 256*sizeof(int), 256*sizeof(int));
++
++ pte = SRMMU_ET_PTD | (((unsigned int)l1 - PROLBASE + highbase) >> 4);
++ for (i = 0; i < NCTX_SWIFT; i++) {
++ ctp[i] = pte;
++ }
++
++ pa = PROLBASE;
++ for (va = PROLBASE; va < PROLDATA; va += PAGE_SIZE) {
++ map_page(l1, va, pa, 0, highbase);
++ pa += PAGE_SIZE;
++ }
++ pa = highbase + PROLDATA - PROLBASE;
++ for (va = PROLDATA; va < PROLBASE + PROLSIZE; va += PAGE_SIZE) {
++ map_page(l1, va, pa, 0, highbase);
++ pa += PAGE_SIZE;
++ }
++
++ /* We need to start from LOADBASE, but kernel wants PAGE_SIZE. */
++ pa = 0;
++ for (va = 0; va < LOWMEMSZ; va += PAGE_SIZE) {
++ map_page(l1, va, pa, 0, highbase);
++ pa += PAGE_SIZE;
++ }
+
-+static int obp_nbgetchar(void);
-+static int obp_nbputchar(int ch);
-+static void obp_reboot(char *);
-+static void obp_abort(void);
-+static void obp_halt(void);
-+static int obp_devopen(char *str);
-+static int obp_devclose(int dev_desc);
-+static int obp_rdblkdev(int dev_desc, int num_blks, int blk_st, char *buf);
++ t->pctp = ctp;
++ t->pl1 = l1;
++ t->pbas = highbase;
++}
+
-+static void doublewalk(unsigned ptab1, unsigned va)
++/*
++ * Create a memory mapping from va to epa in page table pgd.
++ * highbase is used for v2p translation.
++ */
++int
++map_page(unsigned int *pgd, unsigned int va,
++ unsigned int epa, int type, unsigned int highbase)
+{
-+unsigned int proc_tablewalk(int ctx, unsigned int va);
-+unsigned int mem_tablewalk(unsigned int pa, unsigned int va);
-+
-+ proc_tablewalk(0, va);
-+ if (ptab1 != 0) mem_tablewalk(ptab1, va);
-+}
++ unsigned int pte;
++ unsigned int *p;
++ unsigned int pa;
++
++ pte = pgd[((va)>>SRMMU_PGDIR_SHIFT) & (SRMMU_PTRS_PER_PGD-1)];
++ if ((pte & SRMMU_ET_MASK) == SRMMU_ET_INVALID) {
++ p = mem_zalloc(&cmem, SRMMU_PTRS_PER_PMD*sizeof(int),
++ SRMMU_PTRS_PER_PMD*sizeof(int));
++ if (p == 0) goto drop;
++ pte = SRMMU_ET_PTD |
++ (((unsigned int)p - PROLBASE + highbase) >> 4);
++ pgd[((va)>>SRMMU_PGDIR_SHIFT) & (SRMMU_PTRS_PER_PGD-1)] = pte;
++ /* barrier() */
++ }
+
-+#ifdef ORIG
-+static const struct linux_romvec romvec0 = {
-+ LINUX_OPPROM_MAGIC, /* pv_magic_cookie */
-+ 0, /* pv_romvers - Format selector! */
-+ 77, /* pv_plugin_revision */
-+ 0x10203, /* pv_printrev */
-+ { /* pv_v0mem */
-+ &ptphys, /* v0_totphys */
-+ &ptmap, /* v0_prommap */
-+ &ptavail /* v0_available */
-+ },
-+ &nodeops0, /* struct linux_nodeops *pv_nodeops; */
-+ (void*)doublewalk, /* P3 */ /* char **pv_bootstr; */
-+ { /* struct linux_dev_v0_funcs pv_v0devops; */
-+ &obp_devopen, /* v0_devopen */
-+ &obp_devclose, /* v0_devclose */
-+ &obp_rdblkdev, /* v0_rdblkdev */
-+ NULL, /* v0_wrblkdev */
-+ NULL, /* v0_wrnetdev */
-+ NULL, /* v0_rdnetdev */
-+ NULL, /* v0_rdchardev */
-+ NULL, /* v0_wrchardev */
-+ NULL /* v0_seekdev */
-+ },
-+ &obp_stdin, /* char *pv_stdin */
-+ &obp_stdout, /* char *pv_stdout; */
-+ obp_nbgetchar, /* int (*pv_getchar)(void); */
-+ obp_nbputchar, /* void (*pv_putchar)(int ch); */
-+ obp_nbgetchar, /* int (*pv_nbgetchar)(void); */
-+ obp_nbputchar, /* int (*pv_nbputchar)(int ch); */
-+ NULL, /* void (*pv_putstr)(char *str, int len); */
-+ obp_reboot, /* void (*pv_reboot)(char *bootstr); */
-+ NULL, /* void (*pv_printf)(__const__ char *fmt, ...); */
-+ obp_abort, /* void (*pv_abort)(void); */
-+ NULL, /* __volatile__ int *pv_ticks; */
-+ obp_halt, /* void (*pv_halt)(void); */
-+ (void *)&synch_hook, /* void (**pv_synchook)(void); */
++ pa = ((pte & 0xFFFFFFF0) << 4);
++ pa += (((va)>>SRMMU_PMD_SHIFT & (SRMMU_PTRS_PER_PMD-1)) << 2);
++ pte = ld_bypass(pa);
++ if ((pte & SRMMU_ET_MASK) == SRMMU_ET_INVALID) {
++ p = mem_zalloc(&cmem, SRMMU_PTRS_PER_PTE*sizeof(int),
++ SRMMU_PTRS_PER_PTE*sizeof(int));
++ if (p == 0) goto drop;
++ pte = SRMMU_ET_PTD |
++ (((unsigned int)p - PROLBASE + highbase) >> 4);
++ st_bypass(pa, pte);
++ }
+
-+#if 0
-+ /* Evaluate a forth string, not different proto for V0 and V2->up. */
-+ union {
-+ void (*v0_eval)(int len, char *str);
-+ void (*v2_eval)(char *str);
-+ } pv_fortheval;
-+#endif
-+ { 0 }, /* pv_fortheval */
-+
-+ &obp_argp, /* struct linux_arguments_v0 **pv_v0bootargs; */
-+ NULL, /* pv_enaddr */
-+ { /* pv_v2bootargs */
-+ NULL, /* char **bootpath; */
-+ NULL, /* char **bootargs; */
-+ NULL, /* fd_stdin; */
-+ NULL, /* fd_stdout */
-+ },
-+ { /* pv_v2devops */
-+ NULL, /* v2_inst2pkg */
-+ NULL, /* v2_dumb_mem_alloc */
-+ NULL, /* v2_dumb_mem_free */
-+ NULL, /* v2_dumb_mmap */
-+ NULL, /* v2_dumb_munmap */
-+ NULL, /* v2_dev_open */
-+ NULL, /* v2_dev_close */
-+ NULL, /* v2_dev_read */
-+ NULL, /* v2_dev_write */
-+ NULL, /* v2_dev_seek */
-+ NULL, /* v2_wheee2 */
-+ NULL, /* v2_wheee3 */
-+ },
-+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* filler[15] */
-+ NULL, /* pv_setctxt */
-+ NULL, /* v3_cpustart */
-+ NULL, /* v3_cpustop */
-+ NULL, /* v3_cpuidle */
-+ NULL /* v3_cpuresume */
-+};
-+#endif
++ pa = ((pte & 0xFFFFFFF0) << 4);
++ pa += (((va)>>PAGE_SHIFT & (SRMMU_PTRS_PER_PTE-1)) << 2);
++
++ pte = SRMMU_ET_PTE | ((epa & PAGE_MASK) >> 4);
++ if (type) { /* I/O */
++ pte |= SRMMU_REF;
++ /* SRMMU cannot make Supervisor-only, but not exectutable */
++ pte |= SRMMU_PRIV;
++ } else { /* memory */
++ pte |= SRMMU_REF|SRMMU_CACHE;
++ pte |= SRMMU_PRIV; /* Supervisor only access */
++ }
++ st_bypass(pa, pte);
++ return 0;
+
-+static struct linux_romvec romvec0;
++drop:
++ return -1;
++}
+
-+void *
-+init_openprom(int bankc, struct bank *bankv, unsigned hiphybas)
++/*
++ * Switch page tables.
++ */
++void
++init_mmu_swift(unsigned int ctp_phy)
+{
-+ int i;
++ unsigned int addr;
+
+ /*
-+ * Avoid data segment allocations
-+ */
-+ ptphys = totphys;
-+ ptmap = totmap;
-+ ptavail = totavail;
-+ /*
-+ * Form memory descriptors.
++ * Flush cache
+ */
-+ for (i = 0; i < bankc; i++) {
-+ totphys[i].theres_more = &totphys[i+1];
-+ totphys[i].start_adr = (char*) bankv[i].start;
-+ totphys[i].num_bytes = bankv[i].length;
++ for (addr = 0; addr < 0x2000; addr += 0x10) {
++ __asm__ __volatile__ ("sta %%g0, [%0] %1\n\t" : :
++ "r" (addr), "i" (ASI_M_DATAC_TAG));
++ __asm__ __volatile__ ("sta %%g0, [%0] %1\n\t" : :
++ "r" (addr<<1), "i" (ASI_M_TXTC_TAG));
+ }
-+ totphys[i-1].theres_more = 0;
+
+ /*
-+ * XXX Merged in normal PROM when full banks touch.
++ * Switch ctx table
+ */
-+ for (i = 0; i < bankc; i++) {
-+ unsigned bankbase = bankv[i].start;
-+ unsigned banksize = bankv[i].length;
-+ if (hiphybas > bankbase &&
-+ hiphybas < bankbase + banksize) {
-+ banksize = hiphybas - bankbase;
-+ }
-+ totavail[i].theres_more = &totavail[i+1];
-+ totavail[i].start_adr = (char*) bankbase;
-+ totavail[i].num_bytes = banksize;
-+ }
-+ totavail[i-1].theres_more = 0;
-+
-+ totmap[0].theres_more = 0;
-+ totmap[0].start_adr = (char*) PROLBASE;
-+ totmap[0].num_bytes = PROLSIZE;
++ ctp_phy >>= 4;
++ /* printk("done flushing, switching to %x\n", ctp_phy); */
++ __asm__ __volatile__ ("sta %0, [%1] %2\n\t" : :
++ "r" (ctp_phy), "r" (AC_M_CTPR), "i" (ASI_M_MMUREGS));
+
+ /*
-+ * idprom
++ * Flush old page table references
+ */
-+ bcopy(idprom, obp_idprom, IDPROM_SIZE);
-+
-+ // Linux wants a R/W romvec table
-+ romvec0.pv_magic_cookie = LINUX_OPPROM_MAGIC;
-+ romvec0.pv_plugin_revision = 77;
-+ romvec0.pv_printrev = 0x10203;
-+ romvec0.pv_v0mem.v0_totphys = &ptphys;
-+ romvec0.pv_v0mem.v0_prommap = &ptmap;
-+ romvec0.pv_v0mem.v0_available = &ptavail;
-+ romvec0.pv_nodeops = &nodeops0;
-+ romvec0.pv_bootstr = (void *)doublewalk;
-+ romvec0.pv_stdin = &obp_stdin;
-+ romvec0.pv_stdout = &obp_stdout;
-+ romvec0.pv_getchar = obp_nbgetchar;
-+ romvec0.pv_putchar = obp_nbputchar;
-+ romvec0.pv_nbgetchar = obp_nbgetchar;
-+ romvec0.pv_nbputchar = obp_nbputchar;
-+ romvec0.pv_reboot = obp_reboot;
-+ romvec0.pv_abort = obp_abort;
-+ romvec0.pv_halt = obp_halt;
-+ romvec0.pv_synchook = &synch_hook;
-+ romvec0.pv_v0bootargs = &obp_argp;
-+ return &romvec0;
++ __asm__ __volatile__ ("sta %%g0, [%0] %1\n\t" : :
++ "r" (0x400), "i" (ASI_M_FLUSH_PROBE) : "memory");
+}
+
-+static const struct property *find_property(int node,char *name)
-+{
-+ const struct property *prop = &nodes[node].properties[0];
-+ while (prop && prop->name) {
-+ if (bcmp(prop->name, name, 128) == 0) return prop;
-+ prop++;
++/*
++ * add_timer, del_timer
++ * This should go into sched.c, but we have it split for different archs.
++ */
++struct timer_list_head {
++ struct timer_list *head, *tail;
++};
++
++static struct timer_list_head timers; /* Anonymous heap of timers */
++
++void add_timer(struct timer_list *timer) {
++ struct timer_list *p;
++ if (timer->prev != NULL || timer->next != NULL) {
++ printk("bug: kernel timer added twice at 0x%x.\n",
++ __builtin_return_address(0));
++ return;
+ }
-+ return NULL;
++ if ((p = timers.tail) != NULL) {
++ timer->prev = p;
++ p->next = timer;
++ timers.tail = timer;
++ } else {
++ timers.head = timer;
++ timers.tail = timer;
++ }
++ return;
+}
+
-+static int obp_nextnode(int node)
-+{
-+ return nodes[node].sibling;
++int del_timer(struct timer_list *timer) {
++ struct timer_list *p;
++ int ret;
++
++ if (timers.head == timer) timers.head = timer->next;
++ if (timers.tail == timer) timers.tail = timer->prev;
++ if ((p = timer->prev) != NULL) p->next = timer->next;
++ if ((p = timer->next) != NULL) p->prev = timer->prev;
++ ret = timer->next != 0 || timer->prev != 0;
++ timer->next = NULL;
++ timer->prev = NULL;
++ return ret;
+}
+
-+static int obp_child(int node)
-+{
-+ return nodes[node].child;
++void run_timers() {
++ struct timer_list *p;
++
++ p = timers.head;
++ while (p != NULL) {
++ if (p->expires < jiffies) {
++ del_timer(p); /* XXX make nonstatic member */
++ (*p->function)(p->data);
++ p = timers.head;
++ } else {
++ p = p->next;
++ }
++ }
+}
+
-+static int obp_proplen(int node, char *name)
++/*
++ * Allocate memory. This is reusable.
++ */
++void mem_init(struct mem *t, char *begin, char *limit)
+{
-+ const struct property *prop = find_property(node,name);
-+ if (prop) return prop->length;
-+ return -1;
++ t->start = begin;
++ t->uplim = limit;
++ t->curp = begin;
+}
+
-+static int obp_getprop(int node, char *name, char *value)
++void mem_fini(struct mem *t)
+{
-+ const struct property *prop;
-+
-+ prop = find_property(node,name);
-+ if (prop) {
-+ memcpy(value,prop->value,prop->length);
-+ //printk("obp_getprop '%s'= %s\n", name, value);
-+ return prop->length;
-+ }
-+ //printk("obp_getprop: not found\n");
-+ return -1;
++ t->curp = 0;
+}
+
-+static int obp_setprop(int node, char *name, char *value, int len)
++void *mem_alloc(struct mem *t, int size, int align)
+{
-+ return -1;
-+}
++ char *p;
+
-+static const char *obp_nextprop(int node,char *name)
-+{
-+ const struct property *prop = find_property(node,name);
-+ if (prop) return prop[1].name;
-+ return NULL;
++ p = (char *)((((unsigned int)t->curp) + (align-1)) & ~(align-1));
++ if (p >= t->uplim || p + size > t->uplim) return 0;
++ t->curp = p + size;
++ return p;
+}
+
-+#if 0
-+static unsigned char calc_idprom_cksum(struct idprom *idprom)
++void *mem_zalloc(struct mem *t, int size, int align)
+{
-+ unsigned char cksum, i, *ptr = (unsigned char *)idprom;
-+
-+ for (i = cksum = 0; i <= 0x0E; i++)
-+ cksum ^= *ptr++;
++ char *p;
+
-+ return cksum;
++ if ((p = mem_alloc(t, size, align)) != 0) bzero(p, size);
++ return p;
+}
-+#endif
+
-+static int obp_nbgetchar(void) {
-+ return -1;
++/*
++ * Library functions
++ */
++void bzero(void *s, int len) {
++ while (len--) *((char *)s)++ = 0;
+}
+
-+static int obp_nbputchar(int ch) {
-+ extern struct vconterm dp0;
-+ char buf = ch;
++void bcopy(const void *f, void *t, int len) {
++ while (len--) *((char *)t)++ = *((char *)f)++;
++}
+
-+ /* We do not use printk() in order to reduce stack depth. */
-+ vcon_write(&dp0, &buf, 1);
++/* Comparison is 7-bit */
++int bcmp(const void *s1, const void *s2, int len)
++{
++ int i;
++ char ch;
++
++ while (len--) {
++ ch = *((char *)s1)++;
++ if ((i = ch - *((char *)s2)++) != 0)
++ return i;
++ if (ch == 0)
++ return 0;
++ }
+ return 0;
+}
+
-+static void obp_reboot(char *str) {
-+ printk("rebooting (%s): not implemented, freezing\n", str);
-+ for (;;) {}
++int strlen(const char *s) {
++ const char *p;
++ for (p = s; *p != 0; p++) { }
++ return p - s;
+}
+
-+static void obp_abort() {
-+ printk("abort, freezing\n");
-+ for (;;) {}
-+}
++extern void *printk_fn;
+
-+static void obp_halt() {
-+ printk("halt, freezing\n");
-+ for (;;) {}
++void printk(char *fmt, ...)
++{
++ struct prf_fp {
++ void *xfp;
++ void (*write)(void *, char *, int);
++ } prfa;
++ extern void prf(struct prf_fp *, char *fmt, va_list adx);
++ va_list x1;
++
++ va_start(x1, fmt);
++ prfa.xfp = &dp0;
++ prfa.write = printk_fn;
++ prf(&prfa, fmt, x1);
++ va_end(x1);
+}
+
-+static int obp_devopen(char *str) {
-+ //printk("open %s\n", str);
-+ return 0;
++void fatal()
++{
++ printk("fatal.");
++loop: goto loop;
+}
+
-+static int obp_devclose(int dev_desc) {
-+ //printk("close %d\n", dev_desc);
-+ return 0;
++/*
++ * Get the highest bit number from the mask.
++ */
++int highc(int mask, int size)
++{
++ int m1;
++
++ m1 = 1 << size;
++ while (size != 0) {
++ size--;
++ m1 >>= 1;
++ if (m1 & mask) break;
++ }
++ return size;
+}
+
-+static int obp_rdblkdev(int dev_desc, int num_blks, int blk_st, char *buf) {
-+ //printk("rdblkdev: fd %d, num_blks %d, blk_st %d, buf 0x%x\n", dev_desc, num_blks, blk_st, buf);
-+ //buf[8] = 'L';
-+ return num_blks;
++/*
++ */
++unsigned int ld_bp_swap(unsigned int ptr) {
++ unsigned int n;
++ n = ld_bypass(ptr);
++ n = (n>>24 & 0xFF) | (n>>8 & 0xFF00) | ((n&0xFF00) << 8) | (n<<24);
++ return n;
+}
-diff -ruN proll_18.orig/src/arp.c proll-patch4/src/arp.c
++
++void st_bp_swap(unsigned int ptr, unsigned int n) {
++ n = (n>>24 & 0xFF) | (n>>8 & 0xFF00) | ((n&0xFF00) << 8) | (n<<24);
++ st_bypass(ptr, n);
++};
+diff -ruN proll_18.orig/src/arp.c proll-patch7/src/arp.c
--- proll_18.orig/src/arp.c 2001-12-24 05:12:31.000000000 +0000
-+++ proll-patch4/src/arp.c 2004-11-13 15:50:49.000000000 +0000
++++ proll-patch7/src/arp.c 2004-11-13 15:50:49.000000000 +0000
@@ -45,7 +45,7 @@
#endif
static struct arp_cache arp_list[ARPNUM]; /* ARP address cache */
+ def_gw = IP_ANY;
return(TRUE);
}
-diff -ruN proll_18.orig/src/arp.h proll-patch4/src/arp.h
+diff -ruN proll_18.orig/src/arp.h proll-patch7/src/arp.h
--- proll_18.orig/src/arp.h 1999-03-18 03:39:43.000000000 +0000
-+++ proll-patch4/src/arp.h 2004-11-13 15:50:49.000000000 +0000
++++ proll-patch7/src/arp.h 2004-11-13 15:50:49.000000000 +0000
@@ -104,7 +104,7 @@
extern int init_arp __P((void));
/* Add a new antry to the ARP cache */
extern void addcache __P((unsigned char *ha, t_ipaddr ip));
-diff -ruN proll_18.orig/src/hconsole.c proll-patch4/src/hconsole.c
+diff -ruN proll_18.orig/src/hconsole.c proll-patch7/src/hconsole.c
--- proll_18.orig/src/hconsole.c 2002-07-23 05:52:48.000000000 +0000
-+++ proll-patch4/src/hconsole.c 2004-11-13 15:50:49.000000000 +0000
-@@ -42,7 +42,11 @@
++++ proll-patch7/src/hconsole.c 2005-03-02 17:03:09.000000000 +0000
+@@ -29,6 +29,10 @@
+ struct raster r_master; /* For a case of resize, whole fb */
+ struct raster r_0; /* malloc() erzatz */
+
++#ifdef QEMU
++extern unsigned int q_height, q_width;
++#endif
++
+ int hcon_init(struct hconsole *t, unsigned int a0)
+ {
+ struct raster *q, *r;
+@@ -42,7 +46,11 @@
* No probing sequence or argument passing, hardcode everything. XXX
*/
raster8_cons_a(q, 768, 1024, (char *)a0);
-+#if 1
++#ifndef QEMU
raster_cons_2(r, q, 768-(24*11)-1, 1024-(8*80)-1, (24*11), (8*80));
+#else
-+ raster_cons_2(r, q, 0, 0, 768, 1024);
++ raster_cons_2(r, q, 0, 0, q_height, q_width);
+#endif
t->r_ = r;
t->r0_ = q;
t->f_ = &f_master;
-diff -ruN proll_18.orig/src/lat7_2.bm proll-patch4/src/lat7_2.bm
+diff -ruN proll_18.orig/src/lat7_2.bm proll-patch7/src/lat7_2.bm
--- proll_18.orig/src/lat7_2.bm 1999-02-27 05:48:54.000000000 +0000
-+++ proll-patch4/src/lat7_2.bm 2004-11-13 15:50:49.000000000 +0000
++++ proll-patch7/src/lat7_2.bm 2004-11-13 15:50:49.000000000 +0000
@@ -1,6 +1,6 @@
#define lat7_2_width 128
#define lat7_2_height 88
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x12, 0x1e, 0x0c, 0x02, 0x70, 0x18,
0x22, 0x22, 0x18, 0x00, 0x00, 0x18, 0x18, 0xff, 0x18, 0x00, 0x12, 0x02,
-diff -ruN proll_18.orig/src/lat7_2_swapped.bm proll-patch4/src/lat7_2_swapped.bm
+diff -ruN proll_18.orig/src/lat7_2_swapped.bm proll-patch7/src/lat7_2_swapped.bm
--- proll_18.orig/src/lat7_2_swapped.bm 1970-01-01 00:00:00.000000000 +0000
-+++ proll-patch4/src/lat7_2_swapped.bm 2004-11-13 15:50:49.000000000 +0000
++++ proll-patch7/src/lat7_2_swapped.bm 2004-11-13 15:50:49.000000000 +0000
@@ -0,0 +1,121 @@
+#define lat7_2_width 128
+#define lat7_2_height 88
+ 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x42, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00};
-diff -ruN proll_18.orig/src/le.c proll-patch4/src/le.c
+diff -ruN proll_18.orig/src/le.c proll-patch7/src/le.c
--- proll_18.orig/src/le.c 2002-07-23 05:52:49.000000000 +0000
-+++ proll-patch4/src/le.c 2004-11-13 15:50:49.000000000 +0000
++++ proll-patch7/src/le.c 2004-11-13 15:50:49.000000000 +0000
@@ -185,8 +185,6 @@
unsigned short rap; /* register address port */
};
/* The Lance uses 24 bit addresses */
/* On the Sun4c the DVMA will provide the remaining bytes for us */
/* On the Sun4m we have to instruct the ledma to provide them */
-diff -ruN proll_18.orig/src/netinit.c proll-patch4/src/netinit.c
+diff -ruN proll_18.orig/src/netinit.c proll-patch7/src/netinit.c
--- proll_18.orig/src/netinit.c 2002-09-13 21:53:33.000000000 +0000
-+++ proll-patch4/src/netinit.c 2004-11-13 15:50:49.000000000 +0000
++++ proll-patch7/src/netinit.c 2004-11-13 15:50:49.000000000 +0000
@@ -49,13 +49,20 @@
unsigned char myhwaddr[ETH_ALEN]; /* my own hardware addr */
t_ipaddr myipaddr; /* my own IP address */
fatal();
}
}
-diff -ruN proll_18.orig/src/netpriv.h proll-patch4/src/netpriv.h
+diff -ruN proll_18.orig/src/netpriv.h proll-patch7/src/netpriv.h
--- proll_18.orig/src/netpriv.h 1999-04-27 05:39:37.000000000 +0000
-+++ proll-patch4/src/netpriv.h 2004-11-13 15:50:49.000000000 +0000
++++ proll-patch7/src/netpriv.h 2004-11-13 15:50:49.000000000 +0000
@@ -130,10 +130,9 @@
*
*/
/* Empty read buffer */
extern void empty_buf __P((void));
-diff -ruN proll_18.orig/src/openprom.h proll-patch4/src/openprom.h
+diff -ruN proll_18.orig/src/openprom.h proll-patch7/src/openprom.h
--- proll_18.orig/src/openprom.h 2002-07-14 02:26:30.000000000 +0000
-+++ proll-patch4/src/openprom.h 2004-11-13 15:50:49.000000000 +0000
++++ proll-patch7/src/openprom.h 2004-11-13 15:50:49.000000000 +0000
@@ -54,20 +54,20 @@
};
};
/* More fun PROM structures for device probing. */
-diff -ruN proll_18.orig/src/packet.c proll-patch4/src/packet.c
+diff -ruN proll_18.orig/src/packet.c proll-patch7/src/packet.c
--- proll_18.orig/src/packet.c 2000-02-11 04:56:45.000000000 +0000
-+++ proll-patch4/src/packet.c 2004-11-13 15:50:49.000000000 +0000
++++ proll-patch7/src/packet.c 2004-11-13 15:50:49.000000000 +0000
@@ -41,7 +41,7 @@
int aligner;
} wbuf;
{
struct sk_buff *skb;
unsigned char *s;
-diff -ruN proll_18.orig/src/printf.c proll-patch4/src/printf.c
+diff -ruN proll_18.orig/src/printf.c proll-patch7/src/printf.c
--- proll_18.orig/src/printf.c 1999-03-19 07:03:59.000000000 +0000
-+++ proll-patch4/src/printf.c 2004-11-13 15:50:49.000000000 +0000
++++ proll-patch7/src/printf.c 2004-11-13 15:50:49.000000000 +0000
@@ -19,7 +19,7 @@
static void printn(struct prf_fp *, unsigned long, unsigned int);
static void putchar(char, struct prf_fp *);
putchar(c,filog);
} else if (c == 'l' || c == 'O') {
printn(filog, (long)va_arg(adx,long), c=='l'?10:8);
-diff -ruN proll_18.orig/src/rconsole.c proll-patch4/src/rconsole.c
+diff -ruN proll_18.orig/src/rconsole.c proll-patch7/src/rconsole.c
--- proll_18.orig/src/rconsole.c 1999-01-16 07:16:55.000000000 +0000
-+++ proll-patch4/src/rconsole.c 2004-11-13 15:50:49.000000000 +0000
++++ proll-patch7/src/rconsole.c 2004-11-13 15:50:49.000000000 +0000
@@ -28,12 +28,18 @@
* move to California. Only plain lat7 survived.
* I recreated lat7-1 changes in lat7-2. --zaitcev
p->nchars_ = LAT7_NCHARS;
p->width_ = LAT7_WIDTH;
p->height_ = LAT7_HEIGHT;
-diff -ruN proll_18.orig/src/rconsole.h proll-patch4/src/rconsole.h
+diff -ruN proll_18.orig/src/rconsole.h proll-patch7/src/rconsole.h
--- proll_18.orig/src/rconsole.h 1999-01-16 05:00:59.000000000 +0000
-+++ proll-patch4/src/rconsole.h 2004-11-13 15:50:49.000000000 +0000
++++ proll-patch7/src/rconsole.h 2004-11-13 15:50:49.000000000 +0000
@@ -13,10 +13,10 @@
*/
int nchars_; /* 128 for ASCII ... 65536 for Unicode */
int width_; /* [Pixels]. Maximum size is 16. */
int height_; /* [Pixels == scan lines]. */
-diff -ruN proll_18.orig/src/romlib.h proll-patch4/src/romlib.h
+diff -ruN proll_18.orig/src/romlib.h proll-patch7/src/romlib.h
--- proll_18.orig/src/romlib.h 1999-04-20 04:26:45.000000000 +0000
-+++ proll-patch4/src/romlib.h 2004-11-13 15:50:49.000000000 +0000
++++ proll-patch7/src/romlib.h 2004-11-13 15:50:49.000000000 +0000
@@ -73,12 +73,12 @@
#define memcpy(dst, src, len) bcopy(src, dst, len)
#define memcmp(x1, x2, len) bcmp(x1, x2, len)
/*
-diff -ruN proll_18.orig/src/sched_4m.c proll-patch4/src/sched_4m.c
+diff -ruN proll_18.orig/src/sched_4m.c proll-patch7/src/sched_4m.c
--- proll_18.orig/src/sched_4m.c 1999-04-27 05:48:51.000000000 +0000
-+++ proll-patch4/src/sched_4m.c 2004-11-13 15:50:49.000000000 +0000
++++ proll-patch7/src/sched_4m.c 2004-11-13 15:50:49.000000000 +0000
@@ -108,7 +108,7 @@
static int set_bolt; /* Tick counter limit */
static struct handsc hndv[16];
0, 0, 0, 0, 0, 0, SUN4M_INT_ETHERNET, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
-diff -ruN proll_18.orig/src/swap.c proll-patch4/src/swap.c
+diff -ruN proll_18.orig/src/swap.c proll-patch7/src/swap.c
--- proll_18.orig/src/swap.c 1970-01-01 00:00:00.000000000 +0000
-+++ proll-patch4/src/swap.c 2004-11-13 15:50:49.000000000 +0000
++++ proll-patch7/src/swap.c 2004-11-13 15:50:49.000000000 +0000
@@ -0,0 +1,21 @@
+// Convert the lat7 font so that no conversion is needed at runtime.
+#define ORIG
+ }
+ printf("\n");
+}
-diff -ruN proll_18.orig/src/system.c proll-patch4/src/system.c
+diff -ruN proll_18.orig/src/system.c proll-patch7/src/system.c
--- proll_18.orig/src/system.c 2002-07-23 05:52:49.000000000 +0000
-+++ proll-patch4/src/system.c 2004-11-13 15:50:49.000000000 +0000
++++ proll-patch7/src/system.c 2004-11-13 15:50:49.000000000 +0000
@@ -298,8 +298,8 @@
}
void fatal()
{
printk("fatal.");
-diff -ruN proll_18.orig/src/system.h proll-patch4/src/system.h
+diff -ruN proll_18.orig/src/system.h proll-patch7/src/system.h
--- proll_18.orig/src/system.h 2002-09-13 21:53:32.000000000 +0000
-+++ proll-patch4/src/system.h 2004-11-13 15:50:49.000000000 +0000
++++ proll-patch7/src/system.h 2004-11-13 15:50:49.000000000 +0000
@@ -16,7 +16,7 @@
#define IOMAPSIZE (1*1024*1024) /* 1 Meg maximum: we do not map framebuffer. */
#define NCTX_SWIFT 0x100
#ifndef __ASSEMBLY__
struct bank {
-diff -ruN proll_18.orig/src/udp.c proll-patch4/src/udp.c
+diff -ruN proll_18.orig/src/udp.c proll-patch7/src/udp.c
--- proll_18.orig/src/udp.c 2001-12-24 05:12:53.000000000 +0000
-+++ proll-patch4/src/udp.c 2004-11-13 15:50:49.000000000 +0000
++++ proll-patch7/src/udp.c 2004-11-13 15:50:49.000000000 +0000
@@ -81,7 +81,7 @@
int source;
int dest;
/* Register IP packet type and set write buffer pointer */
if ((writebuf = reg_type(htons(ETH_P_IP), ip_recv)) == NULL)
return(FALSE);
+diff -ruN proll_18.orig/src/vcons_zs.c proll-patch7/src/vcons_zs.c
+--- proll_18.orig/src/vcons_zs.c 1970-01-01 00:00:00.000000000 +0000
++++ proll-patch7/src/vcons_zs.c 2005-03-02 12:07:41.000000000 +0000
+@@ -0,0 +1,68 @@
++/**
++ ** Console over 'zs' (Zilog serial port)
++ ** Copyright 1999 Pete Zaitcev
++ ** This code is licensed under GNU General Public License.
++ **/
++
++#include "vconsole.h"
++#include <system.h>
++
++#define ZS_DATA 0x02
++
++int vcon_zs_init(struct vconterm *t, unsigned int a0)
++{
++
++ t->impl = (void *) a0;
++
++ t->vc_x = 0; t->vc_y = 0;
++ t->backp = 0; t->backc = 0;
++
++ stb_bypass(a0, 3); // reg 3
++ stb_bypass(a0, 1); // enable rx
++
++ stb_bypass(a0, 5); // reg 5
++ stb_bypass(a0, 8); // enable tx
++
++ return 0;
++}
++
++int vcon_zs_putch(struct vconterm *t, char c)
++{
++ unsigned zs_ptr = (unsigned) t->impl;
++
++ //while ((ldb_bypass(zs_ptr + ZS_LSR) & 0x60) != 0x60) { }
++ stb_bypass(zs_ptr + ZS_DATA, c);
++ return 0;
++}
++
++int vcon_zs_write(struct vconterm *t, char *data, int leng)
++{
++ while (leng != 0) {
++ leng--;
++ vcon_zs_putch(t, *data++);
++ }
++ return leng;
++}
++
++int vcon_zs_read(struct vconterm *t, char *data, int leng)
++{
++ unsigned zs_ptr = (unsigned) t->impl;
++
++ while ((ldb_bypass(zs_ptr) & 1) != 1) { }
++ *data = ldb_bypass(zs_ptr + ZS_DATA);
++ return 0;
++}
++
++int vcon_zs_getch(struct vconterm *t)
++{
++ unsigned zs_ptr = (unsigned) t->impl;
++
++ while ((ldb_bypass(zs_ptr) & 1) != 1) { }
++ return ldb_bypass(zs_ptr + ZS_DATA);
++}
++
++void vcon_zs_fini(struct vconterm *t)
++{
++ /* violent crash in the end */
++ ;
++}
+diff -ruN proll_18.orig/src/vconsole.c proll-patch7/src/vconsole.c
+--- proll_18.orig/src/vconsole.c 1999-11-08 03:10:28.000000000 +0000
++++ proll-patch7/src/vconsole.c 2005-03-02 14:29:05.000000000 +0000
+@@ -13,6 +13,10 @@
+
+ struct hconsole hcons0;
+
++enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
++ EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
++ ESpalette };
++
+ int vcon_init(struct vconterm *t, unsigned int a0)
+ {
+ struct hconsole *hconp;
+@@ -25,11 +29,49 @@
+
+ t->vc_x = 0; t->vc_y = 0;
+ t->backp = 0; t->backc = 0;
++ t->vc_state = ESnormal;
+
+ hcon_clear(hconp, 0, 0, hconp->ydim_, hconp->xdim_);
+ return 0;
+ }
+
++/*
++ * gotoxy() must verify all boundaries, because the arguments
++ * might also be negative. If the given position is out of
++ * bounds, the cursor is placed at the nearest margin.
++ */
++static void gotoxy(struct vconterm *vc, int new_x, int new_y)
++{
++ int max_x, max_y;
++ struct hconsole *hconp = vc->impl;
++
++ max_x = hcon_qxdim(hconp);
++ max_y = hcon_qydim(hconp);
++
++ if (new_x < 0)
++ vc->vc_x = 0;
++ else {
++ if (new_x >= max_x)
++ vc->vc_x = max_x - 1;
++ else
++ vc->vc_x = new_x;
++ }
++
++ if (new_y < 0)
++ vc->vc_y = 0;
++ else if (new_y >= max_y)
++ vc->vc_y = max_y - 1;
++ else
++ vc->vc_y = new_y;
++
++}
++
++/* for absolute user moves, when decom is set */
++static void gotoxay(struct vconterm *t, int new_x, int new_y)
++{
++ gotoxy(t, new_x, new_y);
++}
++
+ int vcon_write(struct vconterm *t, char *data, int leng)
+ {
+ int l = leng;
+@@ -40,29 +82,84 @@
+ if (l <= 0) break;
+ c = *data++; --l;
+
+- switch (c) {
+- case 0x07: /* Bell */
+- vcon_i_backflush(t);
+- break;
+- case 0x0A: /* Linefeed */
+- vcon_i_backflush(t);
+- vcon_i_cursfeed(t);
++ switch(t->vc_state) {
++ case ESesc:
++ t->vc_state = ESnormal;
++ switch (c) {
++ case '[':
++ t->vc_state = ESsquare;
++ break;
++ case 'M':
++ hcon_scroll(hconp, 0, hcon_qydim(hconp), SM_UP, 1);
++ break;
++ }
+ break;
+- case 0x0D: /* Return */
+- vcon_i_backflush(t);
+- t->vc_x = 0;
++ case ESsquare:
++ for(t->vc_npar = 0 ; t->vc_npar < NPAR ; t->vc_npar++)
++ t->vc_par[t->vc_npar] = 0;
++ t->vc_npar = 0;
++ t->vc_state = ESgetpars;
++ case ESgetpars:
++ if (c==';' && t->vc_npar<NPAR-1) {
++ t->vc_npar++;
++ break;
++ } else if (c>='0' && c<='9') {
++ t->vc_par[t->vc_npar] *= 10;
++ t->vc_par[t->vc_npar] += c-'0';
++ break;
++ } else t->vc_state=ESgotpars;
++ case ESgotpars:
++ t->vc_state = ESnormal;
++ switch(c) {
++ case 'H': case 'f':
++ if (t->vc_par[0]) t->vc_par[0]--;
++ if (t->vc_par[1]) t->vc_par[1]--;
++ gotoxay(t, t->vc_par[1], t->vc_par[0]);
++ break;
++ case 'M':
++ hcon_scroll(hconp, 0, hcon_qydim(hconp), SM_UP, 1);
++ break;
++ }
+ break;
+ default:
+- if (t->backp == 0) {
+- t->backc = 1;
+- t->backp = data-1;
+- } else {
+- t->backc++;
+- }
+- if (t->vc_x + t->backc >= hcon_qxdim(hconp)) {
++ t->vc_state = ESnormal;
++ switch (c) {
++ case 0x07: /* Bell */
++ vcon_i_backflush(t);
++ break;
++ case 0x08: /* BS */
++ vcon_i_backflush(t);
++ if (t->vc_x > 0)
++ t->vc_x--;
++ break;
++ case 0x0A: /* Linefeed */
+ vcon_i_backflush(t);
+- t->vc_x = 0;
+ vcon_i_cursfeed(t);
++ break;
++ case 0x0D: /* Return */
++ vcon_i_backflush(t);
++ t->vc_x = 0;
++ break;
++ case 24: case 26:
++ vcon_i_backflush(t);
++ t->vc_state = ESnormal;
++ break;
++ case 27:
++ vcon_i_backflush(t);
++ t->vc_state = ESesc;
++ break;
++ default:
++ if (t->backp == 0) {
++ t->backc = 1;
++ t->backp = data-1;
++ } else {
++ t->backc++;
++ }
++ if (t->vc_x + t->backc >= hcon_qxdim(hconp)) {
++ vcon_i_backflush(t);
++ t->vc_x = 0;
++ vcon_i_cursfeed(t);
++ }
+ }
+ }
+ }
+diff -ruN proll_18.orig/src/vconsole.h proll-patch7/src/vconsole.h
+--- proll_18.orig/src/vconsole.h 1999-11-08 00:58:13.000000000 +0000
++++ proll-patch7/src/vconsole.h 2005-03-02 12:40:12.000000000 +0000
+@@ -6,6 +6,8 @@
+ #ifndef VCONSOLE_H
+ #define VCONSOLE_H
+
++#define NPAR 16
++
+ struct vconterm {
+ void *impl;
+
+@@ -13,6 +15,8 @@
+ int backc; /* Same, count */
+
+ int vc_x, vc_y; /* XXX Make vcon_xxx() to use cellmap->xpos_ */
++ int vc_state;
++ unsigned int vc_npar,vc_par[NPAR]; /* Parameters of current escape sequence */
+ };
+
+ int vcon_init(struct vconterm *t, unsigned int a0);