Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Porting #SF patch #565 Real Time Clock /CMOS fix #4

Merged
merged 26 commits into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b9fa528
fix SHA1RNDS4 instruction implementation (#86)
stlintel Oct 10, 2023
e88dfa2
Porting #SF patch #565 Real Time Clock /CMOS fix
Aug 26, 2022
3e913fa
after this patch BX_HAVE_TIMELOCAL/BX_HAVE_GMTIME/BX_HAVE_MKTIME are …
Aug 26, 2022
f77bec8
guard SVM functions with ifdef
Nov 19, 2023
fd472d3
fix SHA1RNDS4 instruction implementation (#86)
stlintel Oct 10, 2023
2dfba66
Porting #SF patch #565 Real Time Clock /CMOS fix
Aug 26, 2022
f98c542
after this patch BX_HAVE_TIMELOCAL/BX_HAVE_GMTIME/BX_HAVE_MKTIME are …
Aug 26, 2022
09bc2d6
sync sha.cc back to master
Nov 19, 2023
a2d27fd
Merge branch 'bochs/real_time_cmos_fix_patch' of https://github.com/b…
Nov 19, 2023
dadb2ec
update sha.cc back to match master
Nov 19, 2023
a7b9d8e
Merge branch 'master' into bochs/real_time_cmos_fix_patch
stlintel Nov 27, 2023
5546b1f
Started working on branch 'real_time_cmos_fix_patch'.
vruppert Nov 27, 2023
2647c28
Merge branch 'master' into bochs/real_time_cmos_fix_patch
vruppert Nov 27, 2023
692c06a
Continued work on branch 'real_time_cmos_fix_patch'.
vruppert Nov 27, 2023
84858dd
Revert "Continued work on branch 'real_time_cmos_fix_patch'."
vruppert Nov 27, 2023
bcbfd1a
Continued work on branch 'real_time_cmos_fix_patch'.
vruppert Nov 27, 2023
950e24a
Merge branch 'master' into bochs/real_time_cmos_fix_patch
vruppert Nov 27, 2023
010cb3e
Changes in branch 'real_time_cmos_fix_patch'.
vruppert Nov 28, 2023
f1d2093
BIOS build fix and recompiled images.
vruppert Nov 28, 2023
f49d44b
Bugfix in branch 'real_time_cmos_fix_patch'.
vruppert Nov 28, 2023
a458765
Merge branch 'master' into bochs/real_time_cmos_fix_patch
vruppert Nov 28, 2023
4d401b4
BIOS bugfixes in branch 'real_time_cmos_fix_patch'.
vruppert Nov 28, 2023
c0c0622
Portability fixes in branch 'real_time_cmos_fix_patch'.
vruppert Nov 30, 2023
c94673c
Some more portability fixes in branch 'real_time_cmos_fix_patch'.
vruppert Nov 30, 2023
79cb934
Merge branch 'master' into bochs/real_time_cmos_fix_patch
vruppert Dec 1, 2023
51858cb
Merge branch 'master' into bochs/real_time_cmos_fix_patch
vruppert Dec 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ bochs-msvc-src.zip

# /bochs/bios/
/bochs/bios/Makefile
/bochs/bios/_rombios*_.c
/bochs/bios/biossums
/bochs/bios/rombios*.s
/bochs/bios/rombios*.sym
/bochs/bios/rombios*.txt
/bochs/bios/rombios*.bin
/bochs/bios/rombios32.out

# /bochs/build/linux/
/bochs/build/linux/DOC-linux.html
Expand Down
Binary file modified bochs/bios/BIOS-bochs-latest
Binary file not shown.
Binary file modified bochs/bios/BIOS-bochs-legacy
Binary file not shown.
7 changes: 4 additions & 3 deletions bochs/bios/Makefile.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (C) 2001-2020 The Bochs Project
# Copyright (C) 2001-2023 The Bochs Project
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -45,8 +45,9 @@ IASL = @IASL@
BX_INCDIRS = -I.. -I$(srcdir)/.. -I../iodev -I$(srcdir)/../iodev
LOCAL_CXXFLAGS =

UPSTREAM_RELEASE_DATE = $(shell grep "Updated:" ../README | sed 's/Updated://')
BUILDDATE = `date -u -d '$(UPSTREAM_RELEASE_DATE)' '+%m/%d/%y'`
# UPSTREAM_RELEASE_DATE = $(shell grep "Updated:" ../README | sed 's/Updated://')
# BUILDDATE = `date -u -d '$(UPSTREAM_RELEASE_DATE)' '+%m/%d/%y'`
BUILDDATE = `date -u '+%m/%d/%y'`
BIOS_BUILD_DATE = "-DBIOS_BUILD_DATE=\"$(BUILDDATE)\""
#
# -------- end configurable options --------------------------
Expand Down
171 changes: 145 additions & 26 deletions bochs/bios/rombios.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2021 The Bochs Project
// Copyright (C) 2001-2023 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -573,6 +573,12 @@ typedef unsigned long Bit32u;
shr ebx, #16
ret

imodu:
div bl
mov al, ah
xor ah, ah
ret

ASM_END

// for access to RAM area which is used by interrupt vectors
Expand Down Expand Up @@ -841,6 +847,8 @@ static Bit16u inw();
static void outw();
static void init_rtc();
static bx_bool rtc_updating();
static Bit8u bin2bcd();
static Bit8u bcd2bin();

static Bit8u _read_byte();
static Bit16u _read_word();
Expand Down Expand Up @@ -928,7 +936,7 @@ Bit16u cdrom_boot();

#endif // BX_ELTORITO_BOOT

static char bios_svn_version_string[] = "$Revision$ $Date$";
// static char bios_svn_version_string[] = "$Revision$ $Date$";

#define BIOS_COPYRIGHT_STRING "(c) 2001-2021 The Bochs Project"

Expand Down Expand Up @@ -1255,6 +1263,51 @@ rtc_updating()
return(1); // update-in-progress never transitioned to 0
}

Bit8u
bin2bcd(value)
Bit8u value;
{
ASM_START
push bp
mov bp, sp

push dx
mov dh, ah
xor ah, ah
mov al, 4[bp]
mov dl, #10
div dl
shl al, #4
add al, ah
mov ah, dh
pop dx

pop bp
ASM_END
}

Bit8u
bcd2bin(value)
Bit8u value;
{
ASM_START
push bp
mov bp, sp

push dx
mov al, 4[bp]
mov dh, al
and dh, #0x0f
shr al, #4
mov dl, #10
mul dl
add al, dh
pop dx

pop bp
ASM_END
}

#define read_byte(seg, offset) _read_byte(offset, seg)

Bit8u
Expand Down Expand Up @@ -2011,8 +2064,7 @@ void s3_resume_panic()
void
print_bios_banner()
{
printf(BX_APPNAME" BIOS - build: %s\n%s\nOptions: ",
BIOS_BUILD_DATE, bios_svn_version_string);
printf(BX_APPNAME" BIOS - build: %s\nOptions: ", BIOS_BUILD_DATE);
printf(
#if BX_APM
"apmbios "
Expand Down Expand Up @@ -2264,7 +2316,7 @@ log_bios_start()
#if BX_DEBUG_SERIAL
outb(BX_DEBUG_PORT+UART_LCR, 0x03); /* setup for serial logging: 8N1 */
#endif
BX_INFO("%s\n", bios_svn_version_string);
BX_INFO("BIOS BUILD DATE: %s\n", BIOS_BUILD_DATE);
}

bx_bool
Expand Down Expand Up @@ -8461,7 +8513,7 @@ int1a_function(regs, ds, iret_addr)
Bit16u ds; // previous DS:, DS set to 0x0000 by asm wrapper
iret_addr_t iret_addr; // CS,IP,Flags pushed from original INT call
{
Bit8u val8;
Bit8u val8,hr;

BX_DEBUG_INT1A("int1a: AX=%04x BX=%04x CX=%04x DX=%04x DS=%04x\n", regs.u.r16.ax, regs.u.r16.bx, regs.u.r16.cx, regs.u.r16.dx, ds);

Expand Down Expand Up @@ -8506,10 +8558,24 @@ int1a_function(regs, ds, iret_addr)
break;
}

regs.u.r8.dh = inb_cmos(0x00); // Seconds
regs.u.r8.cl = inb_cmos(0x02); // Minutes
regs.u.r8.ch = inb_cmos(0x04); // Hours
regs.u.r8.dl = inb_cmos(0x0b) & 0x01; // Stat Reg B
val8 = inb_cmos(0x0b);
if(val8&0x04){
regs.u.r8.dh = bin2bcd(inb_cmos(0x00)); // Seconds
regs.u.r8.cl = bin2bcd(inb_cmos(0x02)); // Minutes
hr = inb_cmos(0x04);
if(!(val8&0x02)&&(hr&0x80)) hr = (hr & 0x7f) + 12;
if(!(val8&0x02)&&(!(hr%12))) hr -= 12;
regs.u.r8.ch = bin2bcd(hr); // Hours
}else{
regs.u.r8.dh = inb_cmos(0x00); // Seconds
regs.u.r8.cl = inb_cmos(0x02); // Minutes
hr = inb_cmos(0x04);
if(!(val8&0x02)&&(hr&0x80)) hr = (hr & 0x7f) + 0x12;
if(!(val8&0x02)&&(!(hr%0x12))) hr -= 0x12;
regs.u.r8.ch = hr; // Hours
}

regs.u.r8.dl = val8 & 0x01; // Stat Reg B
regs.u.r8.ah = 0;
regs.u.r8.al = regs.u.r8.ch;
ClearCF(iret_addr.flags); // OK
Expand All @@ -8530,11 +8596,29 @@ int1a_function(regs, ds, iret_addr)
init_rtc();
// fall through as if an update were not in progress
}
outb_cmos(0x00, regs.u.r8.dh); // Seconds
outb_cmos(0x02, regs.u.r8.cl); // Minutes
outb_cmos(0x04, regs.u.r8.ch); // Hours

val8 = inb_cmos(0x0b);

if(val8 & 0x04){
hr = bcd2bin(regs.u.r8.ch);
if(!(val8&0x02)&&(hr>=12)) hr |= 0x80;
if(!(val8&0x02)&&(hr>12)) hr -= 12;
if(!(val8&0x02)&&(hr==00)) hr = 12;
outb_cmos(0x00, bcd2bin(regs.u.r8.dh)); // Seconds
outb_cmos(0x02, bcd2bin(regs.u.r8.cl)); // Minutes
outb_cmos(0x04, hr); // Hours
}else{
hr = regs.u.r8.ch;
if(!(val8&0x02)&&(hr>=0x12)) hr |= 0x80;
if(!(val8&0x02)&&(hr>0x12)) hr -= 0x12;
if(!(val8&0x02)&&(hr==0x00)) hr = 0x12;
outb_cmos(0x00, regs.u.r8.dh); // Seconds
outb_cmos(0x02, regs.u.r8.cl); // Minutes
outb_cmos(0x04, hr); // Hours
}

// Set Daylight Savings time enabled bit to requested value
val8 = (inb_cmos(0x0b) & 0x60) | 0x02 | (regs.u.r8.dl & 0x01);
val8 = (val8 & 0x66) | (regs.u.r8.dl & 0x01);
// (reg B already selected)
outb_cmos(0x0b, val8);
regs.u.r8.ah = 0;
Expand All @@ -8548,10 +8632,21 @@ int1a_function(regs, ds, iret_addr)
SetCF(iret_addr.flags);
break;
}
regs.u.r8.cl = inb_cmos(0x09); // Year
regs.u.r8.dh = inb_cmos(0x08); // Month
regs.u.r8.dl = inb_cmos(0x07); // Day of Month
regs.u.r8.ch = inb_cmos(0x32); // Century

