rp2040js 0.16.0 → 0.17.1

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.
@@ -11,6 +11,27 @@ const logging_1 = require("../utils/logging");
11
11
  const gdb_utils_1 = require("./gdb-utils");
12
12
  exports.STOP_REPLY_SIGINT = 'S02';
13
13
  exports.STOP_REPLY_TRAP = 'S05';
14
+ /* string value: armv6m-none-unknown-eabi */
15
+ const lldbTriple = '61726d76366d2d6e6f6e652d756e6b6e6f776e2d65616269';
16
+ const registers = [
17
+ `name:r0;bitsize:32;offset:0;encoding:int;format:hex;set:General Purpose Registers;generic:arg1;gcc:0;dwarf:0;`,
18
+ `name:r1;bitsize:32;offset:4;encoding:int;format:hex;set:General Purpose Registers;generic:arg2;gcc:1;dwarf:1;`,
19
+ `name:r2;bitsize:32;offset:8;encoding:int;format:hex;set:General Purpose Registers;generic:arg3;gcc:2;dwarf:2;`,
20
+ `name:r3;bitsize:32;offset:12;encoding:int;format:hex;set:General Purpose Registers;generic:arg4;gcc:3;dwarf:3;`,
21
+ `name:r4;bitsize:32;offset:16;encoding:int;format:hex;set:General Purpose Registers;gcc:4;dwarf:4;`,
22
+ `name:r5;bitsize:32;offset:20;encoding:int;format:hex;set:General Purpose Registers;gcc:5;dwarf:5;`,
23
+ `name:r6;bitsize:32;offset:24;encoding:int;format:hex;set:General Purpose Registers;gcc:6;dwarf:6;`,
24
+ `name:r7;bitsize:32;offset:28;encoding:int;format:hex;set:General Purpose Registers;gcc:7;dwarf:7;`,
25
+ `name:r8;bitsize:32;offset:32;encoding:int;format:hex;set:General Purpose Registers;gcc:8;dwarf:8;`,
26
+ `name:r9;bitsize:32;offset:36;encoding:int;format:hex;set:General Purpose Registers;gcc:9;dwarf:9;`,
27
+ `name:r10;bitsize:32;offset:40;encoding:int;format:hex;set:General Purpose Registers;gcc:10;dwarf:10;`,
28
+ `name:r11;bitsize:32;offset:44;encoding:int;format:hex;set:General Purpose Registers;generic:fp;gcc:11;dwarf:11;`,
29
+ `name:r12;bitsize:32;offset:48;encoding:int;format:hex;set:General Purpose Registers;gcc:12;dwarf:12;`,
30
+ `name:sp;bitsize:32;offset:52;encoding:int;format:hex;set:General Purpose Registers;generic:sp;alt-name:r13;gcc:13;dwarf:13;`,
31
+ `name:lr;bitsize:32;offset:56;encoding:int;format:hex;set:General Purpose Registers;generic:ra;alt-name:r14;gcc:14;dwarf:14;`,
32
+ `name:pc;bitsize:32;offset:60;encoding:int;format:hex;set:General Purpose Registers;generic:pc;alt-name:r15;gcc:15;dwarf:15;`,
33
+ `name:cpsr;bitsize:32;offset:64;encoding:int;format:hex;set:General Purpose Registers;generic:flags;alt-name:psr;gcc:16;dwarf:16;`,
34
+ ];
14
35
  const targetXML = `<?xml version="1.0"?>
15
36
  <!DOCTYPE target SYSTEM "gdb-target.dtd">
16
37
  <target version="1.0">
@@ -70,6 +91,22 @@ class GDBServer {
70
91
  if (cmd.startsWith('qXfer:features:read:target.xml')) {
71
92
  return gdb_utils_1.gdbMessage('l' + targetXML);
72
93
  }
94
+ if (cmd.startsWith('qRegisterInfo')) {
95
+ const index = parseInt(cmd.substring(13), 16);
96
+ const register = registers[index];
97
+ if (register) {
98
+ return gdb_utils_1.gdbMessage(register);
99
+ }
100
+ else {
101
+ return gdb_utils_1.gdbMessage(`E45`);
102
+ }
103
+ }
104
+ if (cmd === 'qHostInfo') {
105
+ return gdb_utils_1.gdbMessage(`triple:${lldbTriple};endian:little;ptrsize:4;`);
106
+ }
107
+ if (cmd === 'qProcessInfo') {
108
+ return gdb_utils_1.gdbMessage('pid:1;endian:little;ptrsize:4;');
109
+ }
73
110
  return gdb_utils_1.gdbMessage('');
74
111
  case 'v':
75
112
  if (cmd === 'vCont?') {
@@ -83,14 +120,19 @@ class GDBServer {
83
120
  }
84
121
  if (cmd.startsWith('vCont;s')) {
85
122
  rp2040.step();
86
- return gdb_utils_1.gdbMessage(exports.STOP_REPLY_TRAP);
123
+ const registerStatus = [];
124
+ for (let i = 0; i < 17; i++) {
125
+ const value = i === 16 ? core.xPSR : core.registers[i];
126
+ registerStatus.push(`${gdb_utils_1.encodeHexByte(i)}:${gdb_utils_1.encodeHexUint32(value)}`);
127
+ }
128
+ return gdb_utils_1.gdbMessage(`T05${registerStatus.join(';')};reason:trace;`);
87
129
  }
88
130
  break;
89
131
  case 'c':
90
132
  if (!rp2040.executing) {
91
133
  rp2040.execute();
92
134
  }
93
- break;
135
+ return gdb_utils_1.gdbMessage('OK');
94
136
  case 'g': {
95
137
  // Read registers
96
138
  const buf = new Uint32Array(17);
@@ -102,8 +102,8 @@ class Interpolator {
102
102
  const sclamp0 = bit_1.s32(result0) < bit_1.s32(this.base0) ? this.base0 : (bit_1.s32(result0) > bit_1.s32(this.base1) ? this.base1 : result0);
103
103
  const clamp0 = ctrl0.signed ? sclamp0 : uclamp0;
104
104
  const alpha1 = result1 & 0xff;
105
- const ublend1 = bit_1.u32(this.base0) + (((alpha1 * (bit_1.u32(this.base1) - bit_1.u32(this.base0))) / 256) | 0);
106
- const sblend1 = bit_1.s32(this.base0) + (((alpha1 * (bit_1.s32(this.base1) - bit_1.s32(this.base0))) / 256) | 0);
105
+ const ublend1 = bit_1.u32(this.base0) + (Math.floor((alpha1 * (bit_1.u32(this.base1) - bit_1.u32(this.base0))) / 256) | 0);
106
+ const sblend1 = bit_1.s32(this.base0) + (Math.floor((alpha1 * (bit_1.s32(this.base1) - bit_1.s32(this.base0))) / 256) | 0);
107
107
  const blend1 = ctrl1.signed ? sblend1 : ublend1;
108
108
  this.smresult0 = bit_1.u32(result0);
109
109
  this.smresult1 = bit_1.u32(result1);
@@ -0,0 +1,4 @@
1
+ import { BasePeripheral, Peripheral } from './peripheral';
2
+ export declare class RP2040SysInfo extends BasePeripheral implements Peripheral {
3
+ readUint32(offset: number): number;
4
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RP2040SysInfo = void 0;
4
+ const peripheral_1 = require("./peripheral");
5
+ const CHIP_ID = 0;
6
+ const PLATFORM = 0x4;
7
+ const GITREF_RP2040 = 0x40;
8
+ class RP2040SysInfo extends peripheral_1.BasePeripheral {
9
+ readUint32(offset) {
10
+ // All the values here were verified against the silicon
11
+ switch (offset) {
12
+ case CHIP_ID:
13
+ return 0x10002927;
14
+ case PLATFORM:
15
+ return 0x00000002;
16
+ case GITREF_RP2040:
17
+ return 0xe0c912e8;
18
+ }
19
+ return super.readUint32(offset);
20
+ }
21
+ }
22
+ exports.RP2040SysInfo = RP2040SysInfo;
@@ -20,6 +20,7 @@ const rtc_1 = require("./peripherals/rtc");
20
20
  const spi_1 = require("./peripherals/spi");
21
21
  const ssi_1 = require("./peripherals/ssi");
22
22
  const syscfg_1 = require("./peripherals/syscfg");
23
+ const sysinfo_1 = require("./peripherals/sysinfo");
23
24
  const timer_1 = require("./peripherals/timer");
24
25
  const uart_1 = require("./peripherals/uart");
25
26
  const usb_1 = require("./peripherals/usb");
@@ -107,7 +108,7 @@ class RP2040 {
107
108
  this.executeTimer = null;
108
109
  this.peripherals = {
109
110
  0x18000: new ssi_1.RPSSI(this, 'SSI'),
110
- 0x40000: new peripheral_1.UnimplementedPeripheral(this, 'SYSINFO_BASE'),
111
+ 0x40000: new sysinfo_1.RP2040SysInfo(this, 'SYSINFO_BASE'),
111
112
  0x40004: new syscfg_1.RP2040SysCfg(this, 'SYSCFG'),
112
113
  0x40008: new clocks_1.RPClocks(this, 'CLOCKS_BASE'),
113
114
  0x4000c: new reset_1.RPReset(this, 'RESETS_BASE'),
@@ -8,6 +8,27 @@ import { ConsoleLogger, LogLevel } from '../utils/logging';
8
8
  import { decodeHexBuf, encodeHexBuf, encodeHexByte, encodeHexUint32, gdbMessage, } from './gdb-utils';
9
9
  export const STOP_REPLY_SIGINT = 'S02';
10
10
  export const STOP_REPLY_TRAP = 'S05';
11
+ /* string value: armv6m-none-unknown-eabi */
12
+ const lldbTriple = '61726d76366d2d6e6f6e652d756e6b6e6f776e2d65616269';
13
+ const registers = [
14
+ `name:r0;bitsize:32;offset:0;encoding:int;format:hex;set:General Purpose Registers;generic:arg1;gcc:0;dwarf:0;`,
15
+ `name:r1;bitsize:32;offset:4;encoding:int;format:hex;set:General Purpose Registers;generic:arg2;gcc:1;dwarf:1;`,
16
+ `name:r2;bitsize:32;offset:8;encoding:int;format:hex;set:General Purpose Registers;generic:arg3;gcc:2;dwarf:2;`,
17
+ `name:r3;bitsize:32;offset:12;encoding:int;format:hex;set:General Purpose Registers;generic:arg4;gcc:3;dwarf:3;`,
18
+ `name:r4;bitsize:32;offset:16;encoding:int;format:hex;set:General Purpose Registers;gcc:4;dwarf:4;`,
19
+ `name:r5;bitsize:32;offset:20;encoding:int;format:hex;set:General Purpose Registers;gcc:5;dwarf:5;`,
20
+ `name:r6;bitsize:32;offset:24;encoding:int;format:hex;set:General Purpose Registers;gcc:6;dwarf:6;`,
21
+ `name:r7;bitsize:32;offset:28;encoding:int;format:hex;set:General Purpose Registers;gcc:7;dwarf:7;`,
22
+ `name:r8;bitsize:32;offset:32;encoding:int;format:hex;set:General Purpose Registers;gcc:8;dwarf:8;`,
23
+ `name:r9;bitsize:32;offset:36;encoding:int;format:hex;set:General Purpose Registers;gcc:9;dwarf:9;`,
24
+ `name:r10;bitsize:32;offset:40;encoding:int;format:hex;set:General Purpose Registers;gcc:10;dwarf:10;`,
25
+ `name:r11;bitsize:32;offset:44;encoding:int;format:hex;set:General Purpose Registers;generic:fp;gcc:11;dwarf:11;`,
26
+ `name:r12;bitsize:32;offset:48;encoding:int;format:hex;set:General Purpose Registers;gcc:12;dwarf:12;`,
27
+ `name:sp;bitsize:32;offset:52;encoding:int;format:hex;set:General Purpose Registers;generic:sp;alt-name:r13;gcc:13;dwarf:13;`,
28
+ `name:lr;bitsize:32;offset:56;encoding:int;format:hex;set:General Purpose Registers;generic:ra;alt-name:r14;gcc:14;dwarf:14;`,
29
+ `name:pc;bitsize:32;offset:60;encoding:int;format:hex;set:General Purpose Registers;generic:pc;alt-name:r15;gcc:15;dwarf:15;`,
30
+ `name:cpsr;bitsize:32;offset:64;encoding:int;format:hex;set:General Purpose Registers;generic:flags;alt-name:psr;gcc:16;dwarf:16;`,
31
+ ];
11
32
  const targetXML = `<?xml version="1.0"?>
