Compare commits
18
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76c419336e | ||
|
|
2ad0ae8420 | ||
|
|
c0c199bfe6 | ||
|
|
7ec3bcb9b9 | ||
|
|
4bd0a2dfbf | ||
|
|
431e5bc8f4 | ||
|
|
8169d93a9c | ||
|
|
547251dbd0 | ||
|
|
7bbcc44c5e | ||
|
|
25475a88a7 | ||
|
|
db49c29627 | ||
|
|
c237553508 | ||
|
|
0c96d32754 | ||
|
|
3f83f279d7 | ||
|
|
82fe9fa6df | ||
|
|
983d9a428d | ||
|
|
2fa77d8295 | ||
|
|
f53afc1d2d |
No files matched your search
@@ -1 +1,8 @@
|
||||
* text=auto eol=lf
|
||||
lvglh/** linguist-vendored
|
||||
lvgl/** linguist-vendored
|
||||
.vscode/* linguist-vendored
|
||||
lib/* linguist-generated
|
||||
release/* linguist-generated
|
||||
iso/* linguist-generated
|
||||
*.asm linguist-detectable
|
||||
@@ -15,3 +15,4 @@ localenv.json
|
||||
dockerout.txt
|
||||
AGENTS.md
|
||||
*.log
|
||||
/doc/*.md
|
||||
Whitespace-only changes.
@@ -18,7 +18,7 @@
|
||||
@author(Aaron Hance <[email protected]>)
|
||||
@author(Kieron Morris <[email protected]>)
|
||||
}
|
||||
unit PCI;
|
||||
unit pci;
|
||||
|
||||
interface
|
||||
|
||||
|
||||
+1762
-33
File diff suppressed because it is too large.
Load diff
@@ -7,7 +7,7 @@
|
||||
|
||||
@author(Kieron Morris <[email protected]>)
|
||||
}
|
||||
unit OHCI;
|
||||
unit ohci;
|
||||
|
||||
interface
|
||||
|
||||
@@ -23,6 +23,7 @@ uses
|
||||
drivermanagement,
|
||||
usbtypes,
|
||||
usbcore,
|
||||
isrmanager,
|
||||
lists,
|
||||
strings;
|
||||
|
||||
@@ -234,6 +235,7 @@ type
|
||||
EDBulk : POHCI_ED; { Head of bulk ED list }
|
||||
EDInterrupt : POHCI_ED; { Dummy head for interrupt ED list }
|
||||
NumPorts : uint8; { Number of downstream ports }
|
||||
PollBusy : boolean; { Re-entrancy guard for poll }
|
||||
PCIBus : uint8; { PCI address }
|
||||
PCISlot : uint8;
|
||||
PCIFunc : uint8;
|
||||
@@ -1022,6 +1024,60 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{ ========================= Interrupt-Driven Completion ========================= }
|
||||
|
||||
const
|
||||
OHCI_MAX_INSTANCES = 4;
|
||||
|
||||
var
|
||||
OHCIInstances : array[0..OHCI_MAX_INSTANCES-1] of PUSBHCDriver;
|
||||
OHCIInstanceCount : uint32;
|
||||
|
||||
{ ISR handler — registered on the PCI interrupt line. }
|
||||
procedure ohci_isr;
|
||||
var
|
||||
i : uint32;
|
||||
hc : PUSBHCDriver;
|
||||
priv : POHCI_PrivData;
|
||||
intSts : uint32;
|
||||
begin
|
||||
for i := 0 to OHCIInstanceCount - 1 do begin
|
||||
hc := OHCIInstances[i];
|
||||
if hc = nil then continue;
|
||||
priv := POHCI_PrivData(hc^.PrivData);
|
||||
if priv = nil then continue;
|
||||
|
||||
{ Check if this controller has pending interrupt status }
|
||||
intSts := ohci_read(priv^.MMIOBase, OHCI_REG_INTSTATUS);
|
||||
if intSts = 0 then continue;
|
||||
|
||||
{ Acknowledge interrupt status NOW to de-assert level-triggered PCI line.
|
||||
Must happen before ohci_poll, because PollBusy guard may skip the
|
||||
acknowledge inside poll — leaving the line asserted = interrupt storm. }
|
||||
ohci_write(priv^.MMIOBase, OHCI_REG_INTSTATUS, intSts);
|
||||
|
||||
{ Process completions (walks ED lists) }
|
||||
ohci_poll(hc);
|
||||
|
||||
{ Hotplug: if RootHubStatusChange, flag for deferred processing }
|
||||
if ((intSts AND OHCI_INT_RHSC) <> 0) and hc^.HotplugArmed then
|
||||
hc^.PortChangePending := true;
|
||||
end;
|
||||
usbcore.fire_completion_hooks;
|
||||
end;
|
||||
|
||||
{ Enable hardware interrupts: WritebackDoneHead, RootHubStatusChange, UnrecoverableError + MIE. }
|
||||
procedure ohci_enable_interrupts(hc : PUSBHCDriver);
|
||||
var
|
||||
priv : POHCI_PrivData;
|
||||
begin
|
||||
if (hc = nil) or (hc^.PrivData = nil) then exit;
|
||||
priv := POHCI_PrivData(hc^.PrivData);
|
||||
ohci_write(priv^.MMIOBase, OHCI_REG_INTENABLE,
|
||||
OHCI_INT_WDH OR OHCI_INT_RHSC OR OHCI_INT_UE OR OHCI_INT_MIE);
|
||||
syslog.logln('OHCI', 'Hardware interrupts enabled.');
|
||||
end;
|
||||
|
||||
procedure ohci_poll(hc : PUSBHCDriver);
|
||||
var
|
||||
priv : POHCI_PrivData;
|
||||
@@ -1038,6 +1094,11 @@ var
|
||||
begin
|
||||
if (hc = nil) or (hc^.PrivData = nil) then exit;
|
||||
priv := POHCI_PrivData(hc^.PrivData);
|
||||
|
||||
{ Re-entrancy guard }
|
||||
if priv^.PollBusy then exit;
|
||||
priv^.PollBusy := true;
|
||||
|
||||
base := priv^.MMIOBase;
|
||||
|
||||
{ Read and acknowledge interrupt status }
|
||||
@@ -1107,6 +1168,7 @@ begin
|
||||
ed := nextED;
|
||||
end;
|
||||
end;
|
||||
priv^.PollBusy := false;
|
||||
end;
|
||||
|
||||
{ ========================= Load / Init ========================= }
|
||||
@@ -1124,6 +1186,7 @@ var
|
||||
begin
|
||||
push_trace('OHCI.load');
|
||||
load := false;
|
||||
OHCIInstanceCount := 0;
|
||||
|
||||
devices := PCI.getDeviceInfo($0C, $03, $10, count);
|
||||
syslog.log('OHCI', 'Found ');
|
||||
@@ -1220,9 +1283,24 @@ begin
|
||||
hcEntry := usbcore.register_hc(@hc);
|
||||
|
||||
{ Scan ports for connected devices (use the stable pointer, not stack-local @hc) }
|
||||
if hcEntry <> nil then
|
||||
usbcore.scan_ports(hcEntry)
|
||||
else
|
||||
if hcEntry <> nil then begin
|
||||
{ Track instance for ISR dispatch }
|
||||
if OHCIInstanceCount < OHCI_MAX_INSTANCES then begin
|
||||
OHCIInstances[OHCIInstanceCount] := hcEntry;
|
||||
inc(OHCIInstanceCount);
|
||||
end;
|
||||
|
||||
{ Register ISR on PCI interrupt line }
|
||||
syslog.log('OHCI', 'Registering ISR on IRQ ');
|
||||
syslog.writeintln(devices[i].interrupt_line);
|
||||
isrmanager.registerISR(32 + devices[i].interrupt_line, @ohci_isr);
|
||||
|
||||
{ Enable hardware interrupts }
|
||||
ohci_enable_interrupts(hcEntry);
|
||||
|
||||
{ Scan for connected devices }
|
||||
usbcore.scan_ports(hcEntry);
|
||||
end else
|
||||
syslog.logln('OHCI', 'Failed to register HC with USB core.');
|
||||
|
||||
syslog.logln('OHCI', 'Controller initialized and registered.');
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
@author(Kieron Morris <[email protected]>)
|
||||
}
|
||||
unit UHCI;
|
||||
unit uhci;
|
||||
|
||||
interface
|
||||
|
||||
@@ -22,6 +22,7 @@ uses
|
||||
drivermanagement,
|
||||
usbtypes,
|
||||
usbcore,
|
||||
isrmanager,
|
||||
lists,
|
||||
strings;
|
||||
|
||||
@@ -154,6 +155,7 @@ type
|
||||
QHControl : PUHCI_QH; { Queue Head for control transfers }
|
||||
QHBulk : PUHCI_QH; { Queue Head for bulk transfers }
|
||||
QHInterrupt : PUHCI_QH; { Queue Head for interrupt transfers }
|
||||
PollBusy : boolean; { Re-entrancy guard for poll }
|
||||
PCIBus : uint8; { PCI bus/slot/func for bus mastering }
|
||||
PCISlot : uint8;
|
||||
PCIFunc : uint8;
|
||||
@@ -750,6 +752,56 @@ begin
|
||||
pop_trace;
|
||||
end;
|
||||
|
||||
{ ========================= Interrupt-Driven Completion ========================= }
|
||||
|
||||
const
|
||||
UHCI_MAX_INSTANCES = 4;
|
||||
|
||||
var
|
||||
UHCIInstances : array[0..UHCI_MAX_INSTANCES-1] of PUSBHCDriver;
|
||||
UHCIInstanceCount : uint32;
|
||||
|
||||
{ ISR handler — registered on the PCI interrupt line. }
|
||||
procedure uhci_isr;
|
||||
var
|
||||
i : uint32;
|
||||
hc : PUSBHCDriver;
|
||||
priv : PUHCI_PrivData;
|
||||
status : uint16;
|
||||
begin
|
||||
for i := 0 to UHCIInstanceCount - 1 do begin
|
||||
hc := UHCIInstances[i];
|
||||
if hc = nil then continue;
|
||||
priv := PUHCI_PrivData(hc^.PrivData);
|
||||
if priv = nil then continue;
|
||||
|
||||
{ Check if this controller has pending interrupt status }
|
||||
status := uhci_read16(priv^.IOBase, UHCI_REG_USBSTS);
|
||||
if (status AND (UHCI_STS_USBINT OR UHCI_STS_ERROR)) = 0 then continue;
|
||||
|
||||
{ Acknowledge interrupt status NOW to de-assert level-triggered PCI line.
|
||||
Must happen before uhci_poll, because PollBusy guard may skip the
|
||||
acknowledge inside poll — leaving the line asserted = interrupt storm. }
|
||||
uhci_write16(priv^.IOBase, UHCI_REG_USBSTS, status AND (UHCI_STS_USBINT OR UHCI_STS_ERROR));
|
||||
|
||||
{ Process completions (walks QH/TD chains) }
|
||||
uhci_poll(hc);
|
||||
end;
|
||||
usbcore.fire_completion_hooks;
|
||||
end;
|
||||
|
||||
{ Enable hardware interrupts: Interrupt-on-Complete, Short Packet, Timeout/CRC. }
|
||||
procedure uhci_enable_interrupts(hc : PUSBHCDriver);
|
||||
var
|
||||
priv : PUHCI_PrivData;
|
||||
begin
|
||||
if (hc = nil) or (hc^.PrivData = nil) then exit;
|
||||
priv := PUHCI_PrivData(hc^.PrivData);
|
||||
uhci_write16(priv^.IOBase, UHCI_REG_USBINTR,
|
||||
UHCI_INTR_IOC OR UHCI_INTR_SP OR UHCI_INTR_TIMEOUT);
|
||||
syslog.logln('UHCI', 'Hardware interrupts enabled.');
|
||||
end;
|
||||
|
||||
{ ========================= Poll / Completion ========================= }
|
||||
|
||||
procedure uhci_poll(hc : PUSBHCDriver);
|
||||
@@ -768,6 +820,10 @@ begin
|
||||
if (hc = nil) or (hc^.PrivData = nil) then exit;
|
||||
priv := PUHCI_PrivData(hc^.PrivData);
|
||||
|
||||
{ Re-entrancy guard }
|
||||
if priv^.PollBusy then exit;
|
||||
priv^.PollBusy := true;
|
||||
|
||||
{ Read and clear status register }
|
||||
status := uhci_read16(priv^.IOBase, UHCI_REG_USBSTS);
|
||||
if (status AND (UHCI_STS_USBINT OR UHCI_STS_ERROR)) <> 0 then
|
||||
@@ -841,6 +897,7 @@ begin
|
||||
end;
|
||||
qh := qh^.SWNext;
|
||||
end;
|
||||
priv^.PollBusy := false;
|
||||
end;
|
||||
|
||||
{ ========================= Load / Init ========================= }
|
||||
@@ -857,6 +914,7 @@ var
|
||||
begin
|
||||
push_trace('UHCI.load');
|
||||
load := false;
|
||||
UHCIInstanceCount := 0;
|
||||
|
||||
devices := PCI.getDeviceInfo($0C, $03, $00, count);
|
||||
syslog.log('UHCI', 'Found ');
|
||||
@@ -945,9 +1003,24 @@ begin
|
||||
hcEntry := usbcore.register_hc(@hc);
|
||||
|
||||
{ Scan ports for connected devices (use the stable pointer, not stack-local @hc) }
|
||||
if hcEntry <> nil then
|
||||
usbcore.scan_ports(hcEntry)
|
||||
else
|
||||
if hcEntry <> nil then begin
|
||||
{ Track instance for ISR dispatch }
|
||||
if UHCIInstanceCount < UHCI_MAX_INSTANCES then begin
|
||||
UHCIInstances[UHCIInstanceCount] := hcEntry;
|
||||
inc(UHCIInstanceCount);
|
||||
end;
|
||||
|
||||
{ Register ISR on PCI interrupt line }
|
||||
syslog.log('UHCI', 'Registering ISR on IRQ ');
|
||||
syslog.writeintln(devices[i].interrupt_line);
|
||||
isrmanager.registerISR(32 + devices[i].interrupt_line, @uhci_isr);
|
||||
|
||||
{ Enable hardware interrupts }
|
||||
uhci_enable_interrupts(hcEntry);
|
||||
|
||||
{ Scan for connected devices }
|
||||
usbcore.scan_ports(hcEntry);
|
||||
end else
|
||||
syslog.logln('UHCI', 'Failed to register HC with USB core.');
|
||||
|
||||
syslog.logln('UHCI', 'Controller initialized and registered.');
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
@author(Kieron Morris <[email protected]>)
|
||||
}
|
||||
unit USB;
|
||||
unit usb;
|
||||
|
||||
interface
|
||||
|
||||
@@ -35,6 +35,7 @@ uses
|
||||
usbhub,
|
||||
usb_keyboard,
|
||||
usb_mouse,
|
||||
usb_storage,
|
||||
OHCI, UHCI, EHCI, XHCI;
|
||||
|
||||
procedure init;
|
||||
@@ -90,6 +91,9 @@ begin
|
||||
usb_keyboard.init;
|
||||
usb_mouse.init;
|
||||
|
||||
{ Initialize storage class driver }
|
||||
usb_storage.init;
|
||||
|
||||
UHCI_ID.Bus:= biPCI;
|
||||
UHCI_ID.id0:= idANY;
|
||||
UHCI_ID.id1:= $0000000C;
|
||||
|
||||
+2355
-33
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -217,6 +217,9 @@ type
|
||||
PUSBHCDriver = ^TUSBHCDriver;
|
||||
PUSBTransfer = ^TUSBTransfer;
|
||||
|
||||
{ ---- Disconnect Callback ---- }
|
||||
TUSBDisconnectCallback = procedure(dev : PUSBDevice);
|
||||
|
||||
{ ---- Transfer Request ---- }
|
||||
|
||||
TUSBTransfer = record
|
||||
@@ -246,6 +249,7 @@ type
|
||||
Endpoints : array[0..USB_MAX_ENDPOINTS-1] of TUSBEndpoint;
|
||||
NumEndpoints : uint8;
|
||||
Configured : boolean;
|
||||
fnDisconnect : TUSBDisconnectCallback; { Called before device is freed on unplug }
|
||||
end;
|
||||
|
||||
{ ---- HC Driver Abstraction (Function Pointer Types) ---- }
|
||||
@@ -269,6 +273,8 @@ type
|
||||
PrivData : Pointer; { HC-specific state }
|
||||
Devices : PLinkedListBase; { List of PUSBDevice attached }
|
||||
NextAddress : uint8; { Next available USB address (1-127) }
|
||||
PortChangePending : boolean; { Set by ISR when port status changes; processed in deferred context }
|
||||
HotplugArmed : boolean; { False during boot; set true after initial scan_ports to ignore spurious RHSC }
|
||||
{ Operations }
|
||||
fnReset : TUSBHCReset;
|
||||
fnStart : TUSBHCStart;
|
||||
|
||||
@@ -33,31 +33,40 @@ uses
|
||||
procedure callback(scan_code : void);
|
||||
var
|
||||
info : TKeyInfo;
|
||||
raw : uint8;
|
||||
baseCode : uint8;
|
||||
isBreak : boolean;
|
||||
begin
|
||||
raw := uint8(scan_code);
|
||||
|
||||
{ In PS/2 scancode set 1, bit 7 set = key release (break code) }
|
||||
isBreak := (raw AND $80) <> 0;
|
||||
baseCode := raw AND $7F;
|
||||
|
||||
{ Update modifier state (use raw codes so both make/break are handled) }
|
||||
if raw = 42 then keyboard.is_shift := true;
|
||||
if raw = 170 then keyboard.is_shift := false;
|
||||
if raw = 29 then keyboard.is_ctrl := true;
|
||||
if raw = 157 then keyboard.is_ctrl := false;
|
||||
if raw = 56 then keyboard.is_alt := true;
|
||||
if raw = 184 then keyboard.is_alt := false;
|
||||
|
||||
info.SHIFT_DOWN := keyboard.is_shift;
|
||||
info.CTRL_DOWN := keyboard.is_ctrl;
|
||||
info.ALT_DOWN := keyboard.is_alt;
|
||||
info.is_down_code := true;
|
||||
info.is_down_code := not isBreak;
|
||||
|
||||
if keyboard.is_shift then begin
|
||||
if key_matrix_shift[uint8(scan_code)].key_code <> 0 then begin
|
||||
info.key_code := key_matrix_shift[uint8(scan_code)].key_code;
|
||||
if key_matrix_shift[baseCode].key_code <> 0 then begin
|
||||
info.key_code := key_matrix_shift[baseCode].key_code;
|
||||
keyboard.reportKeyEvent(info);
|
||||
end;
|
||||
end else begin
|
||||
if key_matrix[uint8(scan_code)].key_code <> 0 then begin
|
||||
info.key_code := key_matrix[uint8(scan_code)].key_code;
|
||||
if key_matrix[baseCode].key_code <> 0 then begin
|
||||
info.key_code := key_matrix[baseCode].key_code;
|
||||
keyboard.reportKeyEvent(info);
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Update modifier state }
|
||||
if uint8(scan_code) = 42 then keyboard.is_shift := true;
|
||||
if uint8(scan_code) = 170 then keyboard.is_shift := false;
|
||||
if uint8(scan_code) = 29 then keyboard.is_ctrl := true;
|
||||
if uint8(scan_code) = 157 then keyboard.is_ctrl := false;
|
||||
if uint8(scan_code) = 56 then keyboard.is_alt := true;
|
||||
if uint8(scan_code) = 184 then keyboard.is_alt := false;
|
||||
end;
|
||||
|
||||
function load(ptr : void) : boolean;
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,52 @@
|
||||
{
|
||||
Driver->Timer->GraphicsRefresh - Timer-driven graphics refresh at ~120FPS.
|
||||
|
||||
Hooks into the 1024Hz timer (TMR_0_ISR) and calls the desktop, uidebug,
|
||||
LVGL and video flush routines every ~9 ticks (1024/9 ≈ 113.8 FPS).
|
||||
|
||||
@author(Kieron Morris <[email protected]>)
|
||||
}
|
||||
unit graphicsrefresh;
|
||||
|
||||
interface
|
||||
|
||||
procedure init;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
util,
|
||||
TMR_0_ISR,
|
||||
desktop,
|
||||
uidebug,
|
||||
lvgl,
|
||||
video,
|
||||
syslog;
|
||||
|
||||
const
|
||||
{ 1024 / 4 ≈ 256 FPS }
|
||||
TICKS_PER_FRAME = 4;
|
||||
|
||||
var
|
||||
TickCounter : uint32;
|
||||
|
||||
procedure on_tick(data : void);
|
||||
begin
|
||||
TickCounter := TickCounter + 1;
|
||||
if TickCounter >= TICKS_PER_FRAME then begin
|
||||
TickCounter := 0;
|
||||
desktop.update;
|
||||
uidebug.update;
|
||||
lvgl_handler;
|
||||
video.Flush;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure init;
|
||||
begin
|
||||
TickCounter := 0;
|
||||
TMR_0_ISR.hook(uint32(@on_tick));
|
||||
syslog.logln('GFXREFRESH', 'Hooked into 1024Hz timer (~120 FPS).');
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
Driver->Timer->USBHotplug - Timer-driven USB hotplug polling at ~1Hz.
|
||||
|
||||
Hooks into the 1024Hz timer (TMR_0_ISR) and calls
|
||||
usbcore.usb_check_hotplug every 1024 ticks (approximately once per second).
|
||||
|
||||
@author(Kieron Morris <[email protected]>)
|
||||
}
|
||||
unit usbhotplug;
|
||||
|
||||
interface
|
||||
|
||||
procedure init;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
util,
|
||||
TMR_0_ISR,
|
||||
usbcore,
|
||||
syslog;
|
||||
|
||||
const
|
||||
{ 1024 ticks at 1024Hz ≈ 1 second }
|
||||
TICKS_PER_POLL = 1024;
|
||||
|
||||
var
|
||||
TickCounter : uint32;
|
||||
|
||||
procedure on_tick(data : void);
|
||||
begin
|
||||
TickCounter := TickCounter + 1;
|
||||
if TickCounter >= TICKS_PER_POLL then begin
|
||||
TickCounter := 0;
|
||||
usbcore.usb_check_hotplug;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure init;
|
||||
begin
|
||||
TickCounter := 0;
|
||||
TMR_0_ISR.hook(uint32(@on_tick));
|
||||
syslog.logln('USBHOTPLUG', 'Hooked into 1024Hz timer (~1Hz polling).');
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -581,12 +581,13 @@ begin
|
||||
syslog.writestring(' EIP: '); syslog.writehex(IntSpec^.EIP); syslog.writestring(' CS: '); syslog.writehex(IntSpec^.CS); syslog.writestring(' EFLAGS: '); syslog.writehexln(IntSpec^.EFLAGS);
|
||||
syslog.writestringln(' ');
|
||||
end;
|
||||
tracer.freeze;
|
||||
syslog.writestring('Call Stack: ');
|
||||
trace:= tracer.get_last_trace;
|
||||
if trace <> nil then begin
|
||||
syslog.writestring('[-0] ');
|
||||
syslog.writestringln(trace);
|
||||
for i:=1 to tracer.get_trace_count-7 do begin
|
||||
for i:=1 to tracer.get_trace_count-1 do begin
|
||||
trace:= tracer.get_trace_N(i);
|
||||
if trace <> nil then begin
|
||||
syslog.writestring(' [');
|
||||
@@ -594,6 +595,12 @@ begin
|
||||
syslog.writeint(i);
|
||||
syslog.writestring('] ');
|
||||
syslog.writestringln(trace);
|
||||
end else begin
|
||||
syslog.writestring(' [');
|
||||
syslog.writestring('-');
|
||||
syslog.writeint(i);
|
||||
syslog.writestring('] ');
|
||||
syslog.writestringln('?????????');
|
||||
end;
|
||||
end;
|
||||
end else begin
|
||||
|
||||
+20
-24
@@ -43,8 +43,11 @@ uses
|
||||
usbhub,
|
||||
usb_keyboard,
|
||||
usb_mouse,
|
||||
usb_storage,
|
||||
UHCI,
|
||||
OHCI,
|
||||
EHCI,
|
||||
XHCI,
|
||||
testdriver,
|
||||
E1000,
|
||||
IDE,
|
||||
@@ -63,7 +66,8 @@ uses
|
||||
rand,
|
||||
hashmap, vfs,
|
||||
video, vesa, doublebuffer, color, lvgl, desktop, uidebug,
|
||||
vterminal;
|
||||
vterminal,
|
||||
graphicsrefresh, usbhotplug;
|
||||
|
||||
procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: uint32); stdcall;
|
||||
|
||||
@@ -100,17 +104,13 @@ begin
|
||||
pop_trace;
|
||||
end;
|
||||
|
||||
procedure myUserLandFunction;
|
||||
var
|
||||
i : uint32;
|
||||
|
||||
procedure yield();
|
||||
begin
|
||||
i:=0;
|
||||
while true do begin
|
||||
i:=i+1;
|
||||
asm
|
||||
MOV EAX, i
|
||||
end;
|
||||
sti
|
||||
@idle:
|
||||
hlt
|
||||
jmp @idle
|
||||
end;
|
||||
end;
|
||||
|
||||
@@ -129,6 +129,7 @@ begin
|
||||
|
||||
{ Syslog Init — right after serial so log hooks work }
|
||||
syslog.init();
|
||||
syslog.writestringln('Booting Asuro...');
|
||||
|
||||
{ Store Multiboot info }
|
||||
multibootinfo:= mbinfo;
|
||||
@@ -137,10 +138,8 @@ begin
|
||||
{ Ensure tracer is frozen }
|
||||
tracer.freeze();
|
||||
|
||||
syslog.writestringln('Booting Asuro...');
|
||||
|
||||
syslog.writestringln('Checking for Multiboot Compliance');
|
||||
{ Check for Multiboot }
|
||||
syslog.writestringln('Checking for Multiboot Compliance');
|
||||
if (multibootmagic <> MULTIBOOT_BOOTLOADER_MAGIC) then begin
|
||||
syslog.logln('KERNEL', 'Multiboot Compliant Boot-Loader Needed!');
|
||||
syslog.logln('KERNEL', 'HALTING.');
|
||||
@@ -267,22 +266,19 @@ begin
|
||||
usbcore.UnitTest;
|
||||
UHCI.UnitTest;
|
||||
OHCI.UnitTest;
|
||||
EHCI.UnitTest;
|
||||
XHCI.UnitTest;
|
||||
usbhub.UnitTest;
|
||||
usb_keyboard.UnitTest;
|
||||
usb_mouse.UnitTest;
|
||||
|
||||
{ Main render loop }
|
||||
syslog.logln('KERNEL', 'Entering main render loop.');
|
||||
while true do begin
|
||||
usbcore.poll_all;
|
||||
usb_keyboard.poll_keyboards;
|
||||
usb_mouse.poll_mice;
|
||||
desktop.update;
|
||||
uidebug.update;
|
||||
lvgl_handler;
|
||||
video.Flush();
|
||||
end;
|
||||
{ Register timer-driven tasks }
|
||||
graphicsrefresh.init;
|
||||
usbhotplug.init;
|
||||
|
||||
{ All work is now driven by timer interrupts — idle the CPU }
|
||||
syslog.logln('KERNEL', 'All tasks registered. Halting into idle.');
|
||||
kernel.yield();
|
||||
end;
|
||||
|
||||
end.
|
||||
+40
-29
@@ -13,7 +13,11 @@
|
||||
// limitations under the License.
|
||||
|
||||
{
|
||||
Tracer - Trace stack for debugging method calls.
|
||||
Tracer - Ring buffer trace log for debugging method calls.
|
||||
|
||||
IMPORTANT: push_trace MUST only be called with pointers to
|
||||
static/persistent data (e.g. string literals). The pointer is
|
||||
stored directly - no copy is made.
|
||||
|
||||
@author(Kieron Morris <kjm@kieronmorris.me>)
|
||||
}
|
||||
@@ -28,19 +32,12 @@ function get_last_trace : pchar;
|
||||
procedure freeze;
|
||||
function get_trace_count : uint32;
|
||||
function get_trace_N(idx : uint32) : pchar;
|
||||
procedure print_traces;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
lmemorymanager, util, strings, serial, stdio;
|
||||
|
||||
type
|
||||
PTracerEntry = ^TTracerEntry;
|
||||
TTracerEntry = record
|
||||
Next : PTracerEntry;
|
||||
Data : pchar;
|
||||
Previous : PTracerEntry;
|
||||
end;
|
||||
util, strings, stdio, syslog;
|
||||
|
||||
const
|
||||
MAX_TRACE = 40;
|
||||
@@ -48,16 +45,12 @@ const
|
||||
var
|
||||
t_ready : Boolean;
|
||||
Locked : Boolean;
|
||||
head : uint32;
|
||||
Traces : Array[0..MAX_TRACE-1] of PChar;
|
||||
c_lock : Boolean = false;
|
||||
|
||||
var
|
||||
head : PTracerEntry;
|
||||
tail : PTracerEntry;
|
||||
|
||||
procedure terminal_command_tracer(Params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||
var
|
||||
p1, p2 : PChar;
|
||||
p1 : PChar;
|
||||
count : uint32;
|
||||
i : uint32;
|
||||
t : PChar;
|
||||
@@ -113,26 +106,19 @@ begin
|
||||
end;
|
||||
|
||||
procedure push_trace(t_name : pchar);
|
||||
var
|
||||
i : uint32;
|
||||
|
||||
begin
|
||||
if TRACER_ENABLE then begin
|
||||
if t_ready then begin
|
||||
if not Locked then begin
|
||||
if not c_lock then begin
|
||||
Locked:= true;
|
||||
if Traces[MAX_TRACE-1] <> nil then kfree(void(Traces[MAX_TRACE-1]));
|
||||
for i:=MAX_TRACE-1 downto 1 do begin
|
||||
Traces[i]:= Traces[i-1];
|
||||
end;
|
||||
Traces[0]:= StringCopy(t_name);
|
||||
head:= head + 1;
|
||||
if head >= MAX_TRACE then head:= 0;
|
||||
Traces[head]:= t_name;
|
||||
Locked:= false;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure pop_trace;
|
||||
begin
|
||||
@@ -141,7 +127,7 @@ end;
|
||||
|
||||
function get_last_trace : pchar;
|
||||
begin
|
||||
get_last_trace:= Traces[0];
|
||||
get_last_trace:= Traces[head];
|
||||
end;
|
||||
|
||||
procedure init;
|
||||
@@ -151,8 +137,10 @@ var
|
||||
begin
|
||||
if TRACER_ENABLE then begin
|
||||
for i:=0 to MAX_TRACE-1 do begin
|
||||
traces[i]:= nil;
|
||||
Traces[i]:= nil;
|
||||
end;
|
||||
Locked:= false;
|
||||
head:= MAX_TRACE - 1;
|
||||
t_ready:= true;
|
||||
push_trace('kmain');
|
||||
end;
|
||||
@@ -166,11 +154,34 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure print_traces;
|
||||
var
|
||||
i : uint32;
|
||||
|
||||
begin
|
||||
for i:=0 to MAX_TRACE-1 do begin
|
||||
syslog.log('TRACER', '[');
|
||||
syslog.writeint(i);
|
||||
syslog.writestring('] ');
|
||||
if Traces[i] <> nil then begin
|
||||
syslog.writestringln(Traces[i]);
|
||||
end else begin
|
||||
syslog.writestringln('?????????');
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function get_trace_N(idx : uint32) : pchar;
|
||||
var
|
||||
slot : uint32;
|
||||
begin
|
||||
if idx > MAX_TRACE-1 then exit;
|
||||
if TRACER_ENABLE then begin
|
||||
get_trace_N:= traces[idx];
|
||||
if head >= idx then
|
||||
slot:= head - idx
|
||||
else
|
||||
slot:= MAX_TRACE - (idx - head);
|
||||
get_trace_N:= Traces[slot];
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
Loaded 20 of 21 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user