val8 = inb_cmos(0x0b);

if(val8 & 0x04){
regs.u.r8.cl = bin2bcd(inb_cmos(0x09)); // Year
regs.u.r8.dh = bin2bcd(inb_cmos(0x08)); // Month
regs.u.r8.dl = bin2bcd(inb_cmos(0x07)); // Day of Month
regs.u.r8.ch = bin2bcd(inb_cmos(0x32)); // Century
}else{
regs.u.r8.cl = inb_cmos(0x09); // Year
regs.u.r8.dh = inb_cmos(0x08); // Month
regs.u.r8.dl = inb_cmos(0x07); // Day of Month
regs.u.r8.ch = inb_cmos(0x32); // Century
}

regs.u.r8.al = regs.u.r8.ch;
ClearCF(iret_addr.flags); // OK
break;
Expand All @@ -8572,11 +8667,21 @@ int1a_function(regs, ds, iret_addr)
SetCF(iret_addr.flags);
break;
}
outb_cmos(0x09, regs.u.r8.cl); // Year
outb_cmos(0x08, regs.u.r8.dh); // Month
outb_cmos(0x07, regs.u.r8.dl); // Day of Month
outb_cmos(0x32, regs.u.r8.ch); // Century
val8 = inb_cmos(0x0b) & 0x7f; // clear halt-clock bit

