@aptre/v86 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/LICENSE +22 -0
  2. package/LICENSE.MIT +22 -0
  3. package/Readme.md +237 -0
  4. package/dist/v86.browser.js +26666 -0
  5. package/dist/v86.browser.js.map +7 -0
  6. package/dist/v86.js +26632 -0
  7. package/dist/v86.js.map +7 -0
  8. package/gen/generate_analyzer.ts +512 -0
  9. package/gen/generate_interpreter.ts +522 -0
  10. package/gen/generate_jit.ts +624 -0
  11. package/gen/rust_ast.ts +107 -0
  12. package/gen/util.ts +35 -0
  13. package/gen/x86_table.ts +1836 -0
  14. package/lib/9p.ts +1547 -0
  15. package/lib/filesystem.ts +1879 -0
  16. package/lib/marshall.ts +168 -0
  17. package/lib/softfloat/softfloat.c +32501 -0
  18. package/lib/zstd/zstddeclib.c +13520 -0
  19. package/package.json +75 -0
  20. package/src/acpi.ts +267 -0
  21. package/src/browser/dummy_screen.ts +106 -0
  22. package/src/browser/fake_network.ts +1771 -0
  23. package/src/browser/fetch_network.ts +361 -0
  24. package/src/browser/filestorage.ts +124 -0
  25. package/src/browser/inbrowser_network.ts +57 -0
  26. package/src/browser/keyboard.ts +564 -0
  27. package/src/browser/main.ts +3415 -0
  28. package/src/browser/mouse.ts +255 -0
  29. package/src/browser/network.ts +142 -0
  30. package/src/browser/print_stats.ts +336 -0
  31. package/src/browser/screen.ts +978 -0
  32. package/src/browser/serial.ts +316 -0
  33. package/src/browser/speaker.ts +1223 -0
  34. package/src/browser/starter.ts +1688 -0
  35. package/src/browser/wisp_network.ts +332 -0
  36. package/src/browser/worker_bus.ts +64 -0
  37. package/src/buffer.ts +652 -0
  38. package/src/bus.ts +78 -0
  39. package/src/const.ts +128 -0
  40. package/src/cpu.ts +2891 -0
  41. package/src/dma.ts +474 -0
  42. package/src/elf.ts +251 -0
  43. package/src/floppy.ts +1778 -0
  44. package/src/ide.ts +3455 -0
  45. package/src/io.ts +504 -0
  46. package/src/iso9660.ts +317 -0
  47. package/src/kernel.ts +250 -0
  48. package/src/lib.ts +645 -0
  49. package/src/log.ts +149 -0
  50. package/src/main.ts +199 -0
  51. package/src/ne2k.ts +1589 -0
  52. package/src/pci.ts +815 -0
  53. package/src/pit.ts +406 -0
  54. package/src/ps2.ts +820 -0
  55. package/src/rtc.ts +537 -0
  56. package/src/rust/analysis.rs +101 -0
  57. package/src/rust/codegen.rs +2660 -0
  58. package/src/rust/config.rs +3 -0
  59. package/src/rust/control_flow.rs +425 -0
  60. package/src/rust/cpu/apic.rs +658 -0
  61. package/src/rust/cpu/arith.rs +1207 -0
  62. package/src/rust/cpu/call_indirect.rs +2 -0
  63. package/src/rust/cpu/cpu.rs +4501 -0
  64. package/src/rust/cpu/fpu.rs +923 -0
  65. package/src/rust/cpu/global_pointers.rs +112 -0
  66. package/src/rust/cpu/instructions.rs +2486 -0
  67. package/src/rust/cpu/instructions_0f.rs +5261 -0
  68. package/src/rust/cpu/ioapic.rs +316 -0
  69. package/src/rust/cpu/memory.rs +351 -0
  70. package/src/rust/cpu/misc_instr.rs +613 -0
  71. package/src/rust/cpu/mod.rs +16 -0
  72. package/src/rust/cpu/modrm.rs +133 -0
  73. package/src/rust/cpu/pic.rs +402 -0
  74. package/src/rust/cpu/sse_instr.rs +361 -0
  75. package/src/rust/cpu/string.rs +701 -0
  76. package/src/rust/cpu/vga.rs +175 -0
  77. package/src/rust/cpu_context.rs +69 -0
  78. package/src/rust/dbg.rs +98 -0
  79. package/src/rust/gen/analyzer.rs +3807 -0
  80. package/src/rust/gen/analyzer0f.rs +3992 -0
  81. package/src/rust/gen/interpreter.rs +4447 -0
  82. package/src/rust/gen/interpreter0f.rs +5404 -0
  83. package/src/rust/gen/jit.rs +5080 -0
  84. package/src/rust/gen/jit0f.rs +5547 -0
  85. package/src/rust/gen/mod.rs +14 -0
  86. package/src/rust/jit.rs +2443 -0
  87. package/src/rust/jit_instructions.rs +7881 -0
  88. package/src/rust/js_api.rs +6 -0
  89. package/src/rust/leb.rs +46 -0
  90. package/src/rust/lib.rs +29 -0
  91. package/src/rust/modrm.rs +330 -0
  92. package/src/rust/opstats.rs +249 -0
  93. package/src/rust/page.rs +15 -0
  94. package/src/rust/paging.rs +25 -0
  95. package/src/rust/prefix.rs +15 -0
  96. package/src/rust/profiler.rs +155 -0
  97. package/src/rust/regs.rs +38 -0
  98. package/src/rust/softfloat.rs +286 -0
  99. package/src/rust/state_flags.rs +27 -0
  100. package/src/rust/wasmgen/mod.rs +2 -0
  101. package/src/rust/wasmgen/wasm_builder.rs +1047 -0
  102. package/src/rust/wasmgen/wasm_opcodes.rs +221 -0
  103. package/src/rust/zstd.rs +105 -0
  104. package/src/sb16.ts +1928 -0
  105. package/src/state.ts +359 -0
  106. package/src/uart.ts +472 -0
  107. package/src/vga.ts +2791 -0
  108. package/src/virtio.ts +1756 -0
  109. package/src/virtio_balloon.ts +273 -0
  110. package/src/virtio_console.ts +372 -0
  111. package/src/virtio_net.ts +326 -0
