Compare commits

...
20 Commits
Author SHA1 Message Date
t3hn3rd d3c164e8af Merge branch 'feature/vtop-fix' into feature/tcp
continuous-integration/drone/push Build is passing
2026-03-03 19:10:38 +00:00
t3hn3rd 76c419336e bug: vtop incorrect bitmask
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
- Fix for issue #32 in which the incorrect bitmask ($FFFFFF) is used where
  $3FFFFF should be used instead. (24 vs 22 bits).
2026-03-03 19:10:08 +00:00
t3hn3rd 5e9d0004d7 feature: implement TCP (RFC 793) protocol driver
continuous-integration/drone/push Build is passing
Add full TCP/IP stack implementation at L4 alongside UDP and ICMP.

Core Protocol Engine:
- TCP types in nettypes.pas (header, TCB, state enum, error codes,
  callbacks, OOO entry, socket structures)
- 3-way handshake (active & passive OPEN)
- Reliable data transfer with ACK and sequence number tracking
- Graceful close (FIN_WAIT, CLOSE_WAIT, LAST_ACK, TIME_WAIT)
- RST send/receive handling
- Retransmission with exponential backoff (max 5 attempts)
- Pseudo-header based checksum (RFC 793)

Server Support:
- LISTEN → SYN_RECEIVED → ESTABLISHED passive open path
- Listen backlog enforcement (configurable per-socket)
- accept() to retrieve established child connections

Robustness & Hardening:
- Delayed ACK timer (~200ms)
- Nagle's algorithm (buffer small sends while unACKed data pending)
- Jacobson/Karels RTT estimation with adaptive RTO
- Congestion control (slow start / congestion avoidance)
- Zero-window probing with exponential backoff
- MSS option negotiation in SYN/SYN-ACK (Kind=2, Len=4)
- Keep-alive (30s idle, 10s interval, 5 probes)
- Out-of-order segment reassembly (4-slot buffer)

Terminal & Testing:
- tcpconnect: active open + send "Hello, World!"
- tcplisten: passive open with syslog output
- tcphttp: HTTP/1.0 GET client