val8=inb_cmos(0x0b);

if(val8&0x04){
outb_cmos(0x09, bcd2bin(regs.u.r8.cl)); // Year
outb_cmos(0x08, bcd2bin(regs.u.r8.dh)); // Month
outb_cmos(0x07, bcd2bin(regs.u.r8.dl)); // Day of Month
outb_cmos(0x32, bcd2bin(regs.u.r8.ch)); // Century
}else{
outb_cmos(0x09, regs.u.r8.cl); // Year
outb_cmos(0x08, regs.u.r8.dh); // Month
outb_cmos(0x07, regs.u.r8.dl); // Day of Month
outb_cmos(0x32, regs.u.r8.ch); // Century
}
val8 = val8 & 0x7f; // clear halt-clock bit
outb_cmos(0x0b, val8);
regs.u.r8.ah = 0;
regs.u.r8.al = val8; // AL = val last written to Reg B
Expand Down Expand Up @@ -8605,9 +8710,23 @@ int1a_function(regs, ds, iret_addr)
init_rtc();
// fall through as if an update were not in progress
}
outb_cmos(0x01, regs.u.r8.dh); // Seconds alarm
outb_cmos(0x03, regs.u.r8.cl); // Minutes alarm
outb_cmos(0x05, regs.u.r8.ch); // Hours alarm

