* arch/x86/include/i486/arch.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
* only indirectly through nuttx/arch.h
*/
#ifndef __ARCH_X86_INCLUDE_I486_ARCH_H
#define __ARCH_X86_INCLUDE_I486_ARCH_H
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifndef __ASSEMBLY__
# include <nuttx/compiler.h>
# include <stdint.h>
#endif
* Pre-processor Definitions
****************************************************************************/
#define X86_FLAGS_CF (1 << 0)
#define X86_FLAGS_PF (1 << 2)
#define X86_FLAGS_AF (1 << 4)
#define X86_FLAGS_ZF (1 << 6)
#define X86_FLAGS_SF (1 << 7)
#define X86_FLAGS_TF (1 << 8)
#define X86_FLAGS_IF (1 << 9)
#define X86_FLAGS_DF (1 << 10)
#define X86_FLAGS_OF (1 << 11)
#define X86_FLAGS_IOPL_SHIFT (12)
#define X86_FLAGS_IOPL_MASK (3 << X86_FLAGS_IOPL_SHIFT)
#define X86_FLAGS_NT (1 << 14)
#define X86_EFLAGS_RF (1 << 16)
#define X86_EFLAGS_VM (1 << 17)
#define X86_EFLAGS_AC (1 << 18)
#define X86_EFLAGS_VIF (1 << 19)
#define X86_EFLAGS_VIP (1 << 20)
#define X86_EFLAGS_ID (1 << 21)
*
* The first instruction the Operation Control Word 1 (OCW1) to set which
* IRQ's to mask and which IRQ's not to.
*/
#define PIC1_OCW1 0x20
#define PIC2_OCW1 0xa0
# define PIC1_OCW1_IRQ0 (1 << 0)
# define PIC1_OCW1_IRQ1 (1 << 1)
# define PIC1_OCW1_IRQ2 (1 << 2)
# define PIC1_OCW1_IRQ3 (1 << 3)
# define PIC1_OCW1_IRQ4 (1 << 4)
# define PIC1_OCW1_IRQ5 (1 << 5)
# define PIC1_OCW1_IRQ6 (1 << 6)
# define PIC1_OCW1_IRQ7 (1 << 7)
# define PIC1_OCW1_ALL
# define PIC2_OCW1_IRQ8 (1 << 0)
# define PIC2_OCW1_IRQ9 (1 << 1)
# define PIC2_OCW1_IRQ10 (1 << 2)
# define PIC2_OCW1_IRQ11 (1 << 3)
# define PIC2_OCW1_IRQ12 (1 << 4)
# define PIC2_OCW1_IRQ13 (1 << 5)
# define PIC2_OCW1_IRQ14 (1 << 6)
# define PIC2_OCW1_IRQ15 (1 << 7)
# define PIC2_OCW1_ALL
* works. The only thing of interest to us in this register is the non-
* specific EOI command, which we must send at the end of our ISR's.
*/
#define PIC1_OCW2 0x20
#define PIC2_OCW2 0xa0
# define PIC_OCW2_ACT_SHIFT (0)
# define PIC_OCW2_ACT_MASK (7 << PIC_OCW2_ACT_SHIFT)
# define PIC1_OCW2_ACT_IRQ0 (0 << PIC_OCW2_ACT_SHIFT)
# define PIC1_OCW2_ACT_IRQ1 (1 << PIC_OCW2_ACT_SHIFT)
# define PIC1_OCW2_ACT_IRQ2 (2 << PIC_OCW2_ACT_SHIFT)
# define PIC1_OCW2_ACT_IRQ3 (3 << PIC_OCW2_ACT_SHIFT)
# define PIC1_OCW2_ACT_IRQ4 (4 << PIC_OCW2_ACT_SHIFT)
# define PIC1_OCW2_ACT_IRQ5 (5 << PIC_OCW2_ACT_SHIFT)
# define PIC1_OCW2_ACT_IRQ6 (6 << PIC_OCW2_ACT_SHIFT)
# define PIC1_OCW2_ACT_IRQ7 (7 << PIC_OCW2_ACT_SHIFT)
# define PIC2_OCW2_ACT_IRQ8 (0 << PIC_OCW2_ACT_SHIFT)
# define PIC2_OCW2_ACT_IRQ9 (1 << PIC_OCW2_ACT_SHIFT)
# define PIC2_OCW2_ACT_IRQ10 (2 << PIC_OCW2_ACT_SHIFT)
# define PIC2_OCW2_ACT_IRQ11 (3 << PIC_OCW2_ACT_SHIFT)
# define PIC2_OCW2_ACT_IRQ12 (4 << PIC_OCW2_ACT_SHIFT)
# define PIC2_OCW2_ACT_IRQ13 (5 << PIC_OCW2_ACT_SHIFT)
# define PIC2_OCW2_ACT_IRQ14 (6 << PIC_OCW2_ACT_SHIFT)
# define PIC2_OCW2_ACT_IRQ15 (7 << PIC_OCW2_ACT_SHIFT)
# define PIC_OCW2_EOI_SHIFT (5)
# define PIC_OCW2_EOI_MASK (7 << PIC_OCW2_EOI_SHIFT)
# define PIC_OCW2_EOI_AUTO (0 << PIC_OCW2_EOI_SHIFT)
# define PIC_OCW2_EOI_NONSPEC (1 << PIC_OCW2_EOI_SHIFT)
# define PIC_OCW2_EOI_SPEC (3 << PIC_OCW2_EOI_SHIFT)
# define PIC_OCW2_EOI_RAUTO (4 << PIC_OCW2_EOI_SHIFT)
# define PIC_OCW2_EOI_RNSPEC (5 << PIC_OCW2_EOI_SHIFT)
# define PIC_OCW2_EOI_PRIO (6 << PIC_OCW2_EOI_SHIFT)
# define PIC_OCW2_EOI_RSPEC (7 << PIC_OCW2_EOI_SHIFT)
* of the Interrupt Request Register (IRR) and the In-Service Register (ISR).
* This is done by setting the appropriate bits correctly and reading the
* register at the Base Address.
*
* For example if we wanted to read the In-Service Register (ISR), then we
* would set both bits 1 and 0 to 1. The next read to the base register,
* (0x20 for PIC1 or 0xa0 for PIC2) will return the status of the In-Service
* Register.
*/
#define PIC1_OCW3 0x20
#define PIC2_OCW3 0xa0
# define PIC_OCW3_PCMD_SHIFT (0)
# define PIC_OCW3_PCMD_MASK (3 << PIC_OCW3_PCMD_SHIFT)
# define PIC_OCW3_PCMD_IRR (2 << PIC_OCW3_PCMD_SHIFT)
# define PIC_OCW3_PCMD_ISR (3 << PIC_OCW3_PCMD_SHIFT)
# define PIC_OCW3_POLLCMD (1 << 2)
# define PIC_OCW3_ONE (1 << 3)
# define PIC_OCW3_SM_SHIFT (5)
# define PIC_OCW3_SM_MASK (3 << PIC_OCW3_SM_SHIFT)
# define PIC_OCW3_RSM (2 << PIC_OCW3_SM_SHIFT)
# define PIC_OCW3_SSM (3 << PIC_OCW3_SM_SHIFT)
* Initialization Command Words (ICW) before it will accept and process
* Interrupt Requests. The following outlines the four possible
* Initialization Command Words.
*/
#define PIC1_ICW1 0x20
#define PIC2_ICW1 0xa0
# define PIC_ICW1_ICW4 (1 << 0)
# define PIC_ICW1_SINGLE (1 << 1)
# define PIC_ICW1_INTERVAL (1 << 2)
# define PIC_ICW1_LEVEL (1 << 3)
# define PIC_ICW1_ICW1 (1 << 4)
# define PIC_ICW1_VEC_SHIFT (5)
# define PIC_ICW1_VEC_MASK (7 << PIC_ICW1_VEC_SHIFT)
* released onto the bus, during the 2nd INTA Pulse. Using the 8086 mode,
* only bits 7:3 need to be used. This will be 00001000 (0x08) for PIC1 and
* 01110000 (0x70) for PIC2. If you wish to relocate the IRQ Vector Table,
* then you can use this register.
*/
#define PIC1_ICW2 0x21
#define PIC2_ICW2 0xa1
* the PIC is a master, while the other is used for slaves.
*/
#define PIC1_ICW3 0x21
#define PIC2_ICW3 0xa1
# define PIC1_ICW3_IRQ0 (1 << 0)
# define PIC1_ICW3_IRQ1 (1 << 1)
# define PIC1_ICW3_IRQ2 (1 << 2)
# define PIC1_ICW3_IRQ3 (1 << 3)
# define PIC1_ICW3_IRQ4 (1 << 4)
# define PIC1_ICW3_IRQ5 (1 << 5)
# define PIC1_ICW3_IRQ6 (1 << 6)
# define PIC1_ICW3_IRQ7 (1 << 7)
# define PIC_ICW3_SID_MASK (0)
# define PIC_ICW3_SID_SHIFT (7 << PIC_ICW3_SID_MASK)
# define PIC_ICW3_SID0 (0 << PIC_ICW3_SID_MASK)
# define PIC_ICW3_SID1 (1 << PIC_ICW3_SID_MASK)
# define PIC_ICW3_SID2 (2 << PIC_ICW3_SID_MASK)
# define PIC_ICW3_SID3 (3 << PIC_ICW3_SID_MASK)
# define PIC_ICW3_SID4 (4 << PIC_ICW3_SID_MASK)
# define PIC_ICW3_SID5 (5 << PIC_ICW3_SID_MASK)
# define PIC_ICW3_SID6 (6 << PIC_ICW3_SID_MASK)
# define PIC_ICW3_SID7 (7 << PIC_ICW3_SID_MASK)
#define PIC1_ICW4 0x21
#define PIC2_ICW4 0xa1
# define PIC_ICW4_FNM (1 << 4)
# define PIC_ICW4_BMODE_SHIFT (2)
# define PIC_ICW4_BMODE_MASK (3 << PIC_ICW4_BMODE_SHIFT)
# define PIC_ICW4_BMODE_NON (0 << PIC_ICW4_BMODE_SHIFT)
# define PIC_ICW4_BMODE_SLAVE (2 << PIC_ICW4_BMODE_SHIFT)
# define PIC_ICW4_BMODE_MSTR (3 << PIC_ICW4_BMODE_SHIFT)
# define PIC_ICW4_AEOI (1 << 1)
# define PIC_ICW4_808XMODE (1 << 0)
#define PIC1_IMR 0x21
#define PIC2_IMR 0xa1
# define PIC1_IMR_IRQ0 (1 << 0)
# define PIC1_IMR_IRQ1 (1 << 1)
# define PIC1_IMR_IRQ2 (1 << 2)
# define PIC1_IMR_IRQ3 (1 << 3)
# define PIC1_IMR_IRQ4 (1 << 4)
# define PIC1_IMR_IRQ5 (1 << 5)
# define PIC1_IMR_IRQ6 (1 << 6)
# define PIC1_IMR_IRQ7 (1 << 7)
# define PIC1_IMR_ALL 0xff
# define PIC2_IMR_IRQ8 (1 << 0)
# define PIC2_IMR_IRQ9 (1 << 1)
# define PIC2_IMR_IRQ10 (1 << 2)
# define PIC2_IMR_IRQ11 (1 << 3)
# define PIC2_IMR_IRQ12 (1 << 4)
# define PIC2_IMR_IRQ13 (1 << 5)
# define PIC2_IMR_IRQ14 (1 << 6)
# define PIC2_IMR_IRQ15 (1 << 7)
# define PIC2_IMR_ALL 0xff
#define PIT_REG_COUNTER0 0x40
#define PIT_REG_COUNTER1 0x41
#define PIT_REG_COUNTER2 0x42
#define PIT_REG_COMMAND 0x43
# define PIT_OCW_BINCOUNT_BCD (1 << 0)
# define PIT_OCW_MODE_SHIFT (1)
# define PIT_OCW_MODE_MASK (7 << PIT_OCW_MODE_SHIFT)
# define PIT_OCW_MODE_TMCNT (0 << PIT_OCW_MODE_SHIFT)
# define PIT_OCW_MODE_ONESHOT (1 << PIT_OCW_MODE_SHIFT)
# define PIT_OCW_MODE_RATEGEN (2 << PIT_OCW_MODE_SHIFT)
# define PIT_OCW_MODE_SQUARE (3 << PIT_OCW_MODE_SHIFT)
# define PIT_OCW_MODE_SWTRIG (4 << PIT_OCW_MODE_SHIFT)
# define PIT_OCW_MODE_HWTRIG (5 << PIT_OCW_MODE_SHIFT)
# define PIT_OCW_RL_SHIFT (4)
# define PIT_OCW_RL_MASK (3 << PIT_OCW_RL_SHIFT)
# define PIT_OCW_RL_LATCH (0 << PIT_OCW_RL_SHIFT)
# define PIT_OCW_RL_LSBONLY (1 << PIT_OCW_RL_SHIFT)
# define PIT_OCW_RL_MSBONLY (2 << PIT_OCW_RL_SHIFT)
# define PIT_OCW_RL_DATA (3 << PIT_OCW_RL_SHIFT)
# define PIT_OCW_COUNTER_SHIFT (6)
# define PIT_OCW_COUNTER_MASK (3 << PIT_OCW_COUNTER_SHIFT)
# define PIT_OCW_COUNTER_0 (0 << PIT_OCW_COUNTER_SHIFT)
# define PIT_OCW_COUNTER_1 (1 << PIT_OCW_COUNTER_SHIFT)
# define PIT_OCW_COUNTER_2 (2 << PIT_OCW_COUNTER_SHIFT)
* Public Types
****************************************************************************/
*
* The Global Descriptor Table or GDT is a data structure used by Intel x86-
* family processors starting with the 80286 in order to define the
* characteristics of the various memory areas used during program execution,
* for example the base address, the size and access privileges like
* executability and writability. These memory areas are called segments in
* Intel terminology.
*/
begin_packed_struct struct gdt_entry_s
{
uint16_t lowlimit;
uint16_t lowbase;
uint8_t midbase;
uint8_t access;
uint8_t granularity;
uint8_t hibase;
} end_packed_struct;
* required by the lgdt instruction.
*/
begin_packed_struct struct gdt_ptr_s
{
uint16_t limit;
uint32_t base;
} end_packed_struct;
*
* The Interrupt Descriptor Table (IDT) is a data structure used by the x86
* architecture to implement an interrupt vector table. IDT is used by the
* processor to determine the correct response to interrupts and exceptions.
*/
begin_packed_struct struct idt_entry_s
{
uint16_t lobase;
uint16_t sel;
uint8_t zero;
uint8_t flags;
uint16_t hibase;
} end_packed_struct;
* in a format suitable for giving to 'lidt'.
*/
begin_packed_struct struct idt_ptr_s
{
uint16_t limit;
uint32_t base;
} end_packed_struct;
#ifndef __ASSEMBLY__
* Public Types
****************************************************************************/
* Public Data
****************************************************************************/
* Public Function Prototypes
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
void gdt_flush(uint32_t gdt_addr);
void idt_flush(uint32_t idt_addr);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif
#endif