Home | History | Annotate | Line # | Download | only in lib
      1  1.12  jmcneill /*	$NetBSD: gatea20.c,v 1.12 2009/08/23 12:31:05 jmcneill Exp $	*/
      2   1.1     perry 
      3   1.1     perry /* extracted from freebsd:sys/i386/boot/biosboot/io.c */
      4   1.1     perry 
      5   1.1     perry #include <sys/types.h>
      6   1.1     perry 
      7   1.1     perry #include <lib/libsa/stand.h>
      8   1.1     perry 
      9   1.1     perry #include "libi386.h"
     10   1.4  jdolecek #include "biosmca.h"
     11   1.9        ad #include "cpufunc.h"
     12   1.1     perry 
     13   1.1     perry #define K_RDWR 		0x60		/* keyboard data & cmds (read/write) */
     14   1.1     perry #define K_STATUS 	0x64		/* keyboard status */
     15   1.1     perry #define K_CMD	 	0x64		/* keybd ctlr command (write-only) */
     16   1.1     perry 
     17   1.1     perry #define K_OBUF_FUL 	0x01		/* output buffer full */
     18   1.1     perry #define K_IBUF_FUL 	0x02		/* input buffer full */
     19   1.1     perry 
     20   1.1     perry #define KC_CMD_WIN	0xd0		/* read  output port */
     21   1.1     perry #define KC_CMD_WOUT	0xd1		/* write output port */
     22   1.1     perry #define KB_A20		0x9f		/* enable A20,
     23   1.2      fvdl 					   reset (!),
     24   1.1     perry 					   enable output buffer full interrupt
     25   1.1     perry 					   enable data line
     26   1.1     perry 					   disable clock line */
     27   1.1     perry 
     28   1.1     perry /*
     29   1.1     perry  * Gate A20 for high memory
     30   1.1     perry  */
     31   1.1     perry static unsigned char	x_20 = KB_A20;
     32   1.7  junyoung 
     33   1.7  junyoung void
     34   1.7  junyoung gateA20(void)
     35   1.1     perry {
     36  1.11        ad 	int biosA20(void);
     37   1.9        ad 	u_long psl;
     38   1.9        ad 
     39  1.11        ad 	/*
     40  1.11        ad 	 * First, try asking the BIOS to enable A20.
     41  1.11        ad 	 *
     42  1.11        ad 	 * If that fails, try system configuration port 0x92 but only
     43  1.11        ad 	 * if known to be necessary.  Not all systems enable A20 via the
     44  1.11        ad 	 * keyboard controller, some don't have keyboard controllers,
     45  1.11        ad 	 * and playing with port 0x92 may cause some systems to break.
     46  1.11        ad 	 *
     47  1.11        ad 	 * Otherwise, use the traditional method (keyboard controller).
     48  1.11        ad 	 */
     49  1.11        ad 	if (!biosA20())
     50  1.11        ad 		return;
     51   1.9        ad 	psl = x86_read_psl();
     52   1.9        ad 	x86_disable_intr();
     53   1.5   thorpej 	if (
     54   1.5   thorpej #ifdef SUPPORT_PS2
     55   1.5   thorpej 	    biosmca_ps2model == 0xf82 ||
     56   1.5   thorpej #endif
     57   1.6      manu 	    (inb(K_STATUS) == 0xff && inb(K_RDWR) == 0xff)) {
     58   1.6      manu 		int data;
     59   1.6      manu 
     60   1.6      manu 		data = inb(0x92);
     61   1.6      manu 		outb(0x92, data | 0x2);
     62   1.5   thorpej 	} else {
     63   1.5   thorpej 		while (inb(K_STATUS) & K_IBUF_FUL);
     64   1.6      manu 
     65   1.5   thorpej 		while (inb(K_STATUS) & K_OBUF_FUL)
     66   1.5   thorpej 			(void)inb(K_RDWR);
     67   1.5   thorpej 
     68   1.5   thorpej 		outb(K_CMD, KC_CMD_WOUT);
     69   1.6      manu 
     70   1.5   thorpej 		while (inb(K_STATUS) & K_IBUF_FUL);
     71   1.6      manu 
     72   1.5   thorpej 		outb(K_RDWR, x_20);
     73   1.6      manu 
     74   1.5   thorpej 		while (inb(K_STATUS) & K_IBUF_FUL);
     75   1.6      manu 
     76   1.6      manu 		while (inb(K_STATUS) & K_OBUF_FUL)
     77   1.6      manu 			(void)inb(K_RDWR);
     78   1.4  jdolecek 	}
     79   1.9        ad 	x86_write_psl(psl);
     80   1.1     perry }
     81