diff options
Diffstat (limited to 'patches/gnumach')
| -rw-r--r-- | patches/gnumach/50_initrd.patch | 326 | ||||
| -rw-r--r-- | patches/gnumach/79_dde-debian.patch | 274 | 
2 files changed, 600 insertions, 0 deletions
diff --git a/patches/gnumach/50_initrd.patch b/patches/gnumach/50_initrd.patch new file mode 100644 index 0000000..4b0226e --- /dev/null +++ b/patches/gnumach/50_initrd.patch @@ -0,0 +1,326 @@ +Jérémie Koenig <jk@jk.fr.eu.org> +Add ramdisk support for d-i. + +Index: gnumach/Makefrag.am +=================================================================== +--- gnumach.orig/Makefrag.am ++++ gnumach/Makefrag.am +@@ -324,6 +324,8 @@ libkernel_a_SOURCES += \ + 	device/net_io.c \ + 	device/net_io.h \ + 	device/param.h \ ++	device/ramdisk.c \ ++	device/ramdisk.h \ + 	device/subrs.c \ + 	device/subrs.h \ + 	device/tty.h +Index: gnumach/i386/i386at/conf.c +=================================================================== +--- gnumach.orig/i386/i386at/conf.c ++++ gnumach/i386/i386at/conf.c +@@ -31,6 +31,7 @@ + #include <device/conf.h> + #include <kern/mach_clock.h> + #include <i386at/model_dep.h> ++#include <device/ramdisk.h> +  + #define	timename		"time" +  +@@ -138,6 +139,8 @@ struct dev_ops	dev_name_list[] = + 	  nodev_info }, + #endif	/* MACH_HYP */ +  ++	RAMDISK_DEV_OPS, ++ + #ifdef	MACH_KMSG +         { kmsgname,     kmsgopen,       kmsgclose,       kmsgread, +           nulldev_write,        kmsggetstat,    nulldev_setstat,           nomap, +Index: gnumach/kern/boot_script.c +=================================================================== +--- gnumach.orig/kern/boot_script.c ++++ gnumach/kern/boot_script.c +@@ -90,12 +90,20 @@ prompt_resume_task (struct cmd *cmd, con +   return boot_script_prompt_task_resume (cmd); + } +  ++/* Create an initial ramdisk */ ++static int ++ramdisk_create (struct cmd *cmd, long *val) ++{ ++  return boot_script_ramdisk_create (cmd, (char **) val); ++} ++ + /* List of builtin symbols.  */ + static struct sym builtin_symbols[] = + { +   { "task-create", VAL_FUNC, (long) create_task, VAL_TASK, 0 }, +   { "task-resume", VAL_FUNC, (long) resume_task, VAL_NONE, 1 }, +   { "prompt-task-resume", VAL_FUNC, (long) prompt_resume_task, VAL_NONE, 1 }, ++  { "ramdisk-create", VAL_FUNC, (long) ramdisk_create, VAL_STR, 0 }, + }; + #define NUM_BUILTIN (sizeof (builtin_symbols) / sizeof (builtin_symbols[0])) +  +Index: gnumach/kern/bootstrap.c +=================================================================== +--- gnumach.orig/kern/bootstrap.c ++++ gnumach/kern/bootstrap.c +@@ -51,6 +51,7 @@ + #include <vm/vm_user.h> + #include <vm/pmap.h> + #include <device/device_port.h> ++#include <device/ramdisk.h> +  + #if	MACH_KDB + #include <machine/db_machdep.h> +@@ -849,6 +850,23 @@ boot_script_free (void *ptr, unsigned in + } +  + int ++boot_script_ramdisk_create (struct cmd *cmd, char **name) ++{ ++  struct multiboot_module *mod = cmd->hook; ++  vm_size_t size = mod->mod_end - mod->mod_start; ++  kern_return_t rc; ++  int no; ++ ++  rc = ramdisk_create (size, (void *) phystokv (mod->mod_start), &no); ++  if (rc != KERN_SUCCESS) ++    return BOOT_SCRIPT_MACH_ERROR; ++ ++  *name = boot_script_malloc (RAMDISK_NAMESZ); ++  sprintf(*name, RAMDISK_NAME "%d", no); ++  return 0; ++} ++ ++int + boot_script_task_create (struct cmd *cmd) + { +   kern_return_t rc = task_create_kernel(TASK_NULL, FALSE, &cmd->task); +Index: gnumach/device/ramdisk.c +=================================================================== +--- /dev/null ++++ gnumach/device/ramdisk.c +@@ -0,0 +1,160 @@ ++#include <mach/vm_param.h> ++#include <machine/vm_param.h> ++#include <vm/vm_kern.h> ++#include <vm/vm_user.h> ++#include <device/device_types.h> ++#include <device/ds_routines.h> ++#include <device/conf.h> ++#include <device/ramdisk.h> ++#include <kern/printf.h> ++#include <string.h> ++ ++static struct ramdisk { ++	void *data; ++	vm_size_t size; ++} ramdisk[RAMDISK_MAX]; ++ ++static int ramdisk_num = 0; ++ ++/* Initial ramdisks are created from the boot scripts */ ++int ramdisk_create(vm_size_t size, const void *initdata, int *out_no) ++{ ++	struct ramdisk *rd = &ramdisk[ramdisk_num]; ++	int err; ++ ++	if(ramdisk_num >= RAMDISK_MAX) ++		return -1; ++ ++	/* allocate the memory */ ++	rd->size = round_page(size); ++	err = kmem_alloc(kernel_map, (vm_offset_t *) &rd->data, rd->size); ++	if(err != KERN_SUCCESS) ++		return err; ++ ++	/* initialize */ ++	if(initdata) ++		memcpy(rd->data, initdata, rd->size); ++	else ++		memset(rd->data, 0, rd->size); ++ ++	/* report */ ++	if(out_no) *out_no = ramdisk_num; ++	printf("%s%d: %lu bytes @%p\n", RAMDISK_NAME, ramdisk_num, ++			(unsigned long) rd->size, rd->data); ++ ++	ramdisk_num++; ++	return KERN_SUCCESS; ++} ++ ++/* On d_open() we just check whether the ramdisk exists */ ++int ramdisk_open(dev_t dev, int mode, io_req_t ior) ++{ ++	return (dev < ramdisk_num) ? D_SUCCESS : D_NO_SUCH_DEVICE; ++} ++ ++/* d_getstat() is used to query the device characteristics */ ++int ramdisk_getstat(dev_t dev, dev_flavor_t flavor, dev_status_t status, ++		mach_msg_type_number_t *status_count) ++{ ++	switch(flavor) { ++		case DEV_GET_SIZE: ++			status[DEV_GET_SIZE_DEVICE_SIZE] = ramdisk[dev].size; ++			status[DEV_GET_SIZE_RECORD_SIZE] = RAMDISK_BLOCKSZ; ++			*status_count = DEV_GET_SIZE_COUNT; ++			return D_SUCCESS; ++ ++		case DEV_GET_RECORDS: ++			status[DEV_GET_RECORDS_DEVICE_RECORDS] ++					= ramdisk[dev].size / RAMDISK_BLOCKSZ; ++			status[DEV_GET_RECORDS_RECORD_SIZE] = RAMDISK_BLOCKSZ; ++			*status_count = DEV_GET_RECORDS_COUNT; ++			return D_SUCCESS; ++	} ++	return D_INVALID_OPERATION; ++} ++ ++/* TODO: implement freeramdisk with setstat() ? */ ++ ++/* Check the given io request and compute a pointer to the ramdisk data and the ++ * amount to be handled. */ ++static int ramdisk_ioreq(int dev, io_req_t ior, void **data, int *amt) ++{ ++	vm_offset_t ofs = ior->io_recnum * RAMDISK_BLOCKSZ; ++	if(ofs >= ramdisk[dev].size) ++		return D_INVALID_RECNUM; ++ ++	*data = (char*) ramdisk[dev].data + ofs; ++	*amt = ior->io_count; ++	if(ofs + *amt > ramdisk[dev].size) ++		*amt = ramdisk[dev].size - ofs; ++ ++	return KERN_SUCCESS; ++} ++ ++/* Copy data from a vm_map_copy by mapping it temporarily. */ ++static int mem_map_cpy(void *dst, vm_map_copy_t src, int amt) ++{ ++	vm_offset_t srcaddr; ++	int err; ++ ++	err = vm_map_copyout(device_io_map, &srcaddr, src); ++	if (err != KERN_SUCCESS) ++		return err; ++ ++	memcpy(dst, (void *) srcaddr, amt); ++	vm_deallocate(device_io_map, srcaddr, amt); ++	return KERN_SUCCESS; ++} ++ ++int ramdisk_read(dev_t dev, io_req_t ior) ++{ ++	void *data; ++	int amt, err; ++ ++	err = ramdisk_ioreq(dev, ior, &data, &amt); ++	if(err != KERN_SUCCESS) ++		return err; ++ ++	err = device_read_alloc (ior, ior->io_count); ++	if (err != KERN_SUCCESS) ++		return err; ++ ++	memcpy(ior->io_data, data, amt); ++	ior->io_residual = ior->io_count - amt; ++ ++	return D_SUCCESS; ++} ++ ++int ramdisk_write(dev_t dev, io_req_t ior) ++{ ++	void *data; ++	int amt, err; ++ ++	err = ramdisk_ioreq(dev, ior, &data, &amt); ++	if(err != KERN_SUCCESS) ++		return err; ++ ++	if (!(ior->io_op & IO_INBAND)) { ++		/* Out-of-band data is transmitted as a vm_map_copy */ ++		err = mem_map_cpy(data, (vm_map_copy_t) ior->io_data, amt); ++		if(err != KERN_SUCCESS) ++			return err; ++	} else { ++		/* In-band data can be accessed directly */ ++		memcpy(data, ior->io_data, amt); ++	} ++ ++	ior->io_residual = ior->io_count - amt; ++	return D_SUCCESS; ++} ++ ++vm_offset_t ramdisk_mmap(dev_t dev, vm_offset_t off, vm_prot_t prot) ++{ ++	if(dev >= ramdisk_num) ++		return -1; ++	if(off >= ramdisk[dev].size) ++		return -1; ++ ++	return pmap_phys_to_frame(kvtophys((vm_offset_t) ramdisk[dev].data + off)); ++} ++ +Index: gnumach/device/ramdisk.h +=================================================================== +--- /dev/null ++++ gnumach/device/ramdisk.h +@@ -0,0 +1,47 @@ ++#ifndef _KERN_RAMDISK_H_ ++#define _KERN_RAMDISK_H_ ++ ++#include <vm/pmap.h> ++#include <device/io_req.h> ++#include <device/conf.h> ++ ++/* Maximum number of ramdisk devices */ ++#define RAMDISK_MAX 4 ++ ++/* The block size used (userspace requires 512) */ ++#define RAMDISK_BLOCKSZ 512 ++ ++/* Name associated to the ramdisk major */ ++#define RAMDISK_NAME "rd" ++#define RAMDISK_NAMESZ (sizeof RAMDISK_NAME + sizeof (int) * 3 + 1) ++ ++/* Create a new ramdisk of the given size. On success, if out_no and/or out_ptr ++ * are not NULL, the device number and pointer to the ramdisk's data are stored ++ * there. Returns D_SUCCESS or D_NO_MEMORY.  */ ++int ramdisk_create(vm_size_t size, const void *initdata, int *out_no); ++ ++/* Device operations */ ++int ramdisk_open(dev_t, int, io_req_t); ++int ramdisk_getstat(dev_t, dev_flavor_t, dev_status_t, mach_msg_type_number_t *); ++int ramdisk_read(dev_t, io_req_t); ++int ramdisk_write(dev_t, io_req_t); ++vm_offset_t ramdisk_mmap(dev_t, vm_offset_t, vm_prot_t); ++ ++/* dev_ops initializer to be used from <machine>/conf.c */ ++#define RAMDISK_DEV_OPS { \ ++		.d_name = RAMDISK_NAME, \ ++		.d_open = ramdisk_open, \ ++		.d_close = nulldev_close, \ ++		.d_read = ramdisk_read, \ ++		.d_write = ramdisk_write, \ ++		.d_getstat = ramdisk_getstat, \ ++		.d_setstat = nulldev_setstat, \ ++		.d_mmap = ramdisk_mmap, \ ++		.d_async_in = nodev_async_in, \ ++		.d_reset = nulldev_reset, \ ++		.d_port_death = nulldev_portdeath, \ ++		.d_subdev = 0, \ ++		.d_dev_info = nodev_info, \ ++	} ++ ++#endif +Index: gnumach/kern/bootstrap.h +=================================================================== +--- gnumach.orig/kern/bootstrap.h ++++ gnumach/kern/bootstrap.h +@@ -22,5 +22,6 @@ + #include <kern/boot_script.h> +  + void bootstrap_create(void); ++int boot_script_ramdisk_create(struct cmd *cmd, char **name); +  + #endif /* _KERN_BOOTSTRAP_H_ */ diff --git a/patches/gnumach/79_dde-debian.patch b/patches/gnumach/79_dde-debian.patch new file mode 100644 index 0000000..b6a0f17 --- /dev/null +++ b/patches/gnumach/79_dde-debian.patch @@ -0,0 +1,274 @@ +This contains a compatibility layer for netdde and rump still using the experimental irq/alloc_contig support. It is the output of + +git diff master master-user_level_drivers-debian + +(master was 6054cda4de2341b9a77ec4421411725f3684006b and +master-user_level_drivers-debian was 19283fdffa782b2e485ef39e0de1574006ec4a1a at +the time) + +When dropping this, break netdde (<< 0.0.20200330-5), +hurd-libs0.3 (<< hurd_1:0.9.git20200718-1+b1) + +--- + Makefrag.am                     |    1  + device/ds_routines.c            |   64 +++++++++++++++++++++++++++++++++++++++- + device/intr.c                   |   16 ++++++---- + device/intr.h                   |    3 + + include/mach/experimental.defs  |   38 +++++++++++++++++++++++ + linux/dev/drivers/block/genhd.c |    4 +- + vm/vm_user.c                    |   14 ++++++++ + 7 files changed, 130 insertions(+), 10 deletions(-) + +--- a/Makefrag.am ++++ b/Makefrag.am +@@ -362,7 +362,6 @@ include_device_HEADERS = \ + 	include/device/disk_status.h \ + 	include/device/input.h \ + 	include/device/net_status.h \ +-	include/device/notify.defs \ + 	include/device/notify.h \ + 	include/device/tape_status.h \ + 	include/device/tty_status.h +--- a/device/ds_routines.c ++++ b/device/ds_routines.c +@@ -354,7 +354,7 @@ ds_device_intr_register (device_t dev, i +   if (! name_equal(mdev->dev_ops->d_name, 3, "irq")) +     return D_INVALID_OPERATION; +  +-  user_intr_t *e = insert_intr_entry (&irqtab, id, receive_port); ++  user_intr_t *e = insert_intr_entry (&irqtab, id, receive_port, 0); +   if (!e) +     return D_NO_MEMORY; +  +@@ -371,6 +371,52 @@ ds_device_intr_register (device_t dev, i + #endif /* MACH_XEN */ + } +  ++static ipc_port_t intr_receive_ports[16]; ++io_return_t ++experimental_device_intr_register (ipc_port_t master_port, int line, ++		       int id, int flags, ipc_port_t receive_port) ++{ ++#ifdef MACH_XEN ++  return D_INVALID_OPERATION; ++#else /* MACH_XEN */ ++  io_return_t ret; ++  /* Open must be called on the master device port.  */ ++  if (master_port != master_device_port) ++    return D_INVALID_OPERATION; ++ ++  /* XXX: move to arch-specific */ ++  if (line < 0 || line >= 16) ++    return D_INVALID_OPERATION; ++ ++  if (flags != 0x04000000) ++    return D_INVALID_OPERATION; ++ ++  user_intr_t *user_intr = insert_intr_entry (&irqtab, line, receive_port, 1); ++  if (!user_intr) ++    return D_NO_MEMORY; ++ ++  // TODO The original port should be replaced ++  // when the same device driver calls it again, ++  // in order to handle the case that the device driver crashes and restarts. ++  ret = install_user_intr_handler (&irqtab, line, 0, user_intr); ++ ++  if (ret == 0) ++  { ++    /* If the port is installed successfully, increase its reference by 1. ++     * Thus, the port won't be destroyed after its task is terminated. */ ++    ip_reference (receive_port); ++ ++    intr_receive_ports[line] = receive_port; ++    /* For now netdde calls device_intr_enable once after registration. Assume ++     * it does so for now. When we move to IRQ acknowledgment convention we will ++     * change this. */ ++    __disable_irq (line); ++  } ++ ++  return ret; ++#endif /* MACH_XEN */ ++} ++ + kern_return_t + ds_device_intr_ack (device_t dev, ipc_port_t receive_port) + { +@@ -399,6 +445,22 @@ ds_device_intr_ack (device_t dev, ipc_po + #endif /* MACH_XEN */ + } +  ++kern_return_t ++experimental_device_intr_enable(ipc_port_t master_port, int line, char status) ++{ ++#ifdef MACH_XEN ++  return D_INVALID_OPERATION; ++#else /* MACH_XEN */ ++  if (master_port != master_device_port) ++    return D_INVALID_OPERATION; ++ ++  if (status != 1) ++    return D_INVALID_OPERATION; ++ ++  return irq_acknowledge(intr_receive_ports[line]); ++#endif /* MACH_XEN */ ++} ++ + boolean_t + ds_notify (mach_msg_header_t *msg) + { +--- a/device/intr.c ++++ b/device/intr.c +@@ -25,7 +25,7 @@ + #ifndef MACH_XEN +  + queue_head_t main_intr_queue; +-static boolean_t deliver_intr (int id, ipc_port_t dst_port); ++static boolean_t deliver_intr (int id, mach_msg_id_t msgh_id, ipc_port_t dst_port); +  + #ifndef LINUX_DEV + #define SA_SHIRQ 0x04000000 +@@ -122,7 +122,7 @@ deliver_user_intr (struct irqdev *dev, i +  * This entry exists in the queue until +  * the corresponding interrupt port is removed.*/ + user_intr_t * +-insert_intr_entry (struct irqdev *dev, int id, ipc_port_t dst_port) ++insert_intr_entry (struct irqdev *dev, int id, ipc_port_t dst_port, int compat) + { +   user_intr_t *e, *new, *ret; +   int free = 0; +@@ -146,7 +146,11 @@ insert_intr_entry (struct irqdev *dev, i +   new->id = id; +   new->dst_port = dst_port; +   new->interrupts = 0; +-  new->n_unacked = 0; ++  new->compat = compat; ++  if (compat) ++    new->n_unacked = 1; ++  else ++    new->n_unacked = 0; +  +   queue_enter (dev->intr_queue, new, user_intr_t *, chain); + out: +@@ -268,7 +272,7 @@ intr_thread (void) + 		  irqtab.tot_num_intr--; +  + 		  splx (s); +-		  deliver_intr (id, dst_port); ++		  deliver_intr (id, e->compat ? 424242 : DEVICE_INTR_NOTIFY, dst_port); + 		  s = splhigh (); + 		} + 	    } +@@ -307,7 +311,7 @@ intr_thread (void) + } +  + static boolean_t +-deliver_intr (int id, ipc_port_t dst_port) ++deliver_intr (int id, mach_msg_id_t msgh_id, ipc_port_t dst_port) + { +   ipc_kmsg_t kmsg; +   device_intr_notification_t *n; +@@ -331,7 +335,7 @@ deliver_intr (int id, ipc_port_t dst_por +   m->msgh_seqno = DEVICE_NOTIFY_MSGH_SEQNO; +   m->msgh_local_port = MACH_PORT_NULL; +   m->msgh_remote_port = MACH_PORT_NULL; +-  m->msgh_id = DEVICE_INTR_NOTIFY; ++  m->msgh_id = msgh_id; +  +   t->msgt_name = MACH_MSG_TYPE_INTEGER_32; +   t->msgt_size = 32; +--- a/device/intr.h ++++ b/device/intr.h +@@ -36,6 +36,7 @@ typedef struct { +   int n_unacked;  /* Number of times irqs were disabled for this */ +   ipc_port_t dst_port; /* Notification port */ +   int id; /* Mapping to machine dependent irq_t array elem */ ++  int compat; + } user_intr_t; +  + struct irqdev { +@@ -52,7 +53,7 @@ struct irqdev { + extern queue_head_t main_intr_queue; + extern int install_user_intr_handler (struct irqdev *dev, int id, unsigned long flags, user_intr_t *e); + extern int deliver_user_intr (struct irqdev *dev, int id, user_intr_t *e); +-extern user_intr_t *insert_intr_entry (struct irqdev *dev, int id, ipc_port_t receive_port); ++extern user_intr_t *insert_intr_entry (struct irqdev *dev, int id, ipc_port_t receive_port, int compat); +  + void intr_thread (void); + kern_return_t irq_acknowledge (ipc_port_t receive_port); +--- a/include/mach/experimental.defs ++++ b/include/mach/experimental.defs +@@ -13,3 +13,41 @@ subsystem + serverprefix experimental_; +  + /* This is free for experimenting RPCs, with no backward compatibility guarantees.  */ ++ ++type notify_port_t = MACH_MSG_TYPE_MOVE_SEND_ONCE ++	ctype: mach_port_t; ++ ++skip; /*simpleroutine mach_intr_notify( ++		notify	: notify_port_t; ++		name	: int);*/ ++ ++routine device_intr_register( ++		master_port	: mach_port_t; ++	in	line		: int; ++	in	id		: int; ++	in	flags		: int; ++	in	receive_port	: mach_port_send_t ++	); ++ ++/* ++ *	enable/disable the specified line. ++ */ ++/* XXX: Naming a function taht can disable something "xxx_enable" is confusing. */ ++/* Is the disable part actually used at all? AIUI, the kernel IRQ handler ++should always disable the line; and the userspace driver only has to ++reenable it, after acknowledging and handling the interrupt... ++*/ ++routine device_intr_enable( ++		master_port	: mach_port_t; ++		line		: int; ++		status		: char); ++ ++/* ++ *	This routine is for compatibility with old userland drivers. ++ */ ++routine vm_allocate_contiguous( ++		host_priv	: host_priv_t; ++		target_task	: vm_task_t; ++	out	vaddr		: vm_address_t; ++	out	paddr		: vm_address_t; ++		size		: vm_size_t); +--- a/linux/dev/drivers/block/genhd.c ++++ b/linux/dev/drivers/block/genhd.c +@@ -1060,7 +1060,9 @@ void device_setup(void) + 	scsi_dev_init(); + #endif + #ifdef CONFIG_INET +-	net_dev_init(); ++	extern char *kernel_cmdline; ++	if (!strstr(kernel_cmdline, " nonetdev")) ++		net_dev_init(); + #endif + #ifndef MACH + 	console_map_init(); +--- a/vm/vm_user.c ++++ b/vm/vm_user.c +@@ -688,3 +688,17 @@ kern_return_t vm_allocate_contiguous( +  + 	return KERN_SUCCESS; + } ++ ++kern_return_t experimental_vm_allocate_contiguous(host_priv, map, result_vaddr, result_paddr, size) ++	host_t			host_priv; ++	vm_map_t		map; ++	vm_address_t		*result_vaddr; ++	vm_address_t		*result_paddr; ++	vm_size_t		size; ++{ ++	rpc_phys_addr_t paddr; ++	kern_return_t ret; ++	ret = vm_allocate_contiguous(host_priv, map, result_vaddr, &paddr, size, 0, ~0ULL, 0); ++	*result_paddr = paddr; ++	return ret; ++}  | 