Also add push_trace() instrumentation to net, eth2, arp, ipv4,
icmp, udp, and dhcp entry points for call tracing, and register
tcp in net.init.
2026-03-03 10:55:50 +00:00
admin 2ad0ae8420 Merge pull request 'feature/gitattributes' (#30) from feature/gitattributes into develop
continuous-integration/drone/push Build is passing
Reviewed-on: #30
2026-03-02 21:56:56 +00:00
t3hn3rd c0c199bfe6 .gitattributes update
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
- Updated .gitattributes linguist excludes for compile-time directories.
2026-03-02 21:48:10 +00:00
t3hn3rd 7ec3bcb9b9 .gitattributes & doc directory
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
- Added gitattributes for linguist exclusions
- Created empty doc folder for local working docs
2026-03-02 21:41:14 +00:00
admin 4bd0a2dfbf Merge pull request 'Merge feature/graphics-interrupts into develop' (#14) from feature/graphics-interrupts into develop
continuous-integration/drone/push Build is passing
Reviewed-on: #14
2026-03-02 19:19:46 +00:00
admin 431e5bc8f4 Merge pull request 'Merge feature/USB into develop' (#13) from feature/USB into develop
continuous-integration/drone/push Build is passing
Reviewed-on: #13
2026-03-02 19:14:05 +00:00
t3hn3rd 8169d93a9c refactor: move render loop & USB hotplug to timer-driven units
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Replace the blocking main render loop in kernel.pas with two new
timer-hooked units that are driven by the 1024Hz PIT interrupt:

- graphicsrefresh: calls desktop.update, uidebug.update, lvgl_handler
  and video.Flush every 4 ticks (~256 FPS target).
- usbhotplug: calls usbcore.usb_check_hotplug every 1024 ticks (~1Hz).

The kernel main procedure now registers both timer hooks and enters an
idle STI/HLT loop (kernel.yield), allowing the CPU to sleep between
interrupts instead of busy-spinning.

Also removes the unused myUserLandFunction and reorders early syslog
init calls for clarity.
2026-03-02 19:04:42 +00:00
t3hn3rd 547251dbd0 update: Kernel.pas changes to align with USB implementation
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
- Kernel.pas updated to init USB devices & check for hotplug.
- USB Poll removed given USB stack is now interrupt driven.
2026-03-02 15:53:40 +00:00
t3hn3rd 7bbcc44c5e Feature: USB - Hotplug, mass storage, disconnect callbacks, dynamic device lists
- Add disconnect callback (fnDisconnect) to TUSBDevice for safe unplug handling
- Add HotplugArmed/PortChangePending flags to TUSBHCDriver for deferred
  hotplug processing from ISR context (OHCI RHSC, EHCI PCD, xHCI PSC)
- Implement usb_rescan_port() and usb_check_hotplug() in usbcore
- Add usb_bulk_transfer_wait() with timer-based timeout (bios_data_area)
- Add timer-based timeout to usb_control_msg polling loop
- Replace static device arrays with dynamic linked lists in class drivers:
  usb_keyboard (KeyboardList), usb_mouse (MouseList), usb_storage (StorageList)
- Add 3-strike fail-count self-deactivation in keyboard/mouse poll loops
- Add unload() disconnect handlers for keyboard, mouse, and storage drivers
- Implement USB Mass Storage BOT driver (usb_storage.pas):
  CBW/CSW transport, SCSI INQUIRY/READ_CAPACITY/READ10/WRITE10,
  storagemanagement integration with read/write callbacks
- xHCI: acknowledge port status change W1C bits in event handler
- Integrate usb_check_hotplug + poll_keyboards/poll_mice into kernel main loop
2026-03-02 15:52:49 +00:00
t3hn3rd 25475a88a7 featur: USB - Add device tracking, stall recovery, removal, and terminal command
- Track enumerated devices per-HC via linked list (hc^.Devices)
- Add usb_clear_halt() for endpoint stall recovery (CLEAR_FEATURE)
- Add usb_remove_device() to clean up and free device records
- Add get_hc() for indexed host controller access
- Implement 'USB' terminal command showing HC info, connected devices,
  speeds, class descriptors, and endpoint details
2026-03-02 15:50:55 +00:00
t3hn3rd db49c29627 fix: lowercase names for units
- PCI.pas -> pci.pas
2026-03-02 13:38:10 +00:00
t3hn3rd c237553508 fix: ps2_keyboard report key-up events for break codes
The PS/2 keyboard callback hardcoded is_down_code := true for every
scancode, so key releases were never reported. This caused keys to
repeat endlessly until the next key was pressed.

In PS/2 scancode set 1, bit 7 indicates a break (release) code.
The callback now:
- Detects break codes via (scancode AND $80)
- Masks to base code (scancode AND $7F) for key matrix lookup
- Sets is_down_code := false for break codes
- Updates modifier state (shift/ctrl/alt) before building the
  key event, so modifier releases take effect immediately

Files changed:
- ps2_keyboard.pas: rewrite callback to handle make/break codes
2026-03-02 13:37:29 +00:00
t3hn3rd 0c96d32754 feature: move all USB HC drivers from polling to interrupt-driven completion
Replace main-loop polling (poll_all, poll_keyboards, poll_mice) with
hardware interrupt handlers for all four USB host controller drivers.

Each HC driver (XHCI, EHCI, OHCI, UHCI) now:
- Registers an ISR on its PCI interrupt line via isrmanager
- Enables hardware interrupts after HC initialization
- Acknowledges interrupt status in the ISR before calling poll,
  preventing interrupt storms on level-triggered PCI lines
- Uses a PollBusy re-entrancy guard to prevent ISR/inline poll races

usbcore gains a completion hook system (register_completion_hook /
fire_completion_hooks) so HID drivers (keyboard, mouse) are notified
directly from the ISR after transfer completion.

Files changed:
- usbcore.pas: completion hook infrastructure
- XHCI.pas: ISR, enable_interrupts, submit ordering fix
- EHCI.pas: ISR, enable_interrupts, status ack in ISR
- OHCI.pas: ISR, enable_interrupts, status ack in ISR
- UHCI.pas: ISR, enable_interrupts, status ack in ISR
- usb_keyboard.pas: register completion hook
- usb_mouse.pas: register completion hook
2026-03-02 13:36:40 +00:00
t3hn3rd 3f83f279d7 XHCI driver implementation
- Beginnings of a functional XHCI driver implemented.
2026-03-02 12:24:02 +00:00
t3hn3rd 82fe9fa6df EHCI Implementation
- Beginnings of a functional EHCI driver implemented.
2026-03-02 12:23:35 +00:00
admin 983d9a428d Merge pull request 'feature: Tracer O(1) ring buffer refactor' (#12) from feature/tracer-optimizations into develop
continuous-integration/drone/push Build is passing
Reviewed-on: #12
2026-03-01 22:29:53 +00:00
t3hn3rd 2fa77d8295 Merge branch 'feature/tracer-optimizations' into feature/USB 2026-03-01 21:26:56 +00:00
t3hn3rd f53afc1d2d feature: Tracer O(1) ring buffer refactor
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
- Replaced O(n) shift loop + StringCopy/kalloc/kfree with O(1) ring
  buffer storing PChar pointers directly (zero allocation).
- Eliminated mod operator (causes int64 promotion + broken RTL helpers
  on i386 bare-metal); uses pure uint32 branch arithmetic.
- Removed dead code: PTracerEntry/TTracerEntry linked list types,
  head/tail PTracerEntry vars, c_lock boolean
- Dropped lmemorymanager and serial from uses clause
- pop_trace remains as no-op stub for ABI compat
- get_trace_N uses underflow-safe index: if head >= idx then
  head - idx else MAX_TRACE - (idx - head)
- Added print_traces debug helper
2026-03-01 21:26:35 +00:00
30 changed files with 7772 additions and 226 deletions

No files matched your search

+7
View File
@@ -1 +1,8 @@
* text=auto eol=lf * 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
+1
View File
@@ -15,3 +15,4 @@ localenv.json
dockerout.txt dockerout.txt
AGENTS.md AGENTS.md
*.log *.log
/doc/*.md
View File
Whitespace-only changes.
+1 -1
View File
@@ -18,7 +18,7 @@
@author(Aaron Hance <[email protected]>) @author(Aaron Hance <[email protected]>)
@author(Kieron Morris <[email protected]>) @author(Kieron Morris <[email protected]>)
} }
unit PCI; unit pci;
interface interface
File diff suppressed because it is too large. Load diff
+82 -4
View File
@@ -7,7 +7,7 @@
@author(Kieron Morris <[email protected]>) @author(Kieron Morris <[email protected]>)
} }
unit OHCI; unit ohci;
interface interface
@@ -23,6 +23,7 @@ uses
drivermanagement, drivermanagement,
usbtypes, usbtypes,
usbcore, usbcore,
isrmanager,
lists, lists,
strings; strings;
@@ -234,6 +235,7 @@ type
EDBulk : POHCI_ED; { Head of bulk ED list } EDBulk : POHCI_ED; { Head of bulk ED list }
EDInterrupt : POHCI_ED; { Dummy head for interrupt ED list } EDInterrupt : POHCI_ED; { Dummy head for interrupt ED list }
NumPorts : uint8; { Number of downstream ports } NumPorts : uint8; { Number of downstream ports }
PollBusy : boolean; { Re-entrancy guard for poll }
PCIBus : uint8; { PCI address } PCIBus : uint8; { PCI address }
PCISlot : uint8; PCISlot : uint8;
PCIFunc : uint8; PCIFunc : uint8;
@@ -1022,6 +1024,60 @@ begin
end; end;
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); procedure ohci_poll(hc : PUSBHCDriver);
var var
priv : POHCI_PrivData; priv : POHCI_PrivData;
@@ -1038,6 +1094,11 @@ var
begin begin
if (hc = nil) or (hc^.PrivData = nil) then exit; if (hc = nil) or (hc^.PrivData = nil) then exit;
priv := POHCI_PrivData(hc^.PrivData); priv := POHCI_PrivData(hc^.PrivData);
{ Re-entrancy guard }
if priv^.PollBusy then exit;
priv^.PollBusy := true;
base := priv^.MMIOBase; base := priv^.MMIOBase;
{ Read and acknowledge interrupt status } { Read and acknowledge interrupt status }
@@ -1107,6 +1168,7 @@ begin
ed := nextED; ed := nextED;
end; end;
end; end;
priv^.PollBusy := false;
end; end;
{ ========================= Load / Init ========================= } { ========================= Load / Init ========================= }
@@ -1124,6 +1186,7 @@ var
begin begin
push_trace('OHCI.load'); push_trace('OHCI.load');
load := false; load := false;
OHCIInstanceCount := 0;
devices := PCI.getDeviceInfo($0C, $03, $10, count); devices := PCI.getDeviceInfo($0C, $03, $10, count);
syslog.log('OHCI', 'Found '); syslog.log('OHCI', 'Found ');
@@ -1220,9 +1283,24 @@ begin
hcEntry := usbcore.register_hc(@hc); hcEntry := usbcore.register_hc(@hc);
{ Scan ports for connected devices (use the stable pointer, not stack-local @hc) } { Scan ports for connected devices (use the stable pointer, not stack-local @hc) }
if hcEntry <> nil then if hcEntry <> nil then begin
usbcore.scan_ports(hcEntry) { Track instance for ISR dispatch }
else 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', 'Failed to register HC with USB core.');
syslog.logln('OHCI', 'Controller initialized and registered.'); syslog.logln('OHCI', 'Controller initialized and registered.');
+77 -4
View File
@@ -6,7 +6,7 @@
@author(Kieron Morris <[email protected]>) @author(Kieron Morris <[email protected]>)
} }
unit UHCI; unit uhci;
interface interface
@@ -22,6 +22,7 @@ uses
drivermanagement, drivermanagement,
usbtypes, usbtypes,
usbcore, usbcore,
isrmanager,
lists, lists,
strings; strings;
@@ -154,6 +155,7 @@ type
QHControl : PUHCI_QH; { Queue Head for control transfers } QHControl : PUHCI_QH; { Queue Head for control transfers }
QHBulk : PUHCI_QH; { Queue Head for bulk transfers } QHBulk : PUHCI_QH; { Queue Head for bulk transfers }
QHInterrupt : PUHCI_QH; { Queue Head for interrupt 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 } PCIBus : uint8; { PCI bus/slot/func for bus mastering }
PCISlot : uint8; PCISlot : uint8;
PCIFunc : uint8; PCIFunc : uint8;
@@ -750,6 +752,56 @@ begin
pop_trace; pop_trace;
end; 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 ========================= } { ========================= Poll / Completion ========================= }
procedure uhci_poll(hc : PUSBHCDriver); procedure uhci_poll(hc : PUSBHCDriver);
@@ -768,6 +820,10 @@ begin
if (hc = nil) or (hc^.PrivData = nil) then exit; if (hc = nil) or (hc^.PrivData = nil) then exit;
priv := PUHCI_PrivData(hc^.PrivData); priv := PUHCI_PrivData(hc^.PrivData);
{ Re-entrancy guard }
if priv^.PollBusy then exit;
priv^.PollBusy := true;
{ Read and clear status register } { Read and clear status register }
status := uhci_read16(priv^.IOBase, UHCI_REG_USBSTS); status := uhci_read16(priv^.IOBase, UHCI_REG_USBSTS);
if (status AND (UHCI_STS_USBINT OR UHCI_STS_ERROR)) <> 0 then if (status AND (UHCI_STS_USBINT OR UHCI_STS_ERROR)) <> 0 then
@@ -841,6 +897,7 @@ begin
end; end;
qh := qh^.SWNext; qh := qh^.SWNext;
end; end;
priv^.PollBusy := false;
end; end;
{ ========================= Load / Init ========================= } { ========================= Load / Init ========================= }
@@ -857,6 +914,7 @@ var
begin begin
push_trace('UHCI.load'); push_trace('UHCI.load');
load := false; load := false;
UHCIInstanceCount := 0;
devices := PCI.getDeviceInfo($0C, $03, $00, count); devices := PCI.getDeviceInfo($0C, $03, $00, count);
syslog.log('UHCI', 'Found '); syslog.log('UHCI', 'Found ');
@@ -945,9 +1003,24 @@ begin
hcEntry := usbcore.register_hc(@hc); hcEntry := usbcore.register_hc(@hc);
{ Scan ports for connected devices (use the stable pointer, not stack-local @hc) } { Scan ports for connected devices (use the stable pointer, not stack-local @hc) }
if hcEntry <> nil then if hcEntry <> nil then begin
usbcore.scan_ports(hcEntry) { Track instance for ISR dispatch }
else 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', 'Failed to register HC with USB core.');
syslog.logln('UHCI', 'Controller initialized and registered.'); syslog.logln('UHCI', 'Controller initialized and registered.');
+5 -1
View File
@@ -17,7 +17,7 @@
@author(Kieron Morris <[email protected]>) @author(Kieron Morris <[email protected]>)
} }
unit USB; unit usb;
interface interface
@@ -35,6 +35,7 @@ uses
usbhub, usbhub,
usb_keyboard, usb_keyboard,
usb_mouse, usb_mouse,
usb_storage,
OHCI, UHCI, EHCI, XHCI; OHCI, UHCI, EHCI, XHCI;
procedure init; procedure init;
@@ -90,6 +91,9 @@ begin
usb_keyboard.init; usb_keyboard.init;
usb_mouse.init; usb_mouse.init;
{ Initialize storage class driver }
usb_storage.init;
UHCI_ID.Bus:= biPCI; UHCI_ID.Bus:= biPCI;
UHCI_ID.id0:= idANY; UHCI_ID.id0:= idANY;
UHCI_ID.id1:= $0000000C; UHCI_ID.id1:= $0000000C;
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+6
View File
@@ -217,6 +217,9 @@ type
PUSBHCDriver = ^TUSBHCDriver; PUSBHCDriver = ^TUSBHCDriver;
PUSBTransfer = ^TUSBTransfer; PUSBTransfer = ^TUSBTransfer;
{ ---- Disconnect Callback ---- }
TUSBDisconnectCallback = procedure(dev : PUSBDevice);
{ ---- Transfer Request ---- } { ---- Transfer Request ---- }
TUSBTransfer = record TUSBTransfer = record
@@ -246,6 +249,7 @@ type
Endpoints : array[0..USB_MAX_ENDPOINTS-1] of TUSBEndpoint; Endpoints : array[0..USB_MAX_ENDPOINTS-1] of TUSBEndpoint;
NumEndpoints : uint8; NumEndpoints : uint8;
Configured : boolean; Configured : boolean;
fnDisconnect : TUSBDisconnectCallback; { Called before device is freed on unplug }
end; end;
{ ---- HC Driver Abstraction (Function Pointer Types) ---- } { ---- HC Driver Abstraction (Function Pointer Types) ---- }
@@ -269,6 +273,8 @@ type
PrivData : Pointer; { HC-specific state } PrivData : Pointer; { HC-specific state }
Devices : PLinkedListBase; { List of PUSBDevice attached } Devices : PLinkedListBase; { List of PUSBDevice attached }
NextAddress : uint8; { Next available USB address (1-127) } 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 } { Operations }
fnReset : TUSBHCReset; fnReset : TUSBHCReset;
fnStart : TUSBHCStart; fnStart : TUSBHCStart;
+26 -17
View File
@@ -32,32 +32,41 @@ uses
procedure callback(scan_code : void); procedure callback(scan_code : void);
var var
info : TKeyInfo; info : TKeyInfo;
raw : uint8;
baseCode : uint8;
isBreak : boolean;
begin begin
info.SHIFT_DOWN := keyboard.is_shift; raw := uint8(scan_code);
info.CTRL_DOWN := keyboard.is_ctrl;
info.ALT_DOWN := keyboard.is_alt; { In PS/2 scancode set 1, bit 7 set = key release (break code) }
info.is_down_code := true; 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 := not isBreak;
if keyboard.is_shift then begin if keyboard.is_shift then begin
if key_matrix_shift[uint8(scan_code)].key_code <> 0 then begin if key_matrix_shift[baseCode].key_code <> 0 then begin
info.key_code := key_matrix_shift[uint8(scan_code)].key_code; info.key_code := key_matrix_shift[baseCode].key_code;
keyboard.reportKeyEvent(info); keyboard.reportKeyEvent(info);
end; end;
end else begin end else begin
if key_matrix[uint8(scan_code)].key_code <> 0 then begin if key_matrix[baseCode].key_code <> 0 then begin
info.key_code := key_matrix[uint8(scan_code)].key_code; info.key_code := key_matrix[baseCode].key_code;
keyboard.reportKeyEvent(info); keyboard.reportKeyEvent(info);
end; end;
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; end;
function load(ptr : void) : boolean; 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
+5 -4
View File
@@ -100,8 +100,8 @@ end;
procedure send(p_data : void; p_len : uint16); procedure send(p_data : void; p_len : uint16);
begin begin
//push_trace('net.send'); push_trace('net.send');
//writeToLogLn('L1: net.send'); writeToLogLn('L1/NET: send');
if CBSend <> nil then CBSend(p_data, p_len); if CBSend <> nil then CBSend(p_data, p_len);
pop_trace; pop_trace;
end; end;
@@ -111,8 +111,7 @@ var
context : PPacketContext; context : PPacketContext;
begin begin
//push_trace('net.recv'); push_trace('net.recv');
//writeToLogLn('L1: net.recv');
context:= newPacketContext; context:= newPacketContext;
if CBNext <> nil then CBNext(p_data, p_len, context); if CBNext <> nil then CBNext(p_data, p_len, context);
freePacketContext(context); freePacketContext(context);
@@ -129,6 +128,7 @@ end;
procedure init; procedure init;
begin begin
push_trace('net.init'); push_trace('net.init');
writeToLogLn('L1/NET: init');
//l2 //l2
eth2.register; eth2.register;
//l3 //l3
@@ -136,6 +136,7 @@ begin
ipv4.register; ipv4.register;
//l4 //l4
icmp.register; icmp.register;
tcp.register;
udp.register; udp.register;
//l5 //l5
dhcp.register; dhcp.register;
+4 -1
View File
@@ -46,6 +46,7 @@ var
procedure registerTypePromisc(eType : uint16; RecvCB : TRecvCallback); procedure registerTypePromisc(eType : uint16; RecvCB : TRecvCallback);
begin begin
push_trace('eth2.registerTypePromisc');
register; register;
if EthTypes[eType] = nil then EthTypes[eType]:= RecvCB; if EthTypes[eType] = nil then EthTypes[eType]:= RecvCB;
Promisc[eType]:= true; Promisc[eType]:= true;
@@ -53,6 +54,7 @@ end;
procedure registerType(eType : uint16; RecvCB : TRecvCallback); procedure registerType(eType : uint16; RecvCB : TRecvCallback);
begin begin
push_trace('eth2.registerType');
register; register;
if EthTypes[eType] = nil then EthTypes[eType]:= RecvCB; if EthTypes[eType] = nil then EthTypes[eType]:= RecvCB;
end; end;
@@ -93,7 +95,7 @@ var
buf : puint8; buf : puint8;
begin begin
//writeToLogLn(' L2: eth2.recv'); push_trace('eth2.recv');
buf:= puint8(p_data); buf:= puint8(p_data);
Header:= PEthernetHeader(buf); Header:= PEthernetHeader(buf);
@@ -120,6 +122,7 @@ var
begin begin
push_trace('eth2.register'); push_trace('eth2.register');
if not Registered then begin if not Registered then begin
writeToLogLn(' L2/ETH: register');
for i:=0 to 65535 do begin for i:=0 to 65535 do begin
EthTypes[i]:= nil; EthTypes[i]:= nil;
Promisc[i]:= false; Promisc[i]:= false;
+9
View File
@@ -96,6 +96,7 @@ var
hSize, pSize : uint8; hSize, pSize : uint8;
begin begin
push_trace('arp.send');
if p_context <> nil then begin if p_context <> nil then begin
buf:= kalloc(sizeof(TARPHeader)); buf:= kalloc(sizeof(TARPHeader));
hdr:= PARPHeader(buf); hdr:= PARPHeader(buf);
@@ -135,6 +136,8 @@ var
context : PPacketContext; context : PPacketContext;
begin begin
push_trace('arp.sendGratuitous');
writeToLogLn(' L3/ARP: sendGratuitous');
context:= newPacketContext; context:= newPacketContext;
CopyIPv4(@getIPv4Config^.Address[0], @context^.IP.Destination[0]); CopyIPv4(@getIPv4Config^.Address[0], @context^.IP.Destination[0]);
CopyIPv4(@getIPv4Config^.Address[0], @context^.IP.Source[0]); CopyIPv4(@getIPv4Config^.Address[0], @context^.IP.Source[0]);
@@ -150,6 +153,7 @@ var
CacheRecord : PARPCacheRecord; CacheRecord : PARPCacheRecord;
begin begin
push_trace('arp.sendRequestGateway');
context:= newPacketContext; context:= newPacketContext;
CacheRecord:= findCacheRecordByIP(@getIPv4Config^.Gateway[0]); CacheRecord:= findCacheRecordByIP(@getIPv4Config^.Gateway[0]);
if CacheRecord <> nil then begin if CacheRecord <> nil then begin
@@ -168,6 +172,8 @@ var
CacheRecord : PARPCacheRecord; CacheRecord : PARPCacheRecord;
begin begin
push_trace('arp.sendRequest');
writeToLogLn(' L3/ARP: sendRequest');
context:= newPacketContext; context:= newPacketContext;
CopyIPv4(ip, @context^.IP.Destination[0]); CopyIPv4(ip, @context^.IP.Destination[0]);
CopyIPv4(@getIPv4Config^.Address[0], @context^.IP.Source[0]); CopyIPv4(@getIPv4Config^.Address[0], @context^.IP.Source[0]);
@@ -184,6 +190,7 @@ var
CacheRecord : PARPCacheRecord; CacheRecord : PARPCacheRecord;
begin begin
push_trace('arp.resolveIP');
CacheRecord:= findCacheRecordByIP(ip); CacheRecord:= findCacheRecordByIP(ip);
resolveIP:= nil; resolveIP:= nil;
if CacheRecord = nil then begin if CacheRecord = nil then begin
@@ -203,6 +210,7 @@ var
context : PPacketContext; context : PPacketContext;
begin begin
push_trace('arp.recv');
{ Get our converted Header } { Get our converted Header }
Header:= PARPHeader(p_data); Header:= PARPHeader(p_data);
AHeader.Hardware_Type:= (Header^.Hardware_Type_Hi SHL 8) + Header^.Hardware_Type_Lo; AHeader.Hardware_Type:= (Header^.Hardware_Type_Hi SHL 8) + Header^.Hardware_Type_Lo;
@@ -298,6 +306,7 @@ procedure register;
begin begin
push_trace('arp.register'); push_trace('arp.register');
if not Registered then begin if not Registered then begin
writeToLogLn(' L3/ARP: register');
Cache:= LL_New(sizeof(TARPCacheRecord)); Cache:= LL_New(sizeof(TARPCacheRecord));
eth2.registerTypePromisc($0806, @recv); eth2.registerTypePromisc($0806, @recv);
stdio.registerCommand('ARP', @terminal_command_arp, 'Get ARP Table.'); stdio.registerCommand('ARP', @terminal_command_arp, 'Get ARP Table.');
+7
View File
@@ -46,7 +46,9 @@ var
function getIPv4Config : PIPv4Configuration; function getIPv4Config : PIPv4Configuration;
begin begin
push_trace('ipv4.getIPv4Config');
getIPv4Config:= @Config; getIPv4Config:= @Config;
pop_trace;
end; end;
procedure send(p_data : void; p_len : uint16; p_context : PPacketContext); procedure send(p_data : void; p_len : uint16; p_context : PPacketContext);
@@ -57,6 +59,7 @@ var
buffer : void; buffer : void;
begin begin
push_trace('ipv4.send');
inc(CurrentID); inc(CurrentID);
Header.version:= 4; Header.version:= 4;
Header.header_len:= 5; Header.header_len:= 5;
@@ -84,6 +87,7 @@ begin
memcpy(uint32(p_data), uint32(Buffer) + (Header.header_len * 4), p_len); memcpy(uint32(p_data), uint32(Buffer) + (Header.header_len * 4), p_len);
eth2.send(Buffer, (Header.header_len * 4) + p_len, $0800, p_context); eth2.send(Buffer, (Header.header_len * 4) + p_len, $0800, p_context);
kfree(Buffer); kfree(Buffer);
pop_trace;
end; end;
procedure recv(p_data : void; p_len : uint16; p_context : PPacketContext); procedure recv(p_data : void; p_len : uint16; p_context : PPacketContext);
@@ -95,6 +99,7 @@ var
len : uint16; len : uint16;
begin begin
push_trace('ipv4.recv');
Header:= PIPV4Header(p_data); Header:= PIPV4Header(p_data);
AHeader.version:= Header^.version; AHeader.version:= Header^.version;
AHeader.header_len:= Header^.header_len; AHeader.header_len:= Header^.header_len;
@@ -195,6 +200,7 @@ var
begin begin
push_trace('ipv4.register'); push_trace('ipv4.register');
if not Registered then begin if not Registered then begin
writeToLogLn(' L3/IPv4: register');
for i:=0 to 255 do begin for i:=0 to 255 do begin
Protocols[i]:= nil; Protocols[i]:= nil;
end; end;
@@ -213,6 +219,7 @@ end;
procedure registerProtocol(Protocol_ID : uint8; recv_callback : TRecvCallback); procedure registerProtocol(Protocol_ID : uint8; recv_callback : TRecvCallback);
begin begin
push_trace('ipv4.registerProtocol');
register; register;
if Protocols[Protocol_ID] = nil then Protocols[Protocol_ID]:= recv_callback; if Protocols[Protocol_ID] = nil then Protocols[Protocol_ID]:= recv_callback;
pop_trace; pop_trace;
+8 -1
View File
@@ -23,7 +23,7 @@ interface
uses uses
bios_data_area, bios_data_area,
lmemorymanager, lmemorymanager, tracer,
net, nettypes, netutils, ipv4, arp, util; net, nettypes, netutils, ipv4, arp, util;
type type
@@ -55,6 +55,7 @@ var
i : uint8; i : uint8;
begin begin
push_trace('icmp.nextInactiveHandler');
nextInactiveHandler:= 0; nextInactiveHandler:= 0;
for i:=1 to 255 do begin for i:=1 to 255 do begin
if not Handlers[i].Active then begin if not Handlers[i].Active then begin
@@ -80,6 +81,8 @@ var
Size : uint32; Size : uint32;
begin begin
push_trace('icmp.sendICMPRequest');
writeToLogLn(' L4/ICMP: sendICMPRequest');
handle:= nextInactiveHandler; handle:= nextInactiveHandler;
Handlers[handle].Active:= true; Handlers[handle].Active:= true;
Handlers[handle].OnReply:= OnRep; Handlers[handle].OnReply:= OnRep;
@@ -135,6 +138,8 @@ var
Handle : uint8; Handle : uint8;
begin begin
push_trace('icmp.recv');
writeToLogLn(' L4/ICMP: recv');
Header:= PICMPHeader(p_data); Header:= PICMPHeader(p_data);
//writehexlnWND(Header^.ICMP_Type, getTerminalHWND); //writehexlnWND(Header^.ICMP_Type, getTerminalHWND);
case Header^.ICMP_Type of case Header^.ICMP_Type of
@@ -243,6 +248,8 @@ var
i : uint32; i : uint32;
begin begin
push_trace('icmp.register');
writeToLogLn(' L4/ICMP: register');
for i:=0 to 255 do begin for i:=0 to 255 do begin
Handlers[i].Active:= false; Handlers[i].Active:= false;
Handlers[i].OnError:= nil; Handlers[i].OnError:= nil;
Loaded 20 of 30 files, more files were not shown because too many files have changed in this diff. Show more