diff -urNX /home/leigh/.diffex prev_linuxppc_2_4_devel-2.4.19-local/arch/ppc/boot/common/util.S linuxppc_2_4_devel-2.4.19-local/arch/ppc/boot/common/util.S
--- prev_linuxppc_2_4_devel-2.4.19-local/arch/ppc/boot/common/util.S	2003-03-30 17:10:19.000000000 +0100
+++ linuxppc_2_4_devel-2.4.19-local/arch/ppc/boot/common/util.S	2003-03-30 17:29:14.000000000 +0100
@@ -192,12 +192,13 @@
 	ori	r3,r3,(HID0_ICE|HID0_DCE|HID0_ICFI|HID0_DCI)
 	mfspr	r4,HID0
 	or	r5,r4,r3
+	andc	r4,r4,r3
+	ori	r4,r4,HID0_ICE
 	isync
 	mtspr	HID0,r5
 	sync
 	isync
-	ori	r5,r4,HID0_ICE	/* Enable cache */
-	mtspr	HID0,r5
+	mtspr	HID0,r4
 	sync
 	isync
 #endif
diff -urNX /home/leigh/.diffex prev_linuxppc_2_4_devel-2.4.19-local/arch/ppc/boot/prep/kbd.c linuxppc_2_4_devel-2.4.19-local/arch/ppc/boot/prep/kbd.c
--- prev_linuxppc_2_4_devel-2.4.19-local/arch/ppc/boot/prep/kbd.c	2003-03-30 17:10:26.000000000 +0100
+++ linuxppc_2_4_devel-2.4.19-local/arch/ppc/boot/prep/kbd.c	2003-03-30 17:29:14.000000000 +0100
@@ -3,35 +3,31 @@
  */
 
 #include <linux/keyboard.h>
-
-#include "defkeymap.c"	/* yeah I know it's bad -- Cort */
-
+#include <linux/pc_keyb.h>
 
 unsigned char shfts, ctls, alts, caps;
 
-#define	KBDATAP		0x60	/* kbd data port */
-#define	KBSTATUSPORT	0x61	/* kbd status */
-#define	KBSTATP		0x64	/* kbd status port */
-#define	KBINRDY		0x01
-#define	KBOUTRDY	0x02
-
 extern unsigned char inb(int port);
 extern void outb(int port, char val);
 extern void puts(const char *);
 extern void puthex(unsigned long val);
 extern void udelay(long x);
 