12
33
  <!DOCTYPE target SYSTEM "gdb-target.dtd">
13
34
  <target version="1.0">
@@ -67,6 +88,22 @@ export class GDBServer {
67
88
  if (cmd.startsWith('qXfer:features:read:target.xml')) {
68
89
  return gdbMessage('l' + targetXML);
69
90
  }
91
+ if (cmd.startsWith('qRegisterInfo')) {
92
+ const index = parseInt(cmd.substring(13), 16);
93
+ const register = registers[index];
94
+ if (register) {
95
+ return gdbMessage(register);
96
+ }
97
+ else {
98
+ return gdbMessage(`E45`);
99
+ }
100
+ }
101
+ if (cmd === 'qHostInfo') {
102
+ return gdbMessage(`triple:${lldbTriple};endian:little;ptrsize:4;`);
103
+ }
104
+ if (cmd === 'qProcessInfo') {
105
+ return gdbMessage('pid:1;endian:little;ptrsize:4;');
106
+ }
70
107
  return gdbMessage('');
71
108
  case 'v':
72
109
  if (cmd === 'vCont?') {
@@ -80,14 +117,19 @@ export class GDBServer {
80
117
  }
81
118
  if (cmd.startsWith('vCont;s')) {
82
119
  rp2040.step();
83
- return gdbMessage(STOP_REPLY_TRAP);
120
+ const registerStatus = [];
121
+ for (let i = 0; i < 17; i++) {
122
+ const value = i === 16 ? core.xPSR : core.registers[i];
123
+ registerStatus.push(`${encodeHexByte(i)}:${encodeHexUint32(value)}`);
124
+ }
125
+ return gdbMessage(`T05${registerStatus.join(';')};reason:trace;`);
84
126
  }
85
127
  break;
86
128
  case 'c':
87
129
  if (!rp2040.executing) {
88
130
  rp2040.execute();
89
131
  }
90
- break;
132
+ return gdbMessage('OK');
91
133
  case 'g': {
92
134
  // Read registers
93
135
  const buf = new Uint32Array(17);
@@ -98,8 +98,8 @@ export class Interpolator {
98
98
  const sclamp0 = s32(result0) < s32(this.base0) ? this.base0 : (s32(result0) > s32(this.base1) ? this.base1 : result0);
99
99
  const clamp0 = ctrl0.signed ? sclamp0 : uclamp0;
100
100
  const alpha1 = result1 & 0xff;
101
- const ublend1 = u32(this.base0) + (((alpha1 * (u32(this.base1) - u32(this.base0))) / 256) | 0);
102
- const sblend1 = s32(this.base0) + (((alpha1 * (s32(this.base1) - s32(this.base0))) / 256) | 0);
101
+ const ublend1 = u32(this.base0) + (Math.floor((alpha1 * (u32(this.base1) - u32(this.base0))) / 256) | 0);
102
+ const sblend1 = s32(this.base0) + (Math.floor((alpha1 * (s32(this.base1) - s32(this.base0))) / 256) | 0);
103
103
  const blend1 = ctrl1.signed ? sblend1 : ublend1;
104
104
  this.smresult0 = u32(result0);
105
105
  this.smresult1 = u32(result1);
@@ -0,0 +1,4 @@
1
+ import { BasePeripheral, Peripheral } from './peripheral';
2
+ export declare class RP2040SysInfo extends BasePeripheral implements Peripheral {
3
+ readUint32(offset: number): number;
4
+ }
@@ -0,0 +1,18 @@
1
+ import { BasePeripheral } from './peripheral';
2
+ const CHIP_ID = 0;
3
+ const PLATFORM = 0x4;
4
+ const GITREF_RP2040 = 0x40;
5
+ export class RP2040SysInfo extends BasePeripheral {
6
+ readUint32(offset) {
7
+ // All the values here were verified against the silicon
8
+ switch (offset) {
9
+ case CHIP_ID:
10
+ return 0x10002927;
11
+ case PLATFORM:
12
+ return 0x00000002;
13
+ case GITREF_RP2040:
14
+ return 0xe0c912e8;
15
+ }
16
+ return super.readUint32(offset);
17
+ }
18
+ }
@@ -17,6 +17,7 @@ import { RP2040RTC } from './peripherals/rtc';
17
17
  import { RPSPI } from './peripherals/spi';
18
18
  import { RPSSI } from './peripherals/ssi';
19
19
  import { RP2040SysCfg } from './peripherals/syscfg';
20
+ import { RP2040SysInfo } from './peripherals/sysinfo';
20
21
  import { RPTimer } from './peripherals/timer';
21
22
  import { RPUART } from './peripherals/uart';
22
23
  import { RPUSBController } from './peripherals/usb';
@@ -104,7 +105,7 @@ export class RP2040 {
104
105
  this.executeTimer = null;
105
106
  this.peripherals = {
106
107
  0x18000: new RPSSI(this, 'SSI'),
107
- 0x40000: new UnimplementedPeripheral(this, 'SYSINFO_BASE'),
108
+ 0x40000: new RP2040SysInfo(this, 'SYSINFO_BASE'),
108
109
  0x40004: new RP2040SysCfg(this, 'SYSCFG'),
109
110
  0x40008: new RPClocks(this, 'CLOCKS_BASE'),
110
111
  0x4000c: new RPReset(this, 'RESETS_BASE'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rp2040js",
3
- "version": "0.16.0",
3
+ "version": "0.17.1",
4
4
  "description": "Raspberry Pi Pico (RP2040) Emulator",
5
5
  "repository": "https://github.com/wokwi/rp2040js",
6
6
  "keywords": [