@@ -0,0 +1,326 @@
1
+ // https://docs.oasis-open.org/virtio/virtio/v1.2/csd01/virtio-v1.2-csd01.html#x1-2900003
2
+
3
+ import { dbg_assert } from './log.js'
4
+ import { VirtIO, VIRTIO_F_VERSION_1 } from './virtio.js'
5
+ import type { VirtQueueBufferChain } from './virtio.js'
6
+ import { format_mac } from './ne2k.js'
7
+ import * as marshall from '../lib/marshall.js'
8
+ import { BusConnector } from './bus.js'
9
+
10
+ // Minimal interface for the CPU fields VirtioNet needs
11
+ interface VirtioNetCPU {
12
+ io: {
13
+ register_read(
14
+ port: number,
15
+ device: object,
16
+ r8?: ((port: number) => number) | undefined,
17
+ r16?: ((port: number) => number) | undefined,
18
+ r32?: ((port: number) => number) | undefined,
19
+ ): void
20
+ register_write(
21
+ port: number,
22
+ device: object,
23
+ w8?: ((port: number) => void) | undefined,
24
+ w16?: ((port: number) => void) | undefined,
25
+ w32?: ((port: number) => void) | undefined,
26
+ ): void
27
+ }
28
+ devices: {
29
+ pci: {
30
+ register_device(device: VirtIO): void
31
+ raise_irq(pci_id: number): void
32
+ lower_irq(pci_id: number): void
33
+ }
34
+ net?: unknown
35
+ }
36
+ read16(addr: number): number
37
+ read32s(addr: number): number
38
+ write16(addr: number, value: number): void
39
+ write32(addr: number, value: number): void
40
+ read_blob(addr: number, length: number): Uint8Array
41
+ write_blob(blob: Uint8Array, addr: number): void
42
+ zero_memory(addr: number, length: number): void
43
+ memory_size: Int32Array
44
+ }
45
+
46
+ const MTU_DEFAULT = 1500
47
+
48
+ const VIRTIO_NET_F_MAC = 5
49
+ const VIRTIO_NET_F_CTRL_VQ = 17
50
+ const VIRTIO_NET_F_STATUS = 16
51
+ const VIRTIO_NET_F_MQ = 22
52
+ const VIRTIO_NET_F_CTRL_MAC_ADDR = 23
53
+ const VIRTIO_NET_F_MTU = 3
54
+
55
+ const VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET = 0
56
+ const VIRTIO_NET_CTRL_MAC_ADDR_SET = 1
57
+
58
+ export class VirtioNet {
59
+ bus: BusConnector
60
+ id: number
61
+ pairs: number
62
+ status: number
63
+ preserve_mac_from_state_image: boolean
64
+ mac: Uint8Array
65
+ virtio: VirtIO
66
+
67
+ constructor(
68
+ cpu: VirtioNetCPU,
69
+ bus: BusConnector,
70
+ preserve_mac_from_state_image: boolean,
71
+ mtu: number = MTU_DEFAULT,
72
+ ) {
73
+ this.bus = bus
74
+ this.id = cpu.devices.net ? 1 : 0
75
+ this.pairs = 1
76
+ this.status = 1
77
+ this.preserve_mac_from_state_image = preserve_mac_from_state_image
78
+ this.mac = new Uint8Array([
79
+ 0x00,
80
+ 0x22,
81
+ 0x15,
82
+ (Math.random() * 255) | 0,
83
+ (Math.random() * 255) | 0,
84
+ (Math.random() * 255) | 0,
85
+ ])
86
+
87
+ this.bus.send('net' + this.id + '-mac', format_mac(this.mac))
88
+
89
+ const queues = []
90
+
91
+ for (let i = 0; i < this.pairs; ++i) {
92
+ queues.push({ size_supported: 1024, notify_offset: 0 })
93
+ queues.push({ size_supported: 1024, notify_offset: 1 })
94
+ }
95
+ queues.push({
96
+ size_supported: 16,
97
+ notify_offset: 2,
98
+ })
99
+
100
+ this.virtio = new VirtIO(cpu, {
101
+ name: 'virtio-net',
102
+ pci_id: 0x0a << 3,
103
+ device_id: 0x1041,
104
+ subsystem_device_id: 1,
105
+ common: {
106
+ initial_port: 0xc800,
107
+ queues: queues,
108
+ features: [
109
+ VIRTIO_NET_F_MAC,
110
+ VIRTIO_NET_F_STATUS,
111
+ VIRTIO_NET_F_MQ,
112
+ VIRTIO_NET_F_MTU,
113
+ VIRTIO_NET_F_CTRL_VQ,
114
+ VIRTIO_NET_F_CTRL_MAC_ADDR,
115
+ VIRTIO_F_VERSION_1,
116
+ ],
117
+ on_driver_ok: () => {},
118
+ },
119
+ notification: {
120
+ initial_port: 0xc900,
121
+ single_handler: false,
122
+ handlers: [
123
+ (_queue_id: number) => {},
124
+ (queue_id: number) => {
125
+ const queue = this.virtio.queues[queue_id]
126
+
127
+ while (queue.has_request()) {
128
+ const bufchain = queue.pop_request()
129
+ const buffer = new Uint8Array(
130
+ bufchain.length_readable,
131
+ )
132
+ bufchain.get_next_blob(buffer)
133
+ this.bus.send(
134
+ 'net' + this.id + '-send',
135
+ buffer.subarray(12),
136
+ )
137
+ this.bus.send('eth-transmit-end', [
138
+ buffer.length - 12,
139
+ ])
140
+ this.virtio.queues[queue_id].push_reply(bufchain)
141
+ }
142
+ this.virtio.queues[queue_id].flush_replies()
143
+ },
144
+ (queue_id: number) => {
145
+ if (queue_id !== this.pairs * 2) {
146
+ dbg_assert(
147
+ false,
148
+ 'VirtioNet Notified for wrong queue: ' +
149
+ queue_id +
150
+ ' (expected queue_id of 3)',
151
+ )
152
+ return
153
+ }
154
+ const queue = this.virtio.queues[queue_id]
155
+
156
+ while (queue.has_request()) {
157
+ const bufchain = queue.pop_request()
158
+ const buffer = new Uint8Array(
159
+ bufchain.length_readable,
160
+ )
161
+ bufchain.get_next_blob(buffer)
162
+
163
+ const parts = marshall.Unmarshall(
164
+ ['b', 'b'],
165
+ buffer,
166
+ {
167
+ offset: 0,
168
+ },
169
+ )
170
+ const xclass = parts[0]
171
+ const command = parts[1]
172
+
173
+ //this.Ack(queue_id, bufchain);
174
+
175
+ switch ((xclass << 8) | command) {
176
+ case (4 << 8) |
177
+ VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET: {
178
+ const data = marshall.Unmarshall(
179
+ ['h'],
180
+ buffer,
181
+ { offset: 2 },
182
+ )
183
+ dbg_assert(data[0] === 1)
184
+ this.Send(
185
+ queue_id,
186
+ bufchain,
187
+ new Uint8Array([0]),
188
+ )
189
+ break
190
+ }
191
+ case (1 << 8) | VIRTIO_NET_CTRL_MAC_ADDR_SET:
192
+ this.mac = buffer.subarray(2, 8)
193
+ this.Send(
194
+ queue_id,
195
+ bufchain,
196
+ new Uint8Array([0]),
197
+ )
198
+ this.bus.send(
199
+ 'net' + this.id + '-mac',
200
+ format_mac(this.mac),
201
+ )
202
+ break
203
+ default:
204
+ dbg_assert(
205
+ false,
206
+ ' VirtioNet received unknown command: ' +
207
+ xclass +
208
+ ':' +
209
+ command,
210
+ )
211
+ this.Send(
212
+ queue_id,
213
+ bufchain,
214
+ new Uint8Array([1]),
215
+ )
216
+ return
217
+ }
218
+ }
219
+ },
220
+ ],
221
+ },
222
+ isr_status: {
223
+ initial_port: 0xc700,
224
+ },
225
+ device_specific: {
226
+ initial_port: 0xc600,
227
+ struct: [0, 1, 2, 3, 4, 5]
228
+ .map((v, k) => ({
229
+ bytes: 1,
230
+ name: 'mac_' + k,
231
+ read: () => this.mac[k],
232
+ write: (_data: number) => {
233
+ /* read only */
234
+ },
235
+ }))
236
+ .concat([
237
+ {
238
+ bytes: 2,
239
+ name: 'status',
240
+ read: () => this.status,
241
+ write: (_data: number) => {
242
+ /* read only */
243
+ },
244
+ },
245
+ {
246
+ bytes: 2,
247
+ name: 'max_pairs',
248
+ read: () => this.pairs,
249
+ write: (_data: number) => {
250
+ /* read only */
251
+ },
252
+ },
253
+ {
254
+ bytes: 2,
255
+ name: 'mtu',
256
+ read: () => mtu,
257
+ write: (_data: number) => {},
258
+ },
259
+ ]),
260
+ },
261
+ })
262
+
263
+ this.bus.register(
264
+ 'net' + this.id + '-receive',
265
+ (data: any) => {
266
+ this.bus.send('eth-receive-end', [data.length])
267
+ const with_header = new Uint8Array(12 + data.byteLength)
268
+ const view = new DataView(
269
+ with_header.buffer,
270
+ with_header.byteOffset,
271
+ with_header.byteLength,
272
+ )
273
+ view.setInt16(10, 1)
274
+ with_header.set(data, 12)
275
+
276
+ const queue = this.virtio.queues[0]
277
+ if (queue.has_request()) {
278
+ const bufchain = queue.pop_request()
279
+ bufchain.set_next_blob(with_header)
280
+ this.virtio.queues[0].push_reply(bufchain)
281
+ this.virtio.queues[0].flush_replies()
282
+ } else {
283
+ console.log('No buffer to write into!')
284
+ }
285
+ },
286
+ this,
287
+ )
288
+ }
289
+
290
+ get_state(): any[] {
291
+ const state: any[] = []
292
+ state[0] = this.virtio
293
+ state[1] = this.id
294
+ state[2] = this.mac
295
+ return state
296
+ }
297
+
298
+ set_state(state: any[]): void {
299
+ this.virtio.set_state(state[0])
300
+ this.id = state[1]
301
+ if (this.preserve_mac_from_state_image) {
302
+ this.mac = state[2]
303
+ this.bus.send('net' + this.id + '-mac', format_mac(this.mac))
304
+ }
305
+ }
306
+
307
+ reset(): void {
308
+ this.virtio.reset()
309
+ }
310
+
311
+ Send(
312
+ queue_id: number,
313
+ bufchain: VirtQueueBufferChain,
314
+ blob: Uint8Array,
315
+ ): void {
316
+ bufchain.set_next_blob(blob)
317
+ this.virtio.queues[queue_id].push_reply(bufchain)
318
+ this.virtio.queues[queue_id].flush_replies()
319
+ }
320
+
321
+ Ack(queue_id: number, bufchain: VirtQueueBufferChain): void {
322
+ //bufchain.set_next_blob(new Uint8Array(0));
323
+ this.virtio.queues[queue_id].push_reply(bufchain)
324
+ this.virtio.queues[queue_id].flush_replies()
325
+ }
326
+ }