+extern u_short plain_map[];
+extern u_short shift_map[];
+extern u_short ctrl_map[];
+
 static int kbd(int noblock)
 {
 	unsigned char dt, brk, val;
 	unsigned code;
 loop:
 	if (noblock) {
-	    if ((inb(KBSTATP) & KBINRDY) == 0)
+	    if ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0)
 		return (-1);
-	} else while((inb(KBSTATP) & KBINRDY) == 0) ;
+	} else while((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) ;
 
-	dt = inb(KBDATAP);
+	dt = inb(KBD_DATA_REG);
 
 	brk = dt & 0x80;	/* brk == 1 on key release */
 	dt = dt & 0x7f;		/* keycode */
@@ -69,8 +65,8 @@
 		else if (val == KVAL(K_ENTER)) {
 enter:		    /* Wait for key up */
 		    while (1) {
-			while((inb(KBSTATP) & KBINRDY) == 0) ;
-			dt = inb(KBDATAP);
+			while((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) ;
+			dt = inb(KBD_DATA_REG);
 			if (dt & 0x80) /* key up */ break;
 		    }
 		    return 10;
@@ -131,75 +127,199 @@
 	goto loop;
 }
 
+#define kbd_read_input() inb(KBD_DATA_REG)
+#define kbd_read_status() inb(KBD_STATUS_REG)
+#define kbd_write_output(val) outb(KBD_DATA_REG, val)
+#define kbd_write_command(val) outb(KBD_CNTL_REG, val)
+
+static unsigned char handle_kbd_event(void)
+{
+	unsigned char status = kbd_read_status();
+	unsigned int work = 10000;
+
+	while ((--work > 0) && (status & KBD_STAT_OBF)) {
+		unsigned char scancode;
+
+		scancode = kbd_read_input();
+		if (!(status & (KBD_STAT_GTO | KBD_STAT_PERR))) {
+			if (status & KBD_STAT_MOUSE_OBF)
+				_printk("(mse)"); /* XXX err.. */
+			else
+				_printk("(kbd)"); /* XXX ditto */
+		}
+		
+		status = kbd_read_status();
+	}
+
+	if (!work)
+		_printk("keyboard controller jammed (0x%02X)\n", status);
+
+	return status;
+}
+
+static void kbd_wait(void)
+{
+	unsigned long timeout = 1000;
+
+	do {
+		unsigned char status = handle_kbd_event();
+
+		if (! (status & KBD_STAT_IBF))
+			return;
+		udelay(1000);
+		timeout--;
+	} while (timeout);
+
+	_printk("Keyboard timed out\n");
+}
+
+#define KBD_NO_DATA	(-1)
+#define KBD_BAD_DATA	(-2)
+
+static int kbd_read_data(void)
+{
+	int retval = KBD_NO_DATA;
+	unsigned char status;
+
+	status = kbd_read_status();
+	if (status & KBD_STAT_OBF) {
+		unsigned char data = kbd_read_input();
+
+		retval = data;
+		if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
+			retval = KBD_BAD_DATA;
+	}
+
+	return retval;
+}
+
+static int kbd_wait_for_input(void)
+{
+	unsigned long timeout = 1000;
+
+	do {
+		int retval = kbd_read_data();
+		if (retval >= 0)
+			return retval;
+		udelay(1000);
+	} while (--timeout);
+
+	return -1;
+}
+
+static void kbd_write_command_w(int data)
+{
+	kbd_wait();
+	kbd_write_command(data);
+}
+
+static int kbd_write_command_w_and_wait(int data)
+{
+	kbd_write_command_w(data);
+	return kbd_wait_for_input();
+}
+
+static void kbd_write_output_w(int data)
+{
+	kbd_wait();
+	kbd_write_output(data);
+}
+
+static int kbd_write_output_w_and_wait(int data)
+{
+	kbd_write_output_w(data);
+	return kbd_wait_for_input();
+}
+
+static void kbd_clear_input(void)
+{
+	int maxread = 100;	/* Random number */
+
+	do {
+		if (kbd_read_data() == KBD_NO_DATA)
+			break;
+	} while (--maxread);
+}
+
 static int __kbdreset(void)
 {
-	unsigned char c;
-	int i, t;
+	int status;
 
 	/* flush input queue */
-	t = 2000;
-	while ((inb(KBSTATP) & KBINRDY))
-	{
-		(void)inb(KBDATAP);
-		if (--t == 0)
-			return 1;
-	}
+	kbd_clear_input();
+
 	/* Send self-test */
-	t = 20000;
-	while (inb(KBSTATP) & KBOUTRDY)
-		if (--t == 0)
-			return 2;
-	outb(KBSTATP,0xAA);
-	t = 200000;
-	while ((inb(KBSTATP) & KBINRDY) == 0)	/* wait input ready */
-		if (--t == 0)
+	kbd_write_command_w(KBD_CCMD_SELF_TEST);
+	if (kbd_wait_for_input() != 0x55) {
+		_printk("Keyboard self test failed\n");
+		return 1;
+	}
+
+	/* Perform a keyboard interface test */
+	kbd_write_command_w(KBD_CCMD_KBD_TEST);
+	if (kbd_wait_for_input() != 0x00) {
+		_printk("Keyboard interface failed self test\n");
+		return 2;
+	}
+
+	/* Enable the keyboard */
+	kbd_write_command_w(KBD_CCMD_KBD_ENABLE);
+
+	/* Reset the keyboard */
+	do {
+		kbd_write_output_w(KBD_CMD_RESET);
+		status = kbd_wait_for_input();
+		if (status == KBD_REPLY_ACK)
+			break;
+		if (status != KBD_REPLY_RESEND) {
+			_printk("Keyboard reset failed, no ACK\n");
 			return 3;
-	if ((c = inb(KBDATAP)) != 0x55)
-	{
-		puts("Keyboard self test failed - result:");
-		puthex(c);
-		puts("\n");
+		}
+	} while (1);
+
+	if (kbd_wait_for_input() != KBD_REPLY_POR) {
+		_printk("Keyboard reset failed, no POR\n");
+		return 4;
 	}
-	/* Enable interrupts and keyboard controller */
-	t = 20000;
-	while (inb(KBSTATP) & KBOUTRDY)
-		if (--t == 0) return 4;
-	outb(KBSTATP,0x60);
-	t = 20000;
-	while (inb(KBSTATP) & KBOUTRDY)
-		if (--t == 0) return 5;
-	outb(KBDATAP,0x45);
-	for (i = 0;  i < 10000;  i++) udelay(1);
-
-	t = 20000;
-	while (inb(KBSTATP) & KBOUTRDY)
-		if (--t == 0) return 6;
-	outb(KBSTATP,0x20);
-	t = 200000;
-	while ((inb(KBSTATP) & KBINRDY) == 0)	/* wait input ready */
-		if (--t == 0) return 7;
-	if (! (inb(KBDATAP) & 0x40)) {
-		/*
-		 * Quote from PS/2 System Reference Manual:
-		 *
-		 * "Address hex 0060 and address hex 0064 should be
-		 * written only when the input-buffer-full bit and
-		 * output-buffer-full bit in the Controller Status
-		 * register are set 0." (KBINRDY and KBOUTRDY)
-		 */
-		t = 200000;
-		while (inb(KBSTATP) & (KBINRDY | KBOUTRDY))
-			if (--t == 0) return 8;
-		outb(KBDATAP,0xF0);
-		t = 200000;
-		while (inb(KBSTATP) & (KBINRDY | KBOUTRDY))
-			if (--t == 0) return 9;
-		outb(KBDATAP,0x01);
-	}
-	t = 20000;
-	while (inb(KBSTATP) & KBOUTRDY)
-		if (--t == 0) return 10;
-	outb(KBSTATP,0xAE);
+
+	/* Disable the keyboard */
+	do {
+		kbd_write_output_w(KBD_CMD_DISABLE);
+		status = kbd_wait_for_input();
+		if (status == KBD_REPLY_ACK)
+			break;
+		if (status != KBD_REPLY_RESEND) {
+			_printk("Disable keyboard failed, no ACK\n");
+			return 5;
+		}
+	} while (1);
+
+	kbd_write_command_w(KBD_CCMD_WRITE_MODE);
+	kbd_write_output_w(   KBD_MODE_SYS /* | KBD_MODE_KBD_INT */
+			    | KBD_MODE_DISABLE_MOUSE
+			    | KBD_MODE_KCC );
+
+	if (!(kbd_write_command_w_and_wait(KBD_CCMD_READ_MODE) & KBD_MODE_KCC)) {
+		kbd_write_output_w(0xF0);
+		kbd_wait_for_input();
+		kbd_write_output_w(0x01);
+		kbd_wait_for_input();
+	}
+
+	if (kbd_write_output_w_and_wait(KBD_CMD_ENABLE) != KBD_REPLY_ACK) {
+		_printk("Enable keyboard failed, no ACK\n");
+		return 6;
+	}
+
+	if (kbd_write_output_w_and_wait(KBD_CMD_SET_RATE) != KBD_REPLY_ACK) {
+		_printk("Set keyboard rate failed, no ACK\n");
+		return 7;
+	}
+	if (kbd_write_output_w_and_wait(0x00) != KBD_REPLY_ACK) {
+		_printk("Set keyboard rate failed, no 2nd ACK\n");
+		return 8;
+	}
+
 	return 0;
 }
 
@@ -244,7 +364,7 @@
 {
 	if (!kbd_reset) {kbdreset(); kbd_reset++; }
 
-        while (key_pending == -1 && ((inb(KBSTATP) & KBINRDY) != 0)) {
+        while (key_pending == -1 && ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) != 0)) {
                 key_pending = kbd(1);
         }
 
diff -urNX /home/leigh/.diffex prev_linuxppc_2_4_devel-2.4.19-local/arch/ppc/boot/prep/keymap.c linuxppc_2_4_devel-2.4.19-local/arch/ppc/boot/prep/keymap.c
--- prev_linuxppc_2_4_devel-2.4.19-local/arch/ppc/boot/prep/keymap.c	1970-01-01 01:00:00.000000000 +0100
+++ linuxppc_2_4_devel-2.4.19-local/arch/ppc/boot/prep/keymap.c	2003-03-30 17:29:14.000000000 +0100
@@ -0,0 +1,78 @@
+/*
+ * arch/ppc/boot/prep/keymap.c
+ *
+ * Copyright (C) Leigh Brown 2002.
+ *
+ * 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 is a custom keymap file for the PReP boot loader
+ *
+ * The unnecessary keymaps and other tables have been removed to
+ * provide a very useful reduction in size.
+ */
+
+#include <linux/types.h>
+#include <linux/keyboard.h>
+#include <linux/kd.h>
+
+u_short plain_map[NR_KEYS] = {
+	0xf200,	0xf01b,	0xf031,	0xf032,	0xf033,	0xf034,	0xf035,	0xf036,
+	0xf037,	0xf038,	0xf039,	0xf030,	0xf02d,	0xf03d,	0xf07f,	0xf009,
+	0xfb71,	0xfb77,	0xfb65,	0xfb72,	0xfb74,	0xfb79,	0xfb75,	0xfb69,
+	0xfb6f,	0xfb70,	0xf05b,	0xf05d,	0xf201,	0xf702,	0xfb61,	0xfb73,
+	0xfb64,	0xfb66,	0xfb67,	0xfb68,	0xfb6a,	0xfb6b,	0xfb6c,	0xf03b,
+	0xf027,	0xf060,	0xf700,	0xf05c,	0xfb7a,	0xfb78,	0xfb63,	0xfb76,
+	0xfb62,	0xfb6e,	0xfb6d,	0xf02c,	0xf02e,	0xf02f,	0xf700,	0xf30c,
+	0xf703,	0xf020,	0xf207,	0xf100,	0xf101,	0xf102,	0xf103,	0xf104,
+	0xf105,	0xf106,	0xf107,	0xf108,	0xf109,	0xf208,	0xf209,	0xf307,
+	0xf308,	0xf309,	0xf30b,	0xf304,	0xf305,	0xf306,	0xf30a,	0xf301,
+	0xf302,	0xf303,	0xf300,	0xf310,	0xf206,	0xf200,	0xf03c,	0xf10a,
+	0xf10b,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+	0xf30e,	0xf702,	0xf30d,	0xf01c,	0xf701,	0xf205,	0xf114,	0xf603,
+	0xf118,	0xf601,	0xf602,	0xf117,	0xf600,	0xf119,	0xf115,	0xf116,
+	0xf11a,	0xf10c,	0xf10d,	0xf11b,	0xf11c,	0xf110,	0xf311,	0xf11d,
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+};
+
+u_short shift_map[NR_KEYS] = {
+	0xf200,	0xf01b,	0xf021,	0xf040,	0xf023,	0xf024,	0xf025,	0xf05e,
+	0xf026,	0xf02a,	0xf028,	0xf029,	0xf05f,	0xf02b,	0xf07f,	0xf009,
+	0xfb51,	0xfb57,	0xfb45,	0xfb52,	0xfb54,	0xfb59,	0xfb55,	0xfb49,
+	0xfb4f,	0xfb50,	0xf07b,	0xf07d,	0xf201,	0xf702,	0xfb41,	0xfb53,
+	0xfb44,	0xfb46,	0xfb47,	0xfb48,	0xfb4a,	0xfb4b,	0xfb4c,	0xf03a,
+	0xf022,	0xf07e,	0xf700,	0xf07c,	0xfb5a,	0xfb58,	0xfb43,	0xfb56,
+	0xfb42,	0xfb4e,	0xfb4d,	0xf03c,	0xf03e,	0xf03f,	0xf700,	0xf30c,
+	0xf703,	0xf020,	0xf207,	0xf10a,	0xf10b,	0xf10c,	0xf10d,	0xf10e,
+	0xf10f,	0xf110,	0xf111,	0xf112,	0xf113,	0xf213,	0xf203,	0xf307,
+	0xf308,	0xf309,	0xf30b,	0xf304,	0xf305,	0xf306,	0xf30a,	0xf301,
+	0xf302,	0xf303,	0xf300,	0xf310,	0xf206,	0xf200,	0xf03e,	0xf10a,
+	0xf10b,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+	0xf30e,	0xf702,	0xf30d,	0xf200,	0xf701,	0xf205,	0xf114,	0xf603,
+	0xf20b,	0xf601,	0xf602,	0xf117,	0xf600,	0xf20a,	0xf115,	0xf116,
+	0xf11a,	0xf10c,	0xf10d,	0xf11b,	0xf11c,	0xf110,	0xf311,	0xf11d,
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+};
+
+u_short ctrl_map[NR_KEYS] = {
+	0xf200,	0xf200,	0xf200,	0xf000,	0xf01b,	0xf01c,	0xf01d,	0xf01e,
+	0xf01f,	0xf07f,	0xf200,	0xf200,	0xf01f,	0xf200,	0xf008,	0xf200,
+	0xf011,	0xf017,	0xf005,	0xf012,	0xf014,	0xf019,	0xf015,	0xf009,
+	0xf00f,	0xf010,	0xf01b,	0xf01d,	0xf201,	0xf702,	0xf001,	0xf013,
+	0xf004,	0xf006,	0xf007,	0xf008,	0xf00a,	0xf00b,	0xf00c,	0xf200,
+	0xf007,	0xf000,	0xf700,	0xf01c,	0xf01a,	0xf018,	0xf003,	0xf016,
+	0xf002,	0xf00e,	0xf00d,	0xf200,	0xf20e,	0xf07f,	0xf700,	0xf30c,
+	0xf703,	0xf000,	0xf207,	0xf100,	0xf101,	0xf102,	0xf103,	0xf104,
+	0xf105,	0xf106,	0xf107,	0xf108,	0xf109,	0xf208,	0xf204,	0xf307,
+	0xf308,	0xf309,	0xf30b,	0xf304,	0xf305,	0xf306,	0xf30a,	0xf301,
+	0xf302,	0xf303,	0xf300,	0xf310,	0xf206,	0xf200,	0xf200,	0xf10a,
+	0xf10b,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+	0xf30e,	0xf702,	0xf30d,	0xf01c,	0xf701,	0xf205,	0xf114,	0xf603,
+	0xf118,	0xf601,	0xf602,	0xf117,	0xf600,	0xf119,	0xf115,	0xf116,
+	0xf11a,	0xf10c,	0xf10d,	0xf11b,	0xf11c,	0xf110,	0xf311,	0xf11d,
+	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
+};
+
diff -urNX /home/leigh/.diffex prev_linuxppc_2_4_devel-2.4.19-local/arch/ppc/boot/prep/Makefile linuxppc_2_4_devel-2.4.19-local/arch/ppc/boot/prep/Makefile
--- prev_linuxppc_2_4_devel-2.4.19-local/arch/ppc/boot/prep/Makefile	2003-03-30 17:10:50.000000000 +0100
+++ linuxppc_2_4_devel-2.4.19-local/arch/ppc/boot/prep/Makefile	2003-03-30 17:29:14.000000000 +0100
@@ -31,7 +31,7 @@
 LIBS 				= ../lib/zlib.a
 
 obj-$(CONFIG_SERIAL_CONSOLE)	+= ../common/ns16550.o
-obj-$(CONFIG_VGA_CONSOLE)	+= vreset.o kbd.o
+obj-$(CONFIG_VGA_CONSOLE)	+= vreset.o kbd.o keymap.o
 
 # Tools
 MKPREP				:= ../utils/mkprep