if(val8&0x04){
hr = bcd2bin(regs.u.r8.ch);
outb_cmos(0x01, bcd2bin(regs.u.r8.dh)); // Seconds alarm
outb_cmos(0x03, bcd2bin(regs.u.r8.cl)); // Minutes alarm
if((val8&0x02)&&(hr>=12)) hr |= 0x80;
if((val8&0x02)&&(hr==00)) hr = 12;
outb_cmos(0x05, hr); // Hours alarm
}else{
hr = regs.u.r8.ch;
outb_cmos(0x01, regs.u.r8.dh); // Seconds alarm
outb_cmos(0x03, regs.u.r8.cl); // Minutes alarm
if((val8&0x02)&&(hr>=0x12)) hr |= 0x80;
if((val8&0x02)&&(hr==0x00)) hr = 0x12;
outb_cmos(0x05, hr); // Hours alarm
}

outb(PORT_PIC2_DATA, inb(PORT_PIC2_DATA) & 0xfe); // enable IRQ 8
// enable Status Reg B alarm bit, clear halt clock bit
outb_cmos(0x0b, (val8 & 0x7f) | 0x20);
Expand Down
42 changes: 32 additions & 10 deletions bochs/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,27 @@ void bx_init_options()

// clock & cmos options
static const char *clock_sync_names[] = { "none", "realtime", "slowdown", "both", NULL };
Bit64s mintime,maxtime;
struct tm mtim,xtim;

mtim.tm_year =0000 -1900;
mtim.tm_mon = 1 - 1;
mtim.tm_mday = 1 ;
mtim.tm_hour = 00 ;
mtim.tm_min = 00 ;
mtim.tm_sec = 00 ;
mtim.tm_isdst = -1 ;

xtim.tm_year =9999 -1900;
xtim.tm_mon = 12 - 1;
xtim.tm_mday = 31 ;
xtim.tm_hour = 23 ;
xtim.tm_min = 59 ;
xtim.tm_sec = 59 ;
xtim.tm_isdst = -1 ;

mintime=mktime(&mtim); //Find which epoch corresponds to the upper limit expressed in local time
maxtime=mktime(&xtim); //Find which epoch corresponds to the lower limit expressed in local time

