This series moves some additional hardware driver code from the main src/ directory to files in the src/hw/ directory. This is a minor cleanup to gather more hardware driver code together.
This series is also at: https://github.com/KevinOConnor/seabios/tree/testing
-Kevin
Kevin O'Connor (4): Move PIT setup from clock.c to hw/timer.c. Rename hw/cmos.h to hw/rtc.h and copy RTC code from clock.c to hw/rtc.c. Move dma code to new file hw/dma.c. Remove ioport.h; disperse its contents to other header files.
Makefile | 2 +- src/apm.c | 2 +- src/block.c | 4 +- src/boot.c | 8 +-- src/clock.c | 168 ++++++++++++++++------------------------------- src/farptr.h | 2 +- src/fw/acpi.c | 1 - src/fw/paravirt.c | 17 +++-- src/fw/paravirt.h | 9 +++ src/fw/pciinit.c | 3 +- src/fw/smm.c | 2 +- src/fw/smp.c | 4 +- src/hw/ahci.c | 2 +- src/hw/ata.c | 3 +- src/hw/ata.h | 5 ++ src/hw/dma.c | 67 +++++++++++++++++++ src/hw/floppy.c | 50 ++++---------- src/hw/pci.c | 1 - src/hw/pci.h | 4 ++ src/hw/pic.h | 7 +- src/hw/pit.h | 29 -------- src/hw/ps2port.c | 2 +- src/hw/ps2port.h | 14 +++- src/hw/rtc.c | 93 ++++++++++++++++++++++++++ src/hw/{cmos.h => rtc.h} | 59 ++++++++--------- src/hw/serialio.h | 21 ++++++ src/hw/timer.c | 67 +++++++++++-------- src/hw/usb-ehci.c | 1 - src/hw/usb-uhci.c | 2 +- src/hw/virtio-pci.h | 2 +- src/ioport.h | 136 -------------------------------------- src/misc.c | 2 + src/output.c | 1 + src/post.c | 4 +- src/resume.c | 20 +----- src/romlayout.S | 8 +-- src/serial.c | 1 + src/stacks.c | 5 +- src/system.c | 3 +- src/util.h | 14 ++-- src/x86.h | 51 ++++++++++++++ vgasrc/bochsvga.c | 12 ++++ vgasrc/bochsvga.h | 12 ---- vgasrc/stdvga.c | 8 +-- vgasrc/stdvgaio.c | 4 +- 45 files changed, 480 insertions(+), 452 deletions(-) create mode 100644 src/hw/dma.c delete mode 100644 src/hw/pit.h create mode 100644 src/hw/rtc.c rename src/hw/{cmos.h => rtc.h} (67%) create mode 100644 src/hw/serialio.h delete mode 100644 src/ioport.h
Move the hardware setup to the hw/timer.c code. This eliminates the need for a separate hw/pit.h file with definitions.
Also, move the IRQ counting code (which is dependent on the BDA) from hw/timer.c to clock.c.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/clock.c | 41 ++++++++++++++++++++++++++++++----------- src/hw/pit.h | 29 ----------------------------- src/hw/timer.c | 58 +++++++++++++++++++++++++++++++++------------------------- src/util.h | 7 ++++--- 4 files changed, 67 insertions(+), 68 deletions(-) delete mode 100644 src/hw/pit.h
diff --git a/src/clock.c b/src/clock.c index 7e24626..e54944b 100644 --- a/src/clock.c +++ b/src/clock.c @@ -9,7 +9,6 @@ #include "bregs.h" // struct bregs #include "hw/cmos.h" // inb_cmos #include "hw/pic.h" // pic_eoi1 -#include "hw/pit.h" // PM_SEL_TIMER0 #include "hw/usb-hid.h" // usb_check_event #include "output.h" // debug_enter #include "stacks.h" // yield @@ -57,16 +56,6 @@ rtc_updating(void) }
static void -pit_setup(void) -{ - // timer0: binary count, 16bit count, mode 2 - outb(PM_SEL_TIMER0|PM_ACCESS_WORD|PM_MODE2|PM_CNT_BINARY, PORT_PIT_MODE); - // maximum count of 0000H = 18.2Hz - outb(0x0, PORT_PIT_COUNTER0); - outb(0x0, PORT_PIT_COUNTER0); -} - -static void rtc_setup(void) { outb_cmos(0x26, CMOS_STATUS_A); // 32,768Khz src, 976.5625us updates @@ -352,6 +341,36 @@ handle_08(void)
/**************************************************************** + * IRQ based timer + ****************************************************************/ + +// Calculate the timer value at 'count' number of full timer ticks in +// the future. +u32 +irqtimer_calc_ticks(u32 count) +{ + return (GET_BDA(timer_counter) + count + 1) % TICKS_PER_DAY; +} + +// Return the timer value that is 'msecs' time in the future. +u32 +irqtimer_calc(u32 msecs) +{ + if (!msecs) + return GET_BDA(timer_counter); + return irqtimer_calc_ticks(ticks_from_ms(msecs)); +} + +// Check if the given timer value has passed. +int +irqtimer_check(u32 end) +{ + return (((GET_BDA(timer_counter) + TICKS_PER_DAY - end) % TICKS_PER_DAY) + < (TICKS_PER_DAY/2)); +} + + +/**************************************************************** * Periodic timer ****************************************************************/
diff --git a/src/hw/pit.h b/src/hw/pit.h deleted file mode 100644 index 098f270..0000000 --- a/src/hw/pit.h +++ /dev/null @@ -1,29 +0,0 @@ -// Definitions for the Intel 8253 Programmable Interrupt Timer (PIT). -#ifndef __PIT_H -#define __PIT_H - -// Bits for PORT_PIT_MODE -#define PM_SEL_TIMER0 (0<<6) -#define PM_SEL_TIMER1 (1<<6) -#define PM_SEL_TIMER2 (2<<6) -#define PM_SEL_READBACK (3<<6) -#define PM_ACCESS_LATCH (0<<4) -#define PM_ACCESS_LOBYTE (1<<4) -#define PM_ACCESS_HIBYTE (2<<4) -#define PM_ACCESS_WORD (3<<4) -#define PM_MODE0 (0<<1) -#define PM_MODE1 (1<<1) -#define PM_MODE2 (2<<1) -#define PM_MODE3 (3<<1) -#define PM_MODE4 (4<<1) -#define PM_MODE5 (5<<1) -#define PM_CNT_BINARY (0<<0) -#define PM_CNT_BCD (1<<0) -#define PM_READ_COUNTER0 (1<<1) -#define PM_READ_COUNTER1 (1<<2) -#define PM_READ_COUNTER2 (1<<3) -#define PM_READ_STATUSVALUE (0<<4) -#define PM_READ_VALUE (1<<4) -#define PM_READ_STATUS (2<<4) - -#endif // pit.h diff --git a/src/hw/timer.c b/src/hw/timer.c index 6477313..ec1e3c5 100644 --- a/src/hw/timer.c +++ b/src/hw/timer.c @@ -8,11 +8,34 @@ #include "config.h" // CONFIG_* #include "ioport.h" // PORT_PIT_MODE #include "output.h" // dprintf -#include "pit.h" // PM_SEL_TIMER0 #include "stacks.h" // yield #include "util.h" // timer_setup #include "x86.h" // cpuid
+// Bits for PORT_PIT_MODE +#define PM_SEL_TIMER0 (0<<6) +#define PM_SEL_TIMER1 (1<<6) +#define PM_SEL_TIMER2 (2<<6) +#define PM_SEL_READBACK (3<<6) +#define PM_ACCESS_LATCH (0<<4) +#define PM_ACCESS_LOBYTE (1<<4) +#define PM_ACCESS_HIBYTE (2<<4) +#define PM_ACCESS_WORD (3<<4) +#define PM_MODE0 (0<<1) +#define PM_MODE1 (1<<1) +#define PM_MODE2 (2<<1) +#define PM_MODE3 (3<<1) +#define PM_MODE4 (4<<1) +#define PM_MODE5 (5<<1) +#define PM_CNT_BINARY (0<<0) +#define PM_CNT_BCD (1<<0) +#define PM_READ_COUNTER0 (1<<1) +#define PM_READ_COUNTER1 (1<<2) +#define PM_READ_COUNTER2 (1<<3) +#define PM_READ_STATUSVALUE (0<<4) +#define PM_READ_VALUE (1<<4) +#define PM_READ_STATUS (2<<4) + // Bits for PORT_PS2_CTRLB #define PPCB_T2GATE (1<<0) #define PPCB_SPKR (1<<1) @@ -27,7 +50,7 @@ u8 ShiftTSC VARFSEG;
/**************************************************************** - * Timer setup + * Internal timer setup ****************************************************************/
#define CALIBRATE_COUNT 0x800 // Approx 1.7ms @@ -197,7 +220,7 @@ timer_calc_usec(u32 usecs)
/**************************************************************** - * IRQ based timer + * PIT setup ****************************************************************/
#define PIT_TICK_INTERVAL 65536 // Default interval for 18.2Hz timer @@ -218,27 +241,12 @@ ticks_from_ms(u32 ms) return DIV_ROUND_UP(t, 1000 * PMTIMER_TO_PIT); }
-// Calculate the timer value at 'count' number of full timer ticks in -// the future. -u32 -irqtimer_calc_ticks(u32 count) -{ - return (GET_BDA(timer_counter) + count + 1) % TICKS_PER_DAY; -} - -// Return the timer value that is 'msecs' time in the future. -u32 -irqtimer_calc(u32 msecs) -{ - if (!msecs) - return GET_BDA(timer_counter); - return irqtimer_calc_ticks(ticks_from_ms(msecs)); -} - -// Check if the given timer value has passed. -int -irqtimer_check(u32 end) +void +pit_setup(void) { - return (((GET_BDA(timer_counter) + TICKS_PER_DAY - end) % TICKS_PER_DAY) - < (TICKS_PER_DAY/2)); + // timer0: binary count, 16bit count, mode 2 + outb(PM_SEL_TIMER0|PM_ACCESS_WORD|PM_MODE2|PM_CNT_BINARY, PORT_PIT_MODE); + // maximum count of 0000H = 18.2Hz + outb(0x0, PORT_PIT_COUNTER0); + outb(0x0, PORT_PIT_COUNTER0); } diff --git a/src/util.h b/src/util.h index 880c04a..57c3ae9 100644 --- a/src/util.h +++ b/src/util.h @@ -55,6 +55,9 @@ int cdrom_boot(struct drive_s *drive_g); // clock.c void clock_setup(void); void handle_1583(struct bregs *regs); +u32 irqtimer_calc_ticks(u32 count); +u32 irqtimer_calc(u32 msecs); +int irqtimer_check(u32 end); void handle_1586(struct bregs *regs); void useRTC(void); void releaseRTC(void); @@ -149,9 +152,7 @@ void usleep(u32 count); void msleep(u32 count); u32 ticks_to_ms(u32 ticks); u32 ticks_from_ms(u32 ms); -u32 irqtimer_calc_ticks(u32 count); -u32 irqtimer_calc(u32 msecs); -int irqtimer_check(u32 end); +void pit_setup(void);
// jpeg.c struct jpeg_decdata *jpeg_alloc(void);
Group the Real Time Clock code into hw/rtc.[ch].
Also, use rtc_read/write/mask function naming (instead of inb/outb_cmos) to be more consistent with other register accessors.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- Makefile | 2 +- src/block.c | 4 +- src/boot.c | 8 +-- src/clock.c | 139 ++++++++++++----------------------------------- src/fw/paravirt.c | 16 +++--- src/fw/smp.c | 4 +- src/hw/ata.c | 1 - src/hw/floppy.c | 4 +- src/hw/rtc.c | 93 +++++++++++++++++++++++++++++++ src/hw/{cmos.h => rtc.h} | 53 ++++++++---------- src/post.c | 4 +- src/resume.c | 6 +- src/romlayout.S | 2 +- src/stacks.c | 5 +- src/util.h | 2 - 15 files changed, 177 insertions(+), 166 deletions(-) create mode 100644 src/hw/rtc.c rename src/hw/{cmos.h => rtc.h} (67%)
diff --git a/Makefile b/Makefile index 70ba8d9..0cdb6d3 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ OUT=out/ SRCBOTH=misc.c stacks.c output.c string.c x86.c block.c cdrom.c mouse.c kbd.c \ serial.c clock.c resume.c pnpbios.c vgahooks.c pcibios.c apm.c \ fw/smp.c \ - hw/pci.c hw/timer.c hw/pic.c hw/ps2port.c \ + hw/pci.c hw/timer.c hw/rtc.c hw/pic.c hw/ps2port.c \ hw/usb.c hw/usb-uhci.c hw/usb-ohci.c hw/usb-ehci.c \ hw/usb-hid.c hw/usb-msc.c hw/usb-uas.c \ hw/blockcmd.c hw/floppy.c hw/ata.c hw/ahci.c hw/ramdisk.c \ diff --git a/src/block.c b/src/block.c index 4560b24..cbcf9e1 100644 --- a/src/block.c +++ b/src/block.c @@ -10,8 +10,8 @@ #include "bregs.h" // struct bregs #include "hw/ata.h" // process_ata_op #include "hw/ahci.h" // process_ahci_op -#include "hw/cmos.h" // inb_cmos #include "hw/blockcmd.h" // cdb_* +#include "hw/rtc.h" // rtc_read #include "hw/virtio-blk.h" // process_virtio_blk_op #include "malloc.h" // malloc_low #include "output.h" // dprintf @@ -72,7 +72,7 @@ get_translation(struct drive_s *drive_g) // Emulators pass in the translation info via nvram. u8 ataid = GET_GLOBAL(drive_g->cntl_id); u8 channel = ataid / 2; - u8 translation = inb_cmos(CMOS_BIOS_DISKTRANSFLAG + channel/2); + u8 translation = rtc_read(CMOS_BIOS_DISKTRANSFLAG + channel/2); translation >>= 2 * (ataid % 4); translation &= 0x03; return translation; diff --git a/src/boot.c b/src/boot.c index a2851b2..b14ced9 100644 --- a/src/boot.c +++ b/src/boot.c @@ -9,8 +9,8 @@ #include "bregs.h" // struct bregs #include "config.h" // CONFIG_* #include "fw/paravirt.h" // qemu_cfg_show_boot_menu -#include "hw/cmos.h" // inb_cmos #include "hw/pci.h" // pci_bdf_to_* +#include "hw/rtc.h" // rtc_read #include "hw/usb.h" // struct usbdevice_s #include "list.h" // hlist_node #include "malloc.h" // free @@ -257,10 +257,10 @@ boot_init(void)
if (CONFIG_QEMU) { // On emulators, get boot order from nvram. - if (inb_cmos(CMOS_BIOS_BOOTFLAG1) & 1) + if (rtc_read(CMOS_BIOS_BOOTFLAG1) & 1) CheckFloppySig = 0; - u32 bootorder = (inb_cmos(CMOS_BIOS_BOOTFLAG2) - | ((inb_cmos(CMOS_BIOS_BOOTFLAG1) & 0xf0) << 4)); + u32 bootorder = (rtc_read(CMOS_BIOS_BOOTFLAG2) + | ((rtc_read(CMOS_BIOS_BOOTFLAG1) & 0xf0) << 4)); DefaultFloppyPrio = DefaultCDPrio = DefaultHDPrio = DefaultBEVPrio = DEFAULT_PRIO; int i; diff --git a/src/clock.c b/src/clock.c index e54944b..9ab0ac0 100644 --- a/src/clock.c +++ b/src/clock.c @@ -7,64 +7,19 @@
#include "biosvar.h" // SET_BDA #include "bregs.h" // struct bregs -#include "hw/cmos.h" // inb_cmos #include "hw/pic.h" // pic_eoi1 +#include "hw/rtc.h" // rtc_read #include "hw/usb-hid.h" // usb_check_event #include "output.h" // debug_enter #include "stacks.h" // yield #include "string.h" // memset #include "util.h" // clock_setup
-// RTC register flags -#define RTC_A_UIP 0x80 - -#define RTC_B_SET 0x80 -#define RTC_B_PIE 0x40 -#define RTC_B_AIE 0x20 -#define RTC_B_UIE 0x10 -#define RTC_B_BIN 0x04 -#define RTC_B_24HR 0x02 -#define RTC_B_DSE 0x01 -
/**************************************************************** * Init ****************************************************************/
-static int -rtc_updating(void) -{ - // This function checks to see if the update-in-progress bit - // is set in CMOS Status Register A. If not, it returns 0. - // If it is set, it tries to wait until there is a transition - // to 0, and will return 0 if such a transition occurs. A -1 - // is returned only after timing out. The maximum period - // that this bit should be set is constrained to (1984+244) - // useconds, but we wait for longer just to be sure. - - if ((inb_cmos(CMOS_STATUS_A) & RTC_A_UIP) == 0) - return 0; - u32 end = timer_calc(15); - for (;;) { - if ((inb_cmos(CMOS_STATUS_A) & RTC_A_UIP) == 0) - return 0; - if (timer_check(end)) - // update-in-progress never transitioned to 0 - return -1; - yield(); - } -} - -static void -rtc_setup(void) -{ - outb_cmos(0x26, CMOS_STATUS_A); // 32,768Khz src, 976.5625us updates - u8 regB = inb_cmos(CMOS_STATUS_B); - outb_cmos((regB & RTC_B_DSE) | RTC_B_24HR, CMOS_STATUS_B); - inb_cmos(CMOS_STATUS_C); - inb_cmos(CMOS_STATUS_D); -} - static u32 bcd2bin(u8 val) { @@ -81,18 +36,18 @@ clock_setup(void)
rtc_setup(); rtc_updating(); - u32 seconds = bcd2bin(inb_cmos(CMOS_RTC_SECONDS)); - u32 minutes = bcd2bin(inb_cmos(CMOS_RTC_MINUTES)); - u32 hours = bcd2bin(inb_cmos(CMOS_RTC_HOURS)); + u32 seconds = bcd2bin(rtc_read(CMOS_RTC_SECONDS)); + u32 minutes = bcd2bin(rtc_read(CMOS_RTC_MINUTES)); + u32 hours = bcd2bin(rtc_read(CMOS_RTC_HOURS)); u32 ticks = ticks_from_ms(((hours * 60 + minutes) * 60 + seconds) * 1000); SET_BDA(timer_counter, ticks % TICKS_PER_DAY);
// Setup Century storage if (CONFIG_QEMU) { - Century = inb_cmos(CMOS_CENTURY); + Century = rtc_read(CMOS_CENTURY); } else { // Infer current century from the year. - u8 year = inb_cmos(CMOS_RTC_YEAR); + u8 year = rtc_read(CMOS_RTC_YEAR); if (year > 0x80) Century = 0x19; else @@ -142,10 +97,10 @@ handle_1a02(struct bregs *regs) return; }
- regs->dh = inb_cmos(CMOS_RTC_SECONDS); - regs->cl = inb_cmos(CMOS_RTC_MINUTES); - regs->ch = inb_cmos(CMOS_RTC_HOURS); - regs->dl = inb_cmos(CMOS_STATUS_B) & RTC_B_DSE; + regs->dh = rtc_read(CMOS_RTC_SECONDS); + regs->cl = rtc_read(CMOS_RTC_MINUTES); + regs->ch = rtc_read(CMOS_RTC_HOURS); + regs->dl = rtc_read(CMOS_STATUS_B) & RTC_B_DSE; regs->ah = 0; regs->al = regs->ch; set_success(regs); @@ -169,13 +124,13 @@ handle_1a03(struct bregs *regs) rtc_setup(); // fall through as if an update were not in progress } - outb_cmos(regs->dh, CMOS_RTC_SECONDS); - outb_cmos(regs->cl, CMOS_RTC_MINUTES); - outb_cmos(regs->ch, CMOS_RTC_HOURS); + rtc_write(CMOS_RTC_SECONDS, regs->dh); + rtc_write(CMOS_RTC_MINUTES, regs->cl); + rtc_write(CMOS_RTC_HOURS, regs->ch); // Set Daylight Savings time enabled bit to requested value - u8 val8 = ((inb_cmos(CMOS_STATUS_B) & (RTC_B_PIE|RTC_B_AIE)) + u8 val8 = ((rtc_read(CMOS_STATUS_B) & (RTC_B_PIE|RTC_B_AIE)) | RTC_B_24HR | (regs->dl & RTC_B_DSE)); - outb_cmos(val8, CMOS_STATUS_B); + rtc_write(CMOS_STATUS_B, val8); regs->ah = 0; regs->al = val8; // val last written to Reg B set_success(regs); @@ -190,9 +145,9 @@ handle_1a04(struct bregs *regs) set_invalid(regs); return; } - regs->cl = inb_cmos(CMOS_RTC_YEAR); - regs->dh = inb_cmos(CMOS_RTC_MONTH); - regs->dl = inb_cmos(CMOS_RTC_DAY_MONTH); + regs->cl = rtc_read(CMOS_RTC_YEAR); + regs->dh = rtc_read(CMOS_RTC_MONTH); + regs->dl = rtc_read(CMOS_RTC_DAY_MONTH); regs->ch = GET_LOW(Century); regs->al = regs->ch; set_success(regs); @@ -217,13 +172,13 @@ handle_1a05(struct bregs *regs) set_invalid(regs); return; } - outb_cmos(regs->cl, CMOS_RTC_YEAR); - outb_cmos(regs->dh, CMOS_RTC_MONTH); - outb_cmos(regs->dl, CMOS_RTC_DAY_MONTH); + rtc_write(CMOS_RTC_YEAR, regs->cl); + rtc_write(CMOS_RTC_MONTH, regs->dh); + rtc_write(CMOS_RTC_DAY_MONTH, regs->dl); SET_LOW(Century, regs->ch); // clear halt-clock bit - u8 val8 = inb_cmos(CMOS_STATUS_B) & ~RTC_B_SET; - outb_cmos(val8, CMOS_STATUS_B); + u8 val8 = rtc_read(CMOS_STATUS_B) & ~RTC_B_SET; + rtc_write(CMOS_STATUS_B, val8); regs->ah = 0; regs->al = val8; // AL = val last written to Reg B set_success(regs); @@ -243,7 +198,7 @@ handle_1a06(struct bregs *regs) // // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1 // My assumption: RegB = ((RegB & 01111111b) | 00100000b) - u8 val8 = inb_cmos(CMOS_STATUS_B); // Get Status Reg B + u8 val8 = rtc_read(CMOS_STATUS_B); // Get Status Reg B regs->ax = 0; if (val8 & RTC_B_AIE) { // Alarm interrupt enabled already @@ -254,11 +209,11 @@ handle_1a06(struct bregs *regs) rtc_setup(); // fall through as if an update were not in progress } - outb_cmos(regs->dh, CMOS_RTC_SECONDS_ALARM); - outb_cmos(regs->cl, CMOS_RTC_MINUTES_ALARM); - outb_cmos(regs->ch, CMOS_RTC_HOURS_ALARM); + rtc_write(CMOS_RTC_SECONDS_ALARM, regs->dh); + rtc_write(CMOS_RTC_MINUTES_ALARM, regs->cl); + rtc_write(CMOS_RTC_HOURS_ALARM, regs->ch); // enable Status Reg B alarm bit, clear halt clock bit - outb_cmos((val8 & ~RTC_B_SET) | RTC_B_AIE, CMOS_STATUS_B); + rtc_write(CMOS_STATUS_B, (val8 & ~RTC_B_SET) | RTC_B_AIE); set_success(regs); }
@@ -276,9 +231,9 @@ handle_1a07(struct bregs *regs) // // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1 // My assumption: RegB = (RegB & 01010111b) - u8 val8 = inb_cmos(CMOS_STATUS_B); // Get Status Reg B + u8 val8 = rtc_read(CMOS_STATUS_B); // Get Status Reg B // clear clock-halt bit, disable alarm bit - outb_cmos(val8 & ~(RTC_B_SET|RTC_B_AIE), CMOS_STATUS_B); + rtc_write(CMOS_STATUS_B, val8 & ~(RTC_B_SET|RTC_B_AIE)); regs->ah = 0; regs->al = val8; // val last written to Reg B set_success(regs); @@ -374,32 +329,6 @@ irqtimer_check(u32 end) * Periodic timer ****************************************************************/
-int RTCusers VARLOW; - -void -useRTC(void) -{ - int count = GET_LOW(RTCusers); - SET_LOW(RTCusers, count+1); - if (count) - return; - // Turn on the Periodic Interrupt timer - u8 bRegister = inb_cmos(CMOS_STATUS_B); - outb_cmos(bRegister | RTC_B_PIE, CMOS_STATUS_B); -} - -void -releaseRTC(void) -{ - int count = GET_LOW(RTCusers); - SET_LOW(RTCusers, count-1); - if (count != 1) - return; - // Clear the Periodic Interrupt. - u8 bRegister = inb_cmos(CMOS_STATUS_B); - outb_cmos(bRegister & ~RTC_B_PIE, CMOS_STATUS_B); -} - static int set_usertimer(u32 usecs, u16 seg, u16 offset) { @@ -410,7 +339,7 @@ set_usertimer(u32 usecs, u16 seg, u16 offset) SET_BDA(rtc_wait_flag, RWS_WAIT_PENDING); // Set status byte. SET_BDA(user_wait_complete_flag, SEGOFF(seg, offset)); SET_BDA(user_wait_timeout, usecs); - useRTC(); + rtc_use(); return 0; }
@@ -421,7 +350,7 @@ clear_usertimer(void) return; // Turn off status byte. SET_BDA(rtc_wait_flag, 0); - releaseRTC(); + rtc_release(); }
#define RET_ECLOCKINUSE 0x83 @@ -489,8 +418,8 @@ handle_70(void) debug_isr(DEBUG_ISR_70);
// Check which modes are enabled and have occurred. - u8 registerB = inb_cmos(CMOS_STATUS_B); - u8 registerC = inb_cmos(CMOS_STATUS_C); + u8 registerB = rtc_read(CMOS_STATUS_B); + u8 registerC = rtc_read(CMOS_STATUS_C);
if (!(registerB & (RTC_B_PIE|RTC_B_AIE))) goto done; diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c index 2524b7b..f8d44d7 100644 --- a/src/fw/paravirt.c +++ b/src/fw/paravirt.c @@ -10,8 +10,8 @@
#include "byteorder.h" // be32_to_cpu #include "config.h" // CONFIG_QEMU -#include "hw/cmos.h" // CMOS_* #include "hw/pci.h" // create_pirtable +#include "hw/rtc.h" // CMOS_* #include "ioport.h" // outw #include "malloc.h" // malloc_tmp #include "memmap.h" // add_e820 @@ -69,21 +69,21 @@ qemu_preinit(void) kvm_preinit();
// On emulators, get memory size from nvram. - u32 rs = ((inb_cmos(CMOS_MEM_EXTMEM2_LOW) << 16) - | (inb_cmos(CMOS_MEM_EXTMEM2_HIGH) << 24)); + u32 rs = ((rtc_read(CMOS_MEM_EXTMEM2_LOW) << 16) + | (rtc_read(CMOS_MEM_EXTMEM2_HIGH) << 24)); if (rs) rs += 16 * 1024 * 1024; else - rs = (((inb_cmos(CMOS_MEM_EXTMEM_LOW) << 10) - | (inb_cmos(CMOS_MEM_EXTMEM_HIGH) << 18)) + rs = (((rtc_read(CMOS_MEM_EXTMEM_LOW) << 10) + | (rtc_read(CMOS_MEM_EXTMEM_HIGH) << 18)) + 1 * 1024 * 1024); RamSize = rs; add_e820(0, rs, E820_RAM);
// Check for memory over 4Gig - u64 high = ((inb_cmos(CMOS_MEM_HIGHMEM_LOW) << 16) - | ((u32)inb_cmos(CMOS_MEM_HIGHMEM_MID) << 24) - | ((u64)inb_cmos(CMOS_MEM_HIGHMEM_HIGH) << 32)); + u64 high = ((rtc_read(CMOS_MEM_HIGHMEM_LOW) << 16) + | ((u32)rtc_read(CMOS_MEM_HIGHMEM_MID) << 24) + | ((u64)rtc_read(CMOS_MEM_HIGHMEM_HIGH) << 32)); RamSizeOver4G = high; add_e820(0x100000000ull, high, E820_RAM);
diff --git a/src/fw/smp.c b/src/fw/smp.c index b96bcfd..38fe383 100644 --- a/src/fw/smp.c +++ b/src/fw/smp.c @@ -6,7 +6,7 @@ // This file may be distributed under the terms of the GNU LGPLv3 license.
#include "config.h" // CONFIG_* -#include "hw/cmos.h" // CMOS_BIOS_SMP_COUNT +#include "hw/rtc.h" // CMOS_BIOS_SMP_COUNT #include "output.h" // dprintf #include "romfile.h" // romfile_loadint #include "stacks.h" // yield @@ -132,7 +132,7 @@ smp_setup(void) writel(APIC_ICR_LOW, 0x000C4600 | sipi_vector);
// Wait for other CPUs to process the SIPI. - u8 cmos_smp_count = inb_cmos(CMOS_BIOS_SMP_COUNT); + u8 cmos_smp_count = rtc_read(CMOS_BIOS_SMP_COUNT); while (cmos_smp_count + 1 != readl(&CountCPUs)) yield();
diff --git a/src/hw/ata.c b/src/hw/ata.c index 34ba119..8165e50 100644 --- a/src/hw/ata.c +++ b/src/hw/ata.c @@ -10,7 +10,6 @@ #include "block.h" // struct drive_s #include "blockcmd.h" // CDB_CMD_READ_10 #include "byteorder.h" // be16_to_cpu -#include "cmos.h" // inb_cmos #include "ioport.h" // inb #include "malloc.h" // malloc_fseg #include "output.h" // dprintf diff --git a/src/hw/floppy.c b/src/hw/floppy.c index 39efaad..cf1ab87 100644 --- a/src/hw/floppy.c +++ b/src/hw/floppy.c @@ -8,7 +8,6 @@ #include "biosvar.h" // SET_BDA #include "block.h" // struct drive_s #include "bregs.h" // struct bregs -#include "cmos.h" // inb_cmos #include "config.h" // CONFIG_FLOPPY #include "malloc.h" // malloc_fseg #include "output.h" // dprintf @@ -16,6 +15,7 @@ #include "pci_ids.h" // PCI_CLASS_BRIDGE_ISA #include "pic.h" // pic_eoi1 #include "romfile.h" // romfile_loadint +#include "rtc.h" // rtc_read #include "stacks.h" // yield #include "std/disk.h" // DISK_RET_SUCCESS #include "string.h" // memset @@ -139,7 +139,7 @@ floppy_setup(void) dprintf(3, "init floppy drives\n");
if (CONFIG_QEMU) { - u8 type = inb_cmos(CMOS_FLOPPY_DRIVE_TYPE); + u8 type = rtc_read(CMOS_FLOPPY_DRIVE_TYPE); if (type & 0xf0) addFloppy(0, type >> 4); if (type & 0x0f) diff --git a/src/hw/rtc.c b/src/hw/rtc.c new file mode 100644 index 0000000..9886aa5 --- /dev/null +++ b/src/hw/rtc.c @@ -0,0 +1,93 @@ +// Support for MC146818 Real Time Clock chip. +// +// Copyright (C) 2008-2013 Kevin O'Connor kevin@koconnor.net +// Copyright (C) 2002 MandrakeSoft S.A. +// +// This file may be distributed under the terms of the GNU LGPLv3 license. + +#include "biosvar.h" // GET_LOW +#include "ioport.h" // inb +#include "rtc.h" // rtc_read +#include "stacks.h" // yield +#include "util.h" // timer_calc + +u8 +rtc_read(u8 index) +{ + index |= NMI_DISABLE_BIT; + outb(index, PORT_CMOS_INDEX); + return inb(PORT_CMOS_DATA); +} + +void +rtc_write(u8 index, u8 val) +{ + index |= NMI_DISABLE_BIT; + outb(index, PORT_CMOS_INDEX); + outb(val, PORT_CMOS_DATA); +} + +void +rtc_mask(u8 index, u8 off, u8 on) +{ + outb(index, PORT_CMOS_INDEX); + u8 val = inb(PORT_CMOS_DATA); + outb((val & ~off) | on, PORT_CMOS_DATA); +} + +int +rtc_updating(void) +{ + // This function checks to see if the update-in-progress bit + // is set in CMOS Status Register A. If not, it returns 0. + // If it is set, it tries to wait until there is a transition + // to 0, and will return 0 if such a transition occurs. A -1 + // is returned only after timing out. The maximum period + // that this bit should be set is constrained to (1984+244) + // useconds, but we wait for longer just to be sure. + + if ((rtc_read(CMOS_STATUS_A) & RTC_A_UIP) == 0) + return 0; + u32 end = timer_calc(15); + for (;;) { + if ((rtc_read(CMOS_STATUS_A) & RTC_A_UIP) == 0) + return 0; + if (timer_check(end)) + // update-in-progress never transitioned to 0 + return -1; + yield(); + } +} + +void +rtc_setup(void) +{ + rtc_write(CMOS_STATUS_A, 0x26); // 32,768Khz src, 976.5625us updates + rtc_mask(CMOS_STATUS_B, ~RTC_B_DSE, RTC_B_24HR); + rtc_read(CMOS_STATUS_C); + rtc_read(CMOS_STATUS_D); +} + +int RTCusers VARLOW; + +void +rtc_use(void) +{ + int count = GET_LOW(RTCusers); + SET_LOW(RTCusers, count+1); + if (count) + return; + // Turn on the Periodic Interrupt timer + rtc_mask(CMOS_STATUS_B, 0, RTC_B_PIE); +} + +void +rtc_release(void) +{ + int count = GET_LOW(RTCusers); + SET_LOW(RTCusers, count-1); + if (count != 1) + return; + // Clear the Periodic Interrupt. + rtc_mask(CMOS_STATUS_B, RTC_B_PIE, 0); +} diff --git a/src/hw/cmos.h b/src/hw/rtc.h similarity index 67% rename from src/hw/cmos.h rename to src/hw/rtc.h index 067c7fa..d975f6b 100644 --- a/src/hw/cmos.h +++ b/src/hw/rtc.h @@ -1,10 +1,5 @@ -// Definitions for X86 CMOS non-volatile memory access. -// -// Copyright (C) 2008 Kevin O'Connor kevin@koconnor.net -// -// This file may be distributed under the terms of the GNU LGPLv3 license. -#ifndef __CMOS_H -#define __CMOS_H +#ifndef __RTC_H +#define __RTC_H
// Standard BIOS RTC chip entries #define CMOS_RTC_SECONDS 0x00 @@ -45,34 +40,30 @@ #define CMOS_MEM_HIGHMEM_HIGH 0x5d #define CMOS_BIOS_SMP_COUNT 0x5f
-// CMOS_FLOPPY_DRIVE_TYPE bitdefs -#define CFD_NO_DRIVE 0 -#define CFD_360KB 1 -#define CFD_12MB 2 -#define CFD_720KB 3 -#define CFD_144MB 4 -#define CFD_288MB 5 +// RTC register flags +#define RTC_A_UIP 0x80
-#ifndef __ASSEMBLY__ +#define RTC_B_SET 0x80 +#define RTC_B_PIE 0x40 +#define RTC_B_AIE 0x20 +#define RTC_B_UIE 0x10 +#define RTC_B_BIN 0x04 +#define RTC_B_24HR 0x02 +#define RTC_B_DSE 0x01
-#include "ioport.h" // inb, outb +#ifndef __ASSEMBLY__
-static inline u8 -inb_cmos(u8 reg) -{ - reg |= NMI_DISABLE_BIT; - outb(reg, PORT_CMOS_INDEX); - return inb(PORT_CMOS_DATA); -} +#include "types.h" // u8
-static inline void -outb_cmos(u8 val, u8 reg) -{ - reg |= NMI_DISABLE_BIT; - outb(reg, PORT_CMOS_INDEX); - outb(val, PORT_CMOS_DATA); -} +// rtc.c +u8 rtc_read(u8 index); +void rtc_write(u8 index, u8 val); +void rtc_mask(u8 index, u8 off, u8 on); +int rtc_updating(void); +void rtc_setup(void); +void rtc_use(void); +void rtc_release(void);
#endif // !__ASSEMBLY__
-#endif // cmos.h +#endif // rtc.h diff --git a/src/post.c b/src/post.c index 592176d..acd2362 100644 --- a/src/post.c +++ b/src/post.c @@ -12,12 +12,12 @@ #include "fw/xen.h" // xen_preinit #include "hw/ahci.h" // ahci_setup #include "hw/ata.h" // ata_setup -#include "hw/cmos.h" // CMOS_* #include "hw/esp-scsi.h" // esp_scsi_setup #include "hw/lsi-scsi.h" // lsi_scsi_setup #include "hw/megasas.h" // megasas_setup #include "hw/pic.h" // pic_setup #include "hw/ps2port.h" // ps2port_setup +#include "hw/rtc.h" // rtc_write #include "hw/usb.h" // usb_setup #include "hw/virtio-blk.h" // virtio_blk_setup #include "hw/virtio-scsi.h" // virtio_scsi_setup @@ -39,7 +39,7 @@ ivt_init(void)
// Setup reset-vector entry point (controls legacy reboots). HaveRunPost = 1; - outb_cmos(0, CMOS_RESET_CODE); + rtc_write(CMOS_RESET_CODE, 0);
// Initialize all vectors to the default handler. int i; diff --git a/src/resume.c b/src/resume.c index af39a1d..12daf0f 100644 --- a/src/resume.c +++ b/src/resume.c @@ -7,10 +7,10 @@ #include "bregs.h" // struct bregs #include "config.h" // CONFIG_* #include "farptr.h" // FLATPTR_TO_SEGOFF -#include "hw/cmos.h" // inb_cmos #include "hw/pci.h" // pci_reboot #include "hw/pic.h" // pic_eoi2 #include "hw/ps2port.h" // i8042_reboot +#include "hw/rtc.h" // rtc_read #include "ioport.h" // outb #include "output.h" // dprintf #include "stacks.h" // farcall16big @@ -40,8 +40,8 @@ handle_resume(void) { ASSERT16(); debug_serial_preinit(); - int status = inb_cmos(CMOS_RESET_CODE); - outb_cmos(0, CMOS_RESET_CODE); + int status = rtc_read(CMOS_RESET_CODE); + rtc_write(CMOS_RESET_CODE, 0); dprintf(1, "In resume (status=%d)\n", status);
dma_setup(); diff --git a/src/romlayout.S b/src/romlayout.S index 17904ae..3307f76 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -8,7 +8,7 @@ #include "config.h" // CONFIG_* #include "ioport.h" // PORT_A20 #include "x86.h" // CR0_* -#include "hw/cmos.h" // CMOS_RESET_CODE +#include "hw/rtc.h" // CMOS_RESET_CODE #include "asm-offsets.h" // BREGS_* #include "entryfuncs.S" // ENTRY_*
diff --git a/src/stacks.c b/src/stacks.c index cc597c6..d8aaca8 100644 --- a/src/stacks.c +++ b/src/stacks.c @@ -6,6 +6,7 @@
#include "biosvar.h" // GET_GLOBAL #include "bregs.h" // CR0_PE +#include "hw/rtc.h" // rtc_use #include "list.h" // hlist_node #include "malloc.h" // free #include "output.h" // dprintf @@ -446,7 +447,7 @@ start_preempt(void) return; CanPreempt = 1; PreemptCount = 0; - useRTC(); + rtc_use(); }
// Turn off RTC irqs / stop checking for thread execution. @@ -458,7 +459,7 @@ finish_preempt(void) return; } CanPreempt = 0; - releaseRTC(); + rtc_release(); dprintf(9, "Done preempt - %d checks\n", PreemptCount); yield(); } diff --git a/src/util.h b/src/util.h index 57c3ae9..9c45925 100644 --- a/src/util.h +++ b/src/util.h @@ -59,8 +59,6 @@ u32 irqtimer_calc_ticks(u32 count); u32 irqtimer_calc(u32 msecs); int irqtimer_check(u32 end); void handle_1586(struct bregs *regs); -void useRTC(void); -void releaseRTC(void);
// fw/acpi.c extern struct rsdp_descriptor *RsdpAddr;
Move the DMA controller code in resume.c and hw/floppy.c to a new file hw/dma.c. This centralizes the DMA controller code into one place.
Also, don't unmask the floppy DRQ during floppy setup - there is no reason to unmask the DRQ prior to a command being programmed into the DMA controller.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- Makefile | 2 +- src/hw/dma.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/hw/floppy.c | 40 ++++++---------------------------------- src/resume.c | 13 ------------- src/util.h | 5 ++++- 5 files changed, 67 insertions(+), 49 deletions(-) create mode 100644 src/hw/dma.c
diff --git a/Makefile b/Makefile index 0cdb6d3..4c78d69 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ OUT=out/ SRCBOTH=misc.c stacks.c output.c string.c x86.c block.c cdrom.c mouse.c kbd.c \ serial.c clock.c resume.c pnpbios.c vgahooks.c pcibios.c apm.c \ fw/smp.c \ - hw/pci.c hw/timer.c hw/rtc.c hw/pic.c hw/ps2port.c \ + hw/pci.c hw/timer.c hw/dma.c hw/rtc.c hw/pic.c hw/ps2port.c \ hw/usb.c hw/usb-uhci.c hw/usb-ohci.c hw/usb-ehci.c \ hw/usb-hid.c hw/usb-msc.c hw/usb-uas.c \ hw/blockcmd.c hw/floppy.c hw/ata.c hw/ahci.c hw/ramdisk.c \ diff --git a/src/hw/dma.c b/src/hw/dma.c new file mode 100644 index 0000000..2051ab0 --- /dev/null +++ b/src/hw/dma.c @@ -0,0 +1,56 @@ +// Code to support legacy Intel 8237 DMA chip. +// +// Copyright (C) 2008,2009 Kevin O'Connor kevin@koconnor.net +// Copyright (C) 2002 MandrakeSoft S.A. +// +// This file may be distributed under the terms of the GNU LGPLv3 license. + +#include "ioport.h" // PORT_DMA1_MASK_REG +#include "util.h" // dma_setup + +// Setup the DMA controller for a floppy transfer. +int +dma_floppy(u32 addr, int count, int isWrite) +{ + // check for 64K boundary overrun + u16 end = count - 1; + u32 last_addr = addr + end; + if ((addr >> 16) != (last_addr >> 16)) + return -1; + + u8 mode_register = 0x46; // single mode, increment, autoinit disable, + if (isWrite) + mode_register = 0x4a; + + outb(0x06, PORT_DMA1_MASK_REG); + outb(0x00, PORT_DMA1_CLEAR_FF_REG); // clear flip-flop + outb(addr, PORT_DMA_ADDR_2); + outb(addr>>8, PORT_DMA_ADDR_2); + outb(0x00, PORT_DMA1_CLEAR_FF_REG); // clear flip-flop + outb(end, PORT_DMA_CNT_2); + outb(end>>8, PORT_DMA_CNT_2); + + // port 0b: DMA-1 Mode Register + // transfer type=write, channel 2 + outb(mode_register, PORT_DMA1_MODE_REG); + + // port 81: DMA-1 Page Register, channel 2 + outb(addr>>16, PORT_DMA_PAGE_2); + + outb(0x02, PORT_DMA1_MASK_REG); // unmask channel 2 + + return 0; +} + +// Reset DMA controller +void +dma_setup(void) +{ + // first reset the DMA controllers + outb(0, PORT_DMA1_MASTER_CLEAR); + outb(0, PORT_DMA2_MASTER_CLEAR); + + // then initialize the DMA controllers + outb(0xc0, PORT_DMA2_MODE_REG); + outb(0x00, PORT_DMA2_MASK_REG); +} diff --git a/src/hw/floppy.c b/src/hw/floppy.c index cf1ab87..0479ac7 100644 --- a/src/hw/floppy.c +++ b/src/hw/floppy.c @@ -153,8 +153,6 @@ floppy_setup(void) addFloppy(1, type); }
- outb(0x02, PORT_DMA1_MASK_REG); - enable_hwirq(6, FUNC16(entry_0e)); }
@@ -433,7 +431,7 @@ check_recal_drive(struct drive_s *drive_g)
/**************************************************************** - * Floppy DMA + * Floppy DMA transfer ****************************************************************/
// Perform a floppy transfer command (setup DMA and issue PIO). @@ -444,39 +442,13 @@ floppy_cmd(struct disk_op_s *op, int blocksize, struct floppy_pio_s *pio) if (ret) return ret;
- // es:bx = pointer to where to place information from diskette - u32 addr = (u32)op->buf_fl; - int count = op->count * blocksize; - - // check for 64K boundary overrun - u16 end = count - 1; - u32 last_addr = addr + end; - if ((addr >> 16) != (last_addr >> 16)) + // Setup DMA controller + int isWrite = pio->data[0] != 0xe6; + ret = dma_floppy((u32)op->buf_fl, op->count * blocksize, isWrite); + if (ret) return DISK_RET_EBOUNDARY;
- u8 mode_register = 0x4a; // single mode, increment, autoinit disable, - if (pio->data[0] == 0xe6) - // read - mode_register = 0x46; - - //DEBUGF("floppy dma c2\n"); - outb(0x06, PORT_DMA1_MASK_REG); - outb(0x00, PORT_DMA1_CLEAR_FF_REG); // clear flip-flop - outb(addr, PORT_DMA_ADDR_2); - outb(addr>>8, PORT_DMA_ADDR_2); - outb(0x00, PORT_DMA1_CLEAR_FF_REG); // clear flip-flop - outb(end, PORT_DMA_CNT_2); - outb(end>>8, PORT_DMA_CNT_2); - - // port 0b: DMA-1 Mode Register - // transfer type=write, channel 2 - outb(mode_register, PORT_DMA1_MODE_REG); - - // port 81: DMA-1 Page Register, channel 2 - outb(addr>>16, PORT_DMA_PAGE_2); - - outb(0x02, PORT_DMA1_MASK_REG); // unmask channel 2 - + // Invoke floppy controller ret = floppy_select_drive(pio->data[1] & 1); if (ret) return ret; diff --git a/src/resume.c b/src/resume.c index 12daf0f..370bfe3 100644 --- a/src/resume.c +++ b/src/resume.c @@ -21,19 +21,6 @@ // Indicator if POST phase has been run. int HaveRunPost VARFSEG;
-// Reset DMA controller -void -dma_setup(void) -{ - // first reset the DMA controllers - outb(0, PORT_DMA1_MASTER_CLEAR); - outb(0, PORT_DMA2_MASTER_CLEAR); - - // then initialize the DMA controllers - outb(0xc0, PORT_DMA2_MODE_REG); - outb(0x00, PORT_DMA2_MASK_REG); -} - // Handler for post calls that look like a resume. void VISIBLE16 handle_resume(void) diff --git a/src/util.h b/src/util.h index 9c45925..d51e30f 100644 --- a/src/util.h +++ b/src/util.h @@ -124,6 +124,10 @@ void wrmsr_smp(u32 index, u64 val); void smp_setup(void); int apic_id_is_present(u8 apic_id);
+// hw/dma.c +int dma_floppy(u32 addr, int count, int isWrite); +void dma_setup(void); + // hw/floppy.c extern struct floppy_ext_dbt_s diskette_param_table2; void floppy_setup(void); @@ -204,7 +208,6 @@ void reloc_preinit(void *f, void *arg);
// resume.c extern int HaveRunPost; -void dma_setup(void);
// romlayout.S void reset_vector(void) __noreturn;
Move the inb(), insb(), etc. code from ioport.h to x86.h. Move the PORT_* definitions to their appropriate hardware files.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/apm.c | 2 +- src/farptr.h | 2 +- src/fw/acpi.c | 1 - src/fw/paravirt.c | 1 - src/fw/paravirt.h | 9 ++++ src/fw/pciinit.c | 3 +- src/fw/smm.c | 2 +- src/hw/ahci.c | 2 +- src/hw/ata.c | 2 +- src/hw/ata.h | 5 ++ src/hw/dma.c | 13 ++++- src/hw/floppy.c | 6 +++ src/hw/pci.c | 1 - src/hw/pci.h | 4 ++ src/hw/pic.h | 7 ++- src/hw/ps2port.c | 2 +- src/hw/ps2port.h | 14 +++++- src/hw/rtc.c | 2 +- src/hw/rtc.h | 6 +++ src/hw/serialio.h | 21 ++++++++ src/hw/timer.c | 9 +++- src/hw/usb-ehci.c | 1 - src/hw/usb-uhci.c | 2 +- src/hw/virtio-pci.h | 2 +- src/ioport.h | 136 ---------------------------------------------------- src/misc.c | 2 + src/output.c | 1 + src/resume.c | 1 - src/romlayout.S | 8 ++-- src/serial.c | 1 + src/system.c | 3 +- src/x86.h | 51 ++++++++++++++++++++ vgasrc/bochsvga.c | 12 +++++ vgasrc/bochsvga.h | 12 ----- vgasrc/stdvga.c | 8 ++-- vgasrc/stdvgaio.c | 4 +- 36 files changed, 179 insertions(+), 179 deletions(-) create mode 100644 src/hw/serialio.h delete mode 100644 src/ioport.h
diff --git a/src/apm.c b/src/apm.c index 7f400fb..fd71a01 100644 --- a/src/apm.c +++ b/src/apm.c @@ -10,10 +10,10 @@ #include "bregs.h" // struct bregs #include "config.h" // CONFIG_* #include "fw/paravirt.h" // runningOnQEMU -#include "ioport.h" // outb #include "output.h" // dprintf #include "stacks.h" // yield_toirq #include "util.h" // apm_shutdown +#include "x86.h" // outb
static void out_str(const char *str_cs) diff --git a/src/farptr.h b/src/farptr.h index b64567e..0a4db68 100644 --- a/src/farptr.h +++ b/src/farptr.h @@ -6,7 +6,7 @@ #ifndef __FARPTR_H #define __FARPTR_H
-#include "ioport.h" // insb +#include "x86.h" // insb
// Dummy definitions used to make sure gcc understands dependencies // between SET_SEG and GET/READ/WRITE_SEG macros. diff --git a/src/fw/acpi.c b/src/fw/acpi.c index 8f99b34..8de24c9 100644 --- a/src/fw/acpi.c +++ b/src/fw/acpi.c @@ -11,7 +11,6 @@ #include "hw/pci.h" // pci_find_init_device #include "hw/pci_ids.h" // PCI_VENDOR_ID_INTEL #include "hw/pci_regs.h" // PCI_INTERRUPT_LINE -#include "ioport.h" // inl #include "malloc.h" // free #include "output.h" // dprintf #include "paravirt.h" // RamSize diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c index f8d44d7..25d2827 100644 --- a/src/fw/paravirt.c +++ b/src/fw/paravirt.c @@ -12,7 +12,6 @@ #include "config.h" // CONFIG_QEMU #include "hw/pci.h" // create_pirtable #include "hw/rtc.h" // CMOS_* -#include "ioport.h" // outw #include "malloc.h" // malloc_tmp #include "memmap.h" // add_e820 #include "output.h" // dprintf diff --git a/src/fw/paravirt.h b/src/fw/paravirt.h index fce5af9..69d7248 100644 --- a/src/fw/paravirt.h +++ b/src/fw/paravirt.h @@ -24,6 +24,15 @@ static inline int runningOnKVM(void) { return CONFIG_QEMU && GET_GLOBAL(PlatformRunningOn) & PF_KVM; }
+// Common paravirt ports. +#define PORT_SMI_CMD 0x00b2 +#define PORT_SMI_STATUS 0x00b3 +#define PORT_QEMU_CFG_CTL 0x0510 +#define PORT_QEMU_CFG_DATA 0x0511 +#define PORT_ACPI_PM_BASE 0xb000 +#define PORT_SMB_BASE 0xb100 +#define PORT_BIOS_APM 0x8900 + void qemu_preinit(void); void qemu_platform_setup(void); void qemu_cfg_init(void); diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c index b29db99..34279a4 100644 --- a/src/fw/pciinit.c +++ b/src/fw/pciinit.c @@ -7,10 +7,10 @@
#include "config.h" // CONFIG_* #include "dev-q35.h" // Q35_HOST_BRIDGE_PCIEXBAR_ADDR +#include "hw/ata.h" // PORT_ATA1_CMD_BASE #include "hw/pci.h" // pci_config_readl #include "hw/pci_ids.h" // PCI_VENDOR_ID_INTEL #include "hw/pci_regs.h" // PCI_COMMAND -#include "ioport.h" // PORT_ATA1_CMD_BASE #include "list.h" // struct hlist_node #include "malloc.h" // free #include "memmap.h" // add_e820 @@ -18,6 +18,7 @@ #include "paravirt.h" // RamSize #include "string.h" // memset #include "util.h" // pci_setup +#include "x86.h" // outb
#define PCI_DEVICE_MEM_MIN 0x1000 #define PCI_BRIDGE_IO_MIN 0x1000 diff --git a/src/fw/smm.c b/src/fw/smm.c index 7142ac0..e1da3f6 100644 --- a/src/fw/smm.c +++ b/src/fw/smm.c @@ -10,8 +10,8 @@ #include "hw/pci.h" // pci_config_writel #include "hw/pci_ids.h" // PCI_VENDOR_ID_INTEL #include "hw/pci_regs.h" // PCI_DEVICE_ID -#include "ioport.h" // outb #include "output.h" // dprintf +#include "paravirt.h" // PORT_SMI_STATUS #include "string.h" // memcpy #include "util.h" // smm_setup #include "x86.h" // wbinvd diff --git a/src/hw/ahci.c b/src/hw/ahci.c index 05a80b3..3e594af 100644 --- a/src/hw/ahci.c +++ b/src/hw/ahci.c @@ -8,7 +8,6 @@ #include "ata.h" // ATA_CB_STAT #include "biosvar.h" // GET_GLOBAL #include "blockcmd.h" // CDB_CMD_READ_10 -#include "ioport.h" // inb #include "malloc.h" // free #include "output.h" // dprintf #include "pci.h" // foreachpci @@ -18,6 +17,7 @@ #include "std/disk.h" // DISK_RET_SUCCESS #include "string.h" // memset #include "util.h" // timer_calc +#include "x86.h" // inb
#define AHCI_REQUEST_TIMEOUT 32000 // 32 seconds max for IDE ops #define AHCI_RESET_TIMEOUT 500 // 500 miliseconds diff --git a/src/hw/ata.c b/src/hw/ata.c index 8165e50..13f28d6 100644 --- a/src/hw/ata.c +++ b/src/hw/ata.c @@ -10,7 +10,6 @@ #include "block.h" // struct drive_s #include "blockcmd.h" // CDB_CMD_READ_10 #include "byteorder.h" // be16_to_cpu -#include "ioport.h" // inb #include "malloc.h" // malloc_fseg #include "output.h" // dprintf #include "pci.h" // foreachpci @@ -21,6 +20,7 @@ #include "std/disk.h" // DISK_RET_SUCCESS #include "string.h" // memset #include "util.h" // timer_calc +#include "x86.h" // inb
#define IDE_TIMEOUT 32000 //32 seconds max for IDE ops
diff --git a/src/hw/ata.h b/src/hw/ata.h index a9f865e..c73892b 100644 --- a/src/hw/ata.h +++ b/src/hw/ata.h @@ -29,6 +29,11 @@ int atapi_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize); void ata_setup(void); int process_ata_op(struct disk_op_s *op);
+#define PORT_ATA2_CMD_BASE 0x0170 +#define PORT_ATA1_CMD_BASE 0x01f0 +#define PORT_ATA2_CTRL_BASE 0x0374 +#define PORT_ATA1_CTRL_BASE 0x03f4 + // Global defines -- ATA register and register bits. // command block & control block regs #define ATA_CB_DATA 0 // data reg in/out pio_base_addr1+0 diff --git a/src/hw/dma.c b/src/hw/dma.c index 2051ab0..20c9fbb 100644 --- a/src/hw/dma.c +++ b/src/hw/dma.c @@ -5,8 +5,19 @@ // // This file may be distributed under the terms of the GNU LGPLv3 license.
-#include "ioport.h" // PORT_DMA1_MASK_REG #include "util.h" // dma_setup +#include "x86.h" // outb + +#define PORT_DMA_ADDR_2 0x0004 +#define PORT_DMA_CNT_2 0x0005 +#define PORT_DMA1_MASK_REG 0x000a +#define PORT_DMA1_MODE_REG 0x000b +#define PORT_DMA1_CLEAR_FF_REG 0x000c +#define PORT_DMA1_MASTER_CLEAR 0x000d +#define PORT_DMA_PAGE_2 0x0081 +#define PORT_DMA2_MASK_REG 0x00d4 +#define PORT_DMA2_MODE_REG 0x00d6 +#define PORT_DMA2_MASTER_CLEAR 0x00da
// Setup the DMA controller for a floppy transfer. int diff --git a/src/hw/floppy.c b/src/hw/floppy.c index 0479ac7..e54f1ba 100644 --- a/src/hw/floppy.c +++ b/src/hw/floppy.c @@ -21,6 +21,12 @@ #include "string.h" // memset #include "util.h" // timer_calc
+#define PORT_FD_BASE 0x03f0 +#define PORT_FD_DOR 0x03f2 +#define PORT_FD_STATUS 0x03f4 +#define PORT_FD_DATA 0x03f5 +#define PORT_FD_DIR 0x03f7 + #define FLOPPY_SIZE_CODE 0x02 // 512 byte sectors #define FLOPPY_DATALEN 0xff // Not used - because size code is 0x02 #define FLOPPY_MOTOR_TICKS 37 // ~2 seconds diff --git a/src/hw/pci.c b/src/hw/pci.c index 4295d01..6c9aa81 100644 --- a/src/hw/pci.c +++ b/src/hw/pci.c @@ -7,7 +7,6 @@
#include "config.h" // CONFIG_* #include "farptr.h" // MAKE_FLATPTR -#include "ioport.h" // outl #include "malloc.h" // malloc_tmp #include "output.h" // dprintf #include "pci.h" // pci_config_writel diff --git a/src/hw/pci.h b/src/hw/pci.h index 8fccefc..9c7351d 100644 --- a/src/hw/pci.h +++ b/src/hw/pci.h @@ -4,6 +4,10 @@ #include "types.h" // u32 #include "list.h" // hlist_node
+#define PORT_PCI_CMD 0x0cf8 +#define PORT_PCI_REBOOT 0x0cf9 +#define PORT_PCI_DATA 0x0cfc + #define PCI_ROM_SLOT 6 #define PCI_NUM_REGIONS 7 #define PCI_BRIDGE_NUM_REGIONS 2 diff --git a/src/hw/pic.h b/src/hw/pic.h index 2a89e3f..6947b6e 100644 --- a/src/hw/pic.h +++ b/src/hw/pic.h @@ -7,7 +7,12 @@ #ifndef __PIC_H #define __PIC_H
-#include "ioport.h" // PORT_PIC* +#include "x86.h" // outb + +#define PORT_PIC1_CMD 0x0020 +#define PORT_PIC1_DATA 0x0021 +#define PORT_PIC2_CMD 0x00a0 +#define PORT_PIC2_DATA 0x00a1
// PORT_PIC1 bitdefs #define PIC1_IRQ0 (1<<0) diff --git a/src/hw/ps2port.c b/src/hw/ps2port.c index 936d152..04995c8 100644 --- a/src/hw/ps2port.c +++ b/src/hw/ps2port.c @@ -6,13 +6,13 @@ // This file may be distributed under the terms of the GNU LGPLv3 license.
#include "biosvar.h" // GET_LOW -#include "ioport.h" // inb #include "output.h" // dprintf #include "pic.h" // pic_eoi1 #include "ps2port.h" // ps2_kbd_command #include "romfile.h" // romfile_loadint #include "stacks.h" // yield #include "util.h" // udelay +#include "x86.h" // inb
/**************************************************************** diff --git a/src/hw/ps2port.h b/src/hw/ps2port.h index dcae391..2e6f25a 100644 --- a/src/hw/ps2port.h +++ b/src/hw/ps2port.h @@ -2,7 +2,13 @@ #ifndef __PS2PORT_H #define __PS2PORT_H
-#include "types.h" // u8 +#define PORT_PS2_DATA 0x0060 +#define PORT_PS2_CTRLB 0x0061 +#define PORT_PS2_STATUS 0x0064 +#define PORT_A20 0x0092 + +// PORT_A20 bitdefs +#define A20_ENABLE_BIT 0x02
// Standard commands. #define I8042_CMD_CTL_RCTR 0x0120 @@ -54,10 +60,16 @@ #define I8042_CTR_AUXDIS 0x20 #define I8042_CTR_XLATE 0x40
+#ifndef __ASSEMBLY__ + +#include "types.h" // u8 + // functions void i8042_reboot(void); int ps2_kbd_command(int command, u8 *param); int ps2_mouse_command(int command, u8 *param); void ps2port_setup(void);
+#endif // !__ASSEMBLY__ + #endif // ps2port.h diff --git a/src/hw/rtc.c b/src/hw/rtc.c index 9886aa5..628d542 100644 --- a/src/hw/rtc.c +++ b/src/hw/rtc.c @@ -6,10 +6,10 @@ // This file may be distributed under the terms of the GNU LGPLv3 license.
#include "biosvar.h" // GET_LOW -#include "ioport.h" // inb #include "rtc.h" // rtc_read #include "stacks.h" // yield #include "util.h" // timer_calc +#include "x86.h" // inb
u8 rtc_read(u8 index) diff --git a/src/hw/rtc.h b/src/hw/rtc.h index d975f6b..252e73a 100644 --- a/src/hw/rtc.h +++ b/src/hw/rtc.h @@ -1,6 +1,12 @@ #ifndef __RTC_H #define __RTC_H
+#define PORT_CMOS_INDEX 0x0070 +#define PORT_CMOS_DATA 0x0071 + +// PORT_CMOS_INDEX nmi disable bit +#define NMI_DISABLE_BIT 0x80 + // Standard BIOS RTC chip entries #define CMOS_RTC_SECONDS 0x00 #define CMOS_RTC_SECONDS_ALARM 0x01 diff --git a/src/hw/serialio.h b/src/hw/serialio.h new file mode 100644 index 0000000..883fc9c --- /dev/null +++ b/src/hw/serialio.h @@ -0,0 +1,21 @@ +#ifndef __SERIALIO_H +#define __SERIALIO_H + +#define PORT_LPT2 0x0278 +#define PORT_SERIAL4 0x02e8 +#define PORT_SERIAL2 0x02f8 +#define PORT_LPT1 0x0378 +#define PORT_SERIAL3 0x03e8 +#define PORT_SERIAL1 0x03f8 + +// Serial port offsets +#define SEROFF_DATA 0 +#define SEROFF_DLL 0 +#define SEROFF_IER 1 +#define SEROFF_DLH 1 +#define SEROFF_IIR 2 +#define SEROFF_LCR 3 +#define SEROFF_LSR 5 +#define SEROFF_MSR 6 + +#endif // serialio.h diff --git a/src/hw/timer.c b/src/hw/timer.c index ec1e3c5..2832dec 100644 --- a/src/hw/timer.c +++ b/src/hw/timer.c @@ -1,4 +1,4 @@ -// Internal timer support. +// Internal timer and Intel 8253 Programmable Interrupt Timer (PIT) support. // // Copyright (C) 2008-2013 Kevin O'Connor kevin@koconnor.net // @@ -6,12 +6,17 @@
#include "biosvar.h" // GET_LOW #include "config.h" // CONFIG_* -#include "ioport.h" // PORT_PIT_MODE #include "output.h" // dprintf +#include "ps2port.h" // PORT_PS2_CTRLB #include "stacks.h" // yield #include "util.h" // timer_setup #include "x86.h" // cpuid
+#define PORT_PIT_COUNTER0 0x0040 +#define PORT_PIT_COUNTER1 0x0041 +#define PORT_PIT_COUNTER2 0x0042 +#define PORT_PIT_MODE 0x0043 + // Bits for PORT_PIT_MODE #define PM_SEL_TIMER0 (0<<6) #define PM_SEL_TIMER1 (1<<6) diff --git a/src/hw/usb-ehci.c b/src/hw/usb-ehci.c index 626f308..b495d6c 100644 --- a/src/hw/usb-ehci.c +++ b/src/hw/usb-ehci.c @@ -6,7 +6,6 @@
#include "biosvar.h" // GET_LOWFLAT #include "config.h" // CONFIG_* -#include "ioport.h" // outw #include "output.h" // dprintf #include "malloc.h" // free #include "pci.h" // pci_bdf_to_bus diff --git a/src/hw/usb-uhci.c b/src/hw/usb-uhci.c index 753e5dd..03eb5e1 100644 --- a/src/hw/usb-uhci.c +++ b/src/hw/usb-uhci.c @@ -6,7 +6,6 @@
#include "biosvar.h" // GET_LOWFLAT #include "config.h" // CONFIG_* -#include "ioport.h" // outw #include "malloc.h" // free #include "output.h" // dprintf #include "pci.h" // pci_bdf_to_bus @@ -15,6 +14,7 @@ #include "usb.h" // struct usb_s #include "usb-uhci.h" // USBLEGSUP #include "util.h" // msleep +#include "x86.h" // outw
struct usb_uhci_s { struct usb_s usb; diff --git a/src/hw/virtio-pci.h b/src/hw/virtio-pci.h index e1d972d..bc04b03 100644 --- a/src/hw/virtio-pci.h +++ b/src/hw/virtio-pci.h @@ -1,7 +1,7 @@ #ifndef _VIRTIO_PCI_H #define _VIRTIO_PCI_H
-#include "ioport.h" // inl +#include "x86.h" // inl
/* A 32-bit r/o bitmask of the features supported by the host */ #define VIRTIO_PCI_HOST_FEATURES 0 diff --git a/src/ioport.h b/src/ioport.h deleted file mode 100644 index 3282fb4..0000000 --- a/src/ioport.h +++ /dev/null @@ -1,136 +0,0 @@ -// Definitions for X86 IO port access. -// -// Copyright (C) 2008 Kevin O'Connor kevin@koconnor.net -// -// This file may be distributed under the terms of the GNU LGPLv3 license. -#ifndef __IOPORT_H -#define __IOPORT_H - -#define PORT_DMA_ADDR_2 0x0004 -#define PORT_DMA_CNT_2 0x0005 -#define PORT_DMA1_MASK_REG 0x000a -#define PORT_DMA1_MODE_REG 0x000b -#define PORT_DMA1_CLEAR_FF_REG 0x000c -#define PORT_DMA1_MASTER_CLEAR 0x000d -#define PORT_PIC1_CMD 0x0020 -#define PORT_PIC1_DATA 0x0021 -#define PORT_PIT_COUNTER0 0x0040 -#define PORT_PIT_COUNTER1 0x0041 -#define PORT_PIT_COUNTER2 0x0042 -#define PORT_PIT_MODE 0x0043 -#define PORT_PS2_DATA 0x0060 -#define PORT_PS2_CTRLB 0x0061 -#define PORT_PS2_STATUS 0x0064 -#define PORT_CMOS_INDEX 0x0070 -#define PORT_CMOS_DATA 0x0071 -#define PORT_DIAG 0x0080 -#define PORT_DMA_PAGE_2 0x0081 -#define PORT_A20 0x0092 -#define PORT_PIC2_CMD 0x00a0 -#define PORT_PIC2_DATA 0x00a1 -#define PORT_SMI_CMD 0x00b2 -#define PORT_SMI_STATUS 0x00b3 -#define PORT_DMA2_MASK_REG 0x00d4 -#define PORT_DMA2_MODE_REG 0x00d6 -#define PORT_DMA2_MASTER_CLEAR 0x00da -#define PORT_MATH_CLEAR 0x00f0 -#define PORT_ATA2_CMD_BASE 0x0170 -#define PORT_ATA1_CMD_BASE 0x01f0 -#define PORT_LPT2 0x0278 -#define PORT_SERIAL4 0x02e8 -#define PORT_SERIAL2 0x02f8 -#define PORT_ATA2_CTRL_BASE 0x0374 -#define PORT_LPT1 0x0378 -#define PORT_SERIAL3 0x03e8 -#define PORT_ATA1_CTRL_BASE 0x03f4 -#define PORT_FD_BASE 0x03f0 -#define PORT_FD_DOR 0x03f2 -#define PORT_FD_STATUS 0x03f4 -#define PORT_FD_DATA 0x03f5 -#define PORT_HD_DATA 0x03f6 -#define PORT_FD_DIR 0x03f7 -#define PORT_SERIAL1 0x03f8 -#define PORT_PCI_CMD 0x0cf8 -#define PORT_PCI_REBOOT 0x0cf9 -#define PORT_PCI_DATA 0x0cfc -#define PORT_BIOS_DEBUG 0x0402 -#define PORT_QEMU_CFG_CTL 0x0510 -#define PORT_QEMU_CFG_DATA 0x0511 -#define PORT_ACPI_PM_BASE 0xb000 -#define PORT_SMB_BASE 0xb100 -#define PORT_BIOS_APM 0x8900 - -// Serial port offsets -#define SEROFF_DATA 0 -#define SEROFF_DLL 0 -#define SEROFF_IER 1 -#define SEROFF_DLH 1 -#define SEROFF_IIR 2 -#define SEROFF_LCR 3 -#define SEROFF_LSR 5 -#define SEROFF_MSR 6 - -// PORT_A20 bitdefs -#define A20_ENABLE_BIT 0x02 - -// PORT_CMOS_INDEX nmi disable bit -#define NMI_DISABLE_BIT 0x80 - -#ifndef __ASSEMBLY__ - -#include "types.h" // u8 - -static inline void outb(u8 value, u16 port) { - __asm__ __volatile__("outb %b0, %w1" : : "a"(value), "Nd"(port)); -} -static inline void outw(u16 value, u16 port) { - __asm__ __volatile__("outw %w0, %w1" : : "a"(value), "Nd"(port)); -} -static inline void outl(u32 value, u16 port) { - __asm__ __volatile__("outl %0, %w1" : : "a"(value), "Nd"(port)); -} -static inline u8 inb(u16 port) { - u8 value; - __asm__ __volatile__("inb %w1, %b0" : "=a"(value) : "Nd"(port)); - return value; -} -static inline u16 inw(u16 port) { - u16 value; - __asm__ __volatile__("inw %w1, %w0" : "=a"(value) : "Nd"(port)); - return value; -} -static inline u32 inl(u16 port) { - u32 value; - __asm__ __volatile__("inl %w1, %0" : "=a"(value) : "Nd"(port)); - return value; -} - -static inline void insb(u16 port, u8 *data, u32 count) { - asm volatile("rep insb (%%dx), %%es:(%%edi)" - : "+c"(count), "+D"(data) : "d"(port) : "memory"); -} -static inline void insw(u16 port, u16 *data, u32 count) { - asm volatile("rep insw (%%dx), %%es:(%%edi)" - : "+c"(count), "+D"(data) : "d"(port) : "memory"); -} -static inline void insl(u16 port, u32 *data, u32 count) { - asm volatile("rep insl (%%dx), %%es:(%%edi)" - : "+c"(count), "+D"(data) : "d"(port) : "memory"); -} -// XXX - outs not limited to es segment -static inline void outsb(u16 port, u8 *data, u32 count) { - asm volatile("rep outsb %%es:(%%esi), (%%dx)" - : "+c"(count), "+S"(data) : "d"(port) : "memory"); -} -static inline void outsw(u16 port, u16 *data, u32 count) { - asm volatile("rep outsw %%es:(%%esi), (%%dx)" - : "+c"(count), "+S"(data) : "d"(port) : "memory"); -} -static inline void outsl(u16 port, u32 *data, u32 count) { - asm volatile("rep outsl %%es:(%%esi), (%%dx)" - : "+c"(count), "+S"(data) : "d"(port) : "memory"); -} - -#endif // !__ASSEMBLY__ - -#endif // ioport.h diff --git a/src/misc.c b/src/misc.c index 43dd16f..191e707 100644 --- a/src/misc.c +++ b/src/misc.c @@ -12,6 +12,8 @@ #include "stacks.h" // call16_int #include "string.h" // memset
+#define PORT_MATH_CLEAR 0x00f0 +
/**************************************************************** * Misc 16bit ISRs diff --git a/src/output.c b/src/output.c index c38c70c..b47625f 100644 --- a/src/output.c +++ b/src/output.c @@ -11,6 +11,7 @@ #include "config.h" // CONFIG_* #include "biosvar.h" // GET_GLOBAL #include "fw/paravirt.h" // PlatformRunningOn +#include "hw/serialio.h" // SEROFF_IER #include "malloc.h" // malloc_tmp #include "output.h" // dprintf #include "stacks.h" // call16_int diff --git a/src/resume.c b/src/resume.c index 370bfe3..fc2fee9 100644 --- a/src/resume.c +++ b/src/resume.c @@ -11,7 +11,6 @@ #include "hw/pic.h" // pic_eoi2 #include "hw/ps2port.h" // i8042_reboot #include "hw/rtc.h" // rtc_read -#include "ioport.h" // outb #include "output.h" // dprintf #include "stacks.h" // farcall16big #include "std/bda.h" // struct bios_data_area_s diff --git a/src/romlayout.S b/src/romlayout.S index 3307f76..37a0264 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -5,12 +5,12 @@ // // This file may be distributed under the terms of the GNU LGPLv3 license.
-#include "config.h" // CONFIG_* -#include "ioport.h" // PORT_A20 -#include "x86.h" // CR0_* -#include "hw/rtc.h" // CMOS_RESET_CODE #include "asm-offsets.h" // BREGS_* +#include "config.h" // CONFIG_* #include "entryfuncs.S" // ENTRY_* +#include "hw/ps2port.h" // PORT_A20 +#include "hw/rtc.h" // CMOS_RESET_CODE +#include "x86.h" // CR0_*
/**************************************************************** diff --git a/src/serial.c b/src/serial.c index 02f30d6..9b6d29f 100644 --- a/src/serial.c +++ b/src/serial.c @@ -7,6 +7,7 @@
#include "biosvar.h" // SET_BDA #include "bregs.h" // struct bregs +#include "hw/serialio.h" // SEROFF_IER #include "output.h" // debug_enter #include "stacks.h" // yield #include "util.h" // serial_setup diff --git a/src/system.c b/src/system.c index aaca059..3daf49b 100644 --- a/src/system.c +++ b/src/system.c @@ -8,12 +8,13 @@ #include "biosvar.h" // GET_GLOBAL #include "bregs.h" // struct bregs #include "hw/pic.h" // pic_reset -#include "ioport.h" // inb +#include "hw/ps2port.h" // PORT_A20 #include "malloc.h" // LegacyRamSize #include "memmap.h" // E820_RAM #include "output.h" // debug_enter #include "string.h" // memcpy_far #include "util.h" // handle_1553 +#include "x86.h" // inb
// Use PS2 System Control port A to set A20 enable static inline u8 diff --git a/src/x86.h b/src/x86.h index 389d747..c51f767 100644 --- a/src/x86.h +++ b/src/x86.h @@ -120,6 +120,57 @@ static inline u32 getesp(void) { return esp; }
+static inline void outb(u8 value, u16 port) { + __asm__ __volatile__("outb %b0, %w1" : : "a"(value), "Nd"(port)); +} +static inline void outw(u16 value, u16 port) { + __asm__ __volatile__("outw %w0, %w1" : : "a"(value), "Nd"(port)); +} +static inline void outl(u32 value, u16 port) { + __asm__ __volatile__("outl %0, %w1" : : "a"(value), "Nd"(port)); +} +static inline u8 inb(u16 port) { + u8 value; + __asm__ __volatile__("inb %w1, %b0" : "=a"(value) : "Nd"(port)); + return value; +} +static inline u16 inw(u16 port) { + u16 value; + __asm__ __volatile__("inw %w1, %w0" : "=a"(value) : "Nd"(port)); + return value; +} +static inline u32 inl(u16 port) { + u32 value; + __asm__ __volatile__("inl %w1, %0" : "=a"(value) : "Nd"(port)); + return value; +} + +static inline void insb(u16 port, u8 *data, u32 count) { + asm volatile("rep insb (%%dx), %%es:(%%edi)" + : "+c"(count), "+D"(data) : "d"(port) : "memory"); +} +static inline void insw(u16 port, u16 *data, u32 count) { + asm volatile("rep insw (%%dx), %%es:(%%edi)" + : "+c"(count), "+D"(data) : "d"(port) : "memory"); +} +static inline void insl(u16 port, u32 *data, u32 count) { + asm volatile("rep insl (%%dx), %%es:(%%edi)" + : "+c"(count), "+D"(data) : "d"(port) : "memory"); +} +// XXX - outs not limited to es segment +static inline void outsb(u16 port, u8 *data, u32 count) { + asm volatile("rep outsb %%es:(%%esi), (%%dx)" + : "+c"(count), "+S"(data) : "d"(port) : "memory"); +} +static inline void outsw(u16 port, u16 *data, u32 count) { + asm volatile("rep outsw %%es:(%%esi), (%%dx)" + : "+c"(count), "+S"(data) : "d"(port) : "memory"); +} +static inline void outsl(u16 port, u32 *data, u32 count) { + asm volatile("rep outsl %%es:(%%esi), (%%dx)" + : "+c"(count), "+S"(data) : "d"(port) : "memory"); +} + static inline void writel(void *addr, u32 val) { *(volatile u32 *)addr = val; } diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c index 750624a..9425a82 100644 --- a/vgasrc/bochsvga.c +++ b/vgasrc/bochsvga.c @@ -15,6 +15,7 @@ #include "std/vbe.h" // VBE_CAPABILITY_8BIT_DAC #include "stdvga.h" // VGAREG_SEQU_ADDRESS #include "vgabios.h" // struct vbe_modeinfo +#include "x86.h" // outw
/**************************************************************** @@ -130,6 +131,17 @@ bochsvga_list_modes(u16 seg, u16 *dest, u16 *last) * Helper functions ****************************************************************/
+static inline u16 dispi_read(u16 reg) +{ + outw(reg, VBE_DISPI_IOPORT_INDEX); + return inw(VBE_DISPI_IOPORT_DATA); +} +static inline void dispi_write(u16 reg, u16 val) +{ + outw(reg, VBE_DISPI_IOPORT_INDEX); + outw(val, VBE_DISPI_IOPORT_DATA); +} + int bochsvga_get_window(struct vgamode_s *vmode_g, int window) { diff --git a/vgasrc/bochsvga.h b/vgasrc/bochsvga.h index 87fb6ea..78b27c8 100644 --- a/vgasrc/bochsvga.h +++ b/vgasrc/bochsvga.h @@ -2,7 +2,6 @@ #define __BOCHSVGA_H
#include "types.h" // u8 -#include "ioport.h" // outw
#define VBE_DISPI_BANK_ADDRESS 0xA0000 #define VBE_DISPI_BANK_SIZE_KB 64 @@ -41,17 +40,6 @@
#define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000
-static inline u16 dispi_read(u16 reg) -{ - outw(reg, VBE_DISPI_IOPORT_INDEX); - return inw(VBE_DISPI_IOPORT_DATA); -} -static inline void dispi_write(u16 reg, u16 val) -{ - outw(reg, VBE_DISPI_IOPORT_INDEX); - outw(val, VBE_DISPI_IOPORT_DATA); -} - struct vgamode_s *bochsvga_find_mode(int mode); void bochsvga_list_modes(u16 seg, u16 *dest, u16 *last); int bochsvga_get_window(struct vgamode_s *vmode_g, int window); diff --git a/vgasrc/stdvga.c b/vgasrc/stdvga.c index baf8135..e0661f1 100644 --- a/vgasrc/stdvga.c +++ b/vgasrc/stdvga.c @@ -5,12 +5,12 @@ // // This file may be distributed under the terms of the GNU LGPLv3 license.
-#include "vgabios.h" // struct vgamode_s -#include "stdvga.h" // stdvga_setup -#include "ioport.h" // outb -#include "farptr.h" // SET_FARVAR #include "biosvar.h" // GET_GLOBAL +#include "farptr.h" // SET_FARVAR +#include "stdvga.h" // stdvga_setup #include "string.h" // memset_far +#include "vgabios.h" // struct vgamode_s +#include "x86.h" // outb
/**************************************************************** diff --git a/vgasrc/stdvgaio.c b/vgasrc/stdvgaio.c index b370d1a..d6138c2 100644 --- a/vgasrc/stdvgaio.c +++ b/vgasrc/stdvgaio.c @@ -4,9 +4,9 @@ // // This file may be distributed under the terms of the GNU LGPLv3 license.
-#include "stdvga.h" // stdvga_pelmask_read #include "farptr.h" // GET_FARVAR -#include "ioport.h" // inb +#include "stdvga.h" // stdvga_pelmask_read +#include "x86.h" // inb
u8 stdvga_pelmask_read(void)
On Wed, Sep 18, 2013 at 09:57:51PM -0400, Kevin O'Connor wrote:
This series moves some additional hardware driver code from the main src/ directory to files in the src/hw/ directory. This is a minor cleanup to gather more hardware driver code together.
This series is also at: https://github.com/KevinOConnor/seabios/tree/testing
FYI, I have committed this series.
-Kevin