mirror of
https://github.com/hermitcore/libhermit.git
synced 2025-03-09 00:00:03 +01:00
add option to define uart port via kernel parameters
This commit is contained in:
parent
ff44f5fa39
commit
26825756a2
10 changed files with 474 additions and 40 deletions
|
@ -69,6 +69,7 @@ align 4
|
|||
global hbmem_size
|
||||
global uhyve
|
||||
global image_size
|
||||
global uartport
|
||||
base dq 0
|
||||
limit dq 0
|
||||
cpu_freq dd 0
|
||||
|
@ -93,6 +94,7 @@ align 4
|
|||
hbmem_base dq 0
|
||||
hbmem_size dq 0
|
||||
uhyve dd 0
|
||||
uartport dq 0
|
||||
|
||||
; Bootstrap page tables are used during the initialization.
|
||||
align 4096
|
||||
|
|
|
@ -99,28 +99,28 @@
|
|||
|
||||
#define DEFAULT_UART_PORT 0xc110
|
||||
|
||||
static size_t iobase = 0;
|
||||
extern size_t uartport;
|
||||
|
||||
static inline unsigned char read_from_uart(uint32_t off)
|
||||
{
|
||||
uint8_t c = 0;
|
||||
|
||||
if (iobase)
|
||||
c = inportb(iobase + off);
|
||||
if (uartport)
|
||||
c = inportb(uartport + off);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static inline void write_to_uart(uint32_t off, unsigned char c)
|
||||
{
|
||||
if (iobase)
|
||||
outportb(iobase + off, c);
|
||||
if (uartport)
|
||||
outportb(uartport + off, c);
|
||||
}
|
||||
|
||||
/* Puts a single character on a serial device */
|
||||
int uart_putchar(unsigned char c)
|
||||
{
|
||||
if (!iobase)
|
||||
if (!uartport)
|
||||
return 0;
|
||||
|
||||
write_to_uart(UART_TX, c);
|
||||
|
@ -133,7 +133,7 @@ int uart_puts(const char *text)
|
|||
{
|
||||
size_t i, len = strlen(text);
|
||||
|
||||
if (!iobase)
|
||||
if (!uartport)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
|
@ -188,6 +188,9 @@ int uart_init(void)
|
|||
if (is_uhyve())
|
||||
return 0;
|
||||
|
||||
if (uartport)
|
||||
return uart_config();
|
||||
|
||||
pci_info_t pci_info;
|
||||
uint32_t bar = 0;
|
||||
|
||||
|
@ -205,15 +208,16 @@ int uart_init(void)
|
|||
goto Lsuccess;
|
||||
|
||||
// default value of our QEMU configuration
|
||||
iobase = DEFAULT_UART_PORT;
|
||||
uartport = DEFAULT_UART_PORT;
|
||||
|
||||
// configure uart
|
||||
return uart_config();;
|
||||
return uart_config();
|
||||
|
||||
Lsuccess:
|
||||
iobase = pci_info.base[bar];
|
||||
uartport = pci_info.base[bar];
|
||||
|
||||
//irq_install_handler(32+pci_info.irq, uart_handler);
|
||||
kprintf("UART uses io address 0x%x\n", iobase);
|
||||
kprintf("UART uses io address 0x%x\n", uartport);
|
||||
|
||||
// configure uart
|
||||
return uart_config();
|
||||
|
|
129
arch/x86/loader/include/ctype.h
Normal file
129
arch/x86/loader/include/ctype.h
Normal file
|
@ -0,0 +1,129 @@
|
|||
/****************************************************************************************
|
||||
*
|
||||
* Author: Stefan Lankes
|
||||
* Chair for Operating Systems, RWTH Aachen University
|
||||
* Date: 24/03/2011
|
||||
*
|
||||
****************************************************************************************
|
||||
*
|
||||
* Written by the Chair for Operating Systems, RWTH Aachen University
|
||||
*
|
||||
* NO Copyright (C) 2010, Stefan Lankes,
|
||||
* consider these trivial functions to be public domain.
|
||||
*
|
||||
* These functions are distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author Stefan Lankes
|
||||
* @file include/ctype.h
|
||||
* @brief Functions related to alphanumerical character values
|
||||
*
|
||||
* This file contains functions helping to determine
|
||||
* the type of alphanumerical character values.
|
||||
*/
|
||||
|
||||
#ifndef __CTYPE_H_
|
||||
#define __CYTPE_H_
|
||||
|
||||
/** Returns true if the value of 'c' is an ASCII-charater */
|
||||
static inline int isascii(int c)
|
||||
{
|
||||
return (((unsigned char)(c))<=0x7f);
|
||||
}
|
||||
|
||||
/** Applies an and-operation to
|
||||
* push the value of 'c' into the ASCII-range */
|
||||
static inline int toascii(int c)
|
||||
{
|
||||
return (((unsigned char)(c))&0x7f);
|
||||
}
|
||||
|
||||
/** Returns true if the value of 'c' is the
|
||||
* space character or a control character */
|
||||
static inline int isspace(int c)
|
||||
{
|
||||
if (!isascii(c))
|
||||
return 0;
|
||||
|
||||
if (' ' == (unsigned char) c)
|
||||
return 1;
|
||||
if ('\n' == (unsigned char) c)
|
||||
return 1;
|
||||
if ('\r' == (unsigned char) c)
|
||||
return 1;
|
||||
if ('\t' == (unsigned char) c)
|
||||
return 1;
|
||||
if ('\v' == (unsigned char) c)
|
||||
return 1;
|
||||
if ('\f' == (unsigned char) c)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Returns true if the value of 'c' is a number */
|
||||
static inline int isdigit(int c)
|
||||
{
|
||||
if (!isascii(c))
|
||||
return 0;
|
||||
|
||||
if (((unsigned char) c >= '0') && ((unsigned char) c <= '9'))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Returns true if the value of 'c' is a lower case letter */
|
||||
static inline int islower(int c)
|
||||
{
|
||||
if (!isascii(c))
|
||||
return 0;
|
||||
|
||||
if (((unsigned char) c >= 'a') && ((unsigned char) c <= 'z'))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Returns true if the value of 'c' is an upper case letter */
|
||||
static inline int isupper(int c)
|
||||
{
|
||||
if (!isascii(c))
|
||||
return 0;
|
||||
|
||||
if (((unsigned char) c >= 'A') && ((unsigned char) c <= 'Z'))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Returns true if the value of 'c' is an alphabetic character */
|
||||
static inline int isalpha(int c)
|
||||
{
|
||||
if (isupper(c) || islower(c))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Makes the input character lower case.\n Will do nothing if it
|
||||
* was something different than an upper case letter before. */
|
||||
static inline unsigned char tolower(unsigned char c)
|
||||
{
|
||||
if (isupper(c))
|
||||
c -= 'A'-'a';
|
||||
return c;
|
||||
}
|
||||
|
||||
/** Makes the input character upper case.\n Will do nothing if it
|
||||
* was something different than a lower case letter before. */
|
||||
static inline unsigned char toupper(unsigned char c)
|
||||
{
|
||||
if (islower(c))
|
||||
c -= 'a'-'A';
|
||||
return c;
|
||||
}
|
||||
|
||||
#endif
|
87
arch/x86/loader/include/limits.h
Normal file
87
arch/x86/loader/include/limits.h
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2010, Stefan Lankes, RWTH Aachen University
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* author Stefan Lankes
|
||||
* @file include/limits.h
|
||||
* @brief Define constants related to numerical value-ranges of variable types
|
||||
*
|
||||
* This file contains define constants for the numerical
|
||||
* ranges of the most typical variable types.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_LIMITS_H__
|
||||
#define __ARCH_LIMITS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Number of bits in a char */
|
||||
#define CHAR_BIT 8
|
||||
|
||||
/** Maximum value for a signed char */
|
||||
#define SCHAR_MAX 0x7f
|
||||
/** Minimum value for a signed char */
|
||||
#define SCHAR_MIN (-0x7f - 1)
|
||||
|
||||
/** Maximum value for an unsigned char */
|
||||
#define UCHAR_MAX 0xff
|
||||
|
||||
/** Maximum value for an unsigned short */
|
||||
#define USHRT_MAX 0xffff
|
||||
/** Maximum value for a short */
|
||||
#define SHRT_MAX 0x7fff
|
||||
/** Minimum value for a short */
|
||||
#define SHRT_MIN (-0x7fff - 1)
|
||||
|
||||
/** Maximum value for an unsigned int */
|
||||
#define UINT_MAX 0xffffffffU
|
||||
/** Maximum value for an int */
|
||||
#define INT_MAX 0x7fffffff
|
||||
/** Minimum value for an int */
|
||||
#define INT_MIN (-0x7fffffff - 1)
|
||||
|
||||
/** Maximum value for an unsigned long */
|
||||
#define ULONG_MAX 0xffffffffUL
|
||||
/** Maximum value for a long */
|
||||
#define LONG_MAX 0x7fffffffL
|
||||
/** Minimum value for a long */
|
||||
#define LONG_MIN (-0x7fffffffL - 1)
|
||||
|
||||
/** Maximum value for an unsigned long long */
|
||||
#define ULLONG_MAX 0xffffffffffffffffULL
|
||||
/** Maximum value for a long long */
|
||||
#define LLONG_MAX 0x7fffffffffffffffLL
|
||||
/** Minimum value for a long long */
|
||||
#define LLONG_MIN (-0x7fffffffffffffffLL - 1)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -85,6 +85,14 @@ typedef char int8_t;
|
|||
/// 16 bit wide char type
|
||||
typedef unsigned short wchar_t;
|
||||
|
||||
/** @brief String to long
|
||||
*
|
||||
* @return Long value of the parsed numerical string
|
||||
*/
|
||||
long _strtol(const char* str, char** endptr, int base);
|
||||
|
||||
#define strtol(str, endptr, base) _strtol((str), (endptr), (base))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -41,7 +41,9 @@ char *strncpy(char *dest, const char *src, size_t n);
|
|||
char *strcpy(char *dest, const char *src);
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
int strncmp(const char *s1, const char *s2, size_t n);
|
||||
char *strstr(const char *s, const char *find);
|
||||
char *_strstr(const char *s, const char *find);
|
||||
|
||||
#define strstr(s, find) _strstr((s), (find))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ extern const void kernel_start;
|
|||
extern const void kernel_end;
|
||||
extern const void bss_start;
|
||||
extern const void bss_end;
|
||||
extern size_t uartport;
|
||||
|
||||
static int load_code(size_t viraddr, size_t phyaddr, size_t limit, uint32_t file_size, size_t mem_size)
|
||||
{
|
||||
|
@ -65,6 +66,7 @@ static int load_code(size_t viraddr, size_t phyaddr, size_t limit, uint32_t file
|
|||
*((uint32_t*) (viraddr + 0x30)) = 0; // apicid
|
||||
*((uint64_t*) (viraddr + 0x38)) = mem_size;
|
||||
*((uint32_t*) (viraddr + 0x60)) = 1; // numa nodes
|
||||
*((uint64_t*) (viraddr + 0x98)) = uartport;
|
||||
|
||||
// move file to a 2 MB boundary
|
||||
for(size_t va = viraddr+(npages << PAGE_BITS)+displacement-sizeof(uint8_t); va >= viraddr+displacement; va-=sizeof(uint8_t))
|
||||
|
|
73
arch/x86/loader/strstr.c
Normal file
73
arch/x86/loader/strstr.c
Normal file
|
@ -0,0 +1,73 @@
|
|||
/* $NetBSD: strstr.c,v 1.1 2005/12/20 19:28:52 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Chris Torek.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The code has been taken from NetBSD (sys/libkern/strstr.c) and is consequently
|
||||
* BSD-licensed. Unnecessary functions have been removed and all typedefs required
|
||||
* have been added.
|
||||
*/
|
||||
|
||||
/* HermiCore prelude */
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
|
||||
/*
|
||||
* Find the first occurrence of find in s.
|
||||
*/
|
||||
char *
|
||||
_strstr(s, find)
|
||||
const char *s, *find;
|
||||
{
|
||||
char c, sc;
|
||||
size_t len;
|
||||
|
||||
if (BUILTIN_EXPECT(!s, 0))
|
||||
return NULL;
|
||||
if (BUILTIN_EXPECT(!find, 0))
|
||||
return NULL;
|
||||
|
||||
if ((c = *find++) != 0) {
|
||||
len = strlen(find);
|
||||
do {
|
||||
do {
|
||||
if ((sc = *s++) == 0)
|
||||
return (NULL);
|
||||
} while (sc != c);
|
||||
} while (strncmp(s, find, len) != 0);
|
||||
s--;
|
||||
}
|
||||
return ((char *) s);
|
||||
}
|
132
arch/x86/loader/strtol.c
Normal file
132
arch/x86/loader/strtol.c
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Chris Torek.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* From: @(#)strtol.c 8.1 (Berkeley) 6/4/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* The code has been taken from FreeBSD (sys/libkern/strtol.c) and is consequently
|
||||
* BSD-licensed. Unnecessary functions have been removed and all typedefs required
|
||||
* have been added.
|
||||
*/
|
||||
|
||||
/* HermitCore prelude */
|
||||
#include <stddef.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
|
||||
/*
|
||||
* Convert a string to a long integer.
|
||||
*
|
||||
* Ignores `locale' stuff. Assumes that the upper and lower case
|
||||
* alphabets and digits are each contiguous.
|
||||
*/
|
||||
long
|
||||
_strtol(nptr, endptr, base)
|
||||
const char *nptr;
|
||||
char **endptr;
|
||||
int base;
|
||||
{
|
||||
const char *s = nptr;
|
||||
unsigned long acc;
|
||||
unsigned char c;
|
||||
unsigned long cutoff;
|
||||
int neg = 0, any, cutlim;
|
||||
|
||||
/*
|
||||
* Skip white space and pick up leading +/- sign if any.
|
||||
* If base is 0, allow 0x for hex and 0 for octal, else
|
||||
* assume decimal; if base is already 16, allow 0x.
|
||||
*/
|
||||
do {
|
||||
c = *s++;
|
||||
} while (isspace(c));
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else if (c == '+')
|
||||
c = *s++;
|
||||
if ((base == 0 || base == 16) &&
|
||||
c == '0' && (*s == 'x' || *s == 'X')) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '0' ? 8 : 10;
|
||||
|
||||
/*
|
||||
* Compute the cutoff value between legal numbers and illegal
|
||||
* numbers. That is the largest legal value, divided by the
|
||||
* base. An input number that is greater than this value, if
|
||||
* followed by a legal input character, is too big. One that
|
||||
* is equal to this value may be valid or not; the limit
|
||||
* between valid and invalid numbers is then based on the last
|
||||
* digit. For instance, if the range for longs is
|
||||
* [-2147483648..2147483647] and the input base is 10,
|
||||
* cutoff will be set to 214748364 and cutlim to either
|
||||
* 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
|
||||
* a value > 214748364, or equal but the next digit is > 7 (or 8),
|
||||
* the number is too big, and we will return a range error.
|
||||
*
|
||||
* Set any if any `digits' consumed; make it negative to indicate
|
||||
* overflow.
|
||||
*/
|
||||
cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
|
||||
cutlim = cutoff % (unsigned long)base;
|
||||
cutoff /= (unsigned long)base;
|
||||
for (acc = 0, any = 0;; c = *s++) {
|
||||
if (!isascii(c))
|
||||
break;
|
||||
if (isdigit(c))
|
||||
c -= '0';
|
||||
else if (isalpha(c))
|
||||
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
|
||||
any = -1;
|
||||
else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
if (any < 0) {
|
||||
acc = neg ? LONG_MIN : LONG_MAX;
|
||||
} else if (neg)
|
||||
acc = -acc;
|
||||
if (endptr != 0)
|
||||
*((const char **)endptr) = any ? s - 1 : nptr;
|
||||
return (acc);
|
||||
}
|
|
@ -92,28 +92,28 @@
|
|||
|
||||
#define DEFAULT_UART_PORT 0 //0xc110
|
||||
|
||||
static size_t iobase = 0;
|
||||
size_t uartport = 0;
|
||||
|
||||
static inline unsigned char read_from_uart(uint32_t off)
|
||||
{
|
||||
uint8_t c;
|
||||
|
||||
if (iobase)
|
||||
c = inportb(iobase + off);
|
||||
if (uartport)
|
||||
c = inportb(uartport + off);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static void write_to_uart(uint32_t off, unsigned char c)
|
||||
{
|
||||
if (iobase)
|
||||
outportb(iobase + off, c);
|
||||
if (uartport)
|
||||
outportb(uartport + off, c);
|
||||
}
|
||||
|
||||
/* Puts a single character on a serial device */
|
||||
int uart_putchar(unsigned char c)
|
||||
{
|
||||
if (!iobase)
|
||||
if (!uartport)
|
||||
return 0;
|
||||
|
||||
write_to_uart(UART_TX, c);
|
||||
|
@ -126,7 +126,7 @@ int uart_puts(const char *text)
|
|||
{
|
||||
size_t i, len = strlen(text);
|
||||
|
||||
if (!iobase)
|
||||
if (!uartport)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
|
@ -137,7 +137,7 @@ int uart_puts(const char *text)
|
|||
|
||||
static int uart_config(void)
|
||||
{
|
||||
if (!iobase)
|
||||
if (!uartport)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
|
@ -181,24 +181,16 @@ extern const void kernel_start;
|
|||
|
||||
int uart_early_init(char* cmdline)
|
||||
{
|
||||
#if 1
|
||||
// default value of our QEMU configuration
|
||||
iobase = DEFAULT_UART_PORT;
|
||||
#else
|
||||
if (BUILTIN_EXPECT(!cmdline, 0))
|
||||
return -EINVAL;
|
||||
char* str = NULL;
|
||||
|
||||
char* str = strstr(cmdline, "uart=");
|
||||
if (!str)
|
||||
return -EINVAL;
|
||||
|
||||
if (strncmp(str, "uart=io:", 8) == 0) {
|
||||
iobase = strtol(str+8, (char **)NULL, 16);
|
||||
if (!iobase)
|
||||
iobase = DEFAULT_UART_PORT;
|
||||
return -EINVAL;
|
||||
if (!cmdline || ((str = strstr(cmdline, "uart=io:")) == NULL)) {
|
||||
// default value of our QEMU configuration
|
||||
uartport = DEFAULT_UART_PORT;
|
||||
} else {
|
||||
uartport = strtol(str+8, (char **)NULL, 16);
|
||||
if (!uartport)
|
||||
uartport = DEFAULT_UART_PORT;
|
||||
}
|
||||
#endif
|
||||
|
||||
// configure uart
|
||||
return uart_config();
|
||||
|
@ -206,6 +198,9 @@ int uart_early_init(char* cmdline)
|
|||
|
||||
int uart_init(void)
|
||||
{
|
||||
if (uartport)
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
pci_info_t pci_info;
|
||||
uint32_t bar = 0;
|
||||
|
@ -223,20 +218,20 @@ int uart_init(void)
|
|||
if (pci_get_device_info(0x1b36, 0x0004, &pci_info) == 0)
|
||||
goto Lsuccess;
|
||||
|
||||
iobase = DEFAULT_UART_PORT;
|
||||
uartport = DEFAULT_UART_PORT;
|
||||
|
||||
return uart_config();
|
||||
|
||||
Lsuccess:
|
||||
iobase = pci_info.base[bar];
|
||||
uartport = pci_info.base[bar];
|
||||
//irq_install_handler(32+pci_info.irq, uart_handler);
|
||||
kprintf("UART uses io address 0x%x\n", iobase);
|
||||
kprintf("UART uses io address 0x%x\n", uartport);
|
||||
|
||||
// configure uart
|
||||
return uart_config();
|
||||
#else
|
||||
// default value of our QEMU configuration
|
||||
iobase = DEFAULT_UART_PORT;
|
||||
uartport = DEFAULT_UART_PORT;
|
||||
|
||||
// configure uart
|
||||
return uart_config();
|
||||
|
|
Loading…
Add table
Reference in a new issue