i8259.c \
klib.S \
memory.c \
+ oxpcie.c \
protect.c \
arch_system.c \
apic.c \
#include "archconst.h"
#include "proto.h"
+#include "serial.h"
+#include "oxpcie.h"
#include "kernel/proc.h"
#include "kernel/debug.h"
fpu_init();
}
-#define COM1_BASE 0x3F8
-#define COM1_THR (COM1_BASE + 0)
-#define COM1_RBR (COM1_BASE + 0)
-#define COM1_LSR (COM1_BASE + 5)
-#define LSR_DR 0x01
-#define LSR_THRE 0x20
-
PUBLIC void ser_putc(char c)
{
int i;
int lsr, thr;
+#if CONFIG_OXPCIE
+ oxpcie_putc(c);
+#endif
+
lsr= COM1_LSR;
thr= COM1_THR;
for (i= 0; i<100000; i++)
{
u8_t c, lsr;
+#if CONFIG_OXPCIE
+ {
+ int oxin;
+ if((oxin = oxpcie_in()) >= 0)
+ ser_debug(oxin);
+ }
+#endif
+
lsr= inb(COM1_LSR);
if (!(lsr & LSR_DR))
return;
#include <string.h>
#include <assert.h>
#include <signal.h>
+#include <stdlib.h>
#include <machine/vm.h>
+#include "oxpcie.h"
#include "proto.h"
#include "kernel/proto.h"
#include "kernel/debug.h"
freepdes[nfreepdes++] = pde;
}
+PRIVATE int lapic_mapping_index = -1, oxpcie_mapping_index = -1;
+
PUBLIC int arch_phys_map(const int index, phys_bytes *addr,
phys_bytes *len, int *flags)
{
+ static int first = 1;
+ int freeidx = 0;
+ static char *ser_var = NULL;
+
+ if(first) {
+#ifdef CONFIG_APIC
+ if(lapic_addr)
+ lapic_mapping_index = freeidx++;
+#endif
+
+#ifdef CONFIG_OXPCIE
+ if((ser_var = env_get("oxpcie"))) {
+ if(ser_var[0] != '0' || ser_var[1] != 'x') {
+ printf("oxpcie address in hex please\n");
+ } else {
+ oxpcie_mapping_index = freeidx++;
+ }
+ }
+#endif
+ first = 0;
+ }
+
#ifdef CONFIG_APIC
/* map the local APIC if enabled */
- if (index == 0 && lapic_addr) {
+ if (index == lapic_mapping_index) {
*addr = vir2phys(lapic_addr);
*len = 4 << 10 /* 4kB */;
*flags = VMMF_UNCACHED;
return OK;
}
- return EINVAL;
-#else
- /* we don't want anything */
- return EINVAL;
#endif
+
+#if CONFIG_OXPCIE
+ if(index == oxpcie_mapping_index) {
+ *addr = strtoul(ser_var+2, NULL, 16);
+ *len = 0x4000;
+ *flags = VMMF_UNCACHED;
+ return OK;
+ }
+#endif
+
+ return EINVAL;
}
PUBLIC int arch_phys_map_reply(const int index, const vir_bytes addr)
{
#ifdef CONFIG_APIC
/* if local APIC is enabled */
- if (index == 0 && lapic_addr) {
+ if (index == lapic_mapping_index && lapic_addr) {
lapic_addr_vaddr = addr;
}
#endif
+
+#if CONFIG_OXPCIE
+ if (index == oxpcie_mapping_index) {
+ oxpcie_set_vaddr((unsigned char *) addr);
+ }
+#endif
+
return OK;
}
--- /dev/null
+
+#include "kernel/kernel.h"
+
+#if CONFIG_OXPCIE
+
+/* Documentation is at http://www.plxtech.com/products/uart/oxpcie952 */
+
+#include "oxpcie.h"
+#include "serial.h"
+
+PRIVATE unsigned char *oxpcie_vaddr = NULL;
+
+PUBLIC void oxpcie_set_vaddr(unsigned char *vaddr)
+{
+ oxpcie_vaddr = vaddr;
+}
+
+PRIVATE void oxpcie_init(void)
+{
+ printf("oxpcie_init\n");
+ /* Enable access to EFR and DLM+DLL */
+ OXPCIE_LCR = 0xBF;
+
+ /* Set FICR[1] to increase FIFO */
+ OXPCIE_FICR = 0x01;
+
+ /* Set enhanced mode [4]
+ * no RTS/CTS [7:6]
+ * no special char detection [5]
+ * no in-band receive flow control [1:0]
+ * no in-band transmit flow control [3:2]
+ */
+ OXPCIE_EFR = 0x10;
+
+ /* Set divisor register to 115200 baud. */
+ OXPCIE_DLM = 0x00;
+ OXPCIE_DLL = 0x22;
+
+ /* Forget DLM and DLL, set LCR to config. */
+ OXPCIE_LCR = LCR_CONFIG;
+ OXPCIE_LCR = LCR_CONFIG;
+
+ OXPCIE_TCR = 0x01;
+ OXPCIE_CPR = 0x20;
+ OXPCIE_CPR2 = 0;
+}
+
+PUBLIC void oxpcie_putc(char c)
+{
+ static int inuse = 0;
+
+ if(vm_running && oxpcie_vaddr && !inuse) {
+ int i;
+ static int init_done;
+ inuse = 1;
+
+ if(!init_done) {
+ oxpcie_init();
+ init_done = 1;
+ }
+
+ for (i= 0; i<100000; i++) {
+ if(OXPCIE_LSR & LSR_THRE)
+ break;
+ }
+ OXPCIE_THR = c;
+ inuse = 0;
+ }
+}
+
+PUBLIC int oxpcie_in(void)
+{
+ if(vm_running && oxpcie_vaddr) {
+ int lsr;
+ lsr = OXPCIE_LSR;
+ if(lsr & LSR_DR)
+ return (int) OXPCIE_RBR;
+ }
+
+ return -1;
+}
+
+#endif
--- /dev/null
+
+_PROTOTYPE( void oxpcie_set_vaddr, (unsigned char *vaddr));
+_PROTOTYPE( void oxpcie_putc, (char c));
+_PROTOTYPE( int oxpcie_in, (void));
+
+#include "serial.h"
+
+/* OXPCIe952 info */
+#define UART1BASE_550 0x1000
+#define UART1BASE_650 0x1090
+#define UART1BASE_950
+#define BASELINEICR (UART1BASE_550 + 0xC0)
+#define OXPCIE_THR oxpcie_vaddr[UART1BASE_550 + THRREG]
+#define OXPCIE_RBR oxpcie_vaddr[UART1BASE_550 + RBRREG]
+#define OXPCIE_LSR oxpcie_vaddr[UART1BASE_550 + LSRREG]
+#define OXPCIE_LCR oxpcie_vaddr[UART1BASE_550 + LCRREG]
+#define OXPCIE_DLL oxpcie_vaddr[UART1BASE_550 + 0x00]
+#define OXPCIE_DLM oxpcie_vaddr[UART1BASE_550 + 0x01]
+#define OXPCIE_FICR oxpcie_vaddr[UART1BASE_550 + FICRREG]
+#define OXPCIE_SPR oxpcie_vaddr[UART1BASE_550 + SPRREG]
+#define OXPCIE_EFR oxpcie_vaddr[UART1BASE_650 + 0x10]
+#define OXPCIE_ICR oxpcie_vaddr[UART1BASE_950 + 0x05]
+
+#define OXPCIE_CPR oxpcie_vaddr[BASELINEICR + 0x01]
+#define OXPCIE_TCR oxpcie_vaddr[BASELINEICR + 0x02]
+#define OXPCIE_CPR2 oxpcie_vaddr[BASELINEICR + 0x03]
+#define OXPCIE_CSR oxpcie_vaddr[BASELINEICR + 0x0C]
+#define OXPCIE_PIDX oxpcie_vaddr[BASELINEICR + 0x12]
+
+#define LCR_CONFIG 0x03 /* bits 6:0 -= 0x03 => 8N1, no break. */
+
--- /dev/null
+
+#ifndef _KERN_SERIAL_H
+#define _KERN_SERIAL_H 1
+
+#define THRREG 0
+#define RBRREG 0
+#define FICRREG 2
+#define LSRREG 5
+#define LCRREG 3
+#define SPRREG 7
+
+#define COM1_BASE 0x3F8
+#define COM1_THR (COM1_BASE + THRREG)
+#define COM1_RBR (COM1_BASE + RBRREG)
+#define COM1_LSR (COM1_BASE + LSRREG)
+#define LSR_DR 0x01
+#define LSR_THRE 0x20
+#define LCR_DLA 0x80
+
+#endif
#define CONFIG_MAX_CPUS 1
#define cpuid 0
+/* OXPCIe952 PCIe with 2 UARTs in-kernel support */
+#define CONFIG_OXPCIE 0
+
/* This is the master header for the kernel. It includes some other files
* and defines the principal constants.
*/
/* start.c */
_PROTOTYPE( void cstart, (u16_t cs, u16_t ds, u16_t mds,
u16_t parmoff, u16_t parmsize) );
+_PROTOTYPE( char *env_get, (const char *key));
/* system.c */
_PROTOTYPE( int get_priv, (register struct proc *rc, int proc_type) );
#include "watchdog.h"
#endif
-FORWARD _PROTOTYPE( char *get_value, (const char *params, const char *key));
/*===========================================================================*
* cstart *
*===========================================================================*/
arch_get_params(params_buffer, sizeof(params_buffer));
/* determine verbosity */
- if ((value = get_value(params_buffer, VERBOSEBOOTVARNAME)))
+ if ((value = env_get(VERBOSEBOOTVARNAME)))
verboseboot = atoi(value);
DEBUGEXTRA(("cstart\n"));
kloadinfo.proc_load_history[h] = 0;
/* Processor? Decide if mode is protected for older machines. */
- machine.processor=atoi(get_value(params_buffer, "processor"));
+ machine.processor=atoi(env_get("processor"));
/* XT, AT or MCA bus? */
- value = get_value(params_buffer, "bus");
+ value = env_get("bus");
if (value == NULL || strcmp(value, "at") == 0) {
machine.pc_at = TRUE; /* PC-AT compatible hardware */
} else if (strcmp(value, "mca") == 0) {
}
/* Type of VDU: */
- value = get_value(params_buffer, "video"); /* EGA or VGA video unit */
+ value = env_get("video"); /* EGA or VGA video unit */
if (strcmp(value, "ega") == 0) machine.vdu_ega = TRUE;
if (strcmp(value, "vga") == 0) machine.vdu_vga = machine.vdu_ega = TRUE;
/* Get clock tick frequency. */
- value = get_value(params_buffer, "hz");
+ value = env_get("hz");
if(value)
system_hz = atoi(value);
if(!value || system_hz < 2 || system_hz > 50000) /* sanity check */
system_hz = DEFAULT_HZ;
- value = get_value(params_buffer, SERVARNAME);
+ value = env_get(SERVARNAME);
if(value && atoi(value) == 0)
do_serial_debug=1;
#ifdef CONFIG_APIC
- value = get_value(params_buffer, "no_apic");
+ value = env_get("no_apic");
if(value)
config_no_apic = atoi(value);
else
#endif
#ifdef CONFIG_WATCHDOG
- value = get_value(params_buffer, "watchdog");
+ value = env_get("watchdog");
if (value)
watchdog_enabled = atoi(value);
#endif
}
return(NULL);
}
+
+/*===========================================================================*
+ * env_get *
+ *===========================================================================*/
+PUBLIC char *env_get(const char *name)
+{
+ return get_value(params_buffer, name);
+}
+