Introduce 'struct segoff_s' to more places.
-- lots of mouse changes, logo, scsi/etherboot hooks, int 1589,
floppy data rate?, int19 calls post
-Possibly introduce a data type for the many seg/off pairs.
-
Audit all sti/cli calls. Audit all call16 calls to make sure flags is
setup properly with respect to irqs.
OFFSET(BREGS_esi, bregs, esi);
OFFSET(BREGS_edi, bregs, edi);
OFFSET(BREGS_flags, bregs, flags);
- OFFSET(BREGS_ip, bregs, ip);
+ OFFSET(BREGS_code, bregs, code);
COMMENT("BDA");
OFFSET(BDA_ebda_seg, bios_data_area_s, ebda_seg);
#include "config.h" // CONFIG_*
#include "disk.h" // struct chs_s
-struct segoff_s {
- union {
- struct {
- u16 offset;
- u16 seg;
- };
- u32 segoff;
- };
-};
-#define SEGOFF(s,o) ({struct segoff_s __so; __so.offset=(o); __so.seg=(s); __so;})
-
/****************************************************************
* Interupt vector table
#define GET_IVT(vector) \
GET_FARVAR(SEG_IVT, ((struct rmode_IVT *)0)->ivec[vector])
-#define SET_IVT(vector, seg, off) \
- SET_FARVAR(SEG_IVT, ((struct rmode_IVT *)0)->ivec[vector].segoff, ((seg) << 16) | (off))
+#define SET_IVT(vector, segoff) \
+ SET_FARVAR(SEG_IVT, ((struct rmode_IVT *)0)->ivec[vector], segoff)
/****************************************************************
u16 crtc_address;
u8 video_msr;
u8 video_pal;
- u16 jump_ip;
- u16 jump_cs;
+ struct segoff_s jump;
u8 other_6b;
u32 timer_counter;
// 40:70
u8 floppy_track[2];
u8 kbd_mode;
u8 kbd_led;
- u32 ptr_user_wait_complete_flag;
+ struct segoff_s user_wait_complete_flag;
u32 user_wait_timeout;
// 40:A0
u8 rtc_wait_flag;
u8 other_a1[7];
- u16 video_savetable_ptr;
- u16 video_savetable_seg;
+ struct segoff_s video_savetable;
u8 other_ac[4];
// 40:B0
u8 other_b0[10];
struct extended_bios_data_area_s {
u8 size;
u8 reserved1[0x21];
- u32 far_call_pointer;
+ struct segoff_s far_call_pointer;
u8 mouse_flag1;
u8 mouse_flag2;
u8 mouse_data[0x08];
fdpt->checksum -= checksum(fdpt, sizeof(*fdpt));
if (driveid == 0)
- SET_IVT(0x41, get_ebda_seg()
- , offsetof(struct extended_bios_data_area_s, fdpt[0]));
+ SET_IVT(0x41, SEGOFF(get_ebda_seg(), offsetof(
+ struct extended_bios_data_area_s, fdpt[0])));
else
- SET_IVT(0x46, get_ebda_seg()
- , offsetof(struct extended_bios_data_area_s, fdpt[1]));
+ SET_IVT(0x46, SEGOFF(get_ebda_seg(), offsetof(
+ struct extended_bios_data_area_s, fdpt[1])));
}
// Map a drive (that was registered via add_bcv_hd)
struct bregs br;
memset(&br, 0, sizeof(br));
- br.ip = bootip;
- br.cs = bootseg;
+ br.code = SEGOFF(bootseg, bootip);
// Set the magic number in ax and the boot drive in dl.
br.dl = bootdrv;
br.ax = 0xaa55;
#ifndef __ASSEMBLY__
+#include "farptr.h" // struct segoff_s
+
/****************************************************************
* Registers saved/restored in romlayout.S
****************************************************************/
UREG(edx, dx, dh, dl);
UREG(ecx, cx, ch, cl);
UREG(eax, ax, ah, al);
- u16 ip;
- u16 cs;
+ struct segoff_s code;
u16 flags;
} PACKED;
// Interval not already set.
SET_BDA(rtc_wait_flag, RWS_WAIT_PENDING); // Set status byte.
- SET_BDA(ptr_user_wait_complete_flag, (seg << 16) | offset);
+ SET_BDA(user_wait_complete_flag, SEGOFF(seg, offset));
SET_BDA(user_wait_timeout, usecs);
// Turn on the Periodic Interrupt timer
u32 time = GET_BDA(user_wait_timeout); // Time left in microseconds.
if (time < 0x3D1) {
// Done waiting - write to specified flag byte.
- u32 segoff = GET_BDA(ptr_user_wait_complete_flag);
- u16 segment = segoff >> 16;
- u16 offset = segoff & 0xffff;
- u8 oldval = GET_FARVAR(segment, *(u8*)(offset+0));
- SET_FARVAR(segment, *(u8*)(offset+0), oldval | 0x80);
+ struct segoff_s segoff = GET_BDA(user_wait_complete_flag);
+ u16 ptr_seg = segoff.seg;
+ u8 *ptr_far = (u8*)(segoff.offset+0);
+ u8 oldval = GET_FARVAR(ptr_seg, *ptr_far);
+ SET_FARVAR(ptr_seg, *ptr_far, oldval | 0x80);
clear_usertimer();
} else {
return;
}
- u16 segment = GET_INT13EXT(regs, segment);
- u16 offset = GET_INT13EXT(regs, offset);
- dop.buf_fl = MAKE_FLATPTR(segment, offset);
+ dop.buf_fl = SEGOFF_TO_FLATPTR(GET_INT13EXT(regs, data));
dop.count = GET_INT13EXT(regs, count);
int status = send_disk_op(&dop);
#include "types.h" // u8
#include "config.h" // CONFIG_*
+#include "farptr.h" // struct segoff_s
#define DISK_RET_SUCCESS 0x00
#define DISK_RET_EPARAM 0x01
u8 size;
u8 reserved;
u16 count;
- u16 offset;
- u16 segment;
+ struct segoff_s data;
u64 lba;
} PACKED;
#endif
+// Definition for common 16bit segment/offset pointers.
+struct segoff_s {
+ union {
+ struct {
+ u16 offset;
+ u16 seg;
+ };
+ u32 segoff;
+ };
+};
+#define SEGOFF(s,o) ({struct segoff_s __so; __so.offset=(o); __so.seg=(s); __so;})
+
+static inline struct segoff_s FLATPTR_TO_SEGOFF(void *p) {
+ return SEGOFF(FLATPTR_TO_SEG(p), FLATPTR_TO_OFFSET(p));
+}
+static inline void *SEGOFF_TO_FLATPTR(struct segoff_s so) {
+ return MAKE_FLATPTR(so.seg, so.offset);
+}
+
#endif // farptr.h
static void
mouse_15c207(struct bregs *regs)
{
- u32 farptr = (regs->es << 16) | regs->bx;
+ struct segoff_s farptr = SEGOFF(regs->es, regs->bx);
u16 ebda_seg = get_ebda_seg();
u8 mouse_flags_2 = GET_EBDA2(ebda_seg, mouse_flag2);
- if (! farptr) {
+ if (! farptr.segoff) {
/* remove handler */
if ((mouse_flags_2 & 0x80) != 0) {
mouse_flags_2 &= ~0x80;
u16 Y = GET_EBDA2(ebda_seg, mouse_data[2]);
SET_EBDA2(ebda_seg, mouse_flag1, 0);
- u32 func = GET_EBDA2(ebda_seg, far_call_pointer);
+ struct segoff_s func = GET_EBDA2(ebda_seg, far_call_pointer);
asm volatile(
"sti\n"
"cli\n"
"cld\n"
:
- : "r"(func), "r"(status), "r"(X), "r"(Y)
+ : "r"(func.segoff), "r"(status), "r"(X), "r"(Y)
: "cc"
);
}
br.dx = 0xffff;
br.es = SEG_BIOS;
br.di = get_pnp_offset();
- br.cs = seg;
- br.ip = offset;
+ br.code = SEGOFF(seg, offset);
call16big(&br);
debug_serial_setup();
, regs->ds, regs->es, GET_SEG(SS));
dprintf(1, " si=%08x di=%08x bp=%08x sp=%08x cs=%04x ip=%04x f=%04x\n"
, regs->esi, regs->edi, regs->ebp, (u32)®s[1]
- , regs->cs, regs->ip, regs->flags);
+ , regs->code.seg, regs->code.offset, regs->flags);
}
// Report entry to an Interrupt Service Routine (ISR).
void
__set_irq(int vector, void *loc)
{
- SET_IVT(vector, SEG_BIOS, (u32)loc - BUILD_BIOS_ADDR);
+ SET_IVT(vector, SEGOFF(SEG_BIOS, (u32)loc - BUILD_BIOS_ADDR));
}
#define set_irq(vector, func) do { \
// set vector 0x79 to zero
// this is used by 'gardian angel' protection system
- SET_IVT(0x79, 0, 0);
+ SET_IVT(0x79, SEGOFF(0, 0));
__set_irq(0x1E, &diskette_param_table2);
}
eoi_pic2();
// NO BREAK
case 0x0a:
-#define BDA_JUMP_IP (((struct bios_data_area_s *)0)->jump_ip)
+#define BDA_JUMP (((struct bios_data_area_s *)0)->jump)
// resume execution by jump via 40h:0067h
asm volatile(
"movw %w1, %%ds\n"
"ljmpw *%0\n"
- : : "m"(BDA_JUMP_IP), "r"(SEG_BDA)
+ : : "m"(BDA_JUMP), "r"(SEG_BDA)
);
break;
"movw %w1, %%ds\n"
"lssw %0, %%sp\n"
"iretw\n"
- : : "m"(BDA_JUMP_IP), "r"(SEG_BDA)
+ : : "m"(BDA_JUMP), "r"(SEG_BDA)
);
break;
"movw %w1, %%ds\n"
"lssw %0, %%sp\n"
"lretw\n"
- : : "m"(BDA_JUMP_IP), "r"(SEG_BDA)
+ : : "m"(BDA_JUMP), "r"(SEG_BDA)
);
break;
}
memset(&br, 0, sizeof(br));
if (s3_resume_vector) {
dprintf(1, "Jump to resume vector (%x)\n", s3_resume_vector);
- br.ip = FLATPTR_TO_OFFSET(s3_resume_vector);
- br.cs = FLATPTR_TO_SEG(s3_resume_vector);
+ br.code = FLATPTR_TO_SEGOFF((void*)s3_resume_vector);
} else {
dprintf(1, "No resume vector set!\n");
// Jump to the post vector to restart with a normal boot.
- br.ip = (u32)reset_vector - BUILD_BIOS_ADDR;
- br.cs = SEG_BIOS;
+ br.code = SEGOFF(SEG_BIOS, (u32)reset_vector - BUILD_BIOS_ADDR);
}
call16big(&br);
}
pushw %cs
pushw $1f // return point
pushw BREGS_flags(%eax) // flags
- pushl BREGS_ip(%eax) // CS:IP
+ pushl BREGS_code(%eax) // CS:IP
// Load calling registers.
movl BREGS_edi(%eax), %edi
__call16_int(struct bregs *callregs, u16 offset)
{
if (MODE16)
- callregs->cs = GET_SEG(CS);
+ callregs->code.seg = GET_SEG(CS);
else
- callregs->cs = SEG_BIOS;
- callregs->ip = offset;
+ callregs->code.seg = SEG_BIOS;
+ callregs->code.offset = offset;
call16(callregs);
}
SET_FARVAR(seg, info->video_pagestart, GET_BDA(video_pagestart));
SET_FARVAR(seg, info->video_page, GET_BDA(video_page));
/* current font */
- SET_FARVAR(seg, *(u32*)&info->font0_off, GET_IVT(0x1f).segoff);
- SET_FARVAR(seg, *(u32*)&info->font1_off, GET_IVT(0x43).segoff);
+ SET_FARVAR(seg, info->font0, GET_IVT(0x1f));
+ SET_FARVAR(seg, info->font1, GET_IVT(0x43));
}
static void
SET_BDA(video_pagestart, GET_FARVAR(seg, info->video_pagestart));
SET_BDA(video_page, GET_FARVAR(seg, info->video_page));
/* current font */
- SET_IVT(0x1f, GET_FARVAR(seg, info->font0_seg)
- , GET_FARVAR(seg, info->font0_off));
- SET_IVT(0x43, GET_FARVAR(seg, info->font1_seg)
- , GET_FARVAR(seg, info->font1_off));
+ SET_IVT(0x1f, GET_FARVAR(seg, info->font0));
+ SET_IVT(0x43, GET_FARVAR(seg, info->font1));
}
// FIXME We nearly have the good tables. to be reworked
SET_BDA(dcc_index, 0x08); // 8 is VGA should be ok for now
- SET_BDA(video_savetable_ptr, (u32)video_save_pointer_table);
- SET_BDA(video_savetable_seg, get_global_seg());
+ SET_BDA(video_savetable
+ , SEGOFF(get_global_seg(), (u32)video_save_pointer_table));
// FIXME
SET_BDA(video_msr, 0x00); // Unavailable on vanilla vga, but...
call16_vgaint(0x1103, 0);
}
// Set the ints 0x1F and 0x43
- SET_IVT(0x1f, get_global_seg(), (u32)&vgafont8[128 * 8]);
+ SET_IVT(0x1f, SEGOFF(get_global_seg(), (u32)&vgafont8[128 * 8]));
switch (cheight) {
case 8:
- SET_IVT(0x43, get_global_seg(), (u32)vgafont8);
+ SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont8));
break;
case 14:
- SET_IVT(0x43, get_global_seg(), (u32)vgafont14);
+ SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont14));
break;
case 16:
- SET_IVT(0x43, get_global_seg(), (u32)vgafont16);
+ SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont16));
break;
}
}
SET_FARVAR(seg, info->static_functionality_seg, get_global_seg());
// Hard coded copy from BIOS area. Should it be cleaner ?
- memcpy_far(seg, info->bda_0x49, SEG_BDA, (void*)0x49, 30);
- memcpy_far(seg, info->bda_0x84, SEG_BDA, (void*)0x84, 3);
+ memcpy_far(seg, info->bda_0x49, SEG_BDA, (void*)0x49
+ , sizeof(info->bda_0x49));
+ memcpy_far(seg, info->bda_0x84, SEG_BDA, (void*)0x84
+ , sizeof(info->bda_0x84));
SET_FARVAR(seg, info->dcc_index, GET_BDA(dcc_index));
SET_FARVAR(seg, info->colors, 16);
vbe_init();
extern void entry_10(void);
- SET_IVT(0x10, get_global_seg(), (u32)entry_10);
+ SET_IVT(0x10, SEGOFF(get_global_seg(), (u32)entry_10));
if (CONFIG_CIRRUS)
cirrus_init();
#define __VGATABLES_H
#include "types.h" // u8
+#include "farptr.h" // struct segoff_s
/*
*
u16 video_pagestart;
u8 video_page;
/* current font */
- u16 font0_off;
- u16 font0_seg;
- u16 font1_off;
- u16 font1_seg;
+ struct segoff_s font0;
+ struct segoff_s font1;
};
struct saveDACcolors {