URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/or1k/trunk/ecos-2.0/packages/hal/i386/pcmb/v2_0/include
- from Rev 1254 to Rev 1765
- ↔ Reverse comparison
Rev 1254 → Rev 1765
/pcmb_intr.h
0,0 → 1,306
#ifndef CYGONCE_HAL_PCMB_INTR_H |
#define CYGONCE_HAL_PCMB_INTR_H |
|
//========================================================================== |
// |
// pcmb_intr.h |
// |
// i386/pc Interrupt and clock support |
// |
//========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos 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 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//========================================================================== |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): proven |
// Contributors: proven, jskov, pjo |
// Date: 1999-10-15 |
// Purpose: Define Interrupt support |
// Description: The macros defined here provide the HAL APIs for handling |
// interrupts and the clock on a standard PC Motherboard. |
// This file contains info about interrupts and |
// peripherals that are common on all PCs; for example, |
// the clock always activates irq 0 and would therefore |
// be listed here. |
// |
// Usage: |
// #include <cyg/hal/pcmb_intr.h> |
// ... |
// |
//####DESCRIPTIONEND#### |
// |
//========================================================================== |
|
#include <pkgconf/hal.h> |
#include <pkgconf/hal_i386.h> |
#include <pkgconf/hal_i386_pcmb.h> |
|
#include <cyg/infra/cyg_type.h> |
|
#include <cyg/hal/plf_intr.h> |
#include <cyg/hal/hal_io.h> |
#include <cyg/hal/hal_smp.h> |
|
//-------------------------------------------------------------------------- |
// Interrupt vectors. |
|
#define CYGNUM_HAL_INTERRUPT_IRQ0 32 |
#define CYGNUM_HAL_INTERRUPT_IRQ1 33 |
#define CYGNUM_HAL_INTERRUPT_IRQ2 34 |
#define CYGNUM_HAL_INTERRUPT_IRQ3 35 |
#define CYGNUM_HAL_INTERRUPT_IRQ4 36 |
#define CYGNUM_HAL_INTERRUPT_IRQ5 37 |
#define CYGNUM_HAL_INTERRUPT_IRQ6 38 |
#define CYGNUM_HAL_INTERRUPT_IRQ7 39 |
#define CYGNUM_HAL_INTERRUPT_IRQ8 40 |
#define CYGNUM_HAL_INTERRUPT_IRQ9 41 |
#define CYGNUM_HAL_INTERRUPT_IRQ10 42 |
#define CYGNUM_HAL_INTERRUPT_IRQ11 43 |
#define CYGNUM_HAL_INTERRUPT_IRQ12 44 |
#define CYGNUM_HAL_INTERRUPT_IRQ13 45 |
#define CYGNUM_HAL_INTERRUPT_IRQ14 46 |
#define CYGNUM_HAL_INTERRUPT_IRQ15 47 |
|
#define CYGNUM_HAL_INTERRUPT_TIMER 32 |
#define CYGNUM_HAL_INTERRUPT_KEYBOARD 33 |
#define CYGNUM_HAL_INTERRUPT_SLAVE8259 34 |
#define CYGNUM_HAL_INTERRUPT_COM2 35 |
#define CYGNUM_HAL_INTERRUPT_COM1 36 |
#define CYGNUM_HAL_INTERRUPT_LPT2 37 |
#define CYGNUM_HAL_INTERRUPT_FDD 38 |
#define CYGNUM_HAL_INTERRUPT_LPT1 39 |
#define CYGNUM_HAL_INTERRUPT_WALLCLOCK 40 |
#define CYGNUM_HAL_INTERRUPT_SLAVE8259REDIR 41 |
#define CYGNUM_HAL_INTERRUPT_COPRO 45 |
#define CYGNUM_HAL_INTERRUPT_HDD 46 |
|
#define CYGNUM_HAL_ISR_MIN 32 |
#define CYGNUM_HAL_ISR_MAX 255 |
#define CYGNUM_HAL_ISR_COUNT (CYGNUM_HAL_ISR_MAX - CYGNUM_HAL_ISR_MIN + 1) |
|
#define CYGNUM_HAL_INTERRUPT_RTC CYGNUM_HAL_INTERRUPT_TIMER |
|
#ifdef CYGPKG_HAL_SMP_SUPPORT |
|
#define CYGNUM_HAL_SMP_CPU_INTERRUPT_VECTOR( _n_ ) (64+(_n_)) |
|
#endif |
|
//-------------------------------------------------------------------------- |
// Interrupt vector translation |
|
#define HAL_TRANSLATE_VECTOR(_vector_,_index_) \ |
((_index_) = ((_vector_)-CYGNUM_HAL_ISR_MIN)) |
|
|
//-------------------------------------------------------------------------- |
// PIC interrupt acknowledge |
|
#ifndef CYGPKG_HAL_SMP_SUPPORT |
|
#define HAL_INTERRUPT_ACKNOWLEDGE( _vector_ ) \ |
CYG_MACRO_START \ |
int x; \ |
HAL_TRANSLATE_VECTOR( _vector_, x ); \ |
if ((x >= 8) && (x < 16)) \ |
HAL_WRITE_UINT8( 0xa0, 0x20 ); \ |
if ((x >= 0) && (x < 16)) \ |
HAL_WRITE_UINT8( 0x20, 0x20 ); \ |
CYG_MACRO_END |
|
#else |
|
#define HAL_INTERRUPT_ACKNOWLEDGE( _vector_ ) \ |
{ \ |
HAL_APIC_WRITE( HAL_APIC_EOI, 0 ); \ |
} |
|
#endif |
|
//-------------------------------------------------------------------------- |
// PIC per-interrupt source masking |
|
#ifndef CYGPKG_HAL_SMP_SUPPORT |
|
#define HAL_INTERRUPT_MASK( _vector_ ) \ |
CYG_MACRO_START \ |
int x; \ |
HAL_TRANSLATE_VECTOR( _vector_, x ); \ |
if (x >= 8) \ |
{ \ |
x = 1 << (x - 8) ; \ |
asm( \ |
"inb $0xA1, %%al;" \ |
"orl %0, %%eax;" \ |
"outb %%al, $0xA1;" \ |
: /* No outputs. */ \ |
: "g" (x) \ |
: "eax" \ |
); \ |
} \ |
else \ |
{ \ |
x = 1 << x ; \ |
asm( \ |
"inb $0x21, %%al;" \ |
"orl %0, %%eax;" \ |
"outb %%al, $0x21;" \ |
: /* No outputs. */ \ |
: "g" (x) \ |
: "eax" \ |
); \ |
} \ |
CYG_MACRO_END |
|
#define HAL_INTERRUPT_UNMASK( _vector_ ) \ |
CYG_MACRO_START \ |
int x; \ |
HAL_TRANSLATE_VECTOR( _vector_, x ); \ |
if (x >= 8) \ |
{ \ |
x = ~(1 << (x - 8)) ; \ |
asm( \ |
"inb $0xA1, %%al;" \ |
"andl %0, %%eax;" \ |
"outb %%al, $0xA1;" \ |
: /* No outputs. */ \ |
: "g" (x) \ |
: "eax" \ |
); \ |
} \ |
else \ |
{ \ |
x = ~(1 << x) ; \ |
asm( \ |
"inb $0x21, %%al;" \ |
"andl %0, %%eax;" \ |
"outb %%al, $0x21;" \ |
: /* No outputs. */ \ |
: "g" (x) \ |
: "eax" \ |
); \ |
} \ |
CYG_MACRO_END |
|
#else |
|
#define HAL_INTERRUPT_MASK( _vector_ ) \ |
{ \ |
cyg_uint32 __vec, __val; \ |
HAL_TRANSLATE_VECTOR( _vector_, __vec ); \ |
HAL_SPINLOCK_SPIN( cyg_hal_ioapic_lock ); \ |
__vec = cyg_hal_isa_bus_irq[__vec]; \ |
HAL_IOAPIC_READ( HAL_IOAPIC_REG_REDIR_LO(__vec), __val ); \ |
__val |= 0x00010000; \ |
HAL_IOAPIC_WRITE( HAL_IOAPIC_REG_REDIR_LO(__vec), __val ); \ |
HAL_SPINLOCK_CLEAR( cyg_hal_ioapic_lock ); \ |
} |
|
#define HAL_INTERRUPT_UNMASK( _vector_ ) \ |
{ \ |
cyg_uint32 __vec, __val; \ |
HAL_TRANSLATE_VECTOR( _vector_, __vec ); \ |
HAL_SPINLOCK_SPIN( cyg_hal_ioapic_lock ); \ |
__vec = cyg_hal_isa_bus_irq[__vec]; \ |
HAL_IOAPIC_READ( HAL_IOAPIC_REG_REDIR_LO(__vec), __val ); \ |
__val &= ~0x00010000; \ |
HAL_IOAPIC_WRITE( HAL_IOAPIC_REG_REDIR_LO(__vec), __val ); \ |
HAL_SPINLOCK_CLEAR( cyg_hal_ioapic_lock ); \ |
} |
|
|
#endif |
|
//-------------------------------------------------------------------------- |
// PIC interrupt configuration |
// Nothing supported here at present |
|
#define HAL_INTERRUPT_CONFIGURE( _vector_, _level_, _up_ ) |
|
#define HAL_INTERRUPT_SET_LEVEL( _vector_, _level_ ) |
|
#ifdef CYGPKG_HAL_SMP_SUPPORT |
|
// Additional SMP interrupt configuration support. |
|
__externC void hal_interrupt_set_cpu( CYG_WORD32 vector, HAL_SMP_CPU_TYPE cpu ); |
__externC void hal_interrupt_get_cpu( CYG_WORD32 vector, HAL_SMP_CPU_TYPE *cpu ); |
|
#define HAL_INTERRUPT_SET_CPU( _vector_, _cpu_ ) \ |
{ \ |
cyg_uint32 __vec, __val; \ |
HAL_TRANSLATE_VECTOR( _vector_, __vec ); \ |
HAL_SPINLOCK_SPIN( cyg_hal_ioapic_lock ); \ |
__vec = cyg_hal_isa_bus_irq[__vec]; \ |
HAL_IOAPIC_READ( HAL_IOAPIC_REG_REDIR_HI(__vec), __val ); \ |
__val &= 0x00FFFFFF; \ |
__val |= (_cpu_)<<24; \ |
HAL_IOAPIC_WRITE( HAL_IOAPIC_REG_REDIR_HI(__vec), __val ); \ |
HAL_SPINLOCK_CLEAR( cyg_hal_ioapic_lock ); \ |
} |
|
|
#define HAL_INTERRUPT_GET_CPU( _vector_, _cpu_ ) \ |
{ \ |
cyg_uint32 __vec, __val; \ |
HAL_TRANSLATE_VECTOR( _vector_, __vec ); \ |
HAL_SPINLOCK_SPIN( cyg_hal_ioapic_lock ); \ |
__vec = cyg_hal_isa_bus_irq[__vec]; \ |
HAL_IOAPIC_READ( HAL_IOAPIC_REG_REDIR_HI(__vec), __val ); \ |
(_cpu_) = (__val>>24) & 0xFF; \ |
HAL_SPINLOCK_CLEAR( cyg_hal_ioapic_lock ); \ |
} |
|
|
#endif |
|
//--------------------------------------------------------------------------- |
// Clock support. |
|
externC void hal_pc_clock_initialize(cyg_uint32) ; |
externC void hal_pc_clock_read(cyg_uint32 *) ; |
|
#define HAL_CLOCK_INITIALIZE(_period_) hal_pc_clock_initialize(_period_) |
#define HAL_CLOCK_RESET(_vec_, _period_) /* Clock automatically reloads. */ |
#define HAL_CLOCK_READ(_pvalue_) hal_pc_clock_read(_pvalue_) |
|
// Timer IO ports |
#define PC_PIT_CONTROL (0x43) |
#define PC_PIT_CLOCK_0 (0x40) |
#define PC_PIT_CLOCK_1 (0x41) |
#define PC_PIT_CLOCK_2 (0x42) |
|
//--------------------------------------------------------------------------- |
#endif // ifndef CYGONCE_HAL_PCMB_INTR_H |
// End of pcmb_intr.h |
/pcmb_serial.h
0,0 → 1,96
#ifndef CYGONCE_HAL_PCMB_SERIAL_H |
#define CYGONCE_HAL_PCMB_SERIAL_H |
|
//========================================================================== |
// |
// pcmb_serial.h |
// |
// i386/pc Motherboard serial device support |
// |
//========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos 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 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//========================================================================== |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): nickg |
// Contributors: |
// Date: 2001-03-07 |
// Purpose: PC serial support |
// Description: |
// |
// |
// |
// |
// |
// |
// Usage: |
// #include <cyg/hal/pcmb_serial.h> |
// ... |
// |
//####DESCRIPTIONEND#### |
// |
//========================================================================== |
|
#include <pkgconf/hal.h> |
#include <pkgconf/hal_i386.h> |
#include <pkgconf/hal_i386_pcmb.h> |
|
#include <cyg/infra/cyg_type.h> |
|
//--------------------------------------------------------------------------- |
|
//============================================================================= |
|
typedef struct { |
cyg_uint16 base; |
cyg_uint16 valid; |
cyg_int32 msec_timeout; |
cyg_int32 isr_vector; |
} channel_data_t; |
|
__externC channel_data_t pc_ser_channels[]; |
|
//============================================================================= |
|
__externC void cyg_hal_plf_serial_init(void); |
|
#ifdef CYGSEM_HAL_I386_PCMB_SCREEN_SUPPORT |
|
__externC void cyg_hal_plf_screen_init(void); |
|
#endif |
|
//--------------------------------------------------------------------------- |
#endif // ifndef CYGONCE_HAL_PCMB_SERIAL_H |
// End of pcmb_serial.h |
/pcmb.inc
0,0 → 1,453
#ifndef CYGONCE_HAL_PCMB_INC |
#define CYGONCE_HAL_PCMB_INC |
##============================================================================= |
## |
## pcmb.inc |
## |
## PC platform support |
## |
##============================================================================= |
#####ECOSGPLCOPYRIGHTBEGIN#### |
## ------------------------------------------- |
## This file is part of eCos, the Embedded Configurable Operating System. |
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
## |
## eCos 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 or (at your option) any later version. |
## |
## eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
## WARRANTY; without even the implied warranty of MERCHANTABILITY or |
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
## for more details. |
## |
## You should have received a copy of the GNU General Public License along |
## with eCos; if not, write to the Free Software Foundation, Inc., |
## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
## |
## As a special exception, if other files instantiate templates or use macros |
## or inline functions from this file, or you compile this file and link it |
## with other works to produce a work based on this file, this file does not |
## by itself cause the resulting work to be covered by the GNU General Public |
## License. However the source code for this file must still be made available |
## in accordance with section (3) of the GNU General Public License. |
## |
## This exception does not invalidate any other reasons why a work based on |
## this file might be covered by the GNU General Public License. |
## |
## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
## at http://sources.redhat.com/ecos/ecos-license/ |
## ------------------------------------------- |
#####ECOSGPLCOPYRIGHTEND#### |
##============================================================================= |
#######DESCRIPTIONBEGIN#### |
## |
## Author(s): jskov |
## Contributors:jskov, pjo, nickg |
## Date: 1999-01-07 |
## Purpose: PC platform support |
## Description: This file contains any PC specific assembler macros needed to |
## run eCos on a standard i386 PC. |
## |
## |
######DESCRIPTIONEND#### |
## |
##============================================================================= |
|
|
##============================================================================= |
## CPU initialization |
|
#ifndef CYGPKG_HAL_I386_CPU_INIT_DEFINED |
|
#ifdef CYG_HAL_STARTUP_FLOPPY |
|
#define CYGPKG_HAL_I386_CPU_INIT_DEFINED |
|
.macro hal_cpu_init |
|
/* This code is loaded from a floppy disk when the PC powers up. */ |
|
.code16 |
|
.extern _end |
|
sectorsPerTrack = 18 |
bytesPerSector = 512 |
esPerSector = 32 /* = 512/16 */ |
|
cld /* always count up. */ |
|
/* Configure a stack that we can use. */ |
|
movl $_start, %eax |
movw %ax, %sp |
shr $4, %eax |
andl $0xF000, %eax |
movw %ax, %ss |
|
/* Ask the BIOS for info about the amount of RAM available. We push |
* these onto the stack for later use. |
*/ |
|
xorl %eax, %eax |
movb $0x88, %ah /* Get the amount of extended memory. */ |
int $0x15 |
shl $10, %eax |
pushl %eax |
|
xorl %eax, %eax |
int $0x12 /* Get the amount of standard memory. */ |
shl $10, %eax |
pushl %eax |
|
/* reset floppy */ |
movb $0,%ah |
movb $0,%dl |
int $0x13 |
jc _error1 |
|
/* Read the rest of the image to _start. This code works by reading |
only one sector at a time to avoid "buffer cross 64k boundary" fatal |
problem... This is slow but should work in almost all situations. |
_start should be aligned on a 512 bytes boundary to be sure. |
*/ |
|
/* destination pointer es:bx */ |
/* With correct alignement, bx should be 0 and es should be a multiple |
* of 32. If not it may cause the "buffer cross 64k boundary" problem |
* (cf above) |
*/ |
movl $_start,%eax |
movw %ax,%bx |
andw $0xF,%bx |
shrl $4,%eax |
movw %ax, %es |
|
/* initials head/track/sector */ |
movw $0,%dx |
movw $1,%cx |
|
movl $_edata,%edi |
addl $(bytesPerSector-1),%edi |
shrl $4,%edi |
|
jmp _loadsector |
|
_nextsector: |
movw %es,%ax |
cmpw %di,%ax |
jge _endload |
addw $esPerSector,%ax |
movw %ax,%es |
incb %cl |
cmpb $sectorsPerTrack, %cl |
jbe _loadsector /* next head ?*/ |
movb $1, %cl |
incb %dh |
cmpb $1, %dh |
je _loadsector /* next track ? */ |
movb $0, %dh |
incb %ch |
|
_loadsector: |
|
pushw %es |
pushw %di |
movw $0x0201, %ax |
clc |
int $0x13 |
popw %di |
popw %es |
jc _error2 |
|
movw $(0x0E*256+'.'), %ax /* print a dot */ |
int $0x10 |
|
/* So go ahead and resume execution at the real starting address. This |
only serves to move us quickly to the real starting location; and has |
no effect after reading additional tracks. If we didn't jump after |
reading the first track, then we limit ourselves to reading images of |
30k bytes max before overwriting ourselves at 0x7C00. |
*/ |
|
ljmp $0,$_nextsector |
|
_error1: |
movw $(0x0E*256+'1'), %ax /* print a ! */ |
int $0x10 |
jmp _error |
|
_error2: |
mov %ah,%al |
pushw %ax |
shrw $4,%ax |
andw $15,%ax |
addw $0x0E41,%ax |
int $0x10 |
popw %ax |
andw $15,%ax |
addw $0x0E41,%ax |
int $0x10 |
|
movw $(0x0E*256+'2'), %ax /* print a ! */ |
int $0x10 |
jmp _error |
|
_error: /* halt on error */ |
movw $(0x0E*256+'!'), %ax /* print a ! */ |
int $0x10 |
|
cli |
hlt |
jmp _start |
|
|
/* Write the 0x55/0xAA signature at the end of the first |
block. Without this signature the BIOS won't consider this |
block to be bootable. |
*/ |
|
. = _start + 510 |
.byte 0x55 |
.byte 0xAA |
|
_endload: |
1: |
|
/* Lets be nice and wait for the diskette drive motor to go off |
* before continuing. */ |
|
movw $0x40, %ax |
movw %ax, %es |
movl $0x40, %ebx |
2: es |
movb (%bx), %al |
cmpb $0, %al |
jne 2b |
|
/* Now we're all loaded up in memory. */ |
|
/* Optionally switch to a high-res video before entering */ |
/* protected mode. The mode is controlled by an option in */ |
/* the RedBoot configuration, which is not readily visible */ |
/* in the application configuration. Therefore RedBoot also */ |
/* performs some information-related BIOS calls, getting the */ |
/* main SVGA BIOS information and the mode-specific */ |
/* information. These are placed in video memory, because */ |
/* nothing else should be touching that and it avoids having */ |
/* some other special buffer shared between RedBoot and the */ |
/* application. The disadvantage is possibly some strange junk */ |
/* visible on the screen after RedBoot has started. */ |
#ifdef CYGNUM_HAL_I386_PC_STARTUP_VIDEO_MODE |
movw $0x4f02, %ax |
movw $ CYGNUM_HAL_I386_PC_STARTUP_VIDEO_MODE, %bx |
int $0x10 |
|
/* SVGA information @ 0x000A0000 */ |
/* Placing VBE2 at this location before the int10 gives more information */ |
movw $0xA000, %ax |
movw %ax, %es |
movw $0x0, %di |
movb $('V'), %es:0(%di) |
movb $('B'), %es:1(%di) |
movb $('E'), %es:2(%di) |
movb $('2'), %es:3(%di) |
movw $0x4f00, %ax |
int $0x10 |
|
/* Information about all supported modes starting @ 0x000A0400 */ |
/* ds:si is used to index the main mode table, offset 14 */ |
movw %es:14(%di),%si |
movw %es:16(%di),%ax |
movw %ax,%ds |
|
/* es:di is used for the destination. */ |
movw $0xA000,%ax |
movw %ax,%es |
movw $0x0400,%di |
|
modes_loop: |
/* The mode table is terminated by a -1 entry */ |
movw %ds:0(%si), %cx |
cmpw $0xffff,%cx |
je modes_done |
movw $0x4f01, %ax |
int $0x10 |
addw $0x0100, %di |
addw $2,%si |
jmp modes_loop |
modes_done: |
|
/* Information about the current mode @ 0x000A0200 */ |
movw $0xA000, %ax |
movw %ax, %es |
movw $0x0200, %di |
movw $0x4f01, %ax |
movw $ CYGNUM_HAL_I386_PC_STARTUP_VIDEO_MODE, %cx |
int $0x10 |
#endif |
|
/* Disable interrupt handling. */ |
cli |
|
/* Load GDTR and IDTR. */ |
|
lgdt %cs:gdt |
lidt %cs:idt |
|
/* Switch to protected mode. */ |
movl %cr0,%eax |
orb $1, %al |
movl %eax,%cr0 |
ljmp $8, $3f |
|
hlt |
|
.align 4, 0xFF |
gdt: |
.word gdtEnd - gdtStart |
.long gdtStart |
|
.align 4, 0xFF |
idt: |
.extern idtStart |
.word 0x07FF # space for 256 entries |
.long idtStart |
|
gdtStart: |
/* Selector 0x00 == invalid. */ |
.word 0x0000 |
.word 0x0000 |
.byte 0x00 |
.byte 0x00 |
.byte 0x00 |
.byte 0x00 |
|
/* Selector 0x08 == code. */ |
.word 0xFFFF |
.word 0x0000 |
.byte 0x00 |
.byte 0x9B |
.byte 0xCF |
.byte 0x00 |
|
/* Selector 0x10 == data. */ |
.word 0xFFFF |
.word 0x0000 |
.byte 0x00 |
.byte 0x93 |
.byte 0xCF |
.byte 0x00 |
|
/* Selector 0x18 == shorter code: faults any code |
* access 0xF0000000-0xFFFFFFFF. |
*/ |
.word 0xFFFF |
.word 0x0000 |
.byte 0x00 |
.byte 0x9B |
.byte 0xC7 |
.byte 0x00 |
|
/* Selector 0x20 == data; faults any access 0xF0000000-0xFFFFFFFF. */ |
.word 0xFFFF |
.word 0x0000 |
.byte 0x00 |
.byte 0x93 |
.byte 0xC7 |
.byte 0x00 |
|
.align 4, 0xFF |
gdtEnd: |
|
.code32 |
3: |
|
movw $0x10, %ax |
movw %ax, %ds |
movw %ax, %es |
movw %ax, %fs |
movw %ax, %gs |
|
/* Make our new stack point to the same place as the old one. */ |
xorl %ebx, %ebx |
movw %ss, %bx |
shl $4, %ebx |
addl %esp, %ebx |
movw %ax, %ss |
movl %ebx, %esp |
movl $0, %ebp |
|
/* Reset the flags register. */ |
pushl $0 |
popfl |
|
hal_cpu_init_end: |
nop |
|
.endm /* hal_cpu_init */ |
|
#endif /* CYG_HAL_STARTUP_FLOPPY */ |
|
#endif // CYGPKG_HAL_I386_CPU_INIT_DEFINED |
|
##============================================================================= |
## Interrupt controller support |
|
#define CYGPKG_HAL_I386_INTC_INIT_DEFINED |
|
#ifndef CYG_HAL_STARTUP_RAM |
|
.macro hal_intc_init |
|
# The interrupt controller is configured so that IRQ levels 0-7 trigger |
# interrupt vector 32-39; levels 8-15 trigger 40-47. |
movb $0x11, %al |
outb %al, $0x20 |
movb $0x20, %al |
outb %al, $0x21 |
movb $0x04, %al |
outb %al, $0x21 |
movb $0x01, %al |
outb %al, $0x21 |
movb $0xFB, %al /* Mask off all interrupts except 2. */ |
outb %al, $0x21 |
|
movb $0x11, %al |
outb %al, $0xA0 |
movb $0x28, %al |
outb %al, $0xA1 |
movb $0x02, %al |
outb %al, $0xA1 |
movb $0x01, %al |
outb %al, $0xA1 |
movb $0xFF, %al /* Mask off all interrupts. */ |
outb %al, $0xA1 |
|
.endm /* hal_intc_init */ |
|
#else |
|
# No need to do any initialization in RAM startup |
.macro hal_intc_init |
.endm |
|
#endif |
|
.macro hal_intc_ack vector |
# Use any registers you like. |
movl \vector, %edx |
movb $0x20, %al |
cmpl $0x20, %edx |
jl 8f |
cmpl $0x28, %edx |
jl 9f |
outb %al, $0xA0 |
9: outb %al, $0x20 |
8: nop |
.endm |
|
##============================================================================= |
#endif // ifndef CYGONCE_HAL_PCMB_INC |
## end of pcmb.inc |
/pcmb_io.h
0,0 → 1,248
#ifndef CYGONCE_PCMB_IO_H |
#define CYGONCE_PCMB_IO_H |
|
//============================================================================= |
// |
// pcmb_io.h |
// |
// PC Motherboard specific IO support |
// |
//============================================================================= |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// Copyright (C) 2002 Gary Thomas |
// |
// eCos 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 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//========================================================================== |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): proven |
// Contributors: proven, jskov, pjo |
// Date: 1999-10-15 |
// Purpose: PC Motherboard IO support |
// Description: The macros defined here provide the HAL APIs for handling |
// basic IO - specifically PCI config access. |
// |
//####DESCRIPTIONEND#### |
// |
//========================================================================== |
|
#include <pkgconf/system.h> |
#include CYGBLD_HAL_PLATFORM_H |
|
#include <cyg/hal/pcmb_io.h> |
|
//---------------------------------------------------------------------------- |
// The PCI resources required by the STPC |
// PCI Config registers in IO space |
|
#define STPC_PCI_ADDR_REG (0xCF8) |
#define STPC_PCI_DATA_REG (0xCFC) |
|
//---------------------------------------------------------------------------- |
|
// Initialize the PCI bus. |
#define HAL_PCI_INIT() \ |
CYG_MACRO_START \ |
CYG_MACRO_END |
|
//---------------------------------------------------------------------------- |
// Compute address necessary to access PCI config space for the given |
// bus and device. |
|
#define HAL_PCI_CONFIG_ADDRESS( __bus, __devfn, __offset ) \ |
((1<<31) | ((__bus) << 16) | ((__devfn) << 8) | ((__offset) & ~3)) |
|
//---------------------------------------------------------------------------- |
// Read a value from the PCI configuration space of the appropriate |
// size at an address composed from the bus, devfn and offset. |
|
#define HAL_PCI_CFG_READ_UINT32( __bus, __devfn, __offset, __val ) \ |
CYG_MACRO_START \ |
HAL_WRITE_UINT32(STPC_PCI_ADDR_REG,HAL_PCI_CONFIG_ADDRESS((__bus),(__devfn),(__offset))); \ |
HAL_READ_UINT32(STPC_PCI_DATA_REG,(__val)); \ |
CYG_MACRO_END |
|
#define HAL_PCI_CFG_READ_UINT8( __bus, __devfn, __offset, __val ) \ |
CYG_MACRO_START \ |
HAL_WRITE_UINT32(STPC_PCI_ADDR_REG,HAL_PCI_CONFIG_ADDRESS((__bus),(__devfn),(__offset))); \ |
HAL_READ_UINT8(STPC_PCI_DATA_REG + ((__offset)&3),(__val)); \ |
CYG_MACRO_END |
|
#define HAL_PCI_CFG_READ_UINT16( __bus, __devfn, __offset, __val ) \ |
CYG_MACRO_START \ |
HAL_WRITE_UINT32(STPC_PCI_ADDR_REG,HAL_PCI_CONFIG_ADDRESS((__bus),(__devfn),(__offset))); \ |
HAL_READ_UINT16(STPC_PCI_DATA_REG + ((__offset)&2),(__val)); \ |
CYG_MACRO_END |
|
//---------------------------------------------------------------------------- |
// Write a value to the PCI configuration space of the appropriate |
// size at an address composed from the bus, devfn and offset. |
|
#define HAL_PCI_CFG_WRITE_UINT32( __bus, __devfn, __offset, __val ) \ |
CYG_MACRO_START \ |
HAL_WRITE_UINT32(STPC_PCI_ADDR_REG,HAL_PCI_CONFIG_ADDRESS((__bus),(__devfn),(__offset))); \ |
HAL_WRITE_UINT32(STPC_PCI_DATA_REG,(__val)); \ |
CYG_MACRO_END |
|
#define HAL_PCI_CFG_WRITE_UINT8( __bus, __devfn, __offset, __val ) \ |
CYG_MACRO_START \ |
HAL_WRITE_UINT32(STPC_PCI_ADDR_REG,HAL_PCI_CONFIG_ADDRESS((__bus),(__devfn),(__offset))); \ |
HAL_WRITE_UINT8(STPC_PCI_DATA_REG+(__offset & 3),(__val)); \ |
CYG_MACRO_END |
|
#define HAL_PCI_CFG_WRITE_UINT16( __bus, __devfn, __offset, __val ) \ |
CYG_MACRO_START \ |
HAL_WRITE_UINT32(STPC_PCI_ADDR_REG,HAL_PCI_CONFIG_ADDRESS((__bus),(__devfn),(__offset))); \ |
HAL_WRITE_UINT16(STPC_PCI_DATA_REG+(__offset & 2),(__val)); \ |
CYG_MACRO_END |
|
|
//----------------------------------------------------------------------------- |
// Resources |
|
#ifdef CYGSEM_HAL_I386_PC_LARGE_PCI_SPACE |
// Use unrestricted PCI space |
#define CYG_PCI_MAX_BUS 256 |
#define CYG_PCI_MIN_DEV 0 |
#define CYG_PCI_MAX_DEV 32 |
#define CYG_PCI_MAX_FN 8 |
#endif |
|
// This is where the PCI spaces are mapped in the CPU's address space. |
// In the PC the PCI address space is mapped 1-1 into the CPU physical |
// address space, so these values are both zero. |
|
#define HAL_PCI_PHYSICAL_MEMORY_BASE 0x00000000 |
#define HAL_PCI_PHYSICAL_IO_BASE 0x0000 |
|
// Map PCI device resources starting from these addresses in PCI space. |
// These are the addresses in PCI space where we should map device |
// memory. Since there is RAM and other devices in low memory and IO |
// space, we allocate from high addresses. In most PC platforms, the |
// BIOS will have actually allocated the PCI devices before we start, |
// so these values are actually academic. |
|
#define HAL_PCI_ALLOC_BASE_MEMORY 0xf0000000 |
#define HAL_PCI_ALLOC_BASE_IO 0xDF00 |
|
//---------------------------------------------------------------------------- |
// Translate the PCI interrupt requested by the device (INTA#, INTB#, |
// INTC# or INTD#) to the associated CPU interrupt (i.e., HAL vector). |
|
#define HAL_PCI_TRANSLATE_INTERRUPT( __bus, __devfn, __vec, __valid) \ |
CYG_MACRO_START \ |
HAL_PCI_CFG_READ_UINT8((__bus),(__devfn),CYG_PCI_CFG_INT_LINE,(__vec)); \ |
if(__vec<=15) __valid=1; \ |
else __valid=0; \ |
__vec += 0x20; \ |
CYG_MACRO_END |
|
//----------------------------------------------------------------------------- |
// CMOS RAM access |
|
#define HAL_CMOS_ADDRESS 0x70 // CMOS address register |
#define HAL_CMOS_DATA 0x71 // CMOS data register |
|
#define HAL_READ_CMOS( __addr, __val ) \ |
CYG_MACRO_START \ |
{ \ |
HAL_WRITE_UINT8( HAL_CMOS_ADDRESS, __addr ); \ |
HAL_READ_UINT8( HAL_CMOS_DATA, (__val) ); \ |
} \ |
CYG_MACRO_END |
|
#define HAL_WRITE_CMOS( __addr, __val ) \ |
CYG_MACRO_START \ |
{ \ |
HAL_WRITE_UINT8( HAL_CMOS_ADDRESS, __addr ); \ |
HAL_WRITE_UINT8( HAL_CMOS_DATA, (__val) ); \ |
} \ |
CYG_MACRO_END |
|
//----------------------------------------------------------------------------- |
// Debug macros |
// Some simple macros for writing useful info to a PC ASCII display |
|
#define PC_WRITE_SCREEN( __pos, __ch ) \ |
(*((short *)(0xB8000)+((__pos)%(80*25))) = (0x0700+(__ch))) |
|
#define PC_SCREEN_LINE( __line ) ((__line)*80) |
|
#define PC_WRITE_SCREEN_8( __pos, __val ) \ |
{ \ |
char __hex[] = "0123456789ABCDEF"; \ |
PC_WRITE_SCREEN( (__pos), __hex[((int)(__val)>>4)&0xF] ); \ |
PC_WRITE_SCREEN( ((__pos)+1), __hex[(int)(__val)&0xF] ); \ |
} |
|
#define PC_WRITE_SCREEN_16( __pos, __val ) \ |
PC_WRITE_SCREEN_8( __pos, (int)(__val)>>8 ); \ |
PC_WRITE_SCREEN_8( (__pos)+2, (int)(__val) ); |
|
#define PC_WRITE_SCREEN_32( __pos, __val ) \ |
PC_WRITE_SCREEN_16( __pos, (int)(__val)>>16 ); \ |
PC_WRITE_SCREEN_16( (__pos)+4, (int)(__val) ); |
|
//----------------------------------------------------------------------------- |
// IDE interface macros |
// |
#define HAL_IDE_NUM_CONTROLLERS 2 |
|
// Initialize the IDE controller(s). |
#define HAL_IDE_INIT() |
|
#define __PCMB_IDE_PRI_CMD 0x1f0 |
#define __PCMB_IDE_PRI_CTL 0x3f4 |
#define __PCMB_IDE_SEC_CMD 0x170 |
#define __PCMB_IDE_SEC_CTL 0x374 |
|
#define __CMD_ADDR(__n) ((__n) ? __PCMB_IDE_SEC_CMD : __PCMB_IDE_PRI_CMD) |
#define __CTL_ADDR(__n) ((__n) ? __PCMB_IDE_SEC_CTL : __PCMB_IDE_PRI_CTL) |
|
#define HAL_IDE_READ_UINT8( __ctlr, __regno, __val ) \ |
HAL_READ_UINT8(__CMD_ADDR(__ctlr) + (__regno), (__val)) |
#define HAL_IDE_READ_UINT16( __ctlr, __regno, __val ) \ |
HAL_READ_UINT16(__CMD_ADDR(__ctlr) + (__regno), (__val)) |
#define HAL_IDE_READ_ALTSTATUS( __ctlr, __val ) \ |
HAL_READ_UINT16(__CTL_ADDR(__ctlr) + 2, (__val)) |
|
#define HAL_IDE_WRITE_UINT8( __ctlr, __regno, __val ) \ |
HAL_WRITE_UINT8(__CMD_ADDR(__ctlr) + (__regno), (__val)) |
#define HAL_IDE_WRITE_UINT16( __ctlr, __regno, __val ) \ |
HAL_WRITE_UINT16(__CMD_ADDR(__ctlr) + (__regno), (__val)) |
#define HAL_IDE_WRITE_CONTROL( __ctlr, __val ) \ |
HAL_WRITE_UINT16(__CTL_ADDR(__ctlr) + 2, (__val)) |
|
|
//----------------------------------------------------------------------------- |
// end of pcmb_io.h |
#endif // CYGONCE_PCMB_IO_H |