mirror of
https://github.com/ipxe/ipxe
synced 2026-02-14 02:31:26 +03:00
Merged mcb30-realmode-redesign back to HEAD
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
#ifdef CONSOLE_BTEXT
|
||||
#ifdef CONFIG_PCI
|
||||
/*
|
||||
* Procedures for drawing on the screen early on in the boot process.
|
||||
*
|
||||
@@ -10,6 +8,8 @@
|
||||
*/
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "console.h"
|
||||
#include "init.h"
|
||||
#include "pci.h"
|
||||
|
||||
#ifdef CONFIG_FILO
|
||||
@@ -36,6 +36,8 @@ static void draw_byte_16(unsigned char *bits, u32 *base, u32 rb);
|
||||
#endif
|
||||
static void draw_byte_8(unsigned char *bits, u32 *base, u32 rb);
|
||||
|
||||
static int pci_find_device_x(int vendorx, int devicex, int index, struct pci_device *dev);
|
||||
|
||||
static u32 g_loc_X;
|
||||
static u32 g_loc_Y;
|
||||
static u32 g_max_loc_X;
|
||||
@@ -62,7 +64,7 @@ boot_infos_t disp_bi;
|
||||
/* This function will enable the early boot text when doing OF booting. This
|
||||
* way, xmon output should work too
|
||||
*/
|
||||
void
|
||||
static void
|
||||
btext_setup_display(u32 width, u32 height, u32 depth, u32 pitch,
|
||||
unsigned long address)
|
||||
{
|
||||
@@ -73,7 +75,7 @@ btext_setup_display(u32 width, u32 height, u32 depth, u32 pitch,
|
||||
g_max_loc_X = width / 8;
|
||||
g_max_loc_Y = height / 16;
|
||||
// bi->logicalDisplayBase = (unsigned char *)address;
|
||||
bi->dispDeviceBase = (unsigned char *)address;
|
||||
bi->dispDeviceBase = address;
|
||||
bi->dispDeviceRowBytes = pitch;
|
||||
bi->dispDeviceDepth = depth;
|
||||
bi->dispDeviceRect[0] = bi->dispDeviceRect[1] = 0;
|
||||
@@ -93,7 +95,7 @@ btext_setup_display(u32 width, u32 height, u32 depth, u32 pitch,
|
||||
* changes.
|
||||
*/
|
||||
|
||||
void
|
||||
static void
|
||||
map_boot_text(void)
|
||||
{
|
||||
boot_infos_t *bi = &disp_bi;
|
||||
@@ -113,18 +115,19 @@ static unsigned char * BTEXT
|
||||
calc_base(boot_infos_t *bi, u32 x, u32 y)
|
||||
{
|
||||
unsigned char *base;
|
||||
#if 1
|
||||
base = bi->logicalDisplayBase;
|
||||
#if 0
|
||||
/* Ummm... which moron wrote this? */
|
||||
if (base == 0)
|
||||
#endif
|
||||
base = bi->dispDeviceBase;
|
||||
#endif
|
||||
base += (x + bi->dispDeviceRect[0]) * (bi->dispDeviceDepth >> 3);
|
||||
base += (y + bi->dispDeviceRect[1]) * bi->dispDeviceRowBytes;
|
||||
return base;
|
||||
}
|
||||
|
||||
|
||||
void BTEXT btext_clearscreen(void)
|
||||
static void BTEXT btext_clearscreen(void)
|
||||
{
|
||||
boot_infos_t* bi = &disp_bi;
|
||||
u32 *base = (u32 *)calc_base(bi, 0, 0);
|
||||
@@ -147,7 +150,7 @@ __inline__ void dcbst(const void* addr)
|
||||
__asm__ __volatile__ ("dcbst 0,%0" :: "r" (addr));
|
||||
}
|
||||
|
||||
void BTEXT btext_flushscreen(void)
|
||||
static void BTEXT btext_flushscreen(void)
|
||||
{
|
||||
boot_infos_t* bi = &disp_bi;
|
||||
u32 *base = (unsigned long *)calc_base(bi, 0, 0);
|
||||
@@ -198,7 +201,7 @@ scrollscreen(void)
|
||||
}
|
||||
#endif /* ndef NO_SCROLL */
|
||||
|
||||
void BTEXT btext_drawchar(char c)
|
||||
static void BTEXT btext_drawchar(char c)
|
||||
{
|
||||
u32 cline = 0;
|
||||
|
||||
@@ -246,7 +249,7 @@ void BTEXT btext_drawchar(char c)
|
||||
#endif
|
||||
}
|
||||
#if 0
|
||||
void BTEXT
|
||||
static void BTEXT
|
||||
btext_drawstring(const char *c)
|
||||
{
|
||||
if (!boot_text_mapped)
|
||||
@@ -254,7 +257,7 @@ btext_drawstring(const char *c)
|
||||
while (*c)
|
||||
btext_drawchar(*c++);
|
||||
}
|
||||
void BTEXT
|
||||
static void BTEXT
|
||||
btext_drawhex(u32 v)
|
||||
{
|
||||
static char hex_table[] = "0123456789abcdef";
|
||||
@@ -394,7 +397,7 @@ draw_byte_8(unsigned char *font, u32 *base, u32 rb)
|
||||
#endif
|
||||
|
||||
|
||||
void btext_init(void)
|
||||
static void btext_init(void)
|
||||
{
|
||||
#if 0
|
||||
// for debug
|
||||
@@ -402,14 +405,16 @@ void btext_init(void)
|
||||
#else
|
||||
uint32_t frame_buffer;// 0xfc000000
|
||||
|
||||
struct pci_device *dev = 0;
|
||||
|
||||
#if USE_FILO_PCI_FIND==0
|
||||
struct pci_device dev;
|
||||
|
||||
pci_find_device_x(0x1002, 0x4752, 0, &dev);
|
||||
if(dev.vendor==0) return; // no fb
|
||||
|
||||
frame_buffer = (uint32_t)dev.membase;
|
||||
#else
|
||||
struct pci_device *dev = 0;
|
||||
|
||||
pci_init();
|
||||
dev = pci_find_device(0x1002, 0x4752, -1, -1, 0);
|
||||
if(!dev) {
|
||||
@@ -422,21 +427,21 @@ void btext_init(void)
|
||||
#endif
|
||||
|
||||
btext_setup_display(640, 480, 8, 640,frame_buffer);
|
||||
// btext_clearscreen(); //move to main
|
||||
// map_boot_text(); //move console_init
|
||||
btext_clearscreen();
|
||||
map_boot_text();
|
||||
}
|
||||
void btext_putc(int c)
|
||||
static void btext_putc(int c)
|
||||
{
|
||||
btext_drawchar((unsigned char)c);
|
||||
}
|
||||
#if 0
|
||||
static struct console_driver btext_console __console = {
|
||||
.init = btext_init,
|
||||
.tx_byte = btext_tx_byte,
|
||||
.rx_byte = 0,
|
||||
.tst_byte = 0,
|
||||
|
||||
static struct console_driver btext_console __console_driver = {
|
||||
.putchar = btext_putc,
|
||||
.disabled = 1,
|
||||
};
|
||||
#endif
|
||||
|
||||
INIT_FN ( INIT_CONSOLE, btext_init, NULL, NULL );
|
||||
|
||||
#if USE_FILO_PCI_FIND==0
|
||||
int pci_find_device_x(int vendorx, int devicex, int index, struct pci_device *dev)
|
||||
{
|
||||
@@ -445,7 +450,6 @@ int pci_find_device_x(int vendorx, int devicex, int index, struct pci_device *de
|
||||
#if 1
|
||||
unsigned char hdr_type = 0;
|
||||
#endif
|
||||
uint32_t class;
|
||||
uint16_t vendor, device;
|
||||
uint32_t l, membase;
|
||||
#if 0
|
||||
@@ -5192,5 +5196,3 @@ static unsigned char vga_font[cmapsz] BTDATA = {
|
||||
0x00, /* 00000000 */
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "nic.h"
|
||||
#include "console.h"
|
||||
#ifdef BUILD_SERIAL
|
||||
#include ".buildserial.h"
|
||||
#define xstr(s) str(s)
|
||||
@@ -104,6 +105,9 @@ void print_config(void)
|
||||
"DNS "
|
||||
#endif
|
||||
"\n");
|
||||
#ifdef KEEP_IT_REAL
|
||||
printf( "Keeping It Real [EXPERIMENTAL]\n" );
|
||||
#endif
|
||||
}
|
||||
|
||||
static const char *driver_name[] = {
|
||||
@@ -159,3 +163,48 @@ void disable(struct dev *dev)
|
||||
dev->disable = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Drag in all requested console types
|
||||
*
|
||||
* At least one of the CONSOLE_xxx has to be set. CONSOLE_DUAL sets
|
||||
* both CONSOLE_FIRMWARE and CONSOLE_SERIAL for legacy compatibility.
|
||||
* If no CONSOLE_xxx is set, CONSOLE_FIRMWARE is assumed.
|
||||
*/
|
||||
|
||||
#ifdef CONSOLE_CRT
|
||||
#define CONSOLE_FIRMWARE
|
||||
#endif
|
||||
|
||||
#ifdef CONSOLE_DUAL
|
||||
#undef CONSOLE_FIRMWARE
|
||||
#define CONSOLE_FIRMWARE
|
||||
#undef CONSOLE_SERIAL
|
||||
#define CONSOLE_SERIAL
|
||||
#endif
|
||||
|
||||
#if !defined(CONSOLE_FIRMWARE) && !defined(CONSOLE_SERIAL)
|
||||
#define CONSOLE_FIRMWARE
|
||||
#endif
|
||||
|
||||
#ifdef CONSOLE_FIRMWARE
|
||||
REQUIRE_OBJECT ( bios_console );
|
||||
#endif
|
||||
|
||||
#ifdef CONSOLE_SERIAL
|
||||
REQUIRE_OBJECT ( serial );
|
||||
#endif
|
||||
|
||||
#ifdef CONSOLE_DIRECT_VGA
|
||||
REQUIRE_OBJECT ( video_subr );
|
||||
#endif
|
||||
|
||||
#ifdef CONSOLE_BTEXT
|
||||
REQUIRE_OBJECT ( btext );
|
||||
#endif
|
||||
|
||||
#ifdef CONSOLE_PC_KBD
|
||||
REQUIRE_OBJECT ( pc_kbd );
|
||||
#endif
|
||||
|
||||
|
||||
102
src/core/console.c
Normal file
102
src/core/console.c
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Central console switch. Various console devices can be selected
|
||||
* via the build options CONSOLE_FIRMWARE, CONSOLE_SERIAL etc.
|
||||
* config.c picks up on these definitions and drags in the relevant
|
||||
* objects. The linker compiles the console_drivers table for us; we
|
||||
* simply delegate to each console_driver that we find in the table.
|
||||
*
|
||||
* Doing it this way allows for changing CONSOLE_XXX without
|
||||
* rebuilding anything other than config.o. This is extremely useful
|
||||
* for rom-o-matic.
|
||||
*/
|
||||
|
||||
#include "stddef.h"
|
||||
#include "console.h"
|
||||
|
||||
/* FIXME: we need a cleaner way to pick up cpu_nap(). It makes a
|
||||
* real-mode call, and so we don't want to use it with LinuxBIOS.
|
||||
*/
|
||||
#include "bios.h"
|
||||
|
||||
extern struct console_driver console_drivers[];
|
||||
extern struct console_driver console_drivers_end[];
|
||||
|
||||
/*****************************************************************************
|
||||
* putchar : write a single character to each console
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
void putchar ( int character ) {
|
||||
struct console_driver *console;
|
||||
|
||||
/* Automatic LF -> CR,LF translation */
|
||||
if ( character == '\n' )
|
||||
putchar ( '\r' );
|
||||
|
||||
for ( console = console_drivers; console < console_drivers_end ;
|
||||
console++ ) {
|
||||
if ( ( ! console->disabled ) && console->putchar )
|
||||
console->putchar ( character );
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* has_input : check to see if any input is available on any console,
|
||||
* and return a pointer to the console device if so
|
||||
*****************************************************************************
|
||||
*/
|
||||
static struct console_driver * has_input ( void ) {
|
||||
struct console_driver *console;
|
||||
|
||||
for ( console = console_drivers; console < console_drivers_end ;
|
||||
console++ ) {
|
||||
if ( ( ! console->disabled ) && console->iskey ) {
|
||||
if ( console->iskey () )
|
||||
return console;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* getchar : read a single character from any console
|
||||
*
|
||||
* NOTE : this function does not echo the character, and it does block
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
int getchar ( void ) {
|
||||
struct console_driver *console;
|
||||
int character = 256;
|
||||
|
||||
while ( character == 256 ) {
|
||||
/* Doze for a while (until the next interrupt). This works
|
||||
* fine, because the keyboard is interrupt-driven, and the
|
||||
* timer interrupt (approx. every 50msec) takes care of the
|
||||
* serial port, which is read by polling. This reduces the
|
||||
* power dissipation of a modern CPU considerably, and also
|
||||
* makes Etherboot waiting for user interaction waste a lot
|
||||
* less CPU time in a VMware session.
|
||||
*/
|
||||
cpu_nap();
|
||||
|
||||
console = has_input();
|
||||
if ( console && console->getchar )
|
||||
character = console->getchar ();
|
||||
}
|
||||
|
||||
/* CR -> LF translation */
|
||||
if ( character == '\r' )
|
||||
character = '\n';
|
||||
|
||||
return character;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* iskey : check to see if any input is available on any console
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
int iskey ( void ) {
|
||||
return has_input() ? 1 : 0;
|
||||
}
|
||||
@@ -1,8 +1,12 @@
|
||||
#include "etherboot.h"
|
||||
#include "init.h"
|
||||
#include "memsizes.h"
|
||||
|
||||
size_t heap_ptr, heap_top, heap_bot;
|
||||
|
||||
void init_heap(void)
|
||||
#define _virt_start 0
|
||||
|
||||
static void init_heap(void)
|
||||
{
|
||||
size_t size;
|
||||
size_t start, end;
|
||||
@@ -82,6 +86,11 @@ void init_heap(void)
|
||||
heap_ptr = heap_bot;
|
||||
}
|
||||
|
||||
static void reset_heap(void)
|
||||
{
|
||||
heap_ptr = heap_bot;
|
||||
}
|
||||
|
||||
void *allot(size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
@@ -166,3 +175,5 @@ void forget2(void *ptr)
|
||||
}
|
||||
heap_ptr = addr;
|
||||
}
|
||||
|
||||
INIT_FN ( INIT_HEAP, init_heap, reset_heap, NULL );
|
||||
|
||||
44
src/core/init.c
Normal file
44
src/core/init.c
Normal file
@@ -0,0 +1,44 @@
|
||||
/**************************************************************************
|
||||
* call_{init,reset,exit}_fns ()
|
||||
*
|
||||
* Call the various initialisation and exit functions. We use a
|
||||
* function table so that we don't end up dragging in an object just
|
||||
* because we call its initialisation function.
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#include "init.h"
|
||||
|
||||
extern struct init_fn init_fns[];
|
||||
extern struct init_fn init_fns_end[];
|
||||
|
||||
void call_init_fns ( void ) {
|
||||
struct init_fn *init_fn;
|
||||
|
||||
for ( init_fn = init_fns; init_fn < init_fns_end ; init_fn++ ) {
|
||||
if ( init_fn->init )
|
||||
init_fn->init ();
|
||||
}
|
||||
}
|
||||
|
||||
void call_reset_fns ( void ) {
|
||||
struct init_fn *init_fn;
|
||||
|
||||
for ( init_fn = init_fns; init_fn < init_fns_end ; init_fn++ ) {
|
||||
if ( init_fn->reset )
|
||||
init_fn->reset ();
|
||||
}
|
||||
}
|
||||
|
||||
void call_exit_fns ( void ) {
|
||||
struct init_fn *init_fn;
|
||||
|
||||
/*
|
||||
* Exit functions are called in reverse order to
|
||||
* initialisation functions.
|
||||
*/
|
||||
for ( init_fn = init_fns_end - 1; init_fn >= init_fns ; init_fn-- ) {
|
||||
if ( init_fn->exit )
|
||||
init_fn->exit ();
|
||||
}
|
||||
}
|
||||
137
src/core/main.c
137
src/core/main.c
@@ -23,12 +23,10 @@ Literature dealing with the network protocols:
|
||||
#include "http.h"
|
||||
#include "timer.h"
|
||||
#include "cpu.h"
|
||||
#include "console.h"
|
||||
#include "init.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef CONSOLE_BTEXT
|
||||
#include "btext.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FILO
|
||||
#include <lib.h>
|
||||
#endif
|
||||
@@ -43,51 +41,6 @@ int freebsd_howto = 0;
|
||||
char freebsd_kernel_env[FREEBSD_KERNEL_ENV_SIZE];
|
||||
#endif
|
||||
|
||||
/* in_call(): the entry point to Etherboot. Generally called from
|
||||
* arch_in_call(), which in turn will have been invoked from
|
||||
* platform-specific assembly code.
|
||||
*/
|
||||
int in_call ( in_call_data_t *data, uint32_t opcode, va_list params ) {
|
||||
int old_as_main_program = as_main_program;
|
||||
int ret = 0;
|
||||
|
||||
/* Set flat to indicate that we are not running as the main
|
||||
* program (i.e. we are something like a PXE stack).
|
||||
*/
|
||||
as_main_program = 0;
|
||||
|
||||
/* NOTE: params will cease to be valid if we relocate, since
|
||||
* it represents a virtual address
|
||||
*/
|
||||
switch ( EB_OPCODE(opcode) ) {
|
||||
|
||||
case EB_OPCODE_CHECK:
|
||||
/* Installation check
|
||||
*/
|
||||
ret = EB_CHECK_RESULT;
|
||||
break;
|
||||
case EB_OPCODE_MAIN:
|
||||
/* Start up Etherboot as a standalone program. */
|
||||
as_main_program = 1;
|
||||
ret = main ( data, params );
|
||||
break;
|
||||
#ifdef PXE_EXPORT
|
||||
case EB_OPCODE_PXE:
|
||||
/* !PXE API call */
|
||||
ret = pxe_in_call ( data, params );
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printf ( "Unsupported API \"%c%c\"\n",
|
||||
EB_OPCODE(opcode) >> 8, EB_OPCODE(opcode) & 0xff );
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
as_main_program = old_as_main_program;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline unsigned long ask_boot(unsigned *index)
|
||||
{
|
||||
unsigned long order = DEFAULT_BOOT_ORDER;
|
||||
@@ -166,26 +119,6 @@ static inline void try_floppy_first(void)
|
||||
#endif /* TRY_FLOPPY_FIRST */
|
||||
}
|
||||
|
||||
void console_init(void)
|
||||
{
|
||||
#ifdef CONSOLE_SERIAL
|
||||
(void)serial_init();
|
||||
#endif
|
||||
#ifdef CONSOLE_DIRECT_VGA
|
||||
video_init();
|
||||
#endif
|
||||
#ifdef CONSOLE_BTEXT
|
||||
map_boot_text();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void console_fini(void)
|
||||
{
|
||||
#ifdef CONSOLE_SERIAL
|
||||
(void)serial_fini();
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct class_operations {
|
||||
struct dev *dev;
|
||||
int (*probe)(struct dev *dev);
|
||||
@@ -204,44 +137,16 @@ static int exit_ok;
|
||||
static int exit_status;
|
||||
static int initialized;
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
MAIN - Kick off routine
|
||||
**************************************************************************/
|
||||
int main(in_call_data_t *data, va_list params)
|
||||
{
|
||||
char *p;
|
||||
int main ( void ) {
|
||||
int state;
|
||||
|
||||
for (p = _bss; p < _ebss; p++)
|
||||
*p = 0; /* Zero BSS */
|
||||
|
||||
console_init();
|
||||
arch_main(data,params);
|
||||
|
||||
#if 0
|
||||
#ifdef CONSOLE_BTEXT
|
||||
btext_init();
|
||||
map_boot_text();
|
||||
btext_clearscreen();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if ( rom.rom_segment ) {
|
||||
printf ( "ROM segment %#hx length %#hx reloc %#x\n",
|
||||
rom.rom_segment, rom.rom_length, _text );
|
||||
}
|
||||
|
||||
cpu_setup();
|
||||
setup_timers();
|
||||
gateA20_set();
|
||||
print_config();
|
||||
get_memsizes();
|
||||
cleanup();
|
||||
|
||||
#ifdef CONFIG_PCMCIA
|
||||
pcmcia_init_all();
|
||||
#endif
|
||||
|
||||
/* -1: timeout or ESC
|
||||
-2: error return from loader
|
||||
-3: finish the current run.
|
||||
@@ -258,10 +163,7 @@ int main(in_call_data_t *data, va_list params)
|
||||
for(;state != 255;) {
|
||||
state = main_loop(state);
|
||||
}
|
||||
arch_on_exit(exit_status);
|
||||
#ifdef CONFIG_PCMCIA
|
||||
pcmcia_shutdown_all();
|
||||
#endif
|
||||
/* arch_on_exit(exit_status) */
|
||||
return exit_status;
|
||||
}
|
||||
|
||||
@@ -283,13 +185,11 @@ static int main_loop(int state)
|
||||
static unsigned boot_index;
|
||||
static struct dev * dev = 0;
|
||||
static struct class_operations *ops;
|
||||
static void *heap_base;
|
||||
static int type;
|
||||
static int i;
|
||||
|
||||
if (!initialized) {
|
||||
initialized = 1;
|
||||
console_init();
|
||||
if (dev && (state >= 1) && (state <= 2)) {
|
||||
dev->how_probe = PROBE_AWAKE;
|
||||
dev->how_probe = ops->probe(dev);
|
||||
@@ -304,21 +204,8 @@ static int main_loop(int state)
|
||||
static int firsttime = 1;
|
||||
/* First time through */
|
||||
if (firsttime) {
|
||||
relocate();
|
||||
/* relocate(); */
|
||||
cleanup();
|
||||
console_init();
|
||||
init_heap();
|
||||
#ifdef CONSOLE_BTEXT
|
||||
//I need to all allot
|
||||
btext_init();
|
||||
map_boot_text();
|
||||
btext_clearscreen();
|
||||
#else
|
||||
#ifdef CONFIG_FILO
|
||||
pci_init();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
firsttime = 0;
|
||||
}
|
||||
#ifdef EXIT_IF_NO_OFFER
|
||||
@@ -327,7 +214,6 @@ static int main_loop(int state)
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
heap_base = allot(0);
|
||||
i = -1;
|
||||
state = 4;
|
||||
dev = 0;
|
||||
@@ -339,8 +225,7 @@ static int main_loop(int state)
|
||||
}
|
||||
case 4:
|
||||
cleanup();
|
||||
console_init();
|
||||
forget(heap_base);
|
||||
call_reset_fns();
|
||||
/* Find a dev entry to probe with */
|
||||
if (!dev) {
|
||||
int boot;
|
||||
@@ -377,7 +262,12 @@ static int main_loop(int state)
|
||||
break;
|
||||
case 3:
|
||||
state = -1;
|
||||
heap_base = allot(0);
|
||||
/* Removed the following line because it was causing
|
||||
* heap.o to be dragged in unnecessarily. It's also
|
||||
* slightly puzzling: by resetting heap_base, doesn't
|
||||
* this mean that we permanently leak memory?
|
||||
*/
|
||||
/* heap_base = allot(0); */
|
||||
dev->how_probe = ops->probe(dev);
|
||||
if (dev->how_probe == PROBE_FAILED) {
|
||||
dev = 0;
|
||||
@@ -518,7 +408,6 @@ void cleanup(void)
|
||||
/* Stop receiving packets */
|
||||
eth_disable();
|
||||
disk_disable();
|
||||
console_fini();
|
||||
initialized = 0;
|
||||
}
|
||||
|
||||
|
||||
143
src/core/misc.c
143
src/core/misc.c
@@ -3,13 +3,7 @@ MISC Support Routines
|
||||
**************************************************************************/
|
||||
|
||||
#include "etherboot.h"
|
||||
#ifdef CONSOLE_BTEXT
|
||||
#include <btext.h>
|
||||
#endif
|
||||
#ifdef CONSOLE_PC_KBD
|
||||
#include <pc_kbd.h>
|
||||
#endif
|
||||
|
||||
#include "console.h"
|
||||
|
||||
/**************************************************************************
|
||||
IPCHKSUM - Checksum IP Header
|
||||
@@ -170,7 +164,6 @@ int inet_aton(const char *start, in_addr *i)
|
||||
return p - start;
|
||||
}
|
||||
|
||||
|
||||
unsigned long strtoul(const char *p, const char **endp, int base)
|
||||
{
|
||||
unsigned long ret = 0;
|
||||
@@ -185,140 +178,6 @@ unsigned long strtoul(const char *p, const char **endp, int base)
|
||||
|
||||
}
|
||||
|
||||
#define K_RDWR 0x60 /* keyboard data & cmds (read/write) */
|
||||
#define K_STATUS 0x64 /* keyboard status */
|
||||
#define K_CMD 0x64 /* keybd ctlr command (write-only) */
|
||||
|
||||
#define K_OBUF_FUL 0x01 /* output buffer full */
|
||||
#define K_IBUF_FUL 0x02 /* input buffer full */
|
||||
|
||||
#define KC_CMD_WIN 0xd0 /* read output port */
|
||||
#define KC_CMD_WOUT 0xd1 /* write output port */
|
||||
#define KB_SET_A20 0xdf /* enable A20,
|
||||
enable output buffer full interrupt
|
||||
enable data line
|
||||
disable clock line */
|
||||
#define KB_UNSET_A20 0xdd /* enable A20,
|
||||
enable output buffer full interrupt
|
||||
enable data line
|
||||
disable clock line */
|
||||
|
||||
enum { Disable_A20 = 0x2400, Enable_A20 = 0x2401, Query_A20_Status = 0x2402,
|
||||
Query_A20_Support = 0x2403 };
|
||||
|
||||
#if defined(PCBIOS) && !defined(IBM_L40)
|
||||
static void empty_8042(void)
|
||||
{
|
||||
unsigned long time;
|
||||
char st;
|
||||
|
||||
time = currticks() + TICKS_PER_SEC; /* max wait of 1 second */
|
||||
while ((((st = inb(K_CMD)) & K_OBUF_FUL) ||
|
||||
(st & K_IBUF_FUL)) &&
|
||||
currticks() < time)
|
||||
inb(K_RDWR);
|
||||
}
|
||||
#endif /* IBM_L40 */
|
||||
|
||||
#if defined(PCBIOS)
|
||||
/*
|
||||
* Gate A20 for high memory
|
||||
*/
|
||||
void gateA20_set(void)
|
||||
{
|
||||
#warning "gateA20_set should test to see if it is already set"
|
||||
if (int15(Enable_A20) == 0) {
|
||||
return;
|
||||
}
|
||||
#ifdef IBM_L40
|
||||
outb(0x2, 0x92);
|
||||
#else /* IBM_L40 */
|
||||
empty_8042();
|
||||
outb(KC_CMD_WOUT, K_CMD);
|
||||
empty_8042();
|
||||
outb(KB_SET_A20, K_RDWR);
|
||||
empty_8042();
|
||||
#endif /* IBM_L40 */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int last_putchar; // From filo
|
||||
|
||||
void
|
||||
putchar(int c)
|
||||
{
|
||||
c &= 0xff;
|
||||
last_putchar = c;
|
||||
|
||||
if (c == '\n')
|
||||
putchar('\r');
|
||||
#ifdef CONSOLE_FIRMWARE
|
||||
console_putc(c);
|
||||
#endif
|
||||
#ifdef CONSOLE_DIRECT_VGA
|
||||
vga_putc(c);
|
||||
#endif
|
||||
#ifdef CONSOLE_BTEXT
|
||||
btext_putc(c);
|
||||
#endif
|
||||
#ifdef CONSOLE_SERIAL
|
||||
serial_putc(c);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
GETCHAR - Read the next character from input device WITHOUT ECHO
|
||||
**************************************************************************/
|
||||
int getchar(void)
|
||||
{
|
||||
int c = 256;
|
||||
|
||||
do {
|
||||
#if defined(PCBIOS) && defined(POWERSAVE)
|
||||
/* Doze for a while (until the next interrupt). This works
|
||||
* fine, because the keyboard is interrupt-driven, and the
|
||||
* timer interrupt (approx. every 50msec) takes care of the
|
||||
* serial port, which is read by polling. This reduces the
|
||||
* power dissipation of a modern CPU considerably, and also
|
||||
* makes Etherboot waiting for user interaction waste a lot
|
||||
* less CPU time in a VMware session. */
|
||||
cpu_nap();
|
||||
#endif /* POWERSAVE */
|
||||
#ifdef CONSOLE_FIRMWARE
|
||||
if (console_ischar())
|
||||
c = console_getc();
|
||||
#endif
|
||||
#ifdef CONSOLE_SERIAL
|
||||
if (serial_ischar())
|
||||
c = serial_getc();
|
||||
#endif
|
||||
#ifdef CONSOLE_PC_KBD
|
||||
if (kbd_ischar())
|
||||
c = kbd_getc();
|
||||
#endif
|
||||
} while (c==256);
|
||||
if (c == '\r')
|
||||
c = '\n';
|
||||
return c;
|
||||
}
|
||||
|
||||
int iskey(void)
|
||||
{
|
||||
#ifdef CONSOLE_FIRMWARE
|
||||
if (console_ischar())
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef CONSOLE_SERIAL
|
||||
if (serial_ischar())
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef CONSOLE_PC_KBD
|
||||
if (kbd_ischar())
|
||||
return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if DEBUG_UTILS
|
||||
|
||||
|
||||
@@ -30,6 +30,22 @@ Modifications: Ken Yap (for Etherboot/16)
|
||||
*/
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "memsizes.h"
|
||||
|
||||
#ifdef KEEP_IT_REAL
|
||||
|
||||
#warning "All download mechanisms are broken under KEEP_IT_REAL"
|
||||
|
||||
os_download_t probe_image(unsigned char *data, unsigned int len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int load_block(unsigned char *data, unsigned int block, unsigned int len, int eof) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else /* KEEP_IT_REAL */
|
||||
|
||||
|
||||
struct os_entry_regs os_regs;
|
||||
|
||||
@@ -128,7 +144,7 @@ static void done(int do_cleanup)
|
||||
*/
|
||||
if ( do_cleanup ) {
|
||||
cleanup();
|
||||
arch_on_exit(0);
|
||||
/* arch_on_exit(0); */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,6 +277,7 @@ PROBE_IMAGE - Detect image file type
|
||||
os_download_t probe_image(unsigned char *data, unsigned int len)
|
||||
{
|
||||
os_download_t os_download = 0;
|
||||
|
||||
#ifdef AOUT_IMAGE
|
||||
if (!os_download) os_download = aout_probe(data, len);
|
||||
#endif
|
||||
@@ -286,6 +303,7 @@ os_download_t probe_image(unsigned char *data, unsigned int len)
|
||||
#ifdef RAW_IMAGE
|
||||
if (!os_download) os_download = raw_probe(data, len);
|
||||
#endif
|
||||
|
||||
return os_download;
|
||||
}
|
||||
|
||||
@@ -363,3 +381,4 @@ int load_block(unsigned char *data, unsigned int block, unsigned int len, int eo
|
||||
* End:
|
||||
*/
|
||||
|
||||
#endif /* KEEP_IT_REAL */
|
||||
|
||||
@@ -9,8 +9,9 @@
|
||||
* 2004-04 moved by LYH From filo to Etherboot
|
||||
* yhlu@tyan.com
|
||||
*/
|
||||
#ifdef CONSOLE_PC_KBD
|
||||
#include "etherboot.h"
|
||||
|
||||
#include "io.h"
|
||||
#include "console.h"
|
||||
|
||||
static char key_map[][128] = {
|
||||
{
|
||||
@@ -69,14 +70,14 @@ static int get_scancode(void)
|
||||
return scan;
|
||||
}
|
||||
|
||||
int kbd_havekey(void)
|
||||
static int kbd_havekey(void)
|
||||
{
|
||||
if (!cur_scan)
|
||||
cur_scan = get_scancode();
|
||||
return cur_scan != 0;
|
||||
}
|
||||
|
||||
int kbd_ischar(void)
|
||||
static int kbd_ischar(void)
|
||||
{
|
||||
if (!kbd_havekey())
|
||||
return 0;
|
||||
@@ -87,7 +88,7 @@ int kbd_ischar(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int kbd_getc(void)
|
||||
static int kbd_getc(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
@@ -105,4 +106,7 @@ int kbd_getc(void)
|
||||
cur_scan = 0;
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct console_driver pc_kbd_console __console_driver = {
|
||||
.getchar = kbd_getc,
|
||||
};
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#ifdef CONFIG_PCMCIA
|
||||
|
||||
/*
|
||||
* pcmcia.c
|
||||
*
|
||||
@@ -25,13 +23,13 @@
|
||||
* at some point. If there's anything obvious or better, not-so-obvious,
|
||||
* please contact me by e-mail: anselm (AT) hoffmeister (DOT) be *THANKS*
|
||||
*/
|
||||
#include "../include/pcmcia.h"
|
||||
#include "../include/i82365.h"
|
||||
#include "pcmcia.h"
|
||||
#include "i82365.h"
|
||||
#define CODE_STATUS "alpha"
|
||||
#define CODE_VERSION "0.1.3"
|
||||
|
||||
#include "../include/pcmcia-opts.h"
|
||||
#include "../include/pcmcia.h"
|
||||
#include "pcmcia-opts.h"
|
||||
#include "console.h"
|
||||
#include "init.h"
|
||||
|
||||
int sockets; /* AHTODO: Phase this out! */
|
||||
u_int pccsocks;
|
||||
@@ -55,7 +53,7 @@ void sleepticks(int numticks ) {
|
||||
return;
|
||||
}
|
||||
|
||||
int pcmcia_init_all(void) {
|
||||
static void pcmcia_init_all(void) {
|
||||
u_int i, j, k, l, m, n, ui, configs = 0;
|
||||
u_int multicard[8];
|
||||
u_char *uc, upc;
|
||||
@@ -253,17 +251,15 @@ int pcmcia_init_all(void) {
|
||||
getchar();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pcmcia_shutdown_all(void) {
|
||||
static void pcmcia_shutdown_all(void) {
|
||||
int i;
|
||||
//if ( PDEBUG > 2 ) {printf("<press key to continue>\n" ); getchar(); }
|
||||
for ( i = 0; i < pccsocks; ++i ) {
|
||||
driver[pccsock[i].drivernum].f(SHUTDOWN,pccsock[i].internalid,0,0,0);
|
||||
}
|
||||
printf("Shutdown of PCMCIA subsystem completed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PCMCIA */
|
||||
INIT_FN ( INIT_PCMCIA, pcmcia_init_all, NULL, pcmcia_shutdown_all );
|
||||
|
||||
@@ -1230,17 +1230,11 @@ PXENV_EXIT_t pxenv_undi_loader ( undi_loader_t *loader ) {
|
||||
* this, but it's currently split interestingly between main()
|
||||
* and main_loop()...
|
||||
*/
|
||||
console_init();
|
||||
cpu_setup();
|
||||
setup_timers();
|
||||
gateA20_set();
|
||||
print_config();
|
||||
get_memsizes();
|
||||
cleanup();
|
||||
relocate();
|
||||
cleanup();
|
||||
console_init();
|
||||
init_heap();
|
||||
|
||||
/* We have relocated; the loader pointer is now invalid */
|
||||
loader = phys_to_virt ( loader_phys );
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef NORELOCATE
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "memsizes.h"
|
||||
|
||||
/* by Eric Biederman */
|
||||
|
||||
@@ -93,10 +94,10 @@ void relocate(void)
|
||||
printf("Relocating _text from: [%lx,%lx) to [%lx,%lx)\n",
|
||||
old_addr, virt_to_phys(_end),
|
||||
addr, eaddr);
|
||||
arch_relocate_to(addr);
|
||||
/* arch_relocate_to ( addr ) */
|
||||
cleanup();
|
||||
relocate_to(addr);
|
||||
arch_relocated_from(old_addr);
|
||||
/* arch_relocated_from ( addr ) */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
#include "etherboot.h"
|
||||
#include "timer.h"
|
||||
#ifdef CONSOLE_SERIAL
|
||||
|
||||
/*
|
||||
* The serial port interface routines implement a simple polled i/o
|
||||
* interface to a standard serial port. Due to the space restrictions
|
||||
@@ -15,25 +11,27 @@
|
||||
* parity, 1 stop bit (8N1). This can be changed in init_serial().
|
||||
*/
|
||||
|
||||
static int found = 0;
|
||||
#include "stddef.h"
|
||||
#include "console.h"
|
||||
#include "init.h"
|
||||
#include "io.h"
|
||||
#include "timer.h"
|
||||
|
||||
/* Set default values if none specified */
|
||||
|
||||
#ifndef COMCONSOLE
|
||||
#define COMCONSOLE ( 0x3f8 )
|
||||
#endif
|
||||
|
||||
#ifndef CONSPEED
|
||||
#define CONSPEED ( 9600 )
|
||||
#endif
|
||||
|
||||
#if defined(COMCONSOLE)
|
||||
#undef UART_BASE
|
||||
#define UART_BASE COMCONSOLE
|
||||
#endif
|
||||
|
||||
#ifndef UART_BASE
|
||||
#error UART_BASE not defined
|
||||
#endif
|
||||
|
||||
#if defined(CONSPEED)
|
||||
#undef UART_BAUD
|
||||
#define UART_BAUD CONSPEED
|
||||
#endif
|
||||
|
||||
#ifndef UART_BAUD
|
||||
#define UART_BAUD 115200
|
||||
#endif
|
||||
|
||||
#if ((115200%UART_BAUD) != 0)
|
||||
#error Bad ttys0 baud rate
|
||||
@@ -83,18 +81,15 @@ static int found = 0;
|
||||
#define uart_writeb(val,addr) outb((val),(addr))
|
||||
#endif
|
||||
|
||||
static struct console_driver serial_console;
|
||||
|
||||
/*
|
||||
* void serial_putc(int ch);
|
||||
* Write character `ch' to port UART_BASE.
|
||||
*/
|
||||
void serial_putc(int ch)
|
||||
{
|
||||
static void serial_putc ( int ch ) {
|
||||
int i;
|
||||
int status;
|
||||
if (!found) {
|
||||
/* no serial interface */
|
||||
return;
|
||||
}
|
||||
i = 1000; /* timeout */
|
||||
while(--i > 0) {
|
||||
status = uart_readb(UART_BASE + UART_LSR);
|
||||
@@ -111,8 +106,7 @@ void serial_putc(int ch)
|
||||
* int serial_getc(void);
|
||||
* Read a character from port UART_BASE.
|
||||
*/
|
||||
int serial_getc(void)
|
||||
{
|
||||
static int serial_getc ( void ) {
|
||||
int status;
|
||||
int ch;
|
||||
do {
|
||||
@@ -131,11 +125,8 @@ int serial_getc(void)
|
||||
* If there is a character in the input buffer of port UART_BASE,
|
||||
* return nonzero; otherwise return 0.
|
||||
*/
|
||||
int serial_ischar(void)
|
||||
{
|
||||
static int serial_ischar ( void ) {
|
||||
int status;
|
||||
if (!found)
|
||||
return 0;
|
||||
status = uart_readb(UART_BASE + UART_LSR); /* line status reg; */
|
||||
return status & 1; /* rx char available */
|
||||
}
|
||||
@@ -144,15 +135,10 @@ int serial_ischar(void)
|
||||
* int serial_init(void);
|
||||
* Initialize port UART_BASE to speed CONSPEED, line settings 8N1.
|
||||
*/
|
||||
int serial_init(void)
|
||||
{
|
||||
int initialized = 0;
|
||||
static void serial_init ( void ) {
|
||||
int status;
|
||||
int divisor, lcs;
|
||||
|
||||
if (found)
|
||||
return 1;
|
||||
|
||||
divisor = COMBRD;
|
||||
lcs = UART_LCS;
|
||||
|
||||
@@ -207,10 +193,9 @@ int serial_init(void)
|
||||
/* line status reg */
|
||||
status = uart_readb(UART_BASE + UART_LSR);
|
||||
} while(status & UART_LSR_DR);
|
||||
initialized = 1;
|
||||
serial_console.disabled = 0;
|
||||
out:
|
||||
found = initialized;
|
||||
return initialized;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -218,10 +203,9 @@ int serial_init(void)
|
||||
* Cleanup our use of the serial port, in particular flush the
|
||||
* output buffer so we don't accidentially loose characters.
|
||||
*/
|
||||
void serial_fini(void)
|
||||
{
|
||||
static void serial_fini ( void ) {
|
||||
int i, status;
|
||||
if (!found) {
|
||||
if (serial_console.disabled) {
|
||||
/* no serial interface */
|
||||
return;
|
||||
}
|
||||
@@ -232,5 +216,15 @@ void serial_fini(void)
|
||||
do {
|
||||
status = uart_readb(UART_BASE + UART_LSR);
|
||||
} while((--i > 0) && !(status & UART_LSR_TEMPT));
|
||||
/* Don't mark it as disabled; it's still usable */
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct console_driver serial_console __console_driver = {
|
||||
.putchar = serial_putc,
|
||||
.getchar = serial_getc,
|
||||
.iskey = serial_ischar,
|
||||
.disabled = 1,
|
||||
};
|
||||
|
||||
INIT_FN ( INIT_CONSOLE, serial_init, NULL, serial_fini );
|
||||
|
||||
|
||||
Reference in New Issue
Block a user