bx_param_enum_c *clock_sync = new bx_param_enum_c(clock_cmos,
"clock_sync", "Synchronisation method",
Expand All @@ -995,7 +1016,7 @@ void bx_init_options()
"time0",
"Initial CMOS time for Bochs\n(1:localtime, 2:utc, other:time in seconds)",
"Initial time for Bochs CMOS clock, used if you really want two runs to be identical",
0, BX_MAX_BIT32U,
mintime, maxtime,
BX_CLOCK_TIME0_LOCAL);
bx_param_bool_c *rtc_sync = new bx_param_bool_c(clock_cmos,
"rtc_sync", "Sync RTC speed with realtime",
Expand Down Expand Up @@ -1025,7 +1046,7 @@ void bx_init_options()
deplist->add(rtc_init);
use_cmosimage->set_dependent_list(deplist);

time0->set_ask_format("Enter Initial CMOS time (1:localtime, 2:utc, other:time in seconds): [%d] ");
time0->set_ask_format("Enter Initial CMOS time (1:localtime, 2:utc, other:time in seconds): [" FMT_LL "d] ");
clock_sync->set_ask_format("Enter Synchronisation method: [%s] ");
clock_cmos->set_options(clock_cmos->SHOW_PARENT);
cmosimage->set_options(cmosimage->SHOW_PARENT);
Expand Down Expand Up @@ -3107,9 +3128,9 @@ static int parse_line_formatted(const char *context, int num_params, char *param
for (i=1; i<num_params; i++) {
if (!strncmp(params[i], "file=", 5)) {
SIM->get_param_string(BXPN_CMOSIMAGE_PATH)->set(&params[i][5]);
} else if (!strcmp(params[i], "rtc_init=time0")) {
} else if (!strncmp(params[i], "rtc_init=time0",14)) {
SIM->get_param_bool(BXPN_CMOSIMAGE_RTC_INIT)->set(0);
} else if (!strcmp(params[i], "rtc_init=image")) {
} else if (!strncmp(params[i], "rtc_init=image",14)) {
SIM->get_param_bool(BXPN_CMOSIMAGE_RTC_INIT)->set(1);
} else {
BX_ERROR(("%s: unknown parameter for cmosimage ignored.", context));
Expand Down Expand Up @@ -3139,17 +3160,19 @@ static int parse_line_formatted(const char *context, int num_params, char *param
else if (!strncmp(params[i], "time0=", 6)) {
if (isalpha(params[i][6])) {
memset(&tm_time, 0, sizeof(tm_time));
n = sscanf(&params[i][6], "%3s %3s%3d %2d:%2d:%2d %d", wday, mon, &tm_time.tm_mday,
n = sscanf(&params[i][6], "%3s %3s %2d %2d:%2d:%2d %d", wday, mon, &tm_time.tm_mday,
&tm_time.tm_hour, &tm_time.tm_min, &tm_time.tm_sec, &year);
if ((n == 7) && (year >= 1980) && (strstr(months, mon) != NULL)) {
if ((n == 7) && (strstr(months, mon) != NULL)) {
tm_time.tm_year = year - 1900;
tm_time.tm_mon = 12 - ((int)strlen(strstr(months, mon)) / 4);
tm_time.tm_isdst = -1;
SIM->get_param_num(BXPN_CLOCK_TIME0)->set(mktime(&tm_time));
} else {
PARSE_ERR(("%s: time0 string format malformed.", context));
}
} else {
SIM->get_param_num(BXPN_CLOCK_TIME0)->set(atoi(&params[i][6]));
Bit64s tmptm=atol(&params[i][6]);
SIM->get_param_num(BXPN_CLOCK_TIME0)->set(tmptm);
}
}
else {
Expand Down Expand Up @@ -3438,16 +3461,15 @@ int bx_write_clock_cmos_options(FILE *fp)
{
fprintf(fp, "clock: sync=%s", SIM->get_param_enum(BXPN_CLOCK_SYNC)->get_selected());

switch (SIM->get_param_num(BXPN_CLOCK_TIME0)->get()) {
case 0: break;
switch (SIM->get_param_num(BXPN_CLOCK_TIME0)->get64()) {
case BX_CLOCK_TIME0_LOCAL:
fprintf(fp, ", time0=local");
break;
case BX_CLOCK_TIME0_UTC:
fprintf(fp, ", time0=utc");
break;
default:
fprintf(fp, ", time0=%u", SIM->get_param_num(BXPN_CLOCK_TIME0)->get());
fprintf(fp, ", time0=" FMT_LL "d", SIM->get_param_num(BXPN_CLOCK_TIME0)->get64());
}

fprintf(fp, ", rtc_sync=%d\n", SIM->get_param_bool(BXPN_CLOCK_RTC_SYNC)->get());
Expand Down